Files
advance-photo-gallery-web-sdk/apps/web/src/lib/seed.ts
T

145 lines
5.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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 12 images and watch them get analyzed. To restore the full demo,
// change this back to `return items;`.
return items.filter((it) => it.kind === 'video');
}