| | import { DB_NAME, CANVAS_STORE_NAME, CANVAS_AUTOSAVE_KEY, DEFAULT_CANVAS_WIDTH, DEFAULT_CANVAS_HEIGHT } from '../constants'; |
| |
|
| | const DB_VERSION = 1; |
| |
|
| | interface CanvasSave { |
| | id: string; |
| | dataURL: string; |
| | width: number; |
| | height: number; |
| | timestamp: number; |
| | } |
| |
|
| | export interface LoadedCanvasState { |
| | dataURL: string; |
| | width: number; |
| | height: number; |
| | } |
| |
|
| | const openDB = (): Promise<IDBDatabase> => { |
| | return new Promise((resolve, reject) => { |
| | if (!window.indexedDB) { |
| | console.warn("IndexedDB not supported by this browser."); |
| | reject(new Error("IndexedDB not supported.")); |
| | return; |
| | } |
| | const request = indexedDB.open(DB_NAME, DB_VERSION); |
| |
|
| | request.onerror = () => reject(new Error('Failed to open IndexedDB: ' + request.error?.message)); |
| | request.onsuccess = () => resolve(request.result); |
| |
|
| | request.onupgradeneeded = (event) => { |
| | const db = (event.target as IDBOpenDBRequest).result; |
| | if (!db.objectStoreNames.contains(CANVAS_STORE_NAME)) { |
| | db.createObjectStore(CANVAS_STORE_NAME, { keyPath: 'id' }); |
| | } |
| | |
| | |
| | }; |
| | }); |
| | }; |
| |
|
| | export const saveCanvasState = async (dataURL: string, width: number, height: number): Promise<void> => { |
| | try { |
| | const db = await openDB(); |
| | const transaction = db.transaction(CANVAS_STORE_NAME, 'readwrite'); |
| | const store = transaction.objectStore(CANVAS_STORE_NAME); |
| | const canvasData: CanvasSave = { |
| | id: CANVAS_AUTOSAVE_KEY, |
| | dataURL, |
| | width, |
| | height, |
| | timestamp: Date.now(), |
| | }; |
| | store.put(canvasData); |
| |
|
| | return new Promise((resolve, reject) => { |
| | transaction.oncomplete = () => resolve(); |
| | transaction.onerror = () => { |
| | console.error('Transaction error saving canvas state:', transaction.error); |
| | reject(new Error('Failed to save canvas state.')); |
| | } |
| | }); |
| | } catch (error) { |
| | console.error('Error saving canvas state to IndexedDB:', error); |
| | |
| | } |
| | }; |
| |
|
| | export const loadCanvasState = async (): Promise<LoadedCanvasState | null> => { |
| | try { |
| | const db = await openDB(); |
| | const transaction = db.transaction(CANVAS_STORE_NAME, 'readonly'); |
| | const store = transaction.objectStore(CANVAS_STORE_NAME); |
| | const request = store.get(CANVAS_AUTOSAVE_KEY); |
| |
|
| | return new Promise((resolve, reject) => { |
| | request.onsuccess = () => { |
| | if (request.result) { |
| | const savedData = request.result as CanvasSave; |
| | resolve({ |
| | dataURL: savedData.dataURL, |
| | |
| | width: savedData.width || DEFAULT_CANVAS_WIDTH, |
| | height: savedData.height || DEFAULT_CANVAS_HEIGHT, |
| | }); |
| | } else { |
| | resolve(null); |
| | } |
| | }; |
| | request.onerror = () => { |
| | console.error('Request error loading canvas state:', request.error); |
| | reject(new Error('Failed to load canvas state.')); |
| | } |
| | }); |
| | } catch (error) { |
| | console.error('Error loading canvas state from IndexedDB:', error); |
| | return null; |
| | } |
| | }; |
| |
|
| | export const clearCanvasStateDB = async (): Promise<void> => { |
| | try { |
| | const db = await openDB(); |
| | const transaction = db.transaction(CANVAS_STORE_NAME, 'readwrite'); |
| | const store = transaction.objectStore(CANVAS_STORE_NAME); |
| | const request = store.delete(CANVAS_AUTOSAVE_KEY); |
| |
|
| | return new Promise((resolve, reject) => { |
| | transaction.oncomplete = () => resolve(); |
| | transaction.onerror = () => { |
| | console.error('Transaction error clearing canvas state:', transaction.error); |
| | reject(new Error('Failed to clear canvas state from DB.')); |
| | } |
| | request.onerror = () => { |
| | console.error('Request error deleting canvas state:', request.error); |
| | reject(new Error('Failed to delete canvas state from DB.')); |
| | }; |
| | }); |
| | } catch (error) { |
| | console.error('Error clearing canvas state from IndexedDB:', error); |
| | } |
| | }; |