diff --git a/admin-frontend/src/api/photos.ts b/admin-frontend/src/api/photos.ts index 3d1aab4..8813558 100644 --- a/admin-frontend/src/api/photos.ts +++ b/admin-frontend/src/api/photos.ts @@ -167,6 +167,7 @@ export interface PhotoSearchResult { date_taken?: string date_added: string processed: boolean + media_type?: string // "image" or "video" person_name?: string tags: string[] has_faces: boolean diff --git a/admin-frontend/src/components/PhotoViewer.tsx b/admin-frontend/src/components/PhotoViewer.tsx index 25d535b..2b0df99 100644 --- a/admin-frontend/src/components/PhotoViewer.tsx +++ b/admin-frontend/src/components/PhotoViewer.tsx @@ -1,6 +1,7 @@ import { useEffect, useState, useRef } from 'react' import { PhotoSearchResult, photosApi } from '../api/photos' import { apiClient } from '../api/client' +import videosApi from '../api/videos' interface PhotoViewerProps { photos: PhotoSearchResult[] @@ -46,29 +47,43 @@ export default function PhotoViewer({ photos, initialIndex, onClose }: PhotoView const canGoPrev = currentIndex > 0 const canGoNext = currentIndex < photos.length - 1 - // Get photo URL - const getPhotoUrl = (photoId: number) => { + // Check if current photo is a video + const isVideo = (photo: PhotoSearchResult) => { + return photo.media_type === 'video' + } + + // Get photo/video URL + const getPhotoUrl = (photoId: number, mediaType?: string) => { + if (mediaType === 'video') { + return videosApi.getVideoUrl(photoId) + } return `${apiClient.defaults.baseURL}/api/v1/photos/${photoId}/image` } - // Preload adjacent images + // Preload adjacent images (skip videos) const preloadAdjacent = (index: number) => { - // Preload next photo + // Preload next photo (only if it's an image) if (index + 1 < photos.length) { - const nextPhotoId = photos[index + 1].id - if (!preloadedImages.current.has(nextPhotoId)) { - const img = new Image() - img.src = getPhotoUrl(nextPhotoId) - preloadedImages.current.add(nextPhotoId) + const nextPhoto = photos[index + 1] + if (!isVideo(nextPhoto)) { + const nextPhotoId = nextPhoto.id + if (!preloadedImages.current.has(nextPhotoId)) { + const img = new Image() + img.src = getPhotoUrl(nextPhotoId, nextPhoto.media_type) + preloadedImages.current.add(nextPhotoId) + } } } - // Preload previous photo + // Preload previous photo (only if it's an image) if (index - 1 >= 0) { - const prevPhotoId = photos[index - 1].id - if (!preloadedImages.current.has(prevPhotoId)) { - const img = new Image() - img.src = getPhotoUrl(prevPhotoId) - preloadedImages.current.add(prevPhotoId) + const prevPhoto = photos[index - 1] + if (!isVideo(prevPhoto)) { + const prevPhotoId = prevPhoto.id + if (!preloadedImages.current.has(prevPhotoId)) { + const img = new Image() + img.src = getPhotoUrl(prevPhotoId, prevPhoto.media_type) + preloadedImages.current.add(prevPhotoId) + } } } } @@ -258,7 +273,8 @@ export default function PhotoViewer({ photos, initialIndex, onClose }: PhotoView return null } - const photoUrl = getPhotoUrl(currentPhoto.id) + const photoUrl = getPhotoUrl(currentPhoto.id, currentPhoto.media_type) + const currentIsVideo = isVideo(currentPhoto) return (