diff options
Diffstat (limited to 'docs/playlists.md')
| -rw-r--r-- | docs/playlists.md | 12 |
1 files changed, 6 insertions, 6 deletions
diff --git a/docs/playlists.md b/docs/playlists.md index 232eae5..6378e63 100644 --- a/docs/playlists.md +++ b/docs/playlists.md @@ -69,7 +69,7 @@ were *wrong* are more useful than the ones that were right. | 1 | MNP MINOR bump to **2.1** | The wire version was already **3.0**; the bump is **3.1**, and `MNP_MIN_SUPPORTED` does not move because nothing here is required | | 2 | `kind` is `playlist:<uuid>` | That refuses `playlist:favorites` — the one playlist every account has. The pattern is `[A-Za-z0-9_-]{1,64}` | | 3 | The blob is **msgpack**, "same as everything else on MNP" | The node never parses it, so the encoding is a private choice; MNP's codec is private to `transport.js`, a classic script. **JSON**, which is what keeps the merge runnable by `node` with nothing around it | -| 4 | Delete confirms inline, "not `window.confirm()`, which blocks the SPA" | Backwards. `prompt()` **throws** in Electron and is banned by a test; `confirm()` is measured to work and is used in twenty places. A *name* needs a field; a *confirmation* uses `confirm` | +| 4 | Delete confirms inline, "not `window.confirm()`, which blocks the SPA" | Right, for a reason nobody had yet. `prompt()` **throws** in Electron; `confirm()` opens, and leaves the window unable to type once it closes. A *name* needs a field; a *confirmation* uses `ask()` from `ask.js`, drawn by the page | | 5 | Submenus fly out, and are a sheet on a coarse pointer | They **expand in place**, which the account menu's language list already does. No flipping, no hover intent, no separate mobile design. The tracklist level loads when it is expanded | | 6 | Add all four new files to `STATIC_FILES` / `SPLIT_FILES` | Those lists check hook ordering. The four hookless modules do not belong in them, exactly as `source-merge.js` does not; only `menu.js` and `playlist-menu.js` do | | 7 | Four modules | **Five**: `playlist-crypto.js` is split out so seal/open can be executed standalone. A crypto layer that cannot be executed is one nobody has checked | @@ -921,15 +921,15 @@ Rules the list items carry: - **New** takes a name only, as asked, typed into **a field**: `window.prompt` does not exist in the desktop client — it throws, which is how the Files toolbar's New folder button came to do nothing at all, and - `test_no_prompt_in_the_spa.py` refuses a build that reintroduces it. The name + `test_no_native_dialogs_in_the_spa.py` refuses a build that reintroduces it. The name must be unique *for this user*, checked against the manifest and folded for case and accents, so "Soirée" and "soiree" are not two playlists. - **Delete** never lists Favourites (§5.1) — the store refuses it anyway, and offering an action that always fails is worse than not offering it. It asks - with **`window.confirm`**, which is the correction: `prompt()` throws in - Electron and is banned by a test, while `confirm()` is measured to work and is - used in twenty places in this SPA. A deletion is a tombstone and nothing in - the interface undoes it, so it is worth one question. + with **`ask()`** (`ask.js`), not `window.confirm`: in the desktop client a + native `confirm()` leaves the window unable to type after it closes, so the + whole SPA asks in the page. A deletion is a tombstone and nothing in the + interface undoes it, so it is worth one question. - **Remove a track** is the two-level one, expanded in place: pick the playlist, then its tracklist, one click per track. The second level is read from IndexedDB when it is opened (§10.1's `loadItems`). |