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
+9 -3
View File
@@ -1,10 +1,10 @@
// Per-user customization of a side panel's group cards: their order, which are collapsed, and
// which are hidden — the same "customize" affordance the feed filter rail had, generalized so
// every panel (feed / plex / playlists) has its own saved layout. Persisted to localStorage and
// every panel (feed / plex / playlists / files) has its own saved layout. Persisted to localStorage and
// the server-side `preferences` blob (schemaless), so it follows the account across devices.
import { LS, readAccount, writeAccount } from "./storage";
export type PanelId = "feed" | "plex" | "playlists";
export type PanelId = "feed" | "plex" | "playlists" | "files";
export interface PanelLayout {
order: string[];
@@ -30,6 +30,7 @@ const PANEL_ORDER: Record<PanelId, string[]> = {
"contentrating",
],
playlists: ["manage", "list"],
files: ["library", "sources", "own"],
};
// localStorage key per panel (feed keeps its original key for backward compatibility).
@@ -37,13 +38,18 @@ const LS_KEY: Record<PanelId, string> = {
feed: LS.sidebarLayout,
plex: LS.plexLayout,
playlists: LS.playlistsLayout,
files: LS.filesLayout,
};
// Key on the server `preferences` blob per panel (feed keeps its original key).
export const PREF_KEY: Record<PanelId, "sidebarLayout" | "plexLayout" | "playlistsLayout"> = {
export const PREF_KEY: Record<
PanelId,
"sidebarLayout" | "plexLayout" | "playlistsLayout" | "filesLayout"
> = {
feed: "sidebarLayout",
plex: "plexLayout",
playlists: "playlistsLayout",
files: "filesLayout",
};
export function defaultLayout(panel: PanelId): PanelLayout {