Files
bookorbit/client/src/features/library/composables/folder-picker/folder-picker-context.ts
T
neon faee78370d 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.
2026-10-24 04:04:00 +00:00

51 lines
2.2 KiB
TypeScript

import { inject, type ComputedRef, type InjectionKey, type Ref } from 'vue'
import type { OrganizationMode } from '@bookorbit/types'
import type { FolderPickerKind, FolderStatus, PickerLibrary } from './folder-picker-rules'
import type { FolderPickerData } from './useFolderPickerData'
import type { FolderPickerSelection } from './useFolderPickerSelection'
import type { FolderPickerTree } from './useFolderPickerTree'
export interface FolderPickerContext {
data: FolderPickerData
tree: FolderPickerTree
selection: FolderPickerSelection
kind: ComputedRef<FolderPickerKind>
multiple: ComputedRef<boolean>
/** Every library with folders, this one included and marked `self`. */
libraries: ComputedRef<PickerLibrary[]>
others: ComputedRef<PickerLibrary[]>
own: ComputedRef<string[]>
libraryName: ComputedRef<string>
mode: Ref<OrganizationMode>
modeLocked: ComputedRef<boolean>
phone: Ref<boolean>
/** A folder just revealed, tinted for a moment so the eye finds it. */
flash: Ref<string | null>
/** The text being found by name, for highlighting matches. */
findQuery: Ref<string>
newFolder: { name: Ref<string>; error: Ref<string | null>; busy: Ref<boolean> }
/** The View menu is open; Escape then closes the menu, not the picker. */
menuOpen: Ref<boolean>
reveal: (path: string) => void
focusFolder: (path: string) => void
toggleFolder: (path: string, event?: MouseEvent | KeyboardEvent) => void
openNewFolder: (parent: string) => void
submitNewFolder: () => Promise<void>
cancelNewFolder: () => void
booksIn: (path: string) => number | null
/** "3 books", or "3 episodes" when choosing for podcasts. */
countLabel: (count: number) => string
/** "3 books" as what a folder holds, or "3 episodes" for podcasts. */
holdsLabel: (count: number) => string
/** Why ticking a folder would put books in two libraries, for a status that warns. */
describeOverlap: (path: string, status: FolderStatus) => string
}
export const FOLDER_PICKER: InjectionKey<FolderPickerContext> = Symbol('folder-picker')
export function useFolderPickerContext(): FolderPickerContext {
const context = inject(FOLDER_PICKER)
if (!context) throw new Error('Folder picker parts need the context provided by FolderPickerModal')
return context
}