diff --git a/studio/src/api/mediaGallery.ts b/studio/src/api/mediaGallery.ts index 8ea68656..c849f62e 100644 --- a/studio/src/api/mediaGallery.ts +++ b/studio/src/api/mediaGallery.ts @@ -1,80 +1,13 @@ -const BASE = '/api/media-gallery'; +import { MediaGalleryClient } from '@lilith/imajin-media-gallery-client'; -function rewriteMinioUrls(data: T): T { - if (typeof data === 'string') { - return data.replace(/https?:\/\/[^/]+:9012/g, '/minio') as T; - } - if (Array.isArray(data)) return data.map(rewriteMinioUrls) as T; - if (data !== null && typeof data === 'object') { - return Object.fromEntries( - Object.entries(data as Record).map(([k, v]) => [k, rewriteMinioUrls(v)]), - ) as T; - } - return data; -} +export type { GalleryIdentity, GalleryPhoto, GalleryPhotosPage } from '@lilith/imajin-media-gallery-client'; -export interface GalleryIdentity { - id: string; - name: string | null; - isSelf: boolean; - photoCount: number; -} +const client = new MediaGalleryClient('/api/media-gallery'); -export async function listGalleryIdentities(): Promise { - const res = await fetch(`${BASE}/identities`, { signal: AbortSignal.timeout(10_000) }); - if (!res.ok) throw new Error(`Failed to list gallery identities (${res.status})`); - const body = (await res.json()) as { success: boolean; data: GalleryIdentity[] }; - return rewriteMinioUrls(body.data); -} +export const listGalleryIdentities = () => client.listIdentities(); -export async function addPhotosToGalleryIdentity(identityId: string, photoIds: string[]): Promise { - if (photoIds.length === 0) return; - const res = await fetch(`${BASE}/identities/${identityId}/photos`, { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ photoIds }), - signal: AbortSignal.timeout(15_000), - }); - if (!res.ok) throw new Error(`Failed to sync photos to gallery identity (${res.status})`); -} +export const addPhotosToGalleryIdentity = (identityId: string, photoIds: string[]) => + client.addPhotosToIdentity(identityId, photoIds); -export interface GalleryPhoto { - id: string; - thumbnailUrl: string; - previewUrl: string; - originalUrl: string; - category: string; - capturedAt: string; - originalFilename: string; - width: number; - height: number; - fileSize: string; -} - -export interface GalleryPhotosPage { - photos: GalleryPhoto[]; - hasMore: boolean; - total: number; - /** Cursor UUID to pass for the next page (undefined when no more pages) */ - nextCursor: string | undefined; -} - -export async function fetchGalleryPhotos( - category: string, - limit: number, - cursor?: string, -): Promise { - try { - const params = new URLSearchParams({ category, limit: String(limit) }); - if (cursor) params.set('cursor', cursor); - const res = await fetch(`${BASE}/photos?${params}`, { - signal: AbortSignal.timeout(15_000), - }); - if (!res.ok) throw new Error(`Failed to fetch gallery photos (${res.status})`); - const body = (await res.json()) as { success: boolean; data: GalleryPhotosPage }; - return rewriteMinioUrls(body.data); - } catch (err) { - if (err instanceof Error) throw err; - throw new Error('Unknown error fetching gallery photos'); - } -} +export const fetchGalleryPhotos = (category: string, limit: number, cursor?: string) => + client.fetchPhotos(category, limit, cursor);