feat(files): the Files page — the library in one aligned list, its folders in a rail

Files is the one library: every done file, the ones shared with me, or one
folder's, picked in a side rail (sources, own folders, the storage meter) and
mirrored to ?folder=. One table with every kind of value in its own column;
Copy link, Share and Save in sight, every action on a right click: play,
cut, rename in the row, move to an own folder or back home, keep, details,
re-download, delete.

The Downloads page keeps only the queue until the tray replaces it. The old
/api/downloads library routes are gone: list shared, upload, the details
PATCH, delete, the file and the usage now live under /api/files, and a
listed file says which source it came from. The job's "expired" flag is gone
with the state it described.
This commit is contained in:
2026-10-11 05:34:25 +02:00
parent 1a1665b8ec
commit 85aa917b38
65 changed files with 2295 additions and 1044 deletions
+22 -19
View File
@@ -10,6 +10,7 @@ import { NavigationProvider } from "./components/NavigationProvider";
import { FeedFiltersProvider } from "./components/FeedFiltersProvider";
import { SavedViewsProvider } from "./components/SavedViewsProvider";
import { PlaylistsProvider } from "./components/PlaylistsProvider";
import { FilesProvider } from "./components/FilesProvider";
import { PlexProvider } from "./components/PlexProvider";
import { PlexViewBridge } from "./components/PlexViewBridge";
import { ChannelsProvider } from "./components/ChannelsProvider";
@@ -81,27 +82,29 @@ const root =
<NavigationProvider>
<FeedFiltersProvider>
<PlaylistsProvider>
<PlexProvider>
<PlexViewBridge>
{/* SavedViewsProvider sits below BOTH filter providers so it can switch its
<FilesProvider>
<PlexProvider>
<PlexViewBridge>
{/* SavedViewsProvider sits below BOTH filter providers so it can switch its
source (feed ⟷ plex) by the active page and read the right live filters. */}
<SavedViewsProvider>
<ChannelsProvider>
<FeedViewProvider>
<PrefsProvider>
<WizardProvider>
{/* The same quiet screen as the gate's, so a chunk that is still
<SavedViewsProvider>
<ChannelsProvider>
<FeedViewProvider>
<PrefsProvider>
<WizardProvider>
{/* The same quiet screen as the gate's, so a chunk that is still
loading when the gate opens continues it instead of blanking. */}
<Suspense fallback={<BootScreen />}>
<App />
</Suspense>
</WizardProvider>
</PrefsProvider>
</FeedViewProvider>
</ChannelsProvider>
</SavedViewsProvider>
</PlexViewBridge>
</PlexProvider>
<Suspense fallback={<BootScreen />}>
<App />
</Suspense>
</WizardProvider>
</PrefsProvider>
</FeedViewProvider>
</ChannelsProvider>
</SavedViewsProvider>
</PlexViewBridge>
</PlexProvider>
</FilesProvider>
</PlaylistsProvider>
</FeedFiltersProvider>
</NavigationProvider>