import type { MediaInput } from '@photo-gallery/sdk'; /** * Demo seed data. Uses free Picsum photos with synthetic-but-realistic metadata * (capture dates, GPS locations, tags, detected objects, sources) so that the * Map, Search, Smart Albums and "find similar object" features all have data to * show without any backend or API key. * * Picsum is allow-listed in the CSP (see next.config.mjs). Videos use Google's * public sample bucket, also allow-listed. */ const CITIES: Array<{ place: string; city: string; country: string; lat: number; lng: number }> = [ { place: 'Mumbai, India', city: 'Mumbai', country: 'India', lat: 19.076, lng: 72.8777 }, { place: 'New Delhi, India', city: 'New Delhi', country: 'India', lat: 28.6139, lng: 77.209 }, { place: 'Bengaluru, India', city: 'Bengaluru', country: 'India', lat: 12.9716, lng: 77.5946 }, { place: 'Goa, India', city: 'Goa', country: 'India', lat: 15.2993, lng: 74.124 }, { place: 'Manali, India', city: 'Manali', country: 'India', lat: 32.2432, lng: 77.1892 }, { place: 'Jaipur, India', city: 'Jaipur', country: 'India', lat: 26.9124, lng: 75.7873 }, { place: 'San Francisco, USA', city: 'San Francisco', country: 'USA', lat: 37.7749, lng: -122.4194 }, { place: 'New York, USA', city: 'New York', country: 'USA', lat: 40.7128, lng: -74.006 }, { place: 'London, UK', city: 'London', country: 'UK', lat: 51.5074, lng: -0.1278 }, { place: 'Paris, France', city: 'Paris', country: 'France', lat: 48.8566, lng: 2.3522 }, { place: 'Tokyo, Japan', city: 'Tokyo', country: 'Japan', lat: 35.6762, lng: 139.6503 }, { place: 'Dubai, UAE', city: 'Dubai', country: 'UAE', lat: 25.2048, lng: 55.2708 }, ]; const TAG_POOL = [ ['beach', 'sunset', 'ocean'], ['mountain', 'snow', 'hike'], ['food', 'restaurant'], ['city', 'building', 'night'], ['nature', 'flower', 'plant'], ['friends', 'party'], ['travel', 'landmark'], ['selfie', 'portrait'], ]; const OBJECT_POOL = [ ['person'], ['dog'], ['cat'], ['car'], ['laptop', 'cup'], ['dining table', 'chair', 'bottle'], ['tv', 'chair'], ['potted plant'], ['bicycle', 'person'], ]; // Served from the demo's own /public so it plays same-origin (no CORS / ORB issues). const SAMPLE_VIDEOS = ['/sample-clip.mp4']; const DAY = 24 * 60 * 60 * 1000; export function buildSeedPhotos(now = Date.now()): MediaInput[] { const items: MediaInput[] = []; for (let i = 0; i < 44; i++) { const seed = `apg-${i}`; const takenAt = now - Math.floor(i * 8.4 + (i % 5) * 3) * DAY; // ~75% of demo photos are geotagged (real photos populate location via EXIF GPS on import). const hasLoc = i % 4 !== 0; const city = CITIES[i % CITIES.length]!; const tags = TAG_POOL[i % TAG_POOL.length]!; const objects = i % 3 === 0 ? OBJECT_POOL[i % OBJECT_POOL.length]! : []; // Distribute sources to populate smart albums. let source: MediaInput['source'] = 'camera'; let name = `IMG_${4000 + i}.jpg`; let width = 1600; let height = 1067; const variant = i % 7; if (variant === 1) { source = 'screenshot'; name = `Screenshot 2026-0${(i % 9) + 1}-12 at 9.41.${10 + i}.png`; width = 1170; height = 2532; } else if (variant === 2) { source = 'download'; name = `download-${i}.jpg`; } else if (variant === 3) { source = 'social'; name = `IMG-2026031${i % 9}-WA00${i % 9}.jpg`; } else if (variant === 5) { // panorama width = 2400; height = 820; name = `PANO_${i}.jpg`; } const isVideo = i % 11 === 4; // a few videos if (isVideo) { const v = SAMPLE_VIDEOS[i % SAMPLE_VIDEOS.length]!; items.push({ src: v, poster: `https://picsum.photos/seed/${seed}/1280/720`, thumbnail: `https://picsum.photos/seed/${seed}/600/400`, name: `MOV_${5000 + i}.mp4`, kind: 'video', mime: 'video/mp4', width: 1280, height: 720, duration: 30 + (i % 4) * 12, takenAt, source: 'camera', bytes: 18_000_000 + i * 250_000, tags, objectLabels: objects, favorite: i % 9 === 0, location: hasLoc ? { ...city } : undefined, }); continue; } items.push({ src: `https://picsum.photos/seed/${seed}/${width}/${height}`, thumbnail: `https://picsum.photos/seed/${seed}/${Math.round(width / 3)}/${Math.round(height / 3)}`, name, kind: 'image', mime: source === 'screenshot' ? 'image/png' : 'image/jpeg', width, height, takenAt, source, bytes: 2_400_000 + i * 90_000, tags, objectLabels: objects, favorite: i % 6 === 0, isPanorama: variant === 5, location: hasLoc ? { ...city } : undefined, exif: source === 'camera' ? { Make: 'Apple', Model: 'iPhone 16 Pro', FNumber: 1.8, ISO: 100 + (i % 8) * 50 } : undefined, }); } // TESTING: seed only the demo video(s) — start with an EMPTY photo library so you // can upload 1–2 images and watch them get analyzed. To restore the full demo, // change this back to `return items;`. return items.filter((it) => it.kind === 'video'); }