maxza258's picture
Upload 23 files
ebf054f verified
Raw
History Blame
3.3 kB
const DB_NAME = "textphantom_local_gallery";
const DB_VERSION = 1;
const STORE_NAME = "sessions";
const IMAGE_PREFIX = "image/";
let dbPromise = null;
function openDb() {
if (dbPromise) return dbPromise;
dbPromise = new Promise((resolve, reject) => {
const req = indexedDB.open(DB_NAME, DB_VERSION);
req.onupgradeneeded = () => {
const db = req.result;
if (!db.objectStoreNames.contains(STORE_NAME)) {
db.createObjectStore(STORE_NAME, { keyPath: "id" });
}
};
req.onsuccess = () => resolve(req.result);
req.onerror = () => reject(req.error || new Error("indexeddb_open_failed"));
});
return dbPromise;
}
function txComplete(tx) {
return new Promise((resolve, reject) => {
tx.oncomplete = () => resolve();
tx.onabort = () => reject(tx.error || new Error("indexeddb_tx_aborted"));
tx.onerror = () => reject(tx.error || new Error("indexeddb_tx_failed"));
});
}
function trimString(v) {
return String(v || "").trim();
}
export function naturalCompare(a, b) {
return new Intl.Collator(undefined, {
numeric: true,
sensitivity: "base",
}).compare(String(a || ""), String(b || ""));
}
export function sortLocalPages(pages) {
return [...(Array.isArray(pages) ? pages : [])].sort((a, b) => {
const pa = trimString(a?.relativePath || a?.name || a?.id);
const pb = trimString(b?.relativePath || b?.name || b?.id);
const byPath = naturalCompare(pa, pb);
if (byPath) return byPath;
return naturalCompare(a?.id, b?.id);
});
}
export function toLocalPageRecord(file, index = 0) {
const name = trimString(file?.name) || `image-${index + 1}`;
const type = trimString(file?.type) || "application/octet-stream";
const relativePath = trimString(file?.webkitRelativePath || "");
return {
id: crypto.randomUUID(),
name,
relativePath,
type,
size: Number(file?.size) || 0,
lastModified: Number(file?.lastModified) || 0,
blob: file,
};
}
export function filterImageFiles(files) {
return [...(files || [])].filter((file) => {
const type = trimString(file?.type).toLowerCase();
return type.startsWith(IMAGE_PREFIX);
});
}
export async function saveLocalSession(session) {
const db = await openDb();
const record = {
id: trimString(session?.id) || crypto.randomUUID(),
createdAt: Number(session?.createdAt) || Date.now(),
title: trimString(session?.title),
pages: Array.isArray(session?.pages) ? [...session.pages] : [],
};
const tx = db.transaction(STORE_NAME, 'readwrite');
tx.objectStore(STORE_NAME).put(record);
await txComplete(tx);
return record;
}
export async function loadLocalSession(id) {
const key = trimString(id);
if (!key) return null;
const db = await openDb();
return await new Promise((resolve, reject) => {
const tx = db.transaction(STORE_NAME, 'readonly');
const req = tx.objectStore(STORE_NAME).get(key);
req.onsuccess = () => resolve(req.result || null);
req.onerror = () => reject(req.error || new Error("indexeddb_get_failed"));
});
}
export async function deleteLocalSession(id) {
const key = trimString(id);
if (!key) return;
const db = await openDb();
const tx = db.transaction(STORE_NAME, 'readwrite');
tx.objectStore(STORE_NAME).delete(key);
await txComplete(tx);
}