mirror of
https://github.com/Stirling-Tools/Stirling-PDF.git
synced 2026-09-03 05:10:16 +03:00
docs(folders): put back the halves that carried the reason
Cutting each block to its first sentence sometimes kept the what and dropped the why, which leaves a comment saying what the signature already says. Those are deleted where the name covers them, and where the second sentence was the point it is back: the OS error codes behind isAlreadyExists, why a virtual folder cannot hang off a server one, the effect that snaps folder selection back to root.
This commit is contained in:
@@ -97,7 +97,7 @@ interface FolderContextValue {
|
||||
ok: boolean;
|
||||
reason?: "endpoint-missing" | "network" | "server" | "client";
|
||||
}>;
|
||||
/** Create a folder. */
|
||||
/** Create a folder. A child takes its parent's kind; only a root create chooses. */
|
||||
createFolder: (
|
||||
name: string,
|
||||
parentFolderId?: FolderId | null,
|
||||
@@ -113,7 +113,7 @@ interface FolderContextValue {
|
||||
appearance: { color?: string; icon?: string | null },
|
||||
) => Promise<FolderRecord | null>;
|
||||
deleteFolder: (id: FolderId) => Promise<FolderId[]>;
|
||||
/** Mount a directory as a local folder, idempotent per directory. */
|
||||
/** Idempotent per directory: mounting one already mounted returns its record. */
|
||||
mountLocalFolder: (directory: string, name: string) => Promise<FolderRecord>;
|
||||
/** Subdirectories a mount listing found under `parentId`. */
|
||||
registerDiskSubfolders: (parentId: FolderId, records: FolderRecord[]) => void;
|
||||
@@ -602,7 +602,7 @@ export function FolderProvider({ children }: FolderProviderProps) {
|
||||
parentFolderId: FolderId | null = currentFolderId,
|
||||
kind?: FolderKind,
|
||||
): Promise<FolderRecord> => {
|
||||
// A child's kind is its parent's.
|
||||
// A child's kind is its parent's: one subtree, one system of record.
|
||||
const effectiveKind: FolderKind =
|
||||
parentFolderId !== null
|
||||
? requireKind(parentFolderId)
|
||||
|
||||
@@ -21,7 +21,8 @@ export function useNewFolderFlow() {
|
||||
const picked = await pickDirectory();
|
||||
if (!picked) return;
|
||||
const record = await folders.mountLocalFolder(picked.path, picked.name);
|
||||
// The path owns folder selection.
|
||||
// The path owns folder selection: setting state here races the effect that
|
||||
// re-runs with the old pathname and snaps back to root.
|
||||
navigate(`/files/${record.id}`);
|
||||
} catch (err) {
|
||||
folders.setError(
|
||||
@@ -58,7 +59,8 @@ export function useNewFolderFlow() {
|
||||
serverFolderBlock,
|
||||
]);
|
||||
|
||||
// Why the single-click surfaces are disabled, or null.
|
||||
// Why the single-click surfaces are disabled, or null. Only the web root blocks:
|
||||
// desktop always has the picker, and subfolders inherit their kind.
|
||||
const createFolderHereBlockedReason =
|
||||
folders.currentFolderId === null && !canPickDirectory
|
||||
? serverFolderBlock
|
||||
|
||||
@@ -7,7 +7,6 @@ export interface PickedDirectory {
|
||||
name: string;
|
||||
}
|
||||
|
||||
/** Whether this build can produce a directory path at all. */
|
||||
export const canPickDirectory = false;
|
||||
|
||||
/** Ask the user for a directory; null when cancelled (or unsupported). */
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
/** Reading a mounted folder's contents straight off the disk. */
|
||||
|
||||
/** One file inside a mounted directory, as the file manager lists it. */
|
||||
export interface DiskFileEntry {
|
||||
/** Absolute path — the file's identity here; nothing about it is stored. */
|
||||
@@ -21,7 +19,6 @@ export interface DiskListing {
|
||||
directories: DiskDirEntry[];
|
||||
}
|
||||
|
||||
/** Whether this build can list a directory at all. */
|
||||
export const canListDirectory = false;
|
||||
|
||||
/**
|
||||
|
||||
@@ -58,7 +58,10 @@ class VirtualFolderStorageService {
|
||||
});
|
||||
}
|
||||
|
||||
/** Create a virtual folder under `parent` (null = root). */
|
||||
/**
|
||||
* Create a virtual folder under `parent` (null = root), which must itself be
|
||||
* virtual: hung off a server folder, a server-side delete orphans the subtree.
|
||||
*/
|
||||
async createFolder(
|
||||
name: string,
|
||||
parentFolderId: FolderId | null,
|
||||
|
||||
@@ -4,7 +4,10 @@ import { connectionModeService } from "@app/services/connectionModeService";
|
||||
import type { ConnectionMode } from "@app/services/connectionModeService";
|
||||
import { useServerFolderBlock as useCoreServerFolderBlock } from "@core/hooks/useServerFolderBlock";
|
||||
|
||||
/** Desktop's blocker speaks in connection modes. */
|
||||
/**
|
||||
* Desktop's blocker speaks in connection modes: local mode has no server at all, so
|
||||
* "storage isn't enabled" would send the user after a setting that does not exist.
|
||||
*/
|
||||
export function useServerFolderBlock(): string | null {
|
||||
const { t } = useTranslation();
|
||||
const coreReason = useCoreServerFolderBlock();
|
||||
|
||||
@@ -103,7 +103,6 @@ export async function listDirectory(
|
||||
return { files: files.slice(0, LIST_CAP), directories };
|
||||
}
|
||||
|
||||
/** Create a subdirectory. */
|
||||
export async function makeDiskDirectory(
|
||||
parent: string,
|
||||
name: string,
|
||||
@@ -185,7 +184,7 @@ export async function writeDiskFile(
|
||||
throw new Error(`No free name for ${name} in ${directory}`);
|
||||
}
|
||||
|
||||
/** The plugin surfaces OS errors as text. */
|
||||
/** The plugin surfaces OS errors as text: EEXIST is 17, Windows 80 or 183. */
|
||||
function isAlreadyExists(err: unknown): boolean {
|
||||
const text = err instanceof Error ? err.message : String(err);
|
||||
return /already exists|file exists|os error (17|80|183)\b/i.test(text);
|
||||
|
||||
Reference in New Issue
Block a user