stamp now uses indexed DB for resources
Signed-off-by: Victor Seiji Hariki <victorseijih@gmail.com>
This commit is contained in:
parent
f279c8457b
commit
b71731b7ca
1 changed files with 84 additions and 33 deletions
|
@ -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) => {
|
||||||
|
|
Loading…
Reference in a new issue