From 14cafca7409fe7fcd2f0455651a7be90765c77df Mon Sep 17 00:00:00 2001 From: Timothy Date: Tue, 7 Jul 2026 15:39:54 +0200 Subject: [PATCH] feat(web): media browse, global search & trash screens (#141) - MediaBrowseScreen (/app/media): one parameterized screen for all 9 top-level kinds with an in-screen kind switcher, per-kind search box, 100/page paging - SearchScreen (/app/search): grouped per-kind results with counts + 'See all'; TopBar search input now navigates here - TrashScreen (/app/trash): state:FileNotFound results, multi-select + Empty Trash via DELETE /api/media-items and /api/maintenance/empty_trash (confirm dialogs) - Shared media/mediaKinds (icon/label maps, hueOf, duration helpers) + MediaPosterCard; ChannelBuilder and CollectionsScreen now reuse the single-source maps (their exhaustive Record had to cover the 6 new kinds anyway) - api: search.ts, mediaItems.ts, maintenance.ts (+ URL-assert tests) - One consolidated 'Browse' nav entry with an in-screen kind switcher instead of 9 per-kind nav rows (deviation from Blazor's per-kind Media links) - Nav: Media group gains Browse/Search/Trash; Settings Classic-UI help trimmed Co-Authored-By: Claude Fable 5 --- web/src/App.tsx | 78 ++++++++- web/src/api/index.ts | 3 + web/src/api/maintenance.test.ts | 25 +++ web/src/api/maintenance.ts | 17 ++ web/src/api/mediaItems.test.ts | 31 ++++ web/src/api/mediaItems.ts | 17 ++ web/src/api/search.test.ts | 63 +++++++ web/src/api/search.ts | 33 ++++ web/src/builder/ChannelBuilder.tsx | 40 +---- web/src/media/MediaPosterCard.tsx | 73 ++++++++ web/src/media/mediaKinds.ts | 113 ++++++++++++ web/src/screens/CollectionsScreen.tsx | 13 +- web/src/screens/MediaBrowseScreen.tsx | 201 +++++++++++++++++++++ web/src/screens/SearchScreen.tsx | 176 +++++++++++++++++++ web/src/screens/SettingsScreen.tsx | 2 +- web/src/screens/TrashScreen.tsx | 243 ++++++++++++++++++++++++++ web/src/shell.css | 104 +++++++++++ 17 files changed, 1178 insertions(+), 54 deletions(-) create mode 100644 web/src/api/maintenance.test.ts create mode 100644 web/src/api/maintenance.ts create mode 100644 web/src/api/mediaItems.test.ts create mode 100644 web/src/api/mediaItems.ts create mode 100644 web/src/api/search.test.ts create mode 100644 web/src/api/search.ts create mode 100644 web/src/media/MediaPosterCard.tsx create mode 100644 web/src/media/mediaKinds.ts create mode 100644 web/src/screens/MediaBrowseScreen.tsx create mode 100644 web/src/screens/SearchScreen.tsx create mode 100644 web/src/screens/TrashScreen.tsx diff --git a/web/src/App.tsx b/web/src/App.tsx index fbce3ee0b..b5a18844e 100644 --- a/web/src/App.tsx +++ b/web/src/App.tsx @@ -62,7 +62,10 @@ import { CollectionsScreen } from './screens/CollectionsScreen'; import { FFmpegProfilesScreen } from './screens/FFmpegProfilesScreen'; import { FillerPresetsScreen } from './screens/FillerPresetsScreen'; import { LogsScreen } from './screens/LogsScreen'; +import { MediaBrowseScreen } from './screens/MediaBrowseScreen'; +import { SearchScreen } from './screens/SearchScreen'; import { SettingsScreen } from './screens/SettingsScreen'; +import { TrashScreen } from './screens/TrashScreen'; import { TroubleshootingScreen } from './screens/TroubleshootingScreen'; import { WatermarksScreen } from './screens/WatermarksScreen'; import { navigateToPath } from './routing'; @@ -138,6 +141,9 @@ type ScreenId = | 'guide' | 'schedules' | 'playouts' + | 'media' + | 'search' + | 'trash' | 'collections' | 'fillerPresets' | 'libraries' @@ -246,6 +252,41 @@ const routes: ScreenRoute[] = [ placeholder: 'Playouts workspace', badge: 3 }, + { + id: 'media', + path: '/app/media', + label: 'Browse', + title: 'Browse Media', + kicker: 'Media', + description: 'Browse indexed movies, shows, episodes, music and more by kind.', + icon: