/** * PDFLibrary - Shared PDF storage for ColorRM apps * Both main (collaborative) and split view (local) apps can access this library */ export const PDFLibrary = { DB_NAME: 'ColorRM_PDFLibrary', DB_VERSION: 1, STORE_NAME: 'pdfs', db: null, modal: null, onSelect: null, // Callback when PDF is selected /** * Initialize the PDF library database */ async init() { return new Promise((resolve, reject) => { const request = indexedDB.open(this.DB_NAME, this.DB_VERSION); request.onerror = () => reject(request.error); request.onsuccess = () => { this.db = request.result; console.log('PDFLibrary: Database initialized'); resolve(); }; request.onupgradeneeded = (event) => { const db = event.target.result; if (!db.objectStoreNames.contains(this.STORE_NAME)) { const store = db.createObjectStore(this.STORE_NAME, { keyPath: 'id' }); store.createIndex('name', 'name', { unique: false }); store.createIndex('timestamp', 'timestamp', { unique: false }); } }; }); }, /** * Upload a PDF to the library */ async upload(file) { if (!this.db) await this.init(); if (!file || !file.type.includes('pdf')) { throw new Error('Invalid file type. Please select a PDF.'); } const id = `pdf_${Date.now()}_${Math.random().toString(36).substring(2, 7)}`; const name = file.name.replace('.pdf', '').replace('.PDF', ''); const entry = { id, name, blob: file, size: file.size, timestamp: Date.now() }; return new Promise((resolve, reject) => { const tx = this.db.transaction([this.STORE_NAME], 'readwrite'); const store = tx.objectStore(this.STORE_NAME); const req = store.put(entry); req.onsuccess = () => { console.log('PDFLibrary: Uploaded', name); resolve(entry); }; req.onerror = () => reject(req.error); }); }, /** * Get all PDFs in the library */ async getAll() { if (!this.db) await this.init(); return new Promise((resolve, reject) => { const tx = this.db.transaction([this.STORE_NAME], 'readonly'); const store = tx.objectStore(this.STORE_NAME); const req = store.getAll(); req.onsuccess = () => { const results = req.result || []; results.sort((a, b) => b.timestamp - a.timestamp); resolve(results); }; req.onerror = () => reject(req.error); }); }, /** * Get a specific PDF by ID */ async get(id) { if (!this.db) await this.init(); return new Promise((resolve, reject) => { const tx = this.db.transaction([this.STORE_NAME], 'readonly'); const store = tx.objectStore(this.STORE_NAME); const req = store.get(id); req.onsuccess = () => resolve(req.result); req.onerror = () => reject(req.error); }); }, /** * Delete a PDF from the library */ async delete(id) { if (!this.db) await this.init(); return new Promise((resolve, reject) => { const tx = this.db.transaction([this.STORE_NAME], 'readwrite'); const store = tx.objectStore(this.STORE_NAME); const req = store.delete(id); req.onsuccess = () => { console.log('PDFLibrary: Deleted', id); resolve(); }; req.onerror = () => reject(req.error); }); }, /** * Format file size for display */ formatSize(bytes) { if (bytes < 1024) return bytes + ' B'; if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + ' KB'; return (bytes / (1024 * 1024)).toFixed(1) + ' MB'; }, /** * Create and inject the modal HTML */ createModal() { if (document.getElementById('pdfLibraryModal')) return; const modal = document.createElement('div'); modal.id = 'pdfLibraryModal'; modal.className = 'overlay'; modal.style.cssText = 'display:none; position:fixed; inset:0; background:rgba(0,0,0,0.85); z-index:10000; align-items:center; justify-content:center;'; modal.innerHTML = `
Select a PDF to open or upload a new one
Click or drag PDF here to upload
No PDFs in library