import { getDB } from './db'; import type { Photo } from '$lib/types'; import { nanoid } from 'nanoid'; /** * Get all photos for a specific item */ export async function getPhotosByItemId(itemId: string): Promise { const db = await getDB(); return db.getAllFromIndex('photos', 'by-item', itemId); } /** * Get a specific photo by ID */ export async function getPhotoById(id: string): Promise { const db = await getDB(); return db.get('photos', id); } /** * Create a new photo * Automatically generates thumbnail (max 200px width) */ export async function createPhoto(itemId: string, blob: Blob): Promise { const thumbnail = await generateThumbnail(blob, 200); const photo: Photo = { id: `photo_${nanoid(10)}`, itemId, blob, thumbnail, createdAt: new Date().toISOString(), }; const db = await getDB(); await db.put('photos', photo); return photo; } /** * Delete a photo */ export async function deletePhoto(id: string): Promise { const db = await getDB(); await db.delete('photos', id); } /** * Delete all photos for an item */ export async function deletePhotosByItemId(itemId: string): Promise { const photos = await getPhotosByItemId(itemId); const db = await getDB(); await Promise.all(photos.map((photo) => db.delete('photos', photo.id))); } /** * Generate a thumbnail from a blob */ async function generateThumbnail(blob: Blob, maxWidth: number): Promise { return new Promise((resolve, reject) => { const img = new Image(); const url = URL.createObjectURL(blob); img.onload = () => { // Calculate dimensions const scale = maxWidth / img.width; const width = maxWidth; const height = img.height * scale; // Create canvas const canvas = document.createElement('canvas'); canvas.width = width; canvas.height = height; // Draw scaled image const ctx = canvas.getContext('2d'); if (!ctx) { reject(new Error('Could not get canvas context')); return; } ctx.drawImage(img, 0, 0, width, height); // Convert to blob canvas.toBlob( (thumbnailBlob) => { URL.revokeObjectURL(url); if (thumbnailBlob) { resolve(thumbnailBlob); } else { reject(new Error('Could not create thumbnail')); } }, 'image/jpeg', 0.8 ); }; img.onerror = () => { URL.revokeObjectURL(url); reject(new Error('Could not load image')); }; img.src = url; }); } /** * Convert a blob to a data URL for display */ export function blobToDataURL(blob: Blob): Promise { return new Promise((resolve, reject) => { const reader = new FileReader(); reader.onload = () => resolve(reader.result as string); reader.onerror = reject; reader.readAsDataURL(blob); }); }