/** The extensions the backend's parser knows; anything else is refused here * rather than read as "pasted text" with a nonsense title. */ const PLAYLIST_EXT = /\.(m3u8?|pls|xspf|csv|json|txt)$/i; /** The playlist-FILE door picks FIRST, like the folder door — the phone's * own document picker (the storage plugin's `pick_file`). Every type is * offered on purpose: Android's providers report m3u and pls under half a * dozen types and often as plain bytes, so a filter that names one greys * out the very file being looked for; the extension is checked here * instead. A document with no path on this phone is copied into the app's * cache under its own name, up to the size the parser itself refuses. * Returns { path, name } — or null when the picker was dismissed. */ export async function pickImportFile() { let picked; try { picked = await api.pickFile("*/*", 8 * 1024 * 1024); } catch (e) { if (/cancelled/.test(String(e))) return null; throw e; } if (!picked?.path) throw new Error("That file isn't on this phone's storage — copy it here first, then import it."); const name = picked.name || ""; if (!PLAYLIST_EXT.test(name)) throw new Error("“" + (name || "That file") + "” isn't a playlist file — M3U, M3U8, PLS, XSPF, CSV, JSON or TXT."); return { path: picked.path, name }; }