Everything written this session that has not been through the device: rounds 43 to 48 (each patch adversarially verified, 43's transient-notice expectation fixed), a partial round 49, the pipeline scripts, the Android Auto design and the icon comparison mock. Also the two harness changes that were never A/B'd — adaptive waits, which may only shorten a declared wait and never lengthen it, and a ship that runs the mock walk and the deploy at the same time. The A/B and its 255-step baseline are in handoff/tools; main stays at what the phone has actually walked.
31 lines
1.6 KiB
Plaintext
31 lines
1.6 KiB
Plaintext
/** The folder door picks FIRST — the phone's own document-tree picker — so
|
|
* the review only opens for a folder that was actually chosen. The tree has
|
|
* to be on this phone's storage: the backend walks a path, and a cloud
|
|
* provider's tree has none. Returns null when the picker was dismissed. */
|
|
export async function pickImportFolder() {
|
|
let picked;
|
|
try { picked = await api.pickLibraryFolder(); }
|
|
catch (e) { if (/cancelled/.test(String(e))) return null; throw e; }
|
|
if (!picked?.path) throw new Error("That folder has no path the phone can read — pick one on this phone's storage.");
|
|
return picked.path;
|
|
}
|
|
/** Stage a folder of audio files. The backend walks the folder and its disc
|
|
* subfolders, orders by the files' own track numbers when every one carries
|
|
* a distinct one and by natural filename order otherwise, and matches each
|
|
* file against the library by path. Every row comes back local, so there is
|
|
* nothing for the catalog pass to verify. */
|
|
export async function startFolder(path) {
|
|
const g = ++gen;
|
|
Object.assign(importer, { door: "folder", source: path, busy: true, error: "", progress: null, draft: null, name: "", includeUnresolved: true, checks: {}, committing: false, links: false });
|
|
try {
|
|
const draft = await api.playlistImportFolder(path);
|
|
if (g !== gen) return;
|
|
importer.busy = false;
|
|
if (!draft) { importer.error = "Nothing came back from that folder."; return; }
|
|
importer.draft = draft;
|
|
importer.name = draft.name ?? "";
|
|
} catch (e) {
|
|
if (g === gen) { importer.error = String(e); importer.busy = false; }
|
|
}
|
|
}
|