stamp now uses indexed DB for resources

Signed-off-by: Victor Seiji Hariki <victorseijih@gmail.com>
This commit is contained in:
Victor Seiji Hariki 2022-12-12 10:03:05 -03:00
parent f279c8457b
commit b71731b7ca

View file

@ -92,16 +92,30 @@ const stampTool = () =>
if (state.loaded) state.movecb(state.lastMouseMove); if (state.loaded) state.movecb(state.lastMouseMove);
}; };
// Open IndexedDB connection
const IDBOpenRequest = window.indexedDB.open("stamp", 1);
// Synchronizes resources array with the DOM and Local Storage // Synchronizes resources array with the DOM and Local Storage
const syncResources = () => { const syncResources = () => {
// Saves to local storage // Saves to IndexedDB
/** @type {IDBDatabase} */
const db = state.stampDB;
const resources = db
.transaction("resources", "readwrite")
.objectStore("resources");
try { try {
localStorage.setItem( const FetchKeysQuery = resources.getAllKeys();
"tools.stamp.resources", FetchKeysQuery.onsuccess = () => {
JSON.stringify( const keys = FetchKeysQuery.result;
keys.forEach((key) => {
if (!state.resources.find((resource) => resource.id === key))
resources.delete(key);
});
};
state.resources state.resources
.filter((resource) => !resource.temporary) .filter((resource) => !resource.temporary && resource.dirty)
.map((resource) => { .forEach((resource) => {
const canvas = document.createElement("canvas"); const canvas = document.createElement("canvas");
canvas.width = resource.image.width; canvas.width = resource.image.width;
canvas.height = resource.image.height; canvas.height = resource.image.height;
@ -109,17 +123,17 @@ const stampTool = () =>
const ctx = canvas.getContext("2d"); const ctx = canvas.getContext("2d");
ctx.drawImage(resource.image, 0, 0); ctx.drawImage(resource.image, 0, 0);
return { resources.put({
id: resource.id, id: resource.id,
name: resource.name, name: resource.name,
src: canvas.toDataURL(), src: canvas.toDataURL(),
}; });
})
) resource.dirty = false;
); });
} catch (e) { } catch (e) {
console.warn( console.warn(
"[stamp] Failed to synchronize resources with local storage" "[stamp] Failed to synchronize resources with IndexedDB"
); );
console.warn(e); console.warn(e);
} }
@ -143,6 +157,7 @@ const stampTool = () =>
resourceTitle.style.pointerEvents = "none"; resourceTitle.style.pointerEvents = "none";
resourceTitle.addEventListener("change", () => { resourceTitle.addEventListener("change", () => {
resource.name = resourceTitle.value; resource.name = resourceTitle.value;
resource.dirty = true;
resourceTitle.title = resourceTitle.value; resourceTitle.title = resourceTitle.value;
syncResources(); syncResources();
@ -246,6 +261,7 @@ const stampTool = () =>
id, id,
name, name,
image, image,
dirty: true,
temporary, temporary,
}; };
@ -390,7 +406,6 @@ const stampTool = () =>
image.onload = () => state.addResource(file.name, image, false); image.onload = () => state.addResource(file.name, image, false);
} }
}); });
uploadButton.value = null; uploadButton.value = null;
}); });
@ -441,29 +456,65 @@ const stampTool = () =>
state.ctxmenu.resourceManager = resourceManager; state.ctxmenu.resourceManager = resourceManager;
state.ctxmenu.resourceList = resourceList; state.ctxmenu.resourceList = resourceList;
// Performs resource fetch from local storage // Performs resource fetch from IndexedDB
(async () => {
const storageResources = localStorage.getItem( IDBOpenRequest.onerror = (e) => {
"tools.stamp.resources" console.warn("[stamp] Failed to connect to IndexedDB");
); console.warn(e);
if (storageResources) { };
const parsed = JSON.parse(storageResources);
IDBOpenRequest.onupgradeneeded = (e) => {
const db = e.target.result;
console.debug(`[stamp] Setting up database version ${db.version}`);
const resourcesStore = db.createObjectStore("resources", {
keyPath: "id",
});
resourcesStore.createIndex("name", "name", {unique: false});
};
IDBOpenRequest.onsuccess = async (e) => {
console.debug("[stamp] Connected to IndexedDB");
state.stampDB = e.target.result;
state.stampDB.onerror = (evn) => {
console.warn(`[stamp] Database Error:`);
console.warn(evn.target.errorCode);
};
/** @type {IDBDatabase} */
const db = state.stampDB;
/** @type {IDBRequest<{id: string, name: string, src: string}[]>} */
const FetchAllTransaction = db
.transaction("resources")
.objectStore("resources")
.getAll();
FetchAllTransaction.onsuccess = async () => {
const data = FetchAllTransaction.result;
state.resources.push( state.resources.push(
...(await Promise.all( ...(await Promise.all(
parsed.map((resource) => { data.map((resource) => {
const image = document.createElement("img"); const image = document.createElement("img");
image.src = resource.src; image.src = resource.src;
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
image.onload = () => image.onload = () =>
resolve({id: resource.id, name: resource.name, image}); resolve({
id: resource.id,
name: resource.name,
image,
});
}); });
}) })
)) ))
); );
syncResources(); syncResources();
} };
})(); };
} }
}, },
populateContextMenu: (menu, state) => { populateContextMenu: (menu, state) => {