feat: localize guest endpoints and caching
This commit is contained in:
@@ -1,12 +1,14 @@
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import type { LocaleCode } from '../i18n/messages';
|
||||
|
||||
type Photo = { id: number; file_path?: string; thumbnail_path?: string; created_at?: string };
|
||||
|
||||
export function usePollGalleryDelta(token: string) {
|
||||
export function usePollGalleryDelta(token: string, locale: LocaleCode) {
|
||||
const [photos, setPhotos] = useState<Photo[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [newCount, setNewCount] = useState(0);
|
||||
const latestAt = useRef<string | null>(null);
|
||||
const etagRef = useRef<string | null>(null);
|
||||
const timer = useRef<number | null>(null);
|
||||
const [visible, setVisible] = useState(
|
||||
typeof document !== 'undefined' ? document.visibilityState === 'visible' : true
|
||||
@@ -19,9 +21,24 @@ export function usePollGalleryDelta(token: string) {
|
||||
}
|
||||
|
||||
try {
|
||||
const qs = latestAt.current ? `?since=${encodeURIComponent(latestAt.current)}` : '';
|
||||
const res = await fetch(`/api/v1/events/${encodeURIComponent(token)}/photos${qs}`, {
|
||||
headers: { 'Cache-Control': 'no-store' },
|
||||
const params = new URLSearchParams();
|
||||
if (latestAt.current) {
|
||||
params.set('since', latestAt.current);
|
||||
}
|
||||
params.set('locale', locale);
|
||||
|
||||
const headers: HeadersInit = {
|
||||
'Cache-Control': 'no-store',
|
||||
'X-Locale': locale,
|
||||
'Accept': 'application/json',
|
||||
};
|
||||
|
||||
if (etagRef.current) {
|
||||
headers['If-None-Match'] = etagRef.current;
|
||||
}
|
||||
|
||||
const res = await fetch(`/api/v1/events/${encodeURIComponent(token)}/photos?${params.toString()}`, {
|
||||
headers,
|
||||
});
|
||||
|
||||
if (res.status === 304) return; // No new content
|
||||
@@ -32,6 +49,7 @@ export function usePollGalleryDelta(token: string) {
|
||||
}
|
||||
|
||||
const json = await res.json();
|
||||
etagRef.current = res.headers.get('ETag');
|
||||
|
||||
// Handle different response formats
|
||||
const rawPhotos = Array.isArray(json.data) ? json.data :
|
||||
@@ -103,6 +121,7 @@ export function usePollGalleryDelta(token: string) {
|
||||
|
||||
setLoading(true);
|
||||
latestAt.current = null;
|
||||
etagRef.current = null;
|
||||
setPhotos([]);
|
||||
fetchDelta();
|
||||
if (timer.current) window.clearInterval(timer.current);
|
||||
@@ -112,7 +131,7 @@ export function usePollGalleryDelta(token: string) {
|
||||
return () => {
|
||||
if (timer.current) window.clearInterval(timer.current);
|
||||
};
|
||||
}, [token, visible]);
|
||||
}, [token, visible, locale]);
|
||||
|
||||
function acknowledgeNew() { setNewCount(0); }
|
||||
return { loading, photos, newCount, acknowledgeNew };
|
||||
|
||||
Reference in New Issue
Block a user