fix(library): split a stored path on the separator it was written with

This commit is contained in:
2026-10-11 11:59:38 +07:00
parent 0ac9f2ddfa
commit 17624945f9
3 changed files with 14 additions and 5 deletions
+4 -1
View File
@@ -1017,7 +1017,10 @@ async function clearWalk(folder: string): Promise<void> {
async function framesAt(root: FileSystemDirectoryHandle, rels: string[]): Promise<WalkFile[]> {
const dirs = new Map<string, FileSystemDirectoryHandle>();
const out: WalkFile[] = [];
for (const rel of rels) {
for (const raw of rels) {
// A walk file written on Windows spells its frame `2017\2017-02-PHUNINH\_DSF1.RAF`;
// normalising once here means everything below sees the same `/` as the rest of the catalogue.
const rel = normPath(raw);
const cut = rel.lastIndexOf('/');
const at = cut < 0 ? '' : rel.slice(0, cut);
let dir = dirs.get(at);
+7 -3
View File
@@ -28,6 +28,7 @@ import {
listEdits,
listFolders,
listPhotos,
normPath,
renameFolder,
restoreCatalogue,
setBackupTileFetcher,
@@ -53,7 +54,9 @@ export async function readBackupTile(id: string): Promise<Blob | null> {
try {
const root = await folderHandle();
if (!root) return null;
const parts = id.split('/');
// A frame id is `folder/dir/name`; a Windows-written one can say `\`, so it is
// spelled the same way here as everywhere else before it is cut.
const parts = normPath(id).split('/');
const name = parts.pop() as string;
const dir = await at(root, [THUMBS, ...parts].join('/'));
const file = await dir.getFileHandle(spell(name));
@@ -274,7 +277,8 @@ async function at(root: FileSystemDirectoryHandle, rel: string, create = false):
if (!cache) opened.set(root, (cache = new Map()));
let node = root;
let path = '';
for (const part of rel.split('/')) {
// Both separators: a path handed in from a Windows-written id may say `\`.
for (const part of rel.split(/[\\/]/)) {
if (!part) continue;
const name = spell(part);
path = path ? `${path}/${name}` : name;
@@ -345,7 +349,7 @@ export async function backupNow(onProgress?: (p: BackupProgress) => void): Promi
const blob = photo.thumb ?? (await getPhotoThumb(photo.id));
if (!blob) continue;
if (had.get(photo.id) === blob.size) continue;
const parts = photo.id.split('/');
const parts = normPath(photo.id).split('/');
parts.pop();
const rel = [THUMBS, ...parts, photo.name].join('/');
try {
+3 -1
View File
@@ -52,7 +52,9 @@ export const SYSTEM_DIR = /^[.@]|^\$RECYCLE\.BIN$|^RECYCLER$|^System Volume Info
export async function openAt(root: FileSystemDirectoryHandle, rel: string): Promise<FileSystemDirectoryHandle | null> {
let dir = root;
try {
for (const part of rel.split('/').filter(Boolean)) dir = await dir.getDirectoryHandle(part);
// ponytail: a path written on Windows can arrive with `\`, so both separators
// split it; a POSIX name holding a literal `\` is the price (normPath pays it already).
for (const part of rel.split(/[\\/]/).filter(Boolean)) dir = await dir.getDirectoryHandle(part);
} catch {
return null;
}