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:
@@ -0,0 +1,35 @@
|
||||
import { Film, Folder, Globe, Server, Upload, type LucideIcon } from "lucide-react";
|
||||
import { YouTubeIcon } from "../lib/brandIcons";
|
||||
import type { FileFolder } from "../lib/api";
|
||||
|
||||
// A library folder's and a file's origin, named and drawn. The backend sends a source folder's KEY
|
||||
// (`youtube`, `plex`, `upload`, `hub`, `site:<host>`, see backend downloads/folders.py) and leaves
|
||||
// its name to the client, in the reader's language; an own folder carries the name its user gave it.
|
||||
|
||||
const SITE_PREFIX = "site:";
|
||||
|
||||
type T = (key: string) => string;
|
||||
|
||||
/** The name of a source: a site is its host, the rest are words of the UI. */
|
||||
export function sourceLabel(key: string, t: T): string {
|
||||
if (key.startsWith(SITE_PREFIX)) return key.slice(SITE_PREFIX.length);
|
||||
if (key === "youtube" || key === "plex" || key === "upload" || key === "hub")
|
||||
return t(`files.source.${key}`);
|
||||
return key;
|
||||
}
|
||||
|
||||
export function sourceIcon(key: string): LucideIcon | typeof YouTubeIcon {
|
||||
if (key === "youtube") return YouTubeIcon;
|
||||
if (key === "plex") return Film;
|
||||
if (key === "upload") return Upload;
|
||||
if (key === "hub") return Server;
|
||||
return Globe;
|
||||
}
|
||||
|
||||
export function folderLabel(folder: FileFolder, t: T): string {
|
||||
return folder.kind === "own" ? (folder.name ?? "") : sourceLabel(folder.source_key ?? "", t);
|
||||
}
|
||||
|
||||
export function folderIcon(folder: FileFolder): LucideIcon | typeof YouTubeIcon {
|
||||
return folder.kind === "own" ? Folder : sourceIcon(folder.source_key ?? "");
|
||||
}
|
||||
Reference in New Issue
Block a user