diff --git a/src/app/components/DirectorySlideshow.tsx b/src/app/components/DirectorySlideshow.tsx new file mode 100644 index 0000000..63a9991 --- /dev/null +++ b/src/app/components/DirectorySlideshow.tsx @@ -0,0 +1,59 @@ +import { useEffect, useState } from 'react'; +import { listDirectory, getWebDAVBaseUrl, type EntryInfo } from '../webdav'; +import { IMAGE_EXTS } from './MediaEntry'; + +interface Props { + path: string; +} + +export default function DirectorySlideshow({ path }: Props) { + const [images, setImages] = useState([]); + const [idx, setIdx] = useState(0); + + useEffect(() => { + if (!path) { setImages([]); return; } + listDirectory(path) + .then(entries => { + const imgs = entries.filter(e => { + if (e.type !== 'file') return false; + const ext = e.name.split('.').pop()?.toLowerCase() ?? ''; + return IMAGE_EXTS.has(ext); + }); + setImages(imgs); + setIdx(0); + }) + .catch(() => setImages([])); + }, [path]); + + useEffect(() => { + if (images.length <= 1) return; + const t = setInterval(() => setIdx(i => (i + 1) % images.length), 4000); + return () => clearInterval(t); + }, [images.length]); + + if (images.length === 0) return null; + + const current = images[idx]; + + return ( +
+ {current.name} + {images.length > 1 && ( +
+ {images.map((_, i) => ( +
+ )} +
+ ); +} diff --git a/src/app/components/StatusPage.tsx b/src/app/components/StatusPage.tsx index 446f250..402d705 100644 --- a/src/app/components/StatusPage.tsx +++ b/src/app/components/StatusPage.tsx @@ -3,6 +3,7 @@ import { HardDrive, Activity, Wifi, Radio, Clock, RefreshCw, Loader2, Printer, P import { listDirectory, deletePath, getFileContents, getWebDAVBaseUrl, humanFileSize, splitPath, type EntryInfo } from '../webdav'; import { toast } from 'sonner'; import { MediaEntry } from './MediaEntry'; +import DirectorySlideshow from './DirectorySlideshow'; import { useWs } from '../ws'; import DeviceDetailOverlay from './DeviceDetailOverlay'; import MediaSet from './MediaSet'; @@ -25,8 +26,7 @@ export default function StatusPage({ config, setConfig, onOpenFileManager }: Sta psram: { total: 8192, free: 4096 }, }; - // Overlay state for active device - const [showDeviceOverlay, setShowDeviceOverlay] = useState(false); + const [showDeviceOverlay, setShowDeviceOverlay] = useState(false); // Find the first enabled device as the active device const findActiveDevice = () => { if (config.iec?.devices) { @@ -41,6 +41,9 @@ export default function StatusPage({ config, setConfig, onOpenFileManager }: Sta }; const activeDevice = findActiveDevice(); + const activeDir = activeDevice + ? (activeDevice.base_url || splitPath(activeDevice.url || '/').parent) + : null; const mediaSetFiles: string[] | null = (() => { if (!activeDevice?.url) return null; @@ -172,6 +175,8 @@ export default function StatusPage({ config, setConfig, onOpenFileManager }: Sta + {activeDir && } + {mediaSetFiles && (