feat: introduce @photo-gallery/data package for centralized photo management

- Added a new package `@photo-gallery/data` to manage photo data and metadata.
- Updated various components to utilize the new photoLoader from the data package.
- Adjusted dependencies in `pnpm-lock.yaml` and `package.json` files to include the new package.
- Refactored imports across the application to streamline photo data access.

Signed-off-by: Innei <tukon479@gmail.com>
This commit is contained in:
Innei
2025-06-08 20:46:19 +08:00
parent 6641ce4404
commit 67a948ddeb
16 changed files with 75 additions and 19 deletions

View File

@@ -0,0 +1,13 @@
{
"name": "@photo-gallery/data",
"type": "module",
"private": true,
"exports": {
".": "./src/index.ts",
"./types": "./src/types.ts"
},
"dependencies": {
"exif-reader": "2.0.2",
"fuji-recipes": "1.0.2"
}
}

View File

@@ -0,0 +1,36 @@
import PhotosManifest from './photos-manifest.json'
import type { PhotoManifest } from './types'
class PhotoLoader {
private photos: PhotoManifest[] = []
private photoMap: Record<string, PhotoManifest> = {}
constructor() {
this.getAllTags = this.getAllTags.bind(this)
this.getPhotos = this.getPhotos.bind(this)
this.getPhoto = this.getPhoto.bind(this)
this.photos = PhotosManifest as unknown as PhotoManifest[]
this.photos.forEach((photo) => {
this.photoMap[photo.id] = photo
})
}
getPhotos() {
return this.photos
}
getPhoto(id: string) {
return this.photoMap[id]
}
getAllTags() {
const tagSet = new Set<string>()
this.photos.forEach((photo) => {
photo.tags.forEach((tag) => tagSet.add(tag))
})
return Array.from(tagSet).sort()
}
}
export const photoLoader = new PhotoLoader()

View File

@@ -0,0 +1 @@
../../../apps/web/src/data/photos-manifest.json

View File

@@ -0,0 +1,23 @@
import type { Exif } from 'exif-reader'
import type getRecipe from 'fuji-recipes'
export interface PhotoManifest {
id: string
title: string
description: string
views: number
tags: string[]
originalUrl: string
thumbnailUrl: string
blurhash: string
width: number
height: number
aspectRatio: number
s3Key: string
lastModified: string
size: number
exif: Exif & { FujiRecipe?: ReturnType<typeof getRecipe> }
isLivePhoto?: boolean
livePhotoVideoUrl?: string
livePhotoVideoS3Key?: string
}