File size: 4,247 Bytes
763be49
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
import { DB_NAME, CANVAS_STORE_NAME, CANVAS_AUTOSAVE_KEY, DEFAULT_CANVAS_WIDTH, DEFAULT_CANVAS_HEIGHT } from '../constants';

const DB_VERSION = 1; // Keep version, onupgradeneeded handles store creation

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' });
      }
      // No need to alter existing stores if only adding properties to stored objects.
      // If keyPath or indexes changed, would need more complex migration.
    };
  });
};

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);
    // Gracefully fail, app can still function
  }
};

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,
            // Provide default dimensions if old data doesn't have them
            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; // Gracefully fail
  }
};

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 = () => { // Also handle request error for delete specifically
        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);
  }
};