|
@@ -10,7 +10,7 @@
|
|
|
* (localStorage, indexedDB).
|
|
|
*/
|
|
|
|
|
|
-import { createStore, keys, del, getMany, set } from "idb-keyval";
|
|
|
+import { createStore, entries, del, getMany, set, setMany } from "idb-keyval";
|
|
|
import { clearAppStateForLocalStorage } from "../../appState";
|
|
|
import { clearElementsForLocalStorage } from "../../element";
|
|
|
import { ExcalidrawElement, FileId } from "../../element/types";
|
|
@@ -25,12 +25,21 @@ const filesStore = createStore("files-db", "files-store");
|
|
|
|
|
|
class LocalFileManager extends FileManager {
|
|
|
clearObsoleteFiles = async (opts: { currentFileIds: FileId[] }) => {
|
|
|
- const allIds = await keys(filesStore);
|
|
|
- for (const id of allIds) {
|
|
|
- if (!opts.currentFileIds.includes(id as FileId)) {
|
|
|
- del(id, filesStore);
|
|
|
+ await entries(filesStore).then((entries) => {
|
|
|
+ for (const [id, imageData] of entries as [FileId, BinaryFileData][]) {
|
|
|
+ // if image is unused (not on canvas) & is older than 1 day, delete it
|
|
|
+ // from storage. We check `lastRetrieved` we care about the last time
|
|
|
+ // the image was used (loaded on canvas), not when it was initially
|
|
|
+ // created.
|
|
|
+ if (
|
|
|
+ (!imageData.lastRetrieved ||
|
|
|
+ Date.now() - imageData.lastRetrieved > 24 * 3600 * 1000) &&
|
|
|
+ !opts.currentFileIds.includes(id as FileId)
|
|
|
+ ) {
|
|
|
+ del(id, filesStore);
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
+ });
|
|
|
};
|
|
|
}
|
|
|
|
|
@@ -111,18 +120,33 @@ export class LocalData {
|
|
|
static fileStorage = new LocalFileManager({
|
|
|
getFiles(ids) {
|
|
|
return getMany(ids, filesStore).then(
|
|
|
- (filesData: (BinaryFileData | undefined)[]) => {
|
|
|
+ async (filesData: (BinaryFileData | undefined)[]) => {
|
|
|
const loadedFiles: BinaryFileData[] = [];
|
|
|
const erroredFiles = new Map<FileId, true>();
|
|
|
+
|
|
|
+ const filesToSave: [FileId, BinaryFileData][] = [];
|
|
|
+
|
|
|
filesData.forEach((data, index) => {
|
|
|
const id = ids[index];
|
|
|
if (data) {
|
|
|
- loadedFiles.push(data);
|
|
|
+ const _data: BinaryFileData = {
|
|
|
+ ...data,
|
|
|
+ lastRetrieved: Date.now(),
|
|
|
+ };
|
|
|
+ filesToSave.push([id, _data]);
|
|
|
+ loadedFiles.push(_data);
|
|
|
} else {
|
|
|
erroredFiles.set(id, true);
|
|
|
}
|
|
|
});
|
|
|
|
|
|
+ try {
|
|
|
+ // save loaded files back to storage with updated `lastRetrieved`
|
|
|
+ setMany(filesToSave, filesStore);
|
|
|
+ } catch (error) {
|
|
|
+ console.warn(error);
|
|
|
+ }
|
|
|
+
|
|
|
return { loadedFiles, erroredFiles };
|
|
|
},
|
|
|
);
|