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.
24 lines
1.1 KiB
Plaintext
24 lines
1.1 KiB
Plaintext
/* ── export: the desktop's five profiles, in the desktop's order and its
|
|
own words. The file itself is built in Rust by the writers the desktop
|
|
uses (playlist_formats), so nothing here knows what an M3U8 looks like —
|
|
two exports that drift are worse than one that is missing. What comes
|
|
back is only where it went: a path on the desktop, the document's name
|
|
on the phone, and null when the sheet was dismissed. ── */
|
|
export const EXPORTS = [
|
|
["m3u8", "M3U8", "one line a track — most players read it"],
|
|
["xspf", "XSPF", "an open format, titles and times carried"],
|
|
["pls", "PLS", "older players want this one"],
|
|
["csv", "CSV", "a row a track, for a spreadsheet"],
|
|
["json", "Backup (JSON)", "everything about it, this app's own"],
|
|
];
|
|
/** Export `p` as `format` — the system's own sheet says where it goes.
|
|
* False, and nothing said, when that sheet was dismissed: nothing
|
|
* happened, so there is nothing to report. */
|
|
export async function exportPlaylist(p, format) {
|
|
const where = await api.playlistExport(p.id, format);
|
|
if (!where) return false;
|
|
note(`Exported as ${basename(where)}`);
|
|
return true;
|
|
}
|
|
|