import {inject, Injectable} from '@angular/core'; import {TuiAlertService} from '@taiga-ui/core'; import {DatabaseAPI} from '@chatenium/chatenium-sdk/storage/database'; @Injectable({ providedIn: 'root' }) export class IndexedDB { private dbVersion = 3 private db: IDBDatabase | null = null getApi(): DatabaseAPI { return { get: async (collection, key) => { return await this.get(collection, key) }, set: (collection, key, value) => { return this.putObject(collection, value, key); }, flush: () => {}, delete: (collection, key) => { return this.delete(collection, key); } } } openDatabase(): Promise { return new Promise(resolve => { const request = indexedDB.open("cache", this.dbVersion); request.onupgradeneeded = (e: IDBVersionChangeEvent) => { const db = (e.target as IDBOpenDBRequest).result; db.createObjectStore('sessions', { keyPath: 'id' }) db.createObjectStore('chats', { keyPath: 'id' }) db.createObjectStore('networks', { keyPath: 'id' }) db.createObjectStore('files', { keyPath: 'id' }) db.createObjectStore('messages', { keyPath: 'id' }) db.createObjectStore('networkmessages', { keyPath: 'id' }) db.createObjectStore('pictures', { keyPath: 'id' }) } request.onsuccess = (event: Event) => { this.db = (event.target as IDBOpenDBRequest).result; console.log("Indexed DB Successfully opened") resolve() } request.onerror = _ => { const request = indexedDB.deleteDatabase("cache"); request.onsuccess = _ => { setTimeout(() => { console.log("Recreated the database.") location.reload() }, 1500) } request.onerror = _ => { console.error("Fatal error. Cannot access indexedDB, check if access is not blocked.") } } }) } public putObject(storeName: string, data: any, id: string) { if (this.db) { const request = this.db.transaction([storeName], 'readwrite') .objectStore(storeName) .put({id: id, data: data}) request.onerror = _ => { console.error("[IDB] ERROR: Adding data failed.") } } else { console.error("[IDB] ERROR: DB Not open. Retrying in 500ms...") setTimeout(() => { console.log("Retrying now...") this.putObject(storeName, data, id) }, 1000) } } clearObjectStore(storeName: string) { return new Promise((resolve, reject) => { if (this.db) { const transaction = this.db.transaction([storeName], "readwrite"); const store = transaction.objectStore(storeName); const request = store.clear(); request.onsuccess = () => { resolve("Ok"); }; request.onerror = () => { console.error("Getting chats cache failed"); reject([]); }; } else { console.error("DB NOT OPEN (CLEAROBJECTSTORE)") } }); } getAll(storeName: string): Promise { return new Promise((resolve, reject) => { if (this.db) { const transaction = this.db.transaction([storeName], "readonly"); const store = transaction.objectStore(storeName); const request = store.getAll(); request.onsuccess = () => { resolve(request.result.map((data) => data.data)); }; request.onerror = () => { console.error("Getting chats cache failed"); reject([]); }; } else { console.error("DB NOT OPEN (GETALL)") } }); } get(storeName: string, key: string): Promise { return new Promise((resolve, reject) => { if (this.db) { const transaction = this.db.transaction([storeName], "readonly"); const store = transaction.objectStore(storeName); const request = store.get(key); request.onsuccess = () => { resolve(request.result == null ? [] : request.result.data); }; request.onerror = () => { console.error("Getting chats cache failed"); reject([]); }; } else { console.error("[IDB GET] ERROR: DB Not open.") } }); } delete(storeName: string, key: string): Promise { return new Promise((resolve, reject) => { if (this.db) { const transaction = this.db.transaction([storeName], "readonly"); const store = transaction.objectStore(storeName); const request = store.delete(key); request.onsuccess = () => { resolve(); }; request.onerror = () => { console.error("Getting chats cache failed"); reject([]); }; } else { console.error("[IDB GET] ERROR: DB Not open.") } }); } }