feat(slideshow): public fullscreen slideshow viewer

- /gallery/:slug/show/:token route + SlideshowPage: splash -> fullscreen kiosk,
  crossfade/cut/slide/kenburns/dip-to-white/dip-to-black transitions, color
  filters, white/original logo watermark overlay, contain/letterbox, cursor
  auto-hide, quiet-append of new uploads, live settings poll, and decode-ahead
  preload (first slide decoded before playback) so transitions do not struggle.
- slideshow.service for session/state + shared style types.
This commit is contained in:
Luca
2026-06-19 22:11:02 +02:00
parent dea5e0f8a6
commit fd02254f78
3 changed files with 557 additions and 0 deletions
+8
View File
@@ -10,6 +10,7 @@ import { ThemeProvider } from './contexts/ThemeContext';
import { GalleryPage } from './pages/GalleryPage';
import { ClientAccessPage } from './pages/ClientAccessPage';
import { PreviewPage } from './pages/gallery/PreviewPage';
const SlideshowPage = lazy(() => import('./pages/gallery/SlideshowPage').then((m) => ({ default: m.SlideshowPage })));
import { LegalPage } from './pages/public/LegalPage';
import {
AdminLoginPage,
@@ -159,6 +160,13 @@ function App() {
<Routes>
{/* Public gallery routes */}
<Route path="/gallery/preview" element={<PreviewPage />} />
{/* Live Slideshow ("Diashow") — token-only fullscreen kiosk.
Self-manages its session token; no GalleryAuthProvider. */}
<Route path="/gallery/:slug/show/:token" element={
<Suspense fallback={<Loading />}>
<SlideshowPage />
</Suspense>
} />
<Route path="/gallery/:slug/client-access" element={
<GalleryAuthProvider>
<ClientAccessPage />