mirror of
https://github.com/bookorbit/bookorbit.git
synced 2026-11-03 08:21:39 -06:00
feat(library): rebuild the folder picker as a tree with a live plan
Pick folders from a lazily loaded tree with find-by-name and typed paths, beside a plan showing the books each organization mode would import, overlaps with other libraries, and folders no library reads yet. New ManageLibraries /path routes walk folders within entry and time bounds. Fix the scanner filing a disc-named library folder such as /mnt/disk1 under the folder above it, and move books already filed there onto their primary file on the next scan.
This commit is contained in:
@@ -13,3 +13,95 @@ export interface CreateFolderRequest {
|
||||
}
|
||||
|
||||
export type CreateFolderResult = DirectoryEntry;
|
||||
|
||||
/** Why a folder could or could not be read. `blocked` is a system path BookOrbit never opens. */
|
||||
export type FolderState = "ok" | "denied" | "missing" | "blocked";
|
||||
|
||||
export interface FolderListingEntry extends DirectoryEntry {
|
||||
/** On a different filesystem than its parent: a Docker volume, a NAS share. */
|
||||
mount: boolean;
|
||||
/** An operating-system folder directly under `/` (bin, usr...), hidden unless asked for. */
|
||||
system: boolean;
|
||||
/** BookOrbit's own data folder (covers, caches, plugins). */
|
||||
appData: boolean;
|
||||
/** Whether it holds any listable folder. Null when the parent was too large to check every child. */
|
||||
hasChildren: boolean | null;
|
||||
}
|
||||
|
||||
export interface FolderListing {
|
||||
path: string;
|
||||
state: FolderState;
|
||||
entries: FolderListingEntry[];
|
||||
/** Only the first folders by name are listed; the rest are reached by typing a path or finding. */
|
||||
truncated: boolean;
|
||||
}
|
||||
|
||||
/** `pending`: the request's time ran out before this folder was walked; ask for it again. */
|
||||
export type FolderSummaryState = FolderState | "pending";
|
||||
|
||||
/**
|
||||
* Counts for one folder from a walk that stops at a fixed number of entries. When `truncated` is
|
||||
* true every count is a lower bound.
|
||||
*/
|
||||
export interface FolderSummary {
|
||||
path: string;
|
||||
state: FolderSummaryState;
|
||||
/** Book files: what File as Book would import. */
|
||||
files: number;
|
||||
/** Books as Folder as Book: one per file directly inside, plus one per folder below holding book files. */
|
||||
folderBooks: number;
|
||||
/** Book files per format, keyed by lower-case extension. */
|
||||
formats: Record<string, number>;
|
||||
/** Folders directly inside. */
|
||||
folders: number;
|
||||
/** Folders below holding several differently named books, which Folder as Book reads as one. */
|
||||
mergedFolders: number;
|
||||
/** Folders below holding several audio files, which File as Book reads as one book each. */
|
||||
splitAudioFolders: number;
|
||||
truncated: boolean;
|
||||
}
|
||||
|
||||
export interface FolderSummariesRequest {
|
||||
paths: string[];
|
||||
}
|
||||
|
||||
export interface FolderInspection extends FolderSummary {
|
||||
/** Size of the book files counted. */
|
||||
bytes: number;
|
||||
/** The first book files found, relative to the folder. */
|
||||
samples: string[];
|
||||
}
|
||||
|
||||
export interface FolderSearchResult {
|
||||
results: string[];
|
||||
truncated: boolean;
|
||||
}
|
||||
|
||||
export interface FolderPickerLibrary {
|
||||
id: number;
|
||||
name: string;
|
||||
icon: string | null;
|
||||
type: string;
|
||||
folders: string[];
|
||||
}
|
||||
|
||||
export interface FolderPlaces {
|
||||
root: string;
|
||||
/** Folders on their own filesystem near the browse root. */
|
||||
mounts: string[];
|
||||
/** BookOrbit's data folder when it is inside the browse root. */
|
||||
appDataPath: string | null;
|
||||
/** Every library and the folders it reads, for landmarks and overlap checks. */
|
||||
libraries: FolderPickerLibrary[];
|
||||
}
|
||||
|
||||
export interface UnclaimedFolder {
|
||||
path: string;
|
||||
files: number;
|
||||
formats: Record<string, number>;
|
||||
}
|
||||
|
||||
export interface UnclaimedFolders {
|
||||
folders: UnclaimedFolder[];
|
||||
truncated: boolean;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user