feat(StatusPage): improve active image selection logic and enhance error handling for media files

This commit is contained in:
Jaime Idolpx 2026-06-11 13:31:53 -04:00
parent 0a9cb90acc
commit f89e57a8be

View File

@ -1,6 +1,6 @@
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import { HardDrive, Activity, Wifi, Radio, Clock, RefreshCw, Loader2, Printer, Power, Computer, Download, Trash2, Eye, FolderOpen } from 'lucide-react'; import { HardDrive, Activity, Wifi, Radio, Clock, RefreshCw, Loader2, Printer, Power, Computer, Download, Trash2, Eye, FolderOpen } from 'lucide-react';
import { listDirectory, deletePath, fileExists, getFileContents, getWebDAVBaseUrl, humanFileSize, splitPath, type EntryInfo } from '../webdav'; import { listDirectory, deletePath, getFileContents, getWebDAVBaseUrl, humanFileSize, splitPath, type EntryInfo } from '../webdav';
import { toast } from 'sonner'; import { toast } from 'sonner';
import { MediaEntry } from './MediaEntry'; import { MediaEntry } from './MediaEntry';
import DirectorySlideshow from './DirectorySlideshow'; import DirectorySlideshow from './DirectorySlideshow';
@ -70,22 +70,23 @@ export default function StatusPage({ config, setConfig, onOpenFileManager }: Sta
if (!url) { setActiveImage(null); return; } if (!url) { setActiveImage(null); return; }
const activeEntry = mediaSetFiles?.find(e => mediaSetEntryUrl(e) === url); const activeEntry = mediaSetFiles?.find(e => mediaSetEntryUrl(e) === url);
const entryName = activeEntry && typeof activeEntry === 'object' ? activeEntry.name : undefined; const entryName = activeEntry && typeof activeEntry === 'object' ? activeEntry.name : undefined;
const urlBase = url.replace(/\.[^/.]+$/, ''); const urlBase = url.replace(/\.[^/.]+$/, '').split('/').pop() ?? '';
const bases = entryName ? [`${splitPath(url).parent}/${entryName}`, urlBase] : [urlBase]; const dir = splitPath(url).parent;
const exts = ['png', 'jpg', 'jpeg', 'gif', 'webp']; const normalize = (s: string) => s.toLowerCase().replace(/[_-]+/g, ' ').trim();
const targets = [entryName ? normalize(entryName) : null, normalize(urlBase)].filter(Boolean) as string[];
const imgExts = new Set(['png', 'jpg', 'jpeg', 'gif', 'webp', 'bmp']);
let cancelled = false; let cancelled = false;
(async () => { listDirectory(dir)
for (const base of bases) { .then(entries => {
for (const ext of exts) { if (cancelled) return;
const path = `${base}.${ext}`; const images = entries.filter(e => e.type === 'file' && imgExts.has(e.name.split('.').pop()?.toLowerCase() ?? ''));
if (await fileExists(path)) { for (const target of targets) {
if (!cancelled) setActiveImage(path); const match = images.find(e => normalize(e.name.replace(/\.[^/.]+$/, '')) === target);
return; if (match) { setActiveImage(match.path); return; }
} }
} setActiveImage(null);
} })
if (!cancelled) setActiveImage(null); .catch(() => { if (!cancelled) setActiveImage(null); });
})();
return () => { cancelled = true; }; return () => { cancelled = true; };
}, [activeDevice?.url, mediaSetFiles]); }, [activeDevice?.url, mediaSetFiles]);