|
|
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); |
|
|
} |
|
|
}; |