mirror of
https://github.com/Afilmory/afilmory
synced 2026-02-01 22:48:17 +00:00
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:
@@ -72,7 +72,6 @@ photo-gallery-site/
|
||||
│ │ │ └── worker/ # 并发处理
|
||||
│ │ ├── modules/ # 功能模块
|
||||
│ │ ├── pages/ # 页面组件
|
||||
│ │ └── data/ # 数据文件
|
||||
│ ├── public/ # 静态资源
|
||||
│ └── scripts/ # 构建脚本
|
||||
├── packages/webgl-viewer/ # WebGL 图像查看器
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
"start": "next start"
|
||||
},
|
||||
"dependencies": {
|
||||
"@photo-gallery/data": "workspace:*",
|
||||
"linkedom": "0.18.11",
|
||||
"react": "19.1.0",
|
||||
"react-dom": "19.1.0"
|
||||
|
||||
@@ -1,11 +1,16 @@
|
||||
import { photoLoader } from '@photo-gallery/data'
|
||||
import type { PhotoManifest } from '@photo-gallery/data/types'
|
||||
import { DOMParser } from 'linkedom'
|
||||
import type { HTMLDocument } from 'linkedom/types/html/document'
|
||||
import type { NextRequest } from 'next/server'
|
||||
|
||||
import { photoLoader } from '../../../../web/src/data/photos'
|
||||
import type { PhotoManifest } from '../../../../web/src/types/photo'
|
||||
import { getIndexHtml } from '../../constants'
|
||||
|
||||
type HtmlElement = ReturnType<typeof DOMParser.prototype.parseFromString>
|
||||
type OnlyHTMLDocument = HtmlElement extends infer T
|
||||
? T extends { [key: string]: any; head: any }
|
||||
? T
|
||||
: never
|
||||
: never
|
||||
export const runtime = 'edge'
|
||||
export const GET = async (
|
||||
request: NextRequest,
|
||||
@@ -54,7 +59,7 @@ export const GET = async (
|
||||
}
|
||||
|
||||
const createAndInsertOpenGraphMeta = (
|
||||
document: HTMLDocument,
|
||||
document: OnlyHTMLDocument,
|
||||
photo: PhotoManifest,
|
||||
request: NextRequest,
|
||||
) => {
|
||||
@@ -68,7 +73,7 @@ const createAndInsertOpenGraphMeta = (
|
||||
}
|
||||
|
||||
for (const [property, content] of Object.entries(ogTags)) {
|
||||
const ogMeta = document.createElement('meta')
|
||||
const ogMeta = document.createElement('meta', {})
|
||||
ogMeta.setAttribute('property', property)
|
||||
ogMeta.setAttribute('content', content)
|
||||
document.head.append(ogMeta as unknown as Node)
|
||||
@@ -83,7 +88,7 @@ const createAndInsertOpenGraphMeta = (
|
||||
}
|
||||
|
||||
for (const [name, content] of Object.entries(twitterTags)) {
|
||||
const twitterMeta = document.createElement('meta')
|
||||
const twitterMeta = document.createElement('meta', {})
|
||||
twitterMeta.setAttribute('name', name)
|
||||
twitterMeta.setAttribute('content', content)
|
||||
document.head.append(twitterMeta as unknown as Node)
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import { photoLoader } from '@photo-gallery/data'
|
||||
import { ImageResponse } from 'next/og'
|
||||
import type { NextRequest } from 'next/server'
|
||||
|
||||
import { photoLoader } from '../../../../../web/src/data/photos'
|
||||
|
||||
export const runtime = 'edge'
|
||||
|
||||
export const GET = async (
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
"incremental": true,
|
||||
"module": "esnext",
|
||||
"esModuleInterop": true,
|
||||
"moduleResolution": "node",
|
||||
"moduleResolution": "bundler",
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"jsx": "preserve",
|
||||
@@ -32,4 +32,4 @@
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,7 @@
|
||||
"@aws-sdk/s3-request-presigner": "3.824.0",
|
||||
"@essentials/request-timeout": "1.3.0",
|
||||
"@headlessui/react": "2.2.4",
|
||||
"@photo-gallery/data": "workspace:*",
|
||||
"@photo-gallery/webgl-viewer": "workspace:*",
|
||||
"@radix-ui/react-context-menu": "2.2.15",
|
||||
"@radix-ui/react-dropdown-menu": "2.1.15",
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { photoLoader } from '@photo-gallery/data'
|
||||
import { atom, useAtom, useAtomValue } from 'jotai'
|
||||
import { useCallback, useEffect, useMemo } from 'react'
|
||||
import { useLocation, useNavigate } from 'react-router'
|
||||
|
||||
import { gallerySettingAtom } from '~/atoms/app'
|
||||
import { photoLoader } from '~/data/photos'
|
||||
|
||||
const openAtom = atom(false)
|
||||
const currentIndexAtom = atom(0)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { siteConfig } from '@config'
|
||||
import { photoLoader } from '@photo-gallery/data'
|
||||
import { repository } from '@pkg'
|
||||
import { useAtom } from 'jotai'
|
||||
import { useRef, useState } from 'react'
|
||||
@@ -13,7 +14,6 @@ import {
|
||||
DropdownMenuTrigger,
|
||||
} from '~/components/ui/dropdown-menu'
|
||||
import { Slider } from '~/components/ui/slider'
|
||||
import { photoLoader } from '~/data/photos'
|
||||
import { useMobile } from '~/hooks/useMobile'
|
||||
|
||||
const allTags = photoLoader.getAllTags()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { siteConfig } from '@config'
|
||||
import { photoLoader } from '@photo-gallery/data'
|
||||
|
||||
import { photoLoader } from '~/data/photos'
|
||||
import { clsxm } from '~/lib/cn'
|
||||
|
||||
import { ActionGroup } from './ActionGroup'
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { photoLoader } from '@photo-gallery/data'
|
||||
import { Blurhash } from 'react-blurhash'
|
||||
|
||||
import { photoLoader } from '~/data/photos'
|
||||
|
||||
export const Component = () => {
|
||||
const photos = photoLoader.getPhotos()
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { siteConfig } from '@config'
|
||||
import { photoLoader } from '@photo-gallery/data'
|
||||
import { useAtomValue, useSetAtom } from 'jotai'
|
||||
import { useEffect, useRef } from 'react'
|
||||
import { Outlet, useParams, useSearchParams } from 'react-router'
|
||||
|
||||
import { gallerySettingAtom } from '~/atoms/app'
|
||||
import { ScrollArea } from '~/components/ui/scroll-areas/ScrollArea'
|
||||
import { photoLoader } from '~/data/photos'
|
||||
import { usePhotoViewer } from '~/hooks/usePhotoViewer'
|
||||
import { MasonryRoot } from '~/modules/gallery/MasonryRoot'
|
||||
|
||||
|
||||
13
packages/data/package.json
Normal file
13
packages/data/package.json
Normal 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"
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { PhotoManifest } from '../types/photo'
|
||||
import PhotosManifest from './photos-manifest.json'
|
||||
import type { PhotoManifest } from './types'
|
||||
|
||||
class PhotoLoader {
|
||||
private photos: PhotoManifest[] = []
|
||||
1
packages/data/src/photos-manifest.json
Symbolic link
1
packages/data/src/photos-manifest.json
Symbolic link
@@ -0,0 +1 @@
|
||||
../../../apps/web/src/data/photos-manifest.json
|
||||
23
packages/data/src/types.ts
Normal file
23
packages/data/src/types.ts
Normal 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
|
||||
}
|
||||
17
pnpm-lock.yaml
generated
17
pnpm-lock.yaml
generated
@@ -69,6 +69,9 @@ importers:
|
||||
|
||||
apps/ssr:
|
||||
dependencies:
|
||||
'@photo-gallery/data':
|
||||
specifier: workspace:*
|
||||
version: link:../../packages/data
|
||||
linkedom:
|
||||
specifier: 0.18.11
|
||||
version: 0.18.11
|
||||
@@ -109,6 +112,9 @@ importers:
|
||||
'@headlessui/react':
|
||||
specifier: 2.2.4
|
||||
version: 2.2.4(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
|
||||
'@photo-gallery/data':
|
||||
specifier: workspace:*
|
||||
version: link:../../packages/data
|
||||
'@photo-gallery/webgl-viewer':
|
||||
specifier: workspace:*
|
||||
version: link:../../packages/webgl-viewer
|
||||
@@ -318,6 +324,15 @@ importers:
|
||||
specifier: 1.0.0-alpha.0
|
||||
version: 1.0.0-alpha.0
|
||||
|
||||
packages/data:
|
||||
dependencies:
|
||||
exif-reader:
|
||||
specifier: 2.0.2
|
||||
version: 2.0.2
|
||||
fuji-recipes:
|
||||
specifier: 1.0.2
|
||||
version: 1.0.2
|
||||
|
||||
packages/webgl-viewer:
|
||||
dependencies:
|
||||
react:
|
||||
@@ -1588,7 +1603,7 @@ packages:
|
||||
resolution: {integrity: sha512-fyjAACV62oPV925xFCrH8DR5xWhg9KYtJT4s3u54jxp+L/hbpTY2kIeEFFbFe+a/HCE94zGQMZLIpVTPVZDhaA==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
react: 18.3.1
|
||||
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
|
||||
Reference in New Issue
Block a user