fix: dedicate watcher to own worker, fix media auth + memories nav

- Move watch_folders to dedicated 'watcher' queue with its own
  single-concurrency container so it never blocks scan/thumbnail slots
- Add get_current_user_media dependency that accepts ?token= query
  param for <img src> / <video src> media endpoints (thumb, original,
  proxy) — fixes 401 on thumbnails
- Append JWT token to all media URLs in the frontend
- Add missing 'memories' case in sidebar navigation switch

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-12 23:34:40 +02:00
parent d693569f59
commit 35d87a2749
7 changed files with 101 additions and 10 deletions

View File

@@ -276,6 +276,9 @@ export function LeftSidebar({ onCollapse }: LeftSidebarProps) {
case 'map':
navigateToSection('map', {})
break
case 'memories':
navigateToSection('memories', {})
break
default:
if (id.startsWith('folder-')) {
const folderId = id.slice('folder-'.length)

View File

@@ -1,5 +1,5 @@
import { useQuery } from '@tanstack/react-query'
import { photos } from '../../services/api'
import { photos, photos as photosApi } from '../../services/api'
import type { MemoryGroup } from '../../services/api'
export function MemoriesView() {
@@ -47,7 +47,7 @@ export function MemoriesView() {
>
{photo.thumb_small ? (
<img
src={`/api/v1/photos/${photo.id}/thumb/small`}
src={photosApi.getThumbnailUrl(photo.id, 'small')}
alt={photo.filename}
className="w-full h-full object-cover"
loading="lazy"

View File

@@ -316,17 +316,23 @@ export const photos = {
},
getThumbnailUrl: (photoId: string, size: 'small' | 'medium' | 'large' = 'medium') => {
return `${API_BASE_URL}/photos/${photoId}/thumb/${size}`
const token = localStorage.getItem('access_token')
const qs = token ? `?token=${encodeURIComponent(token)}` : ''
return `${API_BASE_URL}/photos/${photoId}/thumb/${size}${qs}`
},
getOriginalUrl: (photoId: string) => {
return `${API_BASE_URL}/photos/${photoId}/original`
const token = localStorage.getItem('access_token')
const qs = token ? `?token=${encodeURIComponent(token)}` : ''
return `${API_BASE_URL}/photos/${photoId}/original${qs}`
},
/** Full-resolution display URL. Backend serves the original for web-safe
* formats and a transcoded WebP for RAW/HEIC/TIFF. */
getProxyUrl: (photoId: string) => {
return `${API_BASE_URL}/photos/${photoId}/proxy`
const token = localStorage.getItem('access_token')
const qs = token ? `?token=${encodeURIComponent(token)}` : ''
return `${API_BASE_URL}/photos/${photoId}/proxy${qs}`
},
/** "On this day" memories — photos taken on this date in previous years. */