diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8cbc06d..0e93eeb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,7 +14,8 @@ jobs: strategy: fail-fast: false matrix: - python-version: ['3.11', '3.12'] + # Every version the classifiers in pyproject.toml declare. + python-version: ['3.11', '3.12', '3.13', '3.14'] steps: - name: Checkout code @@ -47,12 +48,10 @@ jobs: - name: Black (format check) run: black --check . - - name: Mypy (advisory — see [tool.mypy] in pyproject.toml) - # Not blocking yet: the codebase predates type checking and carries a - # sizeable pre-existing error backlog. Surfaced in the log so it's - # visible and can be tightened incrementally, without turning every - # unrelated PR red today. - run: mypy mornye || true + - name: Mypy + # Blocking since the backlog reached zero (2026-11). The settings in + # [tool.mypy] are still lenient; tighten them module by module. + run: mypy mornye - name: Pytest (with coverage) run: pytest -v --cov=mornye --cov-report=term-missing --cov-fail-under=30 @@ -81,11 +80,16 @@ jobs: node --check "$f" done - test-windows: - # A pywebview desktop app lives or dies on Windows; the matrix above only - # ever ran on Linux. This doesn't repeat lint/format/mypy — just the test - # suite, to catch path-separator/encoding/subprocess issues Linux CI can't. - runs-on: windows-latest + test-desktop: + # A pywebview desktop app lives or dies on Windows and macOS; the matrix + # above only ever ran on Linux. This doesn't repeat lint/format/mypy — + # just the test suite, to catch path-separator/encoding/subprocess issues + # (and, on macOS, the pyobjc install) that Linux CI can't. + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [windows-latest, macos-latest] steps: - name: Checkout code uses: actions/checkout@v5 diff --git a/.gitignore b/.gitignore index 275a906..e04a6f7 100644 --- a/.gitignore +++ b/.gitignore @@ -30,3 +30,6 @@ htmlcov/ /.claude /mornye.egg-info /.mornye + +# Fresh captures from tests/visual/capture_tui.py; the baseline is committed. +tests/visual/out/ diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 8b51ffe..dad93ed 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -6,7 +6,9 @@ repos: additional_dependencies: ["ruff>=0.12.0"] - repo: https://github.com/psf/black - rev: 24.0 + # Keep in step with the `black` floor in requirements-dev.txt: a hook on + # an older release formats differently from CI. + rev: 26.10.1 hooks: - id: black language_version: python3 diff --git a/docs/mocks/console.css b/docs/mocks/console.css new file mode 100644 index 0000000..e620208 --- /dev/null +++ b/docs/mocks/console.css @@ -0,0 +1,153 @@ +/* docs/mocks/console.css — direction A, "Console da studio" (redesign-plan §2). + A static mock, not the app: values here are proposals for token v2 (voce 8). */ + +@font-face { + font-family: 'JetBrains Mono'; + src: url('../../mornye/frontend/assets/fonts/JetBrainsMono-Variable.woff2') format('woff2'); + font-weight: 100 800; +} + +:root { + /* Graphite, no warm or blue cast: four surfaces, two rules. */ + --g-0: #0d0d0d; /* ground */ + --g-1: #141414; /* panel */ + --g-2: #1b1b1b; /* hover, field */ + --g-3: #242424; /* selected row */ + --rule: #2c2c2c; + --rule-strong: #3d3d3d; + --text: #e8e8e8; + --text-2: #b5b5b5; + --muted: #858585; + /* The one signal: focus, selection, primary action, active level. */ + --signal: #ffb000; + --signal-ink: #120d00; + /* State only, never decoration. */ + --ok: #5ec46b; + --err: #ff5a4f; + + --row: 32px; + --r: 2px; + --font: 'JetBrains Mono', ui-monospace, Menlo, monospace; + color-scheme: dark; +} + +* { box-sizing: border-box; } +html, body { margin: 0; height: 100%; background: var(--g-0); color: var(--text); } +body { + font: 400 13px/1.4 var(--font); + font-variant-ligatures: none; + -webkit-font-smoothing: antialiased; +} + +/* ── Shell ─────────────────────────────────────────────────────────────── */ +.app { display: grid; grid-template: 32px 1fr 40px / 176px 1fr; height: 100vh; } + +.titlebar { + grid-column: 1 / -1; display: flex; align-items: center; gap: 12px; + padding: 0 12px; border-bottom: 1px solid var(--rule); background: var(--g-1); +} +.wordmark { font-weight: 700; letter-spacing: .24em; font-size: 12px; } +.wordmark small { font-weight: 400; color: var(--muted); letter-spacing: .08em; margin-left: 8px; } +.titlebar .rule { flex: 1; height: 1px; background: var(--rule); } + +.rail { border-right: 1px solid var(--rule); background: var(--g-1); padding: 8px 0; overflow: hidden; } +.rail-group { margin-bottom: 12px; } +.rail-head, .label { + font-size: 10.5px; font-weight: 500; letter-spacing: .14em; text-transform: uppercase; color: var(--muted); +} +.rail-head { padding: 8px 16px 4px; } +.rail a { + display: flex; align-items: center; gap: 10px; height: var(--row); padding: 0 16px; + color: var(--text-2); text-decoration: none; font-size: 12px; letter-spacing: .04em; + border-left: 2px solid transparent; +} +.rail a:hover { background: var(--g-2); color: var(--text); } +.rail a.on { border-left-color: var(--signal); color: var(--text); background: var(--g-2); } +.rail a .ico { width: 14px; text-align: center; color: var(--muted); } +.rail a.on .ico { color: var(--signal); } +.rail a .count { margin-left: auto; color: var(--signal); font-size: 11px; } + +.main { overflow: auto; padding: 20px 20px 24px; display: flex; flex-direction: column; gap: 24px; } + +/* ── Panels: the label sits in the border, like a silk-screened legend ── */ +.panel { position: relative; border: 1px solid var(--rule); background: var(--g-1); border-radius: var(--r); } +.panel > .legend { + position: absolute; top: -8px; left: 12px; padding: 0 6px; background: var(--g-0); + font-size: 10.5px; font-weight: 500; letter-spacing: .14em; text-transform: uppercase; color: var(--muted); + line-height: 16px; +} +.panel > .legend b { color: var(--text); font-weight: 500; } +.panel > .legend-r { left: auto; right: 12px; } +.panel-body { padding: 16px; } + +/* ── Controls ──────────────────────────────────────────────────────────── */ +.field { + display: flex; align-items: center; height: var(--row); border: 1px solid var(--rule-strong); + background: var(--g-2); border-radius: var(--r); flex: 1; min-width: 0; +} +.field .pre { padding: 0 10px; color: var(--muted); border-right: 1px solid var(--rule); height: 100%; display: flex; align-items: center; font-size: 11px; letter-spacing: .12em; } +.field input { flex: 1; min-width: 0; background: none; border: 0; color: var(--text); font: inherit; padding: 0 10px; outline: none; } +.field:focus-within { border-color: var(--signal); } + +.btn { + height: var(--row); padding: 0 14px; border: 1px solid var(--rule-strong); background: var(--g-2); + color: var(--text); font: 500 12px var(--font); letter-spacing: .06em; border-radius: var(--r); + cursor: pointer; white-space: nowrap; display: inline-flex; align-items: center; gap: 8px; +} +.btn:hover { border-color: var(--text-2); } +.btn.primary { background: var(--signal); border-color: var(--signal); color: var(--signal-ink); } +.btn.ghost { background: none; } +.btn:focus-visible, a:focus-visible { outline: 1px solid var(--signal); outline-offset: 2px; } +.key { font-size: 10.5px; color: var(--muted); border: 1px solid var(--rule-strong); padding: 0 4px; border-radius: var(--r); } + +/* Signature 1 — the quality display: a readout, not a coloured badge. */ +.qd { + display: inline-flex; align-items: center; height: 20px; padding: 0 6px; gap: 6px; + border: 1px solid var(--signal); color: var(--signal); border-radius: var(--r); + font-size: 11px; font-weight: 500; letter-spacing: .06em; white-space: nowrap; +} +.qd.dim { border-color: var(--rule-strong); color: var(--text-2); } +.state { font-size: 11px; letter-spacing: .1em; text-transform: uppercase; white-space: nowrap; } +.state.ok { color: var(--ok); } +.state.err { color: var(--err); } +.state.run { color: var(--signal); } +.state.idle { color: var(--muted); } + +/* Signature 2 — the segment meter: LED steps, never a smooth fill. */ +.meter { display: inline-flex; gap: 2px; height: 10px; align-items: stretch; vertical-align: middle; } +.meter i { width: 6px; background: var(--rule-strong); } +.meter i.on { background: var(--signal); } +.meter.lg { height: 14px; } +.meter.lg i { width: 8px; } +.meter.err i.on { background: var(--err); } +.meter.ok i.on { background: var(--ok); } + +/* ── Tables: 32px rows, rules not cards ───────────────────────────────── */ +.table { width: 100%; border-collapse: collapse; } +.table th { + height: 28px; text-align: left; font-size: 10.5px; font-weight: 500; letter-spacing: .14em; + text-transform: uppercase; color: var(--muted); border-bottom: 1px solid var(--rule); padding: 0 10px; +} +.table td { height: var(--row); padding: 0 10px; border-bottom: 1px solid var(--rule); white-space: nowrap; } +.table tr:last-child td { border-bottom: 0; } +.table tbody tr:hover td { background: var(--g-2); } +.table tr.sel td { background: var(--g-3); } +.table tr.sel td:first-child { box-shadow: inset 2px 0 0 var(--signal); } +.table .num { color: var(--muted); width: 36px; text-align: right; } +.table .t { color: var(--text); max-width: 0; overflow: hidden; text-overflow: ellipsis; width: 100%; } +.table .t small { color: var(--muted); margin-left: 10px; font-size: 12px; } +.table .dur { color: var(--text-2); text-align: right; } +.check { width: 12px; height: 12px; border: 1px solid var(--rule-strong); display: inline-block; vertical-align: middle; } +.check.on { background: var(--signal); border-color: var(--signal); } + +/* ── Dock ─────────────────────────────────────────────────────────────── */ +.dock { + grid-column: 1 / -1; display: flex; align-items: center; gap: 16px; padding: 0 12px; + border-top: 1px solid var(--rule); background: var(--g-1); font-size: 12px; +} +.dock .what { color: var(--text-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex: 1; } +.dock .sep { width: 1px; height: 20px; background: var(--rule); } +.muted { color: var(--muted); } +.signal { color: var(--signal); } +.row { display: flex; align-items: center; gap: 10px; } +.spacer { flex: 1; } diff --git a/docs/mocks/home.html b/docs/mocks/home.html new file mode 100644 index 0000000..9223d04 --- /dev/null +++ b/docs/mocks/home.html @@ -0,0 +1,134 @@ + + + + + +Mock · Home + + + + +
+
+ MORNYE2.0.6 + + ● downloading 3 / 12 +
+ + + +
+
+ + + +
+ +
+ Album · Spotify + Tidal → Qobuz → Deezer +
+ + + + + + + + + +
+

Night Signals

+
Arden Vale
+
Album202612 tracks41:07Explicit
+
24 / 96 · FLACATMOS
+
+ LabelUPCReleasedGenre + Low Hours Rec.06025678912342026-10-03Electronic +
+
+ + + + 4 selected +
+
+
+
+ +
+ Tracks 12 + + + + + + + + + + + + + +
#TitleQualityTimeState
1Carrier WaveArden Vale24 / 963:42done
2Static BloomArden Vale, Mira Sol24 / 964:05done
3Low HoursArden Vale24 / 963:18
4Second AntennaArden Vale24 / 965:11queued
5Glass HarbourArden Vale24 / 962:57
6Interference (feat. Kō)Arden Vale, Kō16 / 44.13:36
7Northbound Signal Path — Extended Version For The Long DriveArden Vale24 / 967:48
8Dial ToneArden Vale24 / 963:02not found
9Quiet BandArden Vale24 / 962:49
+
+
+ + +
+ + + diff --git a/docs/mocks/make_tui_mock.py b/docs/mocks/make_tui_mock.py new file mode 100644 index 0000000..ab8bbfc --- /dev/null +++ b/docs/mocks/make_tui_mock.py @@ -0,0 +1,222 @@ +"""Writes docs/mocks/tui-download.html: the TUI's Download panel, direction A. + +A 120×40 character grid drawn with the same palette as console.css, so the +two materials of the one interface can be judged side by side. Run it again +after changing the layout below: python docs/mocks/make_tui_mock.py +""" + +from __future__ import annotations + +import html +from pathlib import Path + +W, H = 120, 40 +SIDE = 22 # sidebar box width + +Seg = tuple[str, str] # (text, css class) + + +def line(*segs: Seg, width: int = W, fill: str = " ") -> list[Seg]: + used = sum(len(t) for t, _ in segs) + assert used <= width, (used, width, segs) + return [*segs, (fill * (width - used), "")] + + +def box( + width: int, + title: str, + right: str, + body: list[list[Seg]], + height: int, + focus: bool = False, +) -> list[list[Seg]]: + """Square single-line border; the title sits in the top rule.""" + edge = "s" if focus else "r" + top_l = [("┌─ ", edge), (title, "s" if focus else "t"), (" ", edge)] + top_r = [(" ", edge), (right, "m"), (" ─┐", edge)] if right else [("─┐", edge)] + used = sum(len(t) for t, _ in top_l + top_r) + rows = [top_l + [("─" * (width - used), edge)] + top_r] + inner = width - 4 + for i in range(height - 2): + content = body[i] if i < len(body) else [] + rows.append([("│ ", edge), *line(*content, width=inner), (" │", edge)]) + rows.append([("└" + "─" * (width - 2) + "┘", edge)]) + return rows + + +def meter(value: float, n: int, cls: str = "s") -> list[Seg]: + lit = round(value * n) + return [("▮" * lit, cls), ("▯" * (n - lit), "r")] + + +def field(name: str, *value: Seg) -> list[Seg]: + return [(f"{name:<9}", "m"), ("│ ", "r"), *value] + + +sidebar = box( + SIDE, + "MODES", + "", + [ + [("▸ Download", "s")], + [(" Search", "t")], + [(" Tracks", "t")], + [(" Queue", "t"), (" 9", "s")], + [(" Live", "t")], + [(" History", "t")], + [(" Session", "t")], + [(" Library", "t")], + [(" Server", "t")], + [(" Extensions", "t")], + [(" Health", "t")], + [(" Signed", "t")], + [(" Command", "t")], + ], + height=35, +) + +MAIN = W - SIDE - 1 +config = box( + MAIN, + "CONFIGURATION", + "[ctrl+r] run", + [ + [], + field("URL", ("https://open.spotify.com/album/5d1Kc0Q7pX3vXa", "t")), + field("CSV", ("—", "m")), + field( + "SOURCES", + ("tidal", "t"), + (" › ", "m"), + ("qobuz", "t"), + (" › ", "m"), + ("deezer", "t"), + ), + field("QUALITY", ("[24/96 FLAC]", "s"), (" hi-res, else lossless", "m")), + field("OUTPUT", ("~/Music/Mornye/{artist}/{album}", "t")), + field("LYRICS", ("apple › binilyrics › lrclib › ext:jellyfin", "t")), + field("TAGS", ("enrich: deezer › apple · cover 3000px", "t")), + [], + ], + height=11, + focus=True, +) + +tracks = [ + ("01", "Carrier Wave", "[24/96]", 1.0, "done", "ok"), + ("02", "Static Bloom", "[24/96]", 1.0, "done", "ok"), + ("03", "Low Hours", "[24/96]", 0.62, " 62%", "s"), + ("04", "Second Antenna", "[24/96]", 0.0, "queued", "m"), + ("05", "Glass Harbour", "[24/96]", 0.0, "queued", "m"), + ("06", "Interference (feat. Kō)", "[16/44]", 0.0, "queued", "m"), + ("08", "Dial Tone", "[ — ]", 0.0, "not found", "e"), +] +dl_body: list[list[Seg]] = [[]] +for num, title, q, v, state, cls in tracks: + dl_body.append( + [ + (num + " ", "m"), + (f"{title:<30}", "t"), + (q + " ", "m" if q == "[ — ]" else "k"), + *meter(v, 20, {"ok": "ok", "e": "e"}.get(cls, "s")), + (" ", ""), + (state, {"ok": "ok", "e": "e", "s": "s", "m": "m"}[cls]), + ] + ) +dl_body += [[], [("tidal-web · 4.2 MB/s · 18.4 / 29.6 MB · 0:03 left", "m")]] +downloads = box(MAIN, "DOWNLOADING", "3 / 12", dl_body, height=12) + +overall = box( + MAIN, + "RUN", + "", + [ + [], + [("all ", "m"), *meter(0.25, 48), (" 3 / 12", "s"), (" 1 failed", "e")], + [], + [("last ", "m"), ("Harbour Lights — Mira Sol · 5 / 5 · 212.6 MB", "t")], + ], + height=12, +) + +main_rows = config + downloads + overall +assert len(main_rows) == len(sidebar) == 35, (len(main_rows), len(sidebar)) + +rows: list[list[Seg]] = [] +rows.append( + line( + ("MORNYE", "tb"), + (" 2.0.6 ", "m"), + ("─" * 78, "r"), + (" ● downloading 3/12 ", "s"), + ("──", "r"), + (" 0:42 ", "m"), + ("─", "r"), + ) +) +rows.append(line()) +for left, right in zip(sidebar, main_rows): + rows.append([*left, (" ", ""), *right]) +rows.append(line()) +rows.append(line(("▌", "s"), (" Downloading Night Signals — track 3 of 12", "t"))) +hints = [ + ("[ctrl+r]", "k"), + (" run ", "m"), + ("[ctrl+c]", "k"), + (" stop ", "m"), + ("[/]", "k"), + (" search ", "m"), + ("[ctrl+y]", "k"), + (" copy cli ", "m"), + ("[t]", "k"), + (" theme ", "m"), + ("[?]", "k"), + (" help", "m"), +] +rows.append(line(*hints)) +assert len(rows) == H, len(rows) +for r in rows: + assert sum(len(t) for t, _ in r) == W, (sum(len(t) for t, _ in r), r[:3]) + + +def render(rows: list[list[Seg]]) -> str: + out = [] + for r in rows: + out.append( + "".join( + f'{html.escape(t)}' if c else html.escape(t) + for t, c in r + ) + ) + return "\n".join(out) + + +PAGE = f""" + + + + +Mock · TUI Download + + + + +
+

TUI · Download panel · {W}×{H}

+
{render(rows)}
+
+ + +""" + +Path(__file__).with_name("tui-download.html").write_text(PAGE, encoding="utf-8") +print("wrote tui-download.html") diff --git a/docs/mocks/queue.html b/docs/mocks/queue.html new file mode 100644 index 0000000..2162fa4 --- /dev/null +++ b/docs/mocks/queue.html @@ -0,0 +1,137 @@ + + + + + +Mock · Queue + + + + +
+
+ MORNYE2.0.6 + + ● downloading 3 / 12 +
+ + + +
+
+

Queue

+ 4 jobs · 35 tracks + + + +
+ +
+ Now +
+ +
+
Low Hours
+
Arden Vale · Night Signals · track 3 of 12
+
62%18.4 / 29.6 MB · 4.2 MB/s · 0:03 left
+
+
+ 24 / 96 · FLAC + via tidal-web +
+
+
+
Done
7
+
Left
27
+
Failed
1
+
Written
212.6 MB
+
+
+ +
+ Jobs 4 + + + + + + + + +
JobTracksProgressState
Night SignalsArden Vale · album3 / 12running
Late Shift Mixplaylist0 / 17queued
Quiet BandArden Vale · single0 / 1queued
Harbour LightsMira Sol · EP5 / 5done
+
+ +
+ Failed 1 +
+ not found + Dial Tone — Arden Vale · no 24/96 on tidal, qobuz or deezer; 16/44.1 on deezer + + +
+
+ Failed tracks stay here until you retry or clear them. + + + +
+
+
+ + +
+ + + diff --git a/docs/mocks/tui-download.html b/docs/mocks/tui-download.html new file mode 100644 index 0000000..89efd76 --- /dev/null +++ b/docs/mocks/tui-download.html @@ -0,0 +1,64 @@ + + + + + +Mock · TUI Download + + + + +
+

TUI · Download panel · 120×40

+
MORNYE 2.0.6 ────────────────────────────────────────────────────────────────────────────── ● downloading 3/12 ── 0:42 ─
+                                                                                                                        
+┌─ MODES ────────────┐ ┌─ CONFIGURATION ──────────────────────────────────────────────────────────────── [ctrl+r] run ─┐
+│ ▸ Download         │ │                                                                                               │
+│   Search           │ │ URL      │ https://open.spotify.com/album/5d1Kc0Q7pX3vXa                                      │
+│   Tracks           │ │ CSV      │ —                                                                                  │
+│   Queue      9     │ │ SOURCES  │ tidal › qobuz › deezer                                                             │
+│   Live             │ │ QUALITY  │ [24/96 FLAC]  hi-res, else lossless                                                │
+│   History          │ │ OUTPUT   │ ~/Music/Mornye/{artist}/{album}                                                    │
+│   Session          │ │ LYRICS   │ apple › binilyrics › lrclib › ext:jellyfin                                         │
+│   Library          │ │ TAGS     │ enrich: deezer › apple · cover 3000px                                              │
+│   Server           │ │                                                                                               │
+│   Extensions       │ └───────────────────────────────────────────────────────────────────────────────────────────────┘
+│   Health           │ ┌─ DOWNLOADING ──────────────────────────────────────────────────────────────────────── 3 / 12 ─┐
+│   Signed           │ │                                                                                               │
+│   Command          │ │ 01  Carrier Wave                  [24/96]  ▮▮▮▮▮▮▮▮▮▮▮▮▮▮▮▮▮▮▮▮  done                         │
+│                    │ │ 02  Static Bloom                  [24/96]  ▮▮▮▮▮▮▮▮▮▮▮▮▮▮▮▮▮▮▮▮  done                         │
+│                    │ │ 03  Low Hours                     [24/96]  ▮▮▮▮▮▮▮▮▮▮▮▮▯▯▯▯▯▯▯▯   62%                         │
+│                    │ │ 04  Second Antenna                [24/96]  ▯▯▯▯▯▯▯▯▯▯▯▯▯▯▯▯▯▯▯▯  queued                       │
+│                    │ │ 05  Glass Harbour                 [24/96]  ▯▯▯▯▯▯▯▯▯▯▯▯▯▯▯▯▯▯▯▯  queued                       │
+│                    │ │ 06  Interference (feat. Kō)       [16/44]  ▯▯▯▯▯▯▯▯▯▯▯▯▯▯▯▯▯▯▯▯  queued                       │
+│                    │ │ 08  Dial Tone                     [  —  ]  ▯▯▯▯▯▯▯▯▯▯▯▯▯▯▯▯▯▯▯▯  not found                    │
+│                    │ │                                                                                               │
+│                    │ │ tidal-web · 4.2 MB/s · 18.4 / 29.6 MB · 0:03 left                                             │
+│                    │ └───────────────────────────────────────────────────────────────────────────────────────────────┘
+│                    │ ┌─ RUN ─────────────────────────────────────────────────────────────────────────────────────────┐
+│                    │ │                                                                                               │
+│                    │ │ all  ▮▮▮▮▮▮▮▮▮▮▮▮▯▯▯▯▯▯▯▯▯▯▯▯▯▯▯▯▯▯▯▯▯▯▯▯▯▯▯▯▯▯▯▯▯▯▯▯  3 / 12   1 failed                      │
+│                    │ │                                                                                               │
+│                    │ │ last  Harbour Lights — Mira Sol · 5 / 5 · 212.6 MB                                            │
+│                    │ │                                                                                               │
+│                    │ │                                                                                               │
+│                    │ │                                                                                               │
+│                    │ │                                                                                               │
+│                    │ │                                                                                               │
+│                    │ │                                                                                               │
+└────────────────────┘ └───────────────────────────────────────────────────────────────────────────────────────────────┘
+                                                                                                                        
+▌ Downloading Night Signals — track 3 of 12                                                                             
+[ctrl+r] run   [ctrl+c] stop   [/] search   [ctrl+y] copy cli   [t] theme   [?] help                                    
+
+ + diff --git a/docs/redesign-plan.md b/docs/redesign-plan.md new file mode 100644 index 0000000..34fa764 --- /dev/null +++ b/docs/redesign-plan.md @@ -0,0 +1,463 @@ +# Piano: nuovo look per GUI e TUI, da zero + +Documento di lavoro. Numeri verificati sul branch `2.0.6` (commit `8c6b323`). + +**Obiettivo:** sostituire per intero il linguaggio visivo di Mornye — GUI +(`mornye/frontend/`) e TUI (`mornye/tui/`) — con un unico design system nuovo, +senza toccare motore di download, API e flussi. + +**Non è in scopo:** riscrittura di `app.js` in un framework, introduzione di +un build step, cambi al contratto delle API di `webapp.py`. + +La §7 aggiunge, dopo una scansione della codebase, fix, miglioramenti e +nuove funzioni: sono binari separati dal look, ognuno agganciato alla fase +in cui costa meno farlo. + +--- + +## 0. Stato e ripartenza (aggiornato 2026-11-12) + +**Chi riprende legga questa sezione, poi la §2 (direzione scelta) e la §4 +(fasi).** Tutto il lavoro è sul branch `2.0.6`, in commit locali **non +pushati**, uno per voce, senza trailer di co-autore. + +### Fatto + +| Voce | Commit | Note | +| --- | --- | --- | +| F2 · task asyncio senza riferimento | `65e3683` | `loop_runner.spawn()`; usato in `core/base.py`, `core/progress.py`, `extensions/provider.py` | +| F4 · errori mypy | `65ca900` | 0 errori; il passo mypy in CI ora è **bloccante** | +| F5 · XML remoto | `962a344` | `core/safe_xml.py` rifiuta DTD/entità; nessuna dipendenza nuova | +| F3 · I/O bloccante (parte) | `3e6f280` | `/api/browse-folder` e `/api/media` ora `def` (threadpool); unione dei segmenti in `to_thread` | +| F8 · strumenti | `2c6759a` | CI su 3.11–3.14 + macOS; hook `black` a 26.10.1 | +| `fetch()` sincrono per le estensioni | `c9d2d1d` | vedi §8 | +| Ricerca su sorgenti solo-ricerca | `2842669` | vedi §8 | +| Jellyfin: lacune piccole | `a2c6d4c` | vedi §9 | +| Fase 0 · voce 3: contratto `id`/handler/classi | `6c9011f` | `tests/test_frontend_dom_contract.py` + inventario `tests/frontend_dom_contract.json`; unico orfano noto `hc-summary` | +| Fase 0 · voce 2: snapshot TUI | `6ad44f5` | `tests/visual/capture_tui.py` → 48 SVG in `tests/visual/baseline/tui` (12 pannelli × 80×24/120×40 × scuro/chiaro), HOME temporanea, deterministico; `--compare` per il confronto | +| J1 · rete locale per estensione | `f5abb18` | `extensions/local_network.py`, interruttore in Settings → Extensions, API admin `set_extension_local_network` | +| J2 · testi dalle estensioni | `00b7ac3` | `core/extension_lyrics.py`, provider `ext:` in GUI/TUI/CLI | +| J3 · home feed in Explore | `33c8b4a` | `core/extension_home_feed.py`; selettore "Feed" in Explore (Spotify + ogni estensione con `capabilities.homeFeed`); ogni item ha un `open_url` apribile dal campo URL | +| J4 · link di sorgenti proprie + flag skip | `641c0b1` | i link che nessun client integrato legge (Jellyfin `…/web/#/details?id=`) vanno all'estensione che li rivendica; le tracce portano `extra_info.source_extension`; `download_one_async` rispetta `skipBuiltInFallback` e `skipMetadataEnrichment` | +| Campi impostazioni estensione troppo stretti | `e26ecc5` | il Server URL di Jellyfin era largo 25px | +| Testi Now Playing che escono a destra | `f69b231` | un pezzo temporizzato con più parole ora è diviso parola per parola (vedi sotto) | +| Fase 0 · voce 1: screenshot GUI | `0ceeb2b` | `tests/visual/capture_gui.py` → 60 PNG in `tests/visual/baseline/gui` (10 viste × desktop/768/375 × scuro/chiaro); Playwright + Chrome installato, extra `visual`; `--compare` tollera il rumore di antialiasing | + +| Fase 1 · voce 4: `style=""` di `index.html` → classi | `105738d` | 164 dei 217 stili inline diventano utility `u-*` (una dichiarazione ciascuna, in fondo a `styles.css`, selettore raddoppiato `.u-x.u-x` per battere regole come `.s-row input`). Restano inline le proprietà che `app.js` azzera (`display`, `opacity`, …) e 11 dichiarazioni che una regola con id o attributo altrimenti sovrascriverebbe; `tests/test_frontend_inline_styles.py` impedisce di aggiungerne | +| Fase 1 · voce 5: stili scritti da `app.js` | `e5fcef9` | gli `style=""` nel markup generato diventano le stesse utility; i colori con un significato diventano `data-tone` (`muted`/`ok`/`warn`/`error`) e il bordo di Save `data-dirty`. Restano scritti da JS solo valori calcolati o di comportamento: mostra/nascondi, larghezze delle barre, moto dei testi, copertine | +| Fase 1 · voce 6: colori fuori token | `8447302` | `branding_tokens.FIXED` + `FIXED_CHANNELS`: inchiostro e tinte di Now Playing, codice a barre, glifi; trasparenze come `rgba(var(--media-ink-rgb), .62)`. Test: nessun colore crudo nelle dichiarazioni (maschere escluse) | + +**Fase 0 completa.** J1–J4 e il fix dei testi sono stati verificati nel +browser (GUI web su una cartella dati di prova): interruttore J1 acceso e +salvato; `ext:jellyfin` primo e spuntato dopo un ricaricamento; Explore con +Apple Music mostra 15 sezioni e il clic apre l'album (17 tracce); con +Jellyfin senza server compare un'unica scheda d'errore. **Mai provato con un +server Jellyfin vero**: login, ricerca, apertura di un link, download +`ORIGINAL`, testi e feed restano da verificare in quest'ordine. + +**Fix dei testi.** Una riga sincronizzata con un solo timestamp +(`[00:51.00]<00:51.00>I don't know how … stay`) diventava un unico `span`: +la copia bianca sovrapposta (`::after`, `white-space: pre`) restava su una +riga e usciva dal bordo, quella grigia sotto andava a capo. Ora +`npSplitTimedPhrases()` divide i pezzi in parole e ripartisce il tempo; un +pezzo senza fine propria dura ~0,32 s a parola, mai oltre la riga dopo. +Per il redesign: il componente "riga di testo" deve nascere con questa +regola (una parola = un elemento). + +### Non fatto — da qui si riparte + +0. **Fase 2 · voce 7 — mock pronti, in attesa di approvazione.** In + `docs/mocks/`: `home.html` (Home con album aperto), `queue.html` (Coda con + pannello falliti), `tui-download.html` (pannello Download della TUI a + 120×40, generato da `make_tui_mock.py`), tutti su `console.css`, che + contiene la proposta di valori per i token v2 (grafite `#0d0d0d`…`#242424`, + segnale `#ffb000`, stato `#5ec46b`/`#ff5a4f`). Si aprono servendo la radice + del repo (`python -m http.server`, configurazione `mocks` in + `.claude/launch.json`). Regole emerse disegnando: la qualità per riga è una + lettura grigia, l'ambra resta a album, selezione, download in corso e + azione primaria (una sola per schermata); gli errori stanno in un solo + pannello "Failed". Jellyfin compare nel rail come *Library → Server*. +1. **Fase 1 completa** (voci 4–6) — l'aspetto è identico per costruzione: + stili calcolati di ogni elemento di `index.html` senza JS (1472 elementi × + desktop/telefono × scuro/chiaro) e della GUI in esecuzione (ogni vista e + scheda delle impostazioni, 52.449 stati) confrontati prima/dopo con 0 + differenze; screenshot uguali alla baseline. Copertura a runtime: 31 dei + 107 tag generati da `app.js` sono comparsi nel giro; per gli altri un + controllo statico delle regole concorrenti ha trovato un solo caso reale + (input password delle impostazioni estensione), lasciato inline. + **Prossimo:** le voci di §7.4 previste "dentro le Fasi 0–1" e non ancora + fatte — F1 (CSP: prima `data-action` al posto dei 166 `onclick=`), M6 + (stringhe in un dizionario), M2 (`create_app`), M4 (test JS con + `node:test`) — oppure direttamente la Fase 2 (mock, token v2, + styleguide). + Suite completa dopo la Fase 1: 2253 passati, 357 saltati. + **Lasciato apposta:** colori dentro `app.js` (tinta di default di Now + Playing in `npApplyColors`, `theme-color`), da portare ai token nella + voce 8. +2. **§2 tutta decisa** (2026-11-12): direzione A, JetBrains Mono come unico + font, segnale ambra, logo invariato fino alla Fase 5, tema chiaro + derivato. Nessuna scelta aperta prima della Fase 2. +3. **F1, F6, F7, F9, M1–M6, N1–N5** — non iniziati. +4. **F3, resto**: restano ~30 avvisi `ASYNC240`, quasi tutti un singolo + `exists()`/`getsize()` su disco locale. Lasciati di proposito. +5. **Jellyfin con un server vero** — vedi sopra. +6. **Note emerse:** a 80×24 il pannello History della TUI taglia il testo a + destra (si vede negli snapshot). `mypy mornye` nella venv locale 3.14 + si ferma su uno stub di `numpy` (`python_version = "3.11"`); con + `--python-version 3.12` resta 1 errore preesistente in + `core/hires_check.py:469`. `hc-summary` è aggiornato da `app.js` ma non + esiste più nell'HTML. Suite completa dopo J4: 2249 passati, 357 saltati + (l'unico fallimento era un test da aggiornare, fatto nello stesso commit). + +### Da sapere prima di toccare qualcosa + +- **Verifiche da rifare su CI.** Le modifiche a `ci.yml` (matrice 3.13/3.14, + job macOS, mypy bloccante) non sono mai girate: `mypy` e `black` sono stati + provati solo in locale (Python 3.14, black 26.5.1 contro il ≥26.10.1 che la + CI installa). Al primo push va guardato l'esito. +- **28 file di test sono saltati di default** (`tests/conftest.py`, + `_OPTIONAL_UTILITIES_TESTS`): girano solo con + `MORNYE_TEST_REAL_EXT_DIR=1` e usano le estensioni installate in + `~/.mornye/extensions`. Con quel flag, **5 test di + `tests/test_search_mixin.py` falliscono già da prima** di questo lavoro + (verificato con `git stash`): da indagare a parte. +- **Hook del progetto (GateGuard):** il primo `Bash` e ogni `Write` di un + file nuovo vengono rifiutati finché non si dichiarano i "fatti" richiesti; + basta riproporre la stessa operazione dopo averli scritti. + +--- + +## 1. Da dove si parte + +| Pezzo | File | Righe | Nota | +| --- | --- | --- | --- | +| Stile GUI | `frontend/styles.css` | 4905 | 45 `@media`/`@container`, 27 `!important`, strati di rebrand successivi | +| Markup GUI | `frontend/index.html` | 1871 | 10 viste, 215 `style=""` inline, 166 `onclick=` | +| Logica GUI | `frontend/app.js` | 9761 | ~580 punti che toccano classi/stili/`innerHTML` | +| Stile TUI | `tui/mornye.tcss` | 723 | grammatica MovieBox-Tui | +| Vocabolario TUI | `tui/branding.py` | 390 | wordmark, titoli pannello, badge, hint | +| Shell TUI | `tui/app.py` | 980 | 12 pannelli, 8+ temi | +| Token condivisi | `branding_tokens.py` | 131 | solo colori; `tests/test_brand_tokens.py` li tiene allineati al CSS | + +Look attuale: "warm dark music app" — neri caldi, teal del logo, ambra, +chrome traslucido, Fraunces + Inter + JetBrains Mono. TUI: wordmark a blocchi, +card arrotondate, badge pieni. + +Cosa rende costoso un restyling oggi, e va quindi sistemato **prima** di +disegnare: + +1. **Lo stile è in tre posti.** CSS, attributi `style=""` nell'HTML e + stringhe HTML generate da `app.js`. Un foglio nuovo non li raggiunge tutti. +2. **I token coprono solo il colore.** Spaziature, raggi, scala tipografica, + ombre e durate sono numeri sparsi: cambiarli significa cercarli uno a uno. +3. **Nessuna rete visiva.** I test verificano il cablaggio + (`test_frontend_new_ui_wiring.py`) e il vocabolario TUI (`test_tui_look.py`), + non l'aspetto. Una regressione di layout passa inosservata. + +--- + +## 2. Direzione visiva — **scelta: A · Console da studio** (2026-11-12) + +Mornye come un apparecchio hi-fi da rack: grafite, un solo colore segnale, +dati tecnici letti su un display. Densa, piatta, precisa. Scelta perché si +traduce quasi 1:1 in un terminale: GUI e TUI diventano la stessa interfaccia +in due materiali. (Scartate: "Copertina di disco", chiara e guidata +dall'artwork; "Nativo morbido", troppo vicina all'attuale.) + +### Regole comuni + +| Aspetto | Regola | +| --- | --- | +| Neutri | Grafite senza dominante (né calda né blu), 4 livelli di superficie | +| Colore | **Un solo segnale** per focus, selezione, azione primaria, livello attivo. Rosso/verde solo come stato, mai come decorazione | +| Separazione | Filetti da 1px. Niente card in rilievo, ombre, blur, gradienti d'ambiente | +| Forma | Raggio 2–3px. Griglia a 4px, righe da 32px | +| Testo | **JetBrains Mono per tutto** — interfaccia, titoli, numeri e dati tecnici (deciso dall'utente, 2026-11-12). Inter e Fraunces escono, con i loro file in `assets/fonts/`. La gerarchia si fa con peso, dimensione e maiuscoletto, non cambiando famiglia | +| Etichette | Sezioni in maiuscoletto spaziato, come le serigrafie di un pannello | +| Movimento | ≤120ms, solo cambi di stato. Niente animazioni d'ingresso | + +Tre elementi firma, identici nei due mondi: + +1. **Il display di qualità** — `24 / 96 · FLAC` sul colore segnale, + al posto dei badge colorati (Hi-Res, Atmos, Lossless). +2. **Il misuratore a segmenti** — l'avanzamento è una barra a tacche tipo + LED (`▮▮▮▮▯▯▯▯`), non un riempimento liscio. +3. **L'etichetta di pannello** — il titolo sta *nel* filetto del bordo. + +### Solo GUI +Rail di navigazione stretto con icone + etichetta, titlebar e dock opachi. +L'artwork resta l'unica immagine a colori: quadrata, senza raggio, senza +alone. + +### Solo TUI +Via il wordmark a blocchi: una riga d'intestazione `MORNYE 2.0.6 ── stato`. +Bordi a linea singola squadrati (non arrotondati), badge come letture tra +parentesi nel colore segnale invece che a fondo pieno, hint in basso +invariati nella forma `[key] action`. + +### Default — **confermati dall'utente** (2026-11-12) +- **Segnale: ambra** (tipo display al fosforo, ~`#ffb000`), non il teal + attuale — altrimenti il cambio non si percepisce. Valori definitivi alla + voce 8, sotto test di contrasto. +- **Logo:** resta com'è fino alla Fase 5; lì si valuta una versione mono. +- **Tema chiaro:** derivato ("carta"), disegnato dopo lo scuro ma coperto + dagli stessi test. +- **Accenti selezionabili (`ACCENTS`):** restano, ma cambiano solo il + segnale. **Temi TUI di terze parti:** restano, sono gratis in Textual. + +--- + +## 3. Architettura del nuovo stile + +**Token v2 — `branding_tokens.py` resta l'unica fonte.** Si estende oltre il +colore: `space-*`, `radius-*`, scala tipografica, `elevation-*`, `motion-*`. +Due livelli: primitivi (`grey-900`) e semantici (`surface`, `text-muted`, +`signal`). GUI e TUI consumano solo i semantici. Il test di parità +Python ↔ CSS e quello di contrasto WCAG AA restano e si allargano ai token +nuovi. + +**GUI — CSS a strati, sempre senza build.** `styles.css` viene sostituito da +file piccoli caricati in ordine con `@layer`: + +``` +frontend/css/tokens.css ← specchio di branding_tokens.py +frontend/css/base.css ← reset, tipografia, focus, scrollbar +frontend/css/layout.css ← shell: rail, titlebar, dock, player bar +frontend/css/components.css ← bottoni, input, chip, tabelle, modali, toast +frontend/css/views/*.css ← una per vista +``` + +Vincolo: gli `id` e i nomi di funzione che `app.js` usa sono un **contratto** +e non cambiano; cambiano classi, struttura della shell e tutto il CSS. + +**TUI — stessa regola.** `mornye.tcss` riscritto da zero sopra i token; +`branding.py` ridisegna i quattro elementi d'identità (wordmark, titolo +pannello, badge, hint). Restano intatti i comportamenti: fallback ASCII, +`NO_COLOR`, layout compatto 80×24, log affiancato/impilato. + +--- + +## 4. Fasi + +Ogni voce numerata è un commit a sé. + +### Fase 0 · Rete di sicurezza (nessun cambio visibile) +1. Script che cattura le 10 viste GUI × scuro/chiaro × 3 larghezze + (finestra desktop, 768, 375) → baseline in `tests/visual/`. +2. Snapshot SVG dei 12 pannelli TUI a 80×24 e 120×40 (`tui_harness.py` + + `App.export_screenshot`). +3. Inventario del contratto: `id`/classi che `app.js` legge o scrive, salvato + come test (fallisce se l'HTML ne perde uno). + +### Fase 1 · Bonifica (look invariato, verificato con la Fase 0) +4. I 215 `style=""` di `index.html` diventano classi. +5. Gli stili scritti da `app.js` (`el.style.*`, HTML in stringa con colori) + diventano classi/attributi di stato (`data-state="failed"`). +6. Colori fuori token in `styles.css` ricondotti ai token. + +### Fase 2 · Direzione e design system +7. Mock statici di 3 schermate chiave (Home con album aperto, Coda, pannello + Download della TUI) nella direzione scelta → approvazione. +8. Token v2 in `branding_tokens.py` + `tokens.css` + temi Textual + test. +9. `frontend/styleguide.html` (solo sviluppo): tutti i componenti in tutti gli + stati, scuro e chiaro. È il banco di prova prima di toccare le viste. + +### Fase 3 · GUI +10. Shell: rail di navigazione, titlebar, dock download, player bar. +11. Home / ricerca / album / tabella tracce (la vista più usata). +12. Coda + pannello falliti · 13. History · 14. Settings (670 righe di + markup: va riorganizzata, non solo ridipinta) · 15. Local · 16. Following + · 17. Explore · 18. Stats · 19. Player e Now Playing · 20. Logs. +21. Toast, modali, stati vuoti, skeleton, `prefers-reduced-motion`. +22. Rimozione di `styles.css` e di ogni residuo; aggiornamento `sw.js`, + `manifest.json`, `MANIFEST.in`/package-data. + +### Fase 4 · TUI +23. `branding.py`: nuovo wordmark, titoli, badge, hint (+ fallback ASCII). +24. `mornye.tcss` nuovo: frame, sidebar, form, tabelle, barre, modali. +25. Passata sui 12 pannelli a 80×24, 120×40 e terminale "plain". +26. Elenco temi rivisto; `test_tui_look.py` riscritto dove descrive il + vecchio vocabolario, lasciato dove descrive capacità. + +### Fase 5 · Contorno +27. `desktop_branding.py`, icone, `theme_color`, eventuale nuovo logo. +28. Migrazione accento/tema per chi aggiorna (già esiste `migrateAccent`). +29. `docs/site.css`, screenshot di README e guide, `CHANGELOG.md`. + +### Fase 6 · Verifica +30. Confronto visivo completo, contrasto AA, navigazione da tastiera e focus. +31. pywebview su macOS (WKWebView), Windows (WebView2), Linux (WebKitGTK); + `--web` in Docker; PWA su telefono. + +--- + +## 5. Rischi + +- **HTML generato da `app.js`.** È dove un foglio nuovo lascia buchi. Le + voci 3 e 5 esistono per questo; saltarle sposta il costo nella Fase 3. +- **Tutto in monospazio.** Con JetBrains Mono ovunque il testo occupa più + larghezza di Inter: titoli lunghi, colonne della tabella tracce e la + Settings vanno provati presto (voce 9, styleguide) alle larghezze strette, + con troncamento e `font-variant-ligatures: none` nei dati. +- **WebKitGTK datato.** `@layer` e le container query (già in uso) non ci + sono nelle versioni vecchie: va fissata la versione minima supportata su + Linux prima della Fase 3. +- **Test che leggono il CSS.** `test_brand_tokens.py` analizza `styles.css`: + va aggiornato nello stesso commit che sposta i file, e vanno cercati altri + test che citano quel percorso. +- **Transizione.** Le Fasi 0–1 possono uscire in una 2.0.x; dalla 2 in poi + conviene un branch dedicato e un rilascio unico: una GUI metà vecchia e + metà nuova è peggio di entrambe. + +## 6. Dove sta il lavoro + +Fasi 0–1: piccole ma noiose. Fase 2: breve, è dove si decide tutto. Fase 3: +il grosso (Settings e Home da sole circa metà). Fase 4: circa un quarto +della 3. Fasi 5–6: rifinitura. + +--- + +## 7. Oltre il look: fix, miglioramenti, nuove funzioni + +Da una scansione statica del 2026-11-12: `ruff` con regole allargate +(B, S, ASYNC, PERF, SIM, UP, BLE, PLW, RUF, C90), `mypy`, `black --check`, +ricerche mirate su frontend e TUI. **Non** ho avviato l'app né eseguito la +suite (2547 test raccolti): le voci sotto sono ciò che il codice mostra, non +bug riprodotti. `ruff` e `black` con la configurazione attuale sono puliti; +nessun `TODO`/`FIXME` nel codice. + +### 7.1 Fix + +| # | Cosa | Dove | Quando | +| --- | --- | --- | --- | +| F1 | **Nessuna Content-Security-Policy né header di sicurezza** su `--web` (nessuna occorrenza in `mornye/`). Oggi una CSP è impossibile: 166 `onclick=` inline, script inline, `document.write` per il cache-busting | `webapp.py`, `index.html` | Fase 1: delega eventi con `data-action`, versione degli asset dal backend; poi CSP + `nosniff` + `frame-ancestors` | +| F2 | **3 task asyncio lanciati senza tenerne il riferimento**: possono essere raccolti dal GC a metà e le loro eccezioni spariscono | `core/base.py:75`, `core/progress.py:1115`, `extensions/provider.py:394` | Subito, indipendente | +| F3 | **I/O su disco bloccante dentro funzioni async** (33 punti): su un NAS lento ferma l'event loop, e con lui il WebSocket dei progressi | `webapp.py:1094-1169` (9), `download_engine.py` (5), `core/animated_artwork.py` (5 + `open()` a :198), `extensions/provider.py:1360` | Subito, indipendente; `webapp.py` per primo | +| F4 | **10 errori mypy rimasti** (il commento in `pyproject.toml` ne cita ~177). I due che contano: tipo di ritorno sbagliato a `extensions/provider.py:700`, `None` passato come `str` a `extensions/runtime.py:463` | 7 file | Subito; poi mypy diventa bloccante in CI | +| F5 | XML remoto letto con `ElementTree` della stdlib (risposte WebDAV, TTML dei testi) | `core/webdav.py:155`, `core/apple_ttml.py:227` | **Fatto** — `core/safe_xml.py` rifiuta DTD ed entità, senza nuova dipendenza | +| F6 | **530 `except Exception`, 70 dei quali con solo `pass`**. `app.py` ne ha 58: è l'API della GUI, quindi errori che dovrebbero diventare un toast spariscono | `app.py` per primo | Fase 3, vista per vista: almeno un log a debug, e un errore visibile dove l'utente aspetta un esito | +| F7 | **Accessibilità GUI**: 19 `div`/`span` cliccabili non raggiungibili da tastiera, 8 `outline: none`, 6 `` senza `alt`, 11 `confirm()` nativi (in pywebview escono fuori stile) | `index.html`, `app.js`, `styles.css` | Fasi 2–3: nascono corretti nei componenti nuovi (bottone, modale di conferma) | +| F8 | **Strumenti disallineati**: pre-commit fissa `black` 24.0 ma `dev` richiede ≥26.10.1; la CI prova solo 3.11/3.12 mentre i classifier dichiarano 3.13 e 3.14; nessun job macOS per un'app desktop | `.pre-commit-config.yaml`, `ci.yml` | Subito | +| F9 | Il tema scelto con `t` nella TUI non risulta salvato da nessuna parte: da verificare a mano, e nel caso persisterlo | `tui/app.py:792` | Fase 4, voce 26 | + +Controllato e **non** un problema: i 10 `innerHTML` con interpolazione non +passata da `escHtml` contengono solo numeri o testo fisso; i 5 avvisi B023 +in `network_destinations.py`/`webdav.py` sono lambda eseguite subito. + +### 7.2 Miglioramenti + +| # | Cosa | Quando | +| --- | --- | --- | +| M1 | **`app.js` in moduli ES per vista** (oggi 9761 righe, 396 funzioni, 123 variabili globali). ` - + + + + + + + + \n" - '\n' - ) - # Before the first app script, whatever its cache-busting version: - # matching one exact `?v=` string silently dropped the shim (and with - # it every API call) the first time index.html bumped the version. - html = re.sub( - r'()', - lambda m: inject + m.group(1), - html, - count=1, + '\n' ) + # Before the first app script. index.html marks the spot with a + # comment, because matching the script tag itself silently dropped the + # shim (and with it every API call) whenever that tag changed shape — + # a bumped `?v=` once, the timestamped loader another time. + marker = " + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + download 120x40 + + + + + + + + + + +MORNYE +                                                         v0.0.0 +╭─ * Modes ──────────────╮╭─ Configuration ──────────────────────────────────────────────────────────────────────────╮ +││││ +│█││▼ Source│ +│█ v Download│││ +│█││+URL│ +│││╭──────────────────────────────────────────────────────────────────────╮│ +│ ? Search│││https://open.spotify.com/album/example││ +│││╰──────────────────────────────────────────────────────────────────────╯│ +││││ +│ # Tracks││+CSV track listwins over the URL│ +│││╭──────────────────────────────────────────────────────────────────────╮│ +││││a .csv or .tsv on this machine││ +│ Q Queue││╰──────────────────────────────────────────────────────────────────────╯▃│ +││││ +│││╭──────────────────────────╮│ +│ = Live│││ Browse for a track list… ││ +│││╰──────────────────────────╯│ +││││ +│ h History│││ +│││▼ Destination│ +││││ +│ @ Session││+Folder│ +│││╭──────────────────────────────────────────────────────────────────────╮│ +││││/Music/Mornye││ +│ - Library││╰──────────────────────────────────────────────────────────────────────╯│ +││││ +│││Exact file path│ +│ + Extensions││╭──────────────────────────────────────────────────────────────────────╮│ +│▂│││leave blank to name files normally││ +│││╰──────────────────────────────────────────────────────────────────────╯│ +│ ! Health│││ +││││ +││││ +││││ +╰────────────────────────╯╰───────────────────────────────────────────────────────────────────── [ Ctrl+R to run ]  ─╯ +▌i  Pick a URL and press Ctrl+R. +[Ctrl+R] Run   [Ctrl+C] Stop   [/] Search   [Ctrl+Y] Copy CLI   [Ctrl+L] Log   [Ctrl+O] Copy log   [?] Help + + + diff --git a/tests/visual/baseline/tui/00-download_120x40_mornye-light.svg b/tests/visual/baseline/tui/00-download_120x40_mornye-light.svg new file mode 100644 index 0000000..9b6bf8f --- /dev/null +++ b/tests/visual/baseline/tui/00-download_120x40_mornye-light.svg @@ -0,0 +1,226 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + download 120x40 + + + + + + + + + + +MORNYE +                                                         v0.0.0 +╭─ * Modes ──────────────╮╭─ Configuration ──────────────────────────────────────────────────────────────────────────╮ +││││ +│█││▼ Source│ +│█ v Download│││ +│█││+URL│ +│││╭──────────────────────────────────────────────────────────────────────╮│ +│ ? Search│││https://open.spotify.com/album/example││ +│││╰──────────────────────────────────────────────────────────────────────╯│ +││││ +│ # Tracks││+CSV track listwins over the URL│ +│││╭──────────────────────────────────────────────────────────────────────╮│ +││││a .csv or .tsv on this machine││ +│ Q Queue││╰──────────────────────────────────────────────────────────────────────╯▃│ +││││ +│││╭──────────────────────────╮│ +│ = Live│││ Browse for a track list… ││ +│││╰──────────────────────────╯│ +││││ +│ h History│││ +│││▼ Destination│ +││││ +│ @ Session││+Folder│ +│││╭──────────────────────────────────────────────────────────────────────╮│ +││││/Music/Mornye││ +│ - Library││╰──────────────────────────────────────────────────────────────────────╯│ +││││ +│││Exact file path│ +│ + Extensions││╭──────────────────────────────────────────────────────────────────────╮│ +│▂│││leave blank to name files normally││ +│││╰──────────────────────────────────────────────────────────────────────╯│ +│ ! Health│││ +││││ +││││ +││││ +╰────────────────────────╯╰───────────────────────────────────────────────────────────────────── [ Ctrl+R to run ]  ─╯ +▌i  Pick a URL and press Ctrl+R. +[Ctrl+R] Run   [Ctrl+C] Stop   [/] Search   [Ctrl+Y] Copy CLI   [Ctrl+L] Log   [Ctrl+O] Copy log   [?] Help + + + diff --git a/tests/visual/baseline/tui/00-download_80x24_mornye-dark.svg b/tests/visual/baseline/tui/00-download_80x24_mornye-dark.svg new file mode 100644 index 0000000..4c0f40e --- /dev/null +++ b/tests/visual/baseline/tui/00-download_80x24_mornye-dark.svg @@ -0,0 +1,161 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + download 80x24 + + + + + + + + + + +MORNYE +                                     v0.0.0 +╭─ * Modes ──────────╮╭─ Configuration ──────────────────────────────────────╮ +│█ v Download│││ +│ ? Search││▼ Source│ +│ # Tracks│││ +│ Q Queue││+URL▄│ +│ = Live││╭───────────────────────────────────────────╮│ +│ h History│││https://open.spotify.com/album/example││ +│ @ Session││╰───────────────────────────────────────────╯│ +│ - Library│││ +│ + Extensions││+CSV track listwins over the URL│ +│ ! Health││╭───────────────────────────────────────────╮│ +│ - Signed│││a .csv or .tsv on this machine││ +│ $ Command││╰───────────────────────────────────────────╯│ +││││ +│││╭──────────────────────────╮│ +││││ Browse for a track list… ││ +│││╰──────────────────────────╯│ +││││ +╰────────────────────╯╰───────────────────────────────── [ Ctrl+R to run ]  ─╯ +▌i  Pick a URL and press Ctrl+R. +[Ctrl+R] Run   [Ctrl+C] Stop   [/] Search   [Ctrl+Y] Copy CLI + + + diff --git a/tests/visual/baseline/tui/00-download_80x24_mornye-light.svg b/tests/visual/baseline/tui/00-download_80x24_mornye-light.svg new file mode 100644 index 0000000..790f807 --- /dev/null +++ b/tests/visual/baseline/tui/00-download_80x24_mornye-light.svg @@ -0,0 +1,161 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + download 80x24 + + + + + + + + + + +MORNYE +                                     v0.0.0 +╭─ * Modes ──────────╮╭─ Configuration ──────────────────────────────────────╮ +│█ v Download│││ +│ ? Search││▼ Source│ +│ # Tracks│││ +│ Q Queue││+URL▄│ +│ = Live││╭───────────────────────────────────────────╮│ +│ h History│││https://open.spotify.com/album/example││ +│ @ Session││╰───────────────────────────────────────────╯│ +│ - Library│││ +│ + Extensions││+CSV track listwins over the URL│ +│ ! Health││╭───────────────────────────────────────────╮│ +│ - Signed│││a .csv or .tsv on this machine││ +│ $ Command││╰───────────────────────────────────────────╯│ +││││ +│││╭──────────────────────────╮│ +││││ Browse for a track list… ││ +│││╰──────────────────────────╯│ +││││ +╰────────────────────╯╰───────────────────────────────── [ Ctrl+R to run ]  ─╯ +▌i  Pick a URL and press Ctrl+R. +[Ctrl+R] Run   [Ctrl+C] Stop   [/] Search   [Ctrl+Y] Copy CLI + + + diff --git a/tests/visual/baseline/tui/01-search_120x40_mornye-dark.svg b/tests/visual/baseline/tui/01-search_120x40_mornye-dark.svg new file mode 100644 index 0000000..fd579ed --- /dev/null +++ b/tests/visual/baseline/tui/01-search_120x40_mornye-dark.svg @@ -0,0 +1,223 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + search 120x40 + + + + + + + + + + +MORNYE +                                                         v0.0.0 +╭─ * Modes ──────────────╮╭─ Search ─────────────────────────────────────────────────────────────────────────────────╮ +││││ +│││Search the catalogue. Pick a result and it becomes the URL to download.│ +│ v Download│││ +│││╭────────────────────────────────────────────────────────────────────────────────────╮│ +│█│││artist, album or track…││ +│█ ? Search││╰────────────────────────────────────────────────────────────────────────────────────╯│ +│█│││ +││││ +│ # Tracks│││ +│││╭────────────────────────────────────────────────────────────────────────────────────╮│ +││││ Kind  Name  By  Detail ││ +│ Q Queue││╰────────────────────────────────────────────────────────────────────────────────────╯│ +││││ +││││ +│ = Live│││ +││││ +││││ +│ h History│││ +││││ +││││ +│ @ Session│││ +││││ +││││ +│ - Library│││ +││││ +││││ +│ + Extensions│││ +│▂│││ +││││ +│ ! Health│││ +││││ +││││ +││││ +╰────────────────────────╯╰─────────────────────────────────────────────────────────────────────── [ / to search ]  ─╯ +▌i  Pick a URL and press Ctrl+R. +[Ctrl+R] Run   [Ctrl+C] Stop   [/] Search   [Ctrl+Y] Copy CLI   [Ctrl+L] Log   [Ctrl+O] Copy log   [?] Help + + + diff --git a/tests/visual/baseline/tui/01-search_120x40_mornye-light.svg b/tests/visual/baseline/tui/01-search_120x40_mornye-light.svg new file mode 100644 index 0000000..73f526d --- /dev/null +++ b/tests/visual/baseline/tui/01-search_120x40_mornye-light.svg @@ -0,0 +1,223 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + search 120x40 + + + + + + + + + + +MORNYE +                                                         v0.0.0 +╭─ * Modes ──────────────╮╭─ Search ─────────────────────────────────────────────────────────────────────────────────╮ +││││ +│││Search the catalogue. Pick a result and it becomes the URL to download.│ +│ v Download│││ +│││╭────────────────────────────────────────────────────────────────────────────────────╮│ +│█│││artist, album or track…││ +│█ ? Search││╰────────────────────────────────────────────────────────────────────────────────────╯│ +│█│││ +││││ +│ # Tracks│││ +│││╭────────────────────────────────────────────────────────────────────────────────────╮│ +││││ Kind  Name  By  Detail ││ +│ Q Queue││╰────────────────────────────────────────────────────────────────────────────────────╯│ +││││ +││││ +│ = Live│││ +││││ +││││ +│ h History│││ +││││ +││││ +│ @ Session│││ +││││ +││││ +│ - Library│││ +││││ +││││ +│ + Extensions│││ +│▂│││ +││││ +│ ! Health│││ +││││ +││││ +││││ +╰────────────────────────╯╰─────────────────────────────────────────────────────────────────────── [ / to search ]  ─╯ +▌i  Pick a URL and press Ctrl+R. +[Ctrl+R] Run   [Ctrl+C] Stop   [/] Search   [Ctrl+Y] Copy CLI   [Ctrl+L] Log   [Ctrl+O] Copy log   [?] Help + + + diff --git a/tests/visual/baseline/tui/01-search_80x24_mornye-dark.svg b/tests/visual/baseline/tui/01-search_80x24_mornye-dark.svg new file mode 100644 index 0000000..e16a86e --- /dev/null +++ b/tests/visual/baseline/tui/01-search_80x24_mornye-dark.svg @@ -0,0 +1,157 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + search 80x24 + + + + + + + + + + +MORNYE +                                     v0.0.0 +╭─ * Modes ──────────╮╭─ Search ─────────────────────────────────────────────╮ +│ v Download│││ +│█ ? Search││Search the catalogue. Pick a result and it becomes│ +│ # Tracks│││ +│ Q Queue││╭────────────────────────────────────────────────╮│ +│ = Live│││artist, album or track…││ +│ h History││╰────────────────────────────────────────────────╯│ +│ @ Session│││ +│ - Library│││ +│ + Extensions│││ +│ ! Health││╭────────────────────────────────────────────────╮│ +│ - Signed│││ Kind  Name  By  Detail ││ +│ $ Command││╰────────────────────────────────────────────────╯│ +││││ +││││ +││││ +││││ +││││ +╰────────────────────╯╰─────────────────────────────────── [ / to search ]  ─╯ +▌i  Pick a URL and press Ctrl+R. +[Ctrl+R] Run   [Ctrl+C] Stop   [/] Search   [Ctrl+Y] Copy CLI + + + diff --git a/tests/visual/baseline/tui/01-search_80x24_mornye-light.svg b/tests/visual/baseline/tui/01-search_80x24_mornye-light.svg new file mode 100644 index 0000000..cc38f92 --- /dev/null +++ b/tests/visual/baseline/tui/01-search_80x24_mornye-light.svg @@ -0,0 +1,157 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + search 80x24 + + + + + + + + + + +MORNYE +                                     v0.0.0 +╭─ * Modes ──────────╮╭─ Search ─────────────────────────────────────────────╮ +│ v Download│││ +│█ ? Search││Search the catalogue. Pick a result and it becomes│ +│ # Tracks│││ +│ Q Queue││╭────────────────────────────────────────────────╮│ +│ = Live│││artist, album or track…││ +│ h History││╰────────────────────────────────────────────────╯│ +│ @ Session│││ +│ - Library│││ +│ + Extensions│││ +│ ! Health││╭────────────────────────────────────────────────╮│ +│ - Signed│││ Kind  Name  By  Detail ││ +│ $ Command││╰────────────────────────────────────────────────╯│ +││││ +││││ +││││ +││││ +││││ +╰────────────────────╯╰─────────────────────────────────── [ / to search ]  ─╯ +▌i  Pick a URL and press Ctrl+R. +[Ctrl+R] Run   [Ctrl+C] Stop   [/] Search   [Ctrl+Y] Copy CLI + + + diff --git a/tests/visual/baseline/tui/02-tracks_120x40_mornye-dark.svg b/tests/visual/baseline/tui/02-tracks_120x40_mornye-dark.svg new file mode 100644 index 0000000..077f21f --- /dev/null +++ b/tests/visual/baseline/tui/02-tracks_120x40_mornye-dark.svg @@ -0,0 +1,224 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + tracks 120x40 + + + + + + + + + + +MORNYE +                                                         v0.0.0 +╭─ * Modes ──────────────╮╭─ Tracks ─────────────────────────────────────────────────────────────────────────────────╮ +││││ +│││The tracks behind the link. Space picks one, a picks all, n picks none, i inverts, l q│ +│ v Download│││ +│││╭──────────────╮╭──────────────╮╭──────────────╮╭─────────────────╮│ +││││ Load tracks ││ All ││ None ││ Queue for later ││ +│ ? Search││╰──────────────╯╰──────────────╯╰──────────────╯╰─────────────────╯│ +││││ +│█│││ +│█ # Tracks││Press Load tracks to see what is behind the link.│ +│█│││ +│││╭────────────────────────────────────────────────────────────────────────────────────╮│ +│ Q Queue│││ #  Title  Artist  Album ││ +│││╰────────────────────────────────────────────────────────────────────────────────────╯│ +││││ +│ = Live│││ +││││ +││││ +│ h History│││ +││││ +││││ +│ @ Session│││ +││││ +││││ +│ - Library│││ +││││ +││││ +│ + Extensions│││ +│▂│││ +││││ +│ ! Health│││ +││││ +││││ +││││ +╰────────────────────────╯╰───────────────────────────────────────────────────────────────────── [ space to pick ]  ─╯ +▌i  Pick a URL and press Ctrl+R. +[Ctrl+R] Run   [Ctrl+C] Stop   [/] Search   [Ctrl+Y] Copy CLI   [Ctrl+L] Log   [Ctrl+O] Copy log   [?] Help + + + diff --git a/tests/visual/baseline/tui/02-tracks_120x40_mornye-light.svg b/tests/visual/baseline/tui/02-tracks_120x40_mornye-light.svg new file mode 100644 index 0000000..694eca3 --- /dev/null +++ b/tests/visual/baseline/tui/02-tracks_120x40_mornye-light.svg @@ -0,0 +1,224 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + tracks 120x40 + + + + + + + + + + +MORNYE +                                                         v0.0.0 +╭─ * Modes ──────────────╮╭─ Tracks ─────────────────────────────────────────────────────────────────────────────────╮ +││││ +│││The tracks behind the link. Space picks one, a picks all, n picks none, i inverts, l q│ +│ v Download│││ +│││╭──────────────╮╭──────────────╮╭──────────────╮╭─────────────────╮│ +││││ Load tracks ││ All ││ None ││ Queue for later ││ +│ ? Search││╰──────────────╯╰──────────────╯╰──────────────╯╰─────────────────╯│ +││││ +│█│││ +│█ # Tracks││Press Load tracks to see what is behind the link.│ +│█│││ +│││╭────────────────────────────────────────────────────────────────────────────────────╮│ +│ Q Queue│││ #  Title  Artist  Album ││ +│││╰────────────────────────────────────────────────────────────────────────────────────╯│ +││││ +│ = Live│││ +││││ +││││ +│ h History│││ +││││ +││││ +│ @ Session│││ +││││ +││││ +│ - Library│││ +││││ +││││ +│ + Extensions│││ +│▂│││ +││││ +│ ! Health│││ +││││ +││││ +││││ +╰────────────────────────╯╰───────────────────────────────────────────────────────────────────── [ space to pick ]  ─╯ +▌i  Pick a URL and press Ctrl+R. +[Ctrl+R] Run   [Ctrl+C] Stop   [/] Search   [Ctrl+Y] Copy CLI   [Ctrl+L] Log   [Ctrl+O] Copy log   [?] Help + + + diff --git a/tests/visual/baseline/tui/02-tracks_80x24_mornye-dark.svg b/tests/visual/baseline/tui/02-tracks_80x24_mornye-dark.svg new file mode 100644 index 0000000..97e22b4 --- /dev/null +++ b/tests/visual/baseline/tui/02-tracks_80x24_mornye-dark.svg @@ -0,0 +1,157 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + tracks 80x24 + + + + + + + + + + +MORNYE +                                     v0.0.0 +╭─ * Modes ──────────╮╭─ Tracks ─────────────────────────────────────────────╮ +│ v Download│││ +│ ? Search││The tracks behind the link. Space picks one, a pic│ +│█ # Tracks│││ +│ Q Queue││╭──────────────╮╭──────────────╮╭──────────────╮│ +│ = Live│││ Load tracks ││ All ││ None ││ +│ h History││╰──────────────╯╰──────────────╯╰──────────────╯│ +│ @ Session│││ +│ - Library│││ +│ + Extensions││Press Load tracks to see what is behind the link.│ +│ ! Health│││ +│ - Signed││╭────────────────────────────────────────────────╮│ +│ $ Command│││ #  Title  Artist  Album ││ +│││╰────────────────────────────────────────────────╯│ +││││ +││││ +││││ +││││ +╰────────────────────╯╰───────────────────────────────── [ space to pick ]  ─╯ +▌i  Pick a URL and press Ctrl+R. +[Ctrl+R] Run   [Ctrl+C] Stop   [/] Search   [Ctrl+Y] Copy CLI + + + diff --git a/tests/visual/baseline/tui/02-tracks_80x24_mornye-light.svg b/tests/visual/baseline/tui/02-tracks_80x24_mornye-light.svg new file mode 100644 index 0000000..51f1112 --- /dev/null +++ b/tests/visual/baseline/tui/02-tracks_80x24_mornye-light.svg @@ -0,0 +1,157 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + tracks 80x24 + + + + + + + + + + +MORNYE +                                     v0.0.0 +╭─ * Modes ──────────╮╭─ Tracks ─────────────────────────────────────────────╮ +│ v Download│││ +│ ? Search││The tracks behind the link. Space picks one, a pic│ +│█ # Tracks│││ +│ Q Queue││╭──────────────╮╭──────────────╮╭──────────────╮│ +│ = Live│││ Load tracks ││ All ││ None ││ +│ h History││╰──────────────╯╰──────────────╯╰──────────────╯│ +│ @ Session│││ +│ - Library│││ +│ + Extensions││Press Load tracks to see what is behind the link.│ +│ ! Health│││ +│ - Signed││╭────────────────────────────────────────────────╮│ +│ $ Command│││ #  Title  Artist  Album ││ +│││╰────────────────────────────────────────────────╯│ +││││ +││││ +││││ +││││ +╰────────────────────╯╰───────────────────────────────── [ space to pick ]  ─╯ +▌i  Pick a URL and press Ctrl+R. +[Ctrl+R] Run   [Ctrl+C] Stop   [/] Search   [Ctrl+Y] Copy CLI + + + diff --git a/tests/visual/baseline/tui/03-staged_120x40_mornye-dark.svg b/tests/visual/baseline/tui/03-staged_120x40_mornye-dark.svg new file mode 100644 index 0000000..e6506f3 --- /dev/null +++ b/tests/visual/baseline/tui/03-staged_120x40_mornye-dark.svg @@ -0,0 +1,227 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + staged 120x40 + + + + + + + + + + +MORNYE +                                                         v0.0.0 +╭─ * Modes ──────────────╮╭─ Queue ──────────────────────────────────────────────────────────────────────────────────╮ +││││ +│││Queued for later — from the Tracks panel (l) or the desktop window. Enter starts the h│ +│ v Download│││ +│││╭──────────────────────╮╭──────────────────────╮╭────────────────────────────────────╮│ +││││All types▼││All statuses▼││Search the queue…││ +│ ? Search││╰──────────────────────╯╰──────────────────────╯╰────────────────────────────────────╯│ +││││ +│││0 item(s) — 0 waiting, 0 running  ·  0 tracks · 0 albums · 0 playlists · 0 artists│ +│ # Tracks│││ +│││╭────────────────────────────────────────────────────────────────────────────────────╮│ +│█│││The queue is empty. Press l on the Tracks panel to add the selection.││ +│█ Q Queue│││││ +│█│││││ +│││╰────────────────────────────────────────────────────────────────────────────────────╯│ +│ = Live│││ +│││╭──────────────╮╭──────────────╮╭──────────────╮╭────────────────╮╭──────────────╮│ +││││ Start ││ Start all ││ Remove ││ Clear finished ││ Clear all ││ +│ h History││╰──────────────╯╰──────────────╯╰──────────────╯╰────────────────╯╰──────────────╯│ +││││ +││││ +│ @ Session│││ +││││ +││││ +│ - Library│││ +││││ +││││ +│ + Extensions│││ +│▂│││ +││││ +│ ! Health│││ +││││ +││││ +││││ +╰────────────────────────╯╰──────────────────────────────────────────────────────────────────── [ Enter to start ]  ─╯ +▌i  Pick a URL and press Ctrl+R. +[Ctrl+R] Run   [Ctrl+C] Stop   [/] Search   [Ctrl+Y] Copy CLI   [Ctrl+L] Log   [Ctrl+O] Copy log   [?] Help + + + diff --git a/tests/visual/baseline/tui/03-staged_120x40_mornye-light.svg b/tests/visual/baseline/tui/03-staged_120x40_mornye-light.svg new file mode 100644 index 0000000..9a6dbd4 --- /dev/null +++ b/tests/visual/baseline/tui/03-staged_120x40_mornye-light.svg @@ -0,0 +1,227 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + staged 120x40 + + + + + + + + + + +MORNYE +                                                         v0.0.0 +╭─ * Modes ──────────────╮╭─ Queue ──────────────────────────────────────────────────────────────────────────────────╮ +││││ +│││Queued for later — from the Tracks panel (l) or the desktop window. Enter starts the h│ +│ v Download│││ +│││╭──────────────────────╮╭──────────────────────╮╭────────────────────────────────────╮│ +││││All types▼││All statuses▼││Search the queue…││ +│ ? Search││╰──────────────────────╯╰──────────────────────╯╰────────────────────────────────────╯│ +││││ +│││0 item(s) — 0 waiting, 0 running  ·  0 tracks · 0 albums · 0 playlists · 0 artists│ +│ # Tracks│││ +│││╭────────────────────────────────────────────────────────────────────────────────────╮│ +│█│││The queue is empty. Press l on the Tracks panel to add the selection.││ +│█ Q Queue│││││ +│█│││││ +│││╰────────────────────────────────────────────────────────────────────────────────────╯│ +│ = Live│││ +│││╭──────────────╮╭──────────────╮╭──────────────╮╭────────────────╮╭──────────────╮│ +││││ Start ││ Start all ││ Remove ││ Clear finished ││ Clear all ││ +│ h History││╰──────────────╯╰──────────────╯╰──────────────╯╰────────────────╯╰──────────────╯│ +││││ +││││ +│ @ Session│││ +││││ +││││ +│ - Library│││ +││││ +││││ +│ + Extensions│││ +│▂│││ +││││ +│ ! Health│││ +││││ +││││ +││││ +╰────────────────────────╯╰──────────────────────────────────────────────────────────────────── [ Enter to start ]  ─╯ +▌i  Pick a URL and press Ctrl+R. +[Ctrl+R] Run   [Ctrl+C] Stop   [/] Search   [Ctrl+Y] Copy CLI   [Ctrl+L] Log   [Ctrl+O] Copy log   [?] Help + + + diff --git a/tests/visual/baseline/tui/03-staged_80x24_mornye-dark.svg b/tests/visual/baseline/tui/03-staged_80x24_mornye-dark.svg new file mode 100644 index 0000000..14d9b74 --- /dev/null +++ b/tests/visual/baseline/tui/03-staged_80x24_mornye-dark.svg @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + staged 80x24 + + + + + + + + + + +MORNYE +                                     v0.0.0 +╭─ * Modes ──────────╮╭─ Queue ──────────────────────────────────────────────╮ +│ v Download│││ +│ ? Search││Queued for later — from the Tracks panel (l) or t│ +│ # Tracks│││ +│█ Q Queue││╭──────────────────────╮╭──────────────────────╮╭│ +│ = Live│││All types▼││All statuses▼│││ +│ h History││╰──────────────────────╯╰──────────────────────╯╰│ +│ @ Session│││ +│ - Library││0 item(s) — 0 waiting, 0 running  ·  0 tracks · │ +│ + Extensions│││ +│ ! Health││╭───────────────────────────────────────────────╮│ +│ - Signed│││The queue is empty. Press l on the Tracks││ +│ $ Command│││panel to add the selection.││ +││││││ +│││╰───────────────────────────────────────────────╯▄│ +││││ +│││╭──────────────╮╭──────────────╮╭──────────────│ +││││ +╰────────────────────╯╰──────────────────────────────── [ Enter to start ]  ─╯ +▌i  Pick a URL and press Ctrl+R. +[Ctrl+R] Run   [Ctrl+C] Stop   [/] Search   [Ctrl+Y] Copy CLI + + + diff --git a/tests/visual/baseline/tui/03-staged_80x24_mornye-light.svg b/tests/visual/baseline/tui/03-staged_80x24_mornye-light.svg new file mode 100644 index 0000000..8386819 --- /dev/null +++ b/tests/visual/baseline/tui/03-staged_80x24_mornye-light.svg @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + staged 80x24 + + + + + + + + + + +MORNYE +                                     v0.0.0 +╭─ * Modes ──────────╮╭─ Queue ──────────────────────────────────────────────╮ +│ v Download│││ +│ ? Search││Queued for later — from the Tracks panel (l) or t│ +│ # Tracks│││ +│█ Q Queue││╭──────────────────────╮╭──────────────────────╮╭│ +│ = Live│││All types▼││All statuses▼│││ +│ h History││╰──────────────────────╯╰──────────────────────╯╰│ +│ @ Session│││ +│ - Library││0 item(s) — 0 waiting, 0 running  ·  0 tracks · │ +│ + Extensions│││ +│ ! Health││╭───────────────────────────────────────────────╮│ +│ - Signed│││The queue is empty. Press l on the Tracks││ +│ $ Command│││panel to add the selection.││ +││││││ +│││╰───────────────────────────────────────────────╯▄│ +││││ +│││╭──────────────╮╭──────────────╮╭──────────────│ +││││ +╰────────────────────╯╰──────────────────────────────── [ Enter to start ]  ─╯ +▌i  Pick a URL and press Ctrl+R. +[Ctrl+R] Run   [Ctrl+C] Stop   [/] Search   [Ctrl+Y] Copy CLI + + + diff --git a/tests/visual/baseline/tui/04-queue_120x40_mornye-dark.svg b/tests/visual/baseline/tui/04-queue_120x40_mornye-dark.svg new file mode 100644 index 0000000..ce1b855 --- /dev/null +++ b/tests/visual/baseline/tui/04-queue_120x40_mornye-dark.svg @@ -0,0 +1,222 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + queue 120x40 + + + + + + + + + + +MORNYE +                                                         v0.0.0 +╭─ * Modes ──────────────╮╭─ Downloading now ────────────────────────────────────────────────────────────────────────╮ +││││ +│││Nothing running│ +│ v Download│││ +│││━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━0%│ +││││ +│ ? Search│││ +││││ +││││ +│ # Tracks│││ +│││The queue fills up once a download starts.│ +││││ +│ Q Queue│││ +││││ +│█│││ +│█ = Live│││ +│█│││ +││││ +│ h History│││ +││││ +││││ +│ @ Session│││ +││││ +││││ +│ - Library│││ +││││ +││││ +│ + Extensions│││ +│▂│││ +││││ +│ ! Health│││ +││││ +││││ +││││ +╰────────────────────────╯╰────────────────────────────────────────────────────────────────────────────── [ live ]  ─╯ +▌i  Pick a URL and press Ctrl+R. +[Ctrl+R] Run   [Ctrl+C] Stop   [/] Search   [Ctrl+Y] Copy CLI   [Ctrl+L] Log   [Ctrl+O] Copy log   [?] Help + + + diff --git a/tests/visual/baseline/tui/04-queue_120x40_mornye-light.svg b/tests/visual/baseline/tui/04-queue_120x40_mornye-light.svg new file mode 100644 index 0000000..a788baa --- /dev/null +++ b/tests/visual/baseline/tui/04-queue_120x40_mornye-light.svg @@ -0,0 +1,222 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + queue 120x40 + + + + + + + + + + +MORNYE +                                                         v0.0.0 +╭─ * Modes ──────────────╮╭─ Downloading now ────────────────────────────────────────────────────────────────────────╮ +││││ +│││Nothing running│ +│ v Download│││ +│││━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━0%│ +││││ +│ ? Search│││ +││││ +││││ +│ # Tracks│││ +│││The queue fills up once a download starts.│ +││││ +│ Q Queue│││ +││││ +│█│││ +│█ = Live│││ +│█│││ +││││ +│ h History│││ +││││ +││││ +│ @ Session│││ +││││ +││││ +│ - Library│││ +││││ +││││ +│ + Extensions│││ +│▂│││ +││││ +│ ! Health│││ +││││ +││││ +││││ +╰────────────────────────╯╰────────────────────────────────────────────────────────────────────────────── [ live ]  ─╯ +▌i  Pick a URL and press Ctrl+R. +[Ctrl+R] Run   [Ctrl+C] Stop   [/] Search   [Ctrl+Y] Copy CLI   [Ctrl+L] Log   [Ctrl+O] Copy log   [?] Help + + + diff --git a/tests/visual/baseline/tui/04-queue_80x24_mornye-dark.svg b/tests/visual/baseline/tui/04-queue_80x24_mornye-dark.svg new file mode 100644 index 0000000..56dbd32 --- /dev/null +++ b/tests/visual/baseline/tui/04-queue_80x24_mornye-dark.svg @@ -0,0 +1,155 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + queue 80x24 + + + + + + + + + + +MORNYE +                                     v0.0.0 +╭─ * Modes ──────────╮╭─ Downloading now ────────────────────────────────────╮ +│ v Download│││ +│ ? Search││Nothing running│ +│ # Tracks│││ +│ Q Queue││━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━0%│ +│█ = Live│││ +│ h History│││ +│ @ Session│││ +│ - Library│││ +│ + Extensions│││ +│ ! Health││The queue fills up once a download starts.│ +│ - Signed│││ +│ $ Command│││ +││││ +││││ +││││ +││││ +││││ +╰────────────────────╯╰────────────────────────────────────────── [ live ]  ─╯ +▌i  Pick a URL and press Ctrl+R. +[Ctrl+R] Run   [Ctrl+C] Stop   [/] Search   [Ctrl+Y] Copy CLI + + + diff --git a/tests/visual/baseline/tui/04-queue_80x24_mornye-light.svg b/tests/visual/baseline/tui/04-queue_80x24_mornye-light.svg new file mode 100644 index 0000000..f85a4e3 --- /dev/null +++ b/tests/visual/baseline/tui/04-queue_80x24_mornye-light.svg @@ -0,0 +1,155 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + queue 80x24 + + + + + + + + + + +MORNYE +                                     v0.0.0 +╭─ * Modes ──────────╮╭─ Downloading now ────────────────────────────────────╮ +│ v Download│││ +│ ? Search││Nothing running│ +│ # Tracks│││ +│ Q Queue││━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━0%│ +│█ = Live│││ +│ h History│││ +│ @ Session│││ +│ - Library│││ +│ + Extensions│││ +│ ! Health││The queue fills up once a download starts.│ +│ - Signed│││ +│ $ Command│││ +││││ +││││ +││││ +││││ +││││ +╰────────────────────╯╰────────────────────────────────────────── [ live ]  ─╯ +▌i  Pick a URL and press Ctrl+R. +[Ctrl+R] Run   [Ctrl+C] Stop   [/] Search   [Ctrl+Y] Copy CLI + + + diff --git a/tests/visual/baseline/tui/05-history_120x40_mornye-dark.svg b/tests/visual/baseline/tui/05-history_120x40_mornye-dark.svg new file mode 100644 index 0000000..f436abb --- /dev/null +++ b/tests/visual/baseline/tui/05-history_120x40_mornye-dark.svg @@ -0,0 +1,226 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + history 120x40 + + + + + + + + + + +MORNYE +                                                         v0.0.0 +╭─ * Modes ──────────────╮╭─ History ────────────────────────────────────────────────────────────────────────────────╮ +││││ +│││What was downloaded, and the links you opened. Enter on a link opens it again.│ +│ v Download│││ +│││╭──────────────────────╮╭────────────────────────────────────╮╭──────────────────────╮│ +││││Downloads▼││Search…││Newest first▼││ +│ ? Search││╰──────────────────────╯╰────────────────────────────────────╯╰──────────────────────╯│ +││││ +│││0 track(s) downloaded · 0 B│ +│ # Tracks│││ +│││╭────────────────────────────────────────────────────────────────────────────────────╮│ +││││No download history yet.││ +│ Q Queue│││││ +││││││ +│││╰────────────────────────────────────────────────────────────────────────────────────╯│ +│ = Live│││ +│││╭──────────────╮╭──────────────╮╭──────────────╮│ +│█│││ Remove ││ Refresh ││ Clear all ││ +│█ h History││╰──────────────╯╰──────────────╯╰──────────────╯│ +│█│││ +││││ +│ @ Session│││ +││││ +││││ +│ - Library│││ +││││ +││││ +│ + Extensions│││ +│▂│││ +││││ +│ ! Health│││ +││││ +││││ +││││ +╰────────────────────────╯╰─────────────────────────────────────────────────────────────── [ downloads · fetches ]  ─╯ +▌i  Pick a URL and press Ctrl+R. +[Ctrl+R] Run   [Ctrl+C] Stop   [/] Search   [Ctrl+Y] Copy CLI   [Ctrl+L] Log   [Ctrl+O] Copy log   [?] Help + + + diff --git a/tests/visual/baseline/tui/05-history_120x40_mornye-light.svg b/tests/visual/baseline/tui/05-history_120x40_mornye-light.svg new file mode 100644 index 0000000..0289d87 --- /dev/null +++ b/tests/visual/baseline/tui/05-history_120x40_mornye-light.svg @@ -0,0 +1,226 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + history 120x40 + + + + + + + + + + +MORNYE +                                                         v0.0.0 +╭─ * Modes ──────────────╮╭─ History ────────────────────────────────────────────────────────────────────────────────╮ +││││ +│││What was downloaded, and the links you opened. Enter on a link opens it again.│ +│ v Download│││ +│││╭──────────────────────╮╭────────────────────────────────────╮╭──────────────────────╮│ +││││Downloads▼││Search…││Newest first▼││ +│ ? Search││╰──────────────────────╯╰────────────────────────────────────╯╰──────────────────────╯│ +││││ +│││0 track(s) downloaded · 0 B│ +│ # Tracks│││ +│││╭────────────────────────────────────────────────────────────────────────────────────╮│ +││││No download history yet.││ +│ Q Queue│││││ +││││││ +│││╰────────────────────────────────────────────────────────────────────────────────────╯│ +│ = Live│││ +│││╭──────────────╮╭──────────────╮╭──────────────╮│ +│█│││ Remove ││ Refresh ││ Clear all ││ +│█ h History││╰──────────────╯╰──────────────╯╰──────────────╯│ +│█│││ +││││ +│ @ Session│││ +││││ +││││ +│ - Library│││ +││││ +││││ +│ + Extensions│││ +│▂│││ +││││ +│ ! Health│││ +││││ +││││ +││││ +╰────────────────────────╯╰─────────────────────────────────────────────────────────────── [ downloads · fetches ]  ─╯ +▌i  Pick a URL and press Ctrl+R. +[Ctrl+R] Run   [Ctrl+C] Stop   [/] Search   [Ctrl+Y] Copy CLI   [Ctrl+L] Log   [Ctrl+O] Copy log   [?] Help + + + diff --git a/tests/visual/baseline/tui/05-history_80x24_mornye-dark.svg b/tests/visual/baseline/tui/05-history_80x24_mornye-dark.svg new file mode 100644 index 0000000..c0a2f8c --- /dev/null +++ b/tests/visual/baseline/tui/05-history_80x24_mornye-dark.svg @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + history 80x24 + + + + + + + + + + +MORNYE +                                     v0.0.0 +╭─ * Modes ──────────╮╭─ History ────────────────────────────────────────────╮ +│ v Download│││ +│ ? Search││What was downloaded, and the links you opened. En│ +│ # Tracks│││ +│ Q Queue││╭──────────────────────╮╭────╮╭──────────────────│ +│ = Live│││Downloads▼││││Newest first│ +│█ h History││╰──────────────────────╯╰────╯╰──────────────────│ +│ @ Session│││ +│ - Library││0 track(s) downloaded · 0 B│ +│ + Extensions│││ +│ ! Health││╭───────────────────────────────────────────────╮│ +│ - Signed│││No download history yet.││ +│ $ Command│││││ +││││││ +│││╰───────────────────────────────────────────────╯▄│ +││││ +│││╭──────────────╮╭──────────────╮╭──────────────│ +││││ +╰────────────────────╯╰─────────────────────────── [ downloads · fetches ]  ─╯ +▌i  Pick a URL and press Ctrl+R. +[Ctrl+R] Run   [Ctrl+C] Stop   [/] Search   [Ctrl+Y] Copy CLI + + + diff --git a/tests/visual/baseline/tui/05-history_80x24_mornye-light.svg b/tests/visual/baseline/tui/05-history_80x24_mornye-light.svg new file mode 100644 index 0000000..52803ca --- /dev/null +++ b/tests/visual/baseline/tui/05-history_80x24_mornye-light.svg @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + history 80x24 + + + + + + + + + + +MORNYE +                                     v0.0.0 +╭─ * Modes ──────────╮╭─ History ────────────────────────────────────────────╮ +│ v Download│││ +│ ? Search││What was downloaded, and the links you opened. En│ +│ # Tracks│││ +│ Q Queue││╭──────────────────────╮╭────╮╭──────────────────│ +│ = Live│││Downloads▼││││Newest first│ +│█ h History││╰──────────────────────╯╰────╯╰──────────────────│ +│ @ Session│││ +│ - Library││0 track(s) downloaded · 0 B│ +│ + Extensions│││ +│ ! Health││╭───────────────────────────────────────────────╮│ +│ - Signed│││No download history yet.││ +│ $ Command│││││ +││││││ +│││╰───────────────────────────────────────────────╯▄│ +││││ +│││╭──────────────╮╭──────────────╮╭──────────────│ +││││ +╰────────────────────╯╰─────────────────────────── [ downloads · fetches ]  ─╯ +▌i  Pick a URL and press Ctrl+R. +[Ctrl+R] Run   [Ctrl+C] Stop   [/] Search   [Ctrl+Y] Copy CLI + + + diff --git a/tests/visual/baseline/tui/06-session_120x40_mornye-dark.svg b/tests/visual/baseline/tui/06-session_120x40_mornye-dark.svg new file mode 100644 index 0000000..c9753c6 --- /dev/null +++ b/tests/visual/baseline/tui/06-session_120x40_mornye-dark.svg @@ -0,0 +1,225 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + session 120x40 + + + + + + + + + + +MORNYE +                                                         v0.0.0 +╭─ * Modes ──────────────╮╭─ Session ────────────────────────────────────────────────────────────────────────────────╮ +││││ +││││ +│ v Download││Recent URLs│ +│││╭────────────────────────────────────────────────────────────────────────────────────╮│ +││││Nothing fetched yet││ +│ ? Search││╰────────────────────────────────────────────────────────────────────────────────────╯│ +││││ +││││ +│ # Tracks││Profiles│ +│││╭────────────────────────────────────────────────────────────────────────────────────╮│ +││││No profiles saved││ +│ Q Queue││╰────────────────────────────────────────────────────────────────────────────────────╯│ +││││ +│││╭──────────────────────────────────────────────────╮╭──────────────╮╭──────────────╮│ +│ = Live│││profile name││ Save ││ Delete ││ +│││╰──────────────────────────────────────────────────╯╰──────────────╯╰──────────────╯│ +││││ +│ h History│││ +││││ +│█│││ +│█ @ Session│││ +│█│││ +││││ +│ - Library│││ +││││ +││││ +│ + Extensions│││ +│▂│││ +││││ +│ ! Health│││ +││││ +││││ +││││ +╰────────────────────────╯╰──────────────────────────────────────────────────────────────── [ history · profiles ]  ─╯ +▌i  Pick a URL and press Ctrl+R. +[Ctrl+R] Run   [Ctrl+C] Stop   [/] Search   [Ctrl+Y] Copy CLI   [Ctrl+L] Log   [Ctrl+O] Copy log   [?] Help + + + diff --git a/tests/visual/baseline/tui/06-session_120x40_mornye-light.svg b/tests/visual/baseline/tui/06-session_120x40_mornye-light.svg new file mode 100644 index 0000000..11021f0 --- /dev/null +++ b/tests/visual/baseline/tui/06-session_120x40_mornye-light.svg @@ -0,0 +1,225 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + session 120x40 + + + + + + + + + + +MORNYE +                                                         v0.0.0 +╭─ * Modes ──────────────╮╭─ Session ────────────────────────────────────────────────────────────────────────────────╮ +││││ +││││ +│ v Download││Recent URLs│ +│││╭────────────────────────────────────────────────────────────────────────────────────╮│ +││││Nothing fetched yet││ +│ ? Search││╰────────────────────────────────────────────────────────────────────────────────────╯│ +││││ +││││ +│ # Tracks││Profiles│ +│││╭────────────────────────────────────────────────────────────────────────────────────╮│ +││││No profiles saved││ +│ Q Queue││╰────────────────────────────────────────────────────────────────────────────────────╯│ +││││ +│││╭──────────────────────────────────────────────────╮╭──────────────╮╭──────────────╮│ +│ = Live│││profile name││ Save ││ Delete ││ +│││╰──────────────────────────────────────────────────╯╰──────────────╯╰──────────────╯│ +││││ +│ h History│││ +││││ +│█│││ +│█ @ Session│││ +│█│││ +││││ +│ - Library│││ +││││ +││││ +│ + Extensions│││ +│▂│││ +││││ +│ ! Health│││ +││││ +││││ +││││ +╰────────────────────────╯╰──────────────────────────────────────────────────────────────── [ history · profiles ]  ─╯ +▌i  Pick a URL and press Ctrl+R. +[Ctrl+R] Run   [Ctrl+C] Stop   [/] Search   [Ctrl+Y] Copy CLI   [Ctrl+L] Log   [Ctrl+O] Copy log   [?] Help + + + diff --git a/tests/visual/baseline/tui/06-session_80x24_mornye-dark.svg b/tests/visual/baseline/tui/06-session_80x24_mornye-dark.svg new file mode 100644 index 0000000..d477bf7 --- /dev/null +++ b/tests/visual/baseline/tui/06-session_80x24_mornye-dark.svg @@ -0,0 +1,160 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + session 80x24 + + + + + + + + + + +MORNYE +                                     v0.0.0 +╭─ * Modes ──────────╮╭─ Session ────────────────────────────────────────────╮ +│ v Download│││ +│ ? Search│││ +│ # Tracks││Recent URLs│ +│ Q Queue││╭───────────────────────────────────────────────╮│ +│ = Live│││Nothing fetched yet││ +│ h History││╰───────────────────────────────────────────────╯│ +│█ @ Session│││ +│ - Library│││ +│ + Extensions││Profiles│ +│ ! Health││╭───────────────────────────────────────────────╮│ +│ - Signed│││No profiles saved││ +│ $ Command││╰───────────────────────────────────────────────╯│ +│││▁│ +│││╭─────────────╮╭──────────────╮╭──────────────╮│ +││││profile ││ Save ││ Delete ││ +│││╰─────────────╯╰──────────────╯╰──────────────╯│ +││││ +╰────────────────────╯╰──────────────────────────── [ history · profiles ]  ─╯ +▌i  Pick a URL and press Ctrl+R. +[Ctrl+R] Run   [Ctrl+C] Stop   [/] Search   [Ctrl+Y] Copy CLI + + + diff --git a/tests/visual/baseline/tui/06-session_80x24_mornye-light.svg b/tests/visual/baseline/tui/06-session_80x24_mornye-light.svg new file mode 100644 index 0000000..9fb76ec --- /dev/null +++ b/tests/visual/baseline/tui/06-session_80x24_mornye-light.svg @@ -0,0 +1,160 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + session 80x24 + + + + + + + + + + +MORNYE +                                     v0.0.0 +╭─ * Modes ──────────╮╭─ Session ────────────────────────────────────────────╮ +│ v Download│││ +│ ? Search│││ +│ # Tracks││Recent URLs│ +│ Q Queue││╭───────────────────────────────────────────────╮│ +│ = Live│││Nothing fetched yet││ +│ h History││╰───────────────────────────────────────────────╯│ +│█ @ Session│││ +│ - Library│││ +│ + Extensions││Profiles│ +│ ! Health││╭───────────────────────────────────────────────╮│ +│ - Signed│││No profiles saved││ +│ $ Command││╰───────────────────────────────────────────────╯│ +│││▁│ +│││╭─────────────╮╭──────────────╮╭──────────────╮│ +││││profile ││ Save ││ Delete ││ +│││╰─────────────╯╰──────────────╯╰──────────────╯│ +││││ +╰────────────────────╯╰──────────────────────────── [ history · profiles ]  ─╯ +▌i  Pick a URL and press Ctrl+R. +[Ctrl+R] Run   [Ctrl+C] Stop   [/] Search   [Ctrl+Y] Copy CLI + + + diff --git a/tests/visual/baseline/tui/07-library_120x40_mornye-dark.svg b/tests/visual/baseline/tui/07-library_120x40_mornye-dark.svg new file mode 100644 index 0000000..60c6f3d --- /dev/null +++ b/tests/visual/baseline/tui/07-library_120x40_mornye-dark.svg @@ -0,0 +1,225 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + library 120x40 + + + + + + + + + + +MORNYE +                                                         v0.0.0 +╭─ * Modes ──────────────╮╭─ Library ────────────────────────────────────────────────────────────────────────────────╮ +││││ +│││Read tags directly from a saved SMB or WebDAV library. The scan does not copy or chan│ +│ v Download│││ +││││ +│││Saved network destination│ +│ ? Search││╭───────────────────────────────────────────────────────────────────────────────────╮│ +││││Choose a destination…▼││ +│││╰───────────────────────────────────────────────────────────────────────────────────╯│ +│ # Tracks│││ +│││Destination profile│ +│││╭───────────────────────────────────────────────────────────────────────────────────╮│ +│ Q Queue│││SMB▼││ +│││╰───────────────────────────────────────────────────────────────────────────────────╯│ +│││╭────────────────────────────────────────╮╭─────────────────────────────────────────╮│ +│ = Live│││Profile name││SMB server or IP││ +│││╰────────────────────────────────────────╯╰─────────────────────────────────────────╯│ +││││ +│ h History││╭────────────────────────────────────────╮╭─────────────────────────────────────────╮│ +││││Share name││Subfolder (optional)││ +│││╰────────────────────────────────────────╯╰─────────────────────────────────────────╯│ +│ @ Session│││ +│││╭────────────────────────────────────────╮╭─────────────────────────────────────────╮▄│ +│█│││Username (optional)││Domain (optional)││ +│█ - Library││╰────────────────────────────────────────╯╰─────────────────────────────────────────╯│ +│█│││ +│││╭────────────────────────────────────────╮╭─────────────────────────────────────────╮│ +│ + Extensions│││Password (session only unless secure││15││ +│▂││╰────────────────────────────────────────╯╰─────────────────────────────────────────╯│ +││││ +│ ! Health││▊▔▔▔▔▔▔▔▔▎Require SMB3 encryption│ +│││▊▎│ +│││▊▁▁▁▁▁▁▁▁▎│ +││││ +╰────────────────────────╯╰────────────────────────────────────────────────────────────────────────── [ SMB scan ]  ─╯ +▌i  Pick a URL and press Ctrl+R. +[Ctrl+R] Run   [Ctrl+C] Stop   [/] Search   [Ctrl+Y] Copy CLI   [Ctrl+L] Log   [Ctrl+O] Copy log   [?] Help + + + diff --git a/tests/visual/baseline/tui/07-library_120x40_mornye-light.svg b/tests/visual/baseline/tui/07-library_120x40_mornye-light.svg new file mode 100644 index 0000000..2a3d259 --- /dev/null +++ b/tests/visual/baseline/tui/07-library_120x40_mornye-light.svg @@ -0,0 +1,225 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + library 120x40 + + + + + + + + + + +MORNYE +                                                         v0.0.0 +╭─ * Modes ──────────────╮╭─ Library ────────────────────────────────────────────────────────────────────────────────╮ +││││ +│││Read tags directly from a saved SMB or WebDAV library. The scan does not copy or chan│ +│ v Download│││ +││││ +│││Saved network destination│ +│ ? Search││╭───────────────────────────────────────────────────────────────────────────────────╮│ +││││Choose a destination…▼││ +│││╰───────────────────────────────────────────────────────────────────────────────────╯│ +│ # Tracks│││ +│││Destination profile│ +│││╭───────────────────────────────────────────────────────────────────────────────────╮│ +│ Q Queue│││SMB▼││ +│││╰───────────────────────────────────────────────────────────────────────────────────╯│ +│││╭────────────────────────────────────────╮╭─────────────────────────────────────────╮│ +│ = Live│││Profile name││SMB server or IP││ +│││╰────────────────────────────────────────╯╰─────────────────────────────────────────╯│ +││││ +│ h History││╭────────────────────────────────────────╮╭─────────────────────────────────────────╮│ +││││Share name││Subfolder (optional)││ +│││╰────────────────────────────────────────╯╰─────────────────────────────────────────╯│ +│ @ Session│││ +│││╭────────────────────────────────────────╮╭─────────────────────────────────────────╮▄│ +│█│││Username (optional)││Domain (optional)││ +│█ - Library││╰────────────────────────────────────────╯╰─────────────────────────────────────────╯│ +│█│││ +│││╭────────────────────────────────────────╮╭─────────────────────────────────────────╮│ +│ + Extensions│││Password (session only unless secure││15││ +│▂││╰────────────────────────────────────────╯╰─────────────────────────────────────────╯│ +││││ +│ ! Health││▊▔▔▔▔▔▔▔▔▎Require SMB3 encryption│ +│││▊▎│ +│││▊▁▁▁▁▁▁▁▁▎│ +││││ +╰────────────────────────╯╰────────────────────────────────────────────────────────────────────────── [ SMB scan ]  ─╯ +▌i  Pick a URL and press Ctrl+R. +[Ctrl+R] Run   [Ctrl+C] Stop   [/] Search   [Ctrl+Y] Copy CLI   [Ctrl+L] Log   [Ctrl+O] Copy log   [?] Help + + + diff --git a/tests/visual/baseline/tui/07-library_80x24_mornye-dark.svg b/tests/visual/baseline/tui/07-library_80x24_mornye-dark.svg new file mode 100644 index 0000000..ee1c655 --- /dev/null +++ b/tests/visual/baseline/tui/07-library_80x24_mornye-dark.svg @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + library 80x24 + + + + + + + + + + +MORNYE +                                     v0.0.0 +╭─ * Modes ──────────╮╭─ Library ────────────────────────────────────────────╮ +│ v Download│││ +│ ? Search││Read tags directly from a saved SMB or WebDAV lib│ +│ # Tracks│││ +│ Q Queue│││ +│ = Live││Saved network destination│ +│ h History││╭───────────────────────────────────────────────╮▁│ +│ @ Session│││Choose a destination…▼││ +│█ - Library││╰───────────────────────────────────────────────╯│ +│ + Extensions│││ +│ ! Health││Destination profile│ +│ - Signed││╭───────────────────────────────────────────────╮│ +│ $ Command│││SMB▼││ +│││╰───────────────────────────────────────────────╯│ +│││╭──────────────────────╮╭───────────────────────╮│ +││││Profile name││SMB server or IP││ +│││╰──────────────────────╯╰───────────────────────╯│ +││││ +╰────────────────────╯╰────────────────────────────────────── [ SMB scan ]  ─╯ +▌i  Pick a URL and press Ctrl+R. +[Ctrl+R] Run   [Ctrl+C] Stop   [/] Search   [Ctrl+Y] Copy CLI + + + diff --git a/tests/visual/baseline/tui/07-library_80x24_mornye-light.svg b/tests/visual/baseline/tui/07-library_80x24_mornye-light.svg new file mode 100644 index 0000000..7f485fa --- /dev/null +++ b/tests/visual/baseline/tui/07-library_80x24_mornye-light.svg @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + library 80x24 + + + + + + + + + + +MORNYE +                                     v0.0.0 +╭─ * Modes ──────────╮╭─ Library ────────────────────────────────────────────╮ +│ v Download│││ +│ ? Search││Read tags directly from a saved SMB or WebDAV lib│ +│ # Tracks│││ +│ Q Queue│││ +│ = Live││Saved network destination│ +│ h History││╭───────────────────────────────────────────────╮▁│ +│ @ Session│││Choose a destination…▼││ +│█ - Library││╰───────────────────────────────────────────────╯│ +│ + Extensions│││ +│ ! Health││Destination profile│ +│ - Signed││╭───────────────────────────────────────────────╮│ +│ $ Command│││SMB▼││ +│││╰───────────────────────────────────────────────╯│ +│││╭──────────────────────╮╭───────────────────────╮│ +││││Profile name││SMB server or IP││ +│││╰──────────────────────╯╰───────────────────────╯│ +││││ +╰────────────────────╯╰────────────────────────────────────── [ SMB scan ]  ─╯ +▌i  Pick a URL and press Ctrl+R. +[Ctrl+R] Run   [Ctrl+C] Stop   [/] Search   [Ctrl+Y] Copy CLI + + + diff --git a/tests/visual/baseline/tui/08-extensions_120x40_mornye-dark.svg b/tests/visual/baseline/tui/08-extensions_120x40_mornye-dark.svg new file mode 100644 index 0000000..c96b329 --- /dev/null +++ b/tests/visual/baseline/tui/08-extensions_120x40_mornye-dark.svg @@ -0,0 +1,226 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + extensions 120x40 + + + + + + + + + + +MORNYE +                                                         v0.0.0 +╭─ * Modes ──────────────╮╭─ Extensions ─────────────────────────────────────────────────────────────────────────────╮ +││││ +│││Registry links. Providers install from these; without one there is nothing to download│ +│ v Download│││ +│││╭────────────────────────────────────────────────────────────────────────────────────╮│ +││││ Registry  Source  State ││ +│ ? Search││╰────────────────────────────────────────────────────────────────────────────────────╯│ +│││╭───────────────────────────────────────────────╮╭──────────────╮╭─────────────────╮│ +││││https://…/registry.json││ Add ││ Remove selected ││ +│ # Tracks││╰───────────────────────────────────────────────╯╰──────────────╯╰─────────────────╯│ +││││ +││││ +│ Q Queue││No registry links configured.│ +││││ +│││Extension settings│ +│ = Live│││ +│││╭────────────────────────────────────────────────────────────────────────────────────╮│ +││││Choose an extension…▼││ +│ h History││╰────────────────────────────────────────────────────────────────────────────────────╯│ +││││ +││││ +│ @ Session│││ +││││ +││││ +│ - Library│││ +││││ +│█│││ +│█ + Extensions│││ +│█▂││╭──────────────╮╭───────────────────╮│ +││││ Save ││ Reset to defaults ││ +│ ! Health││╰──────────────╯╰───────────────────╯│ +││││ +│││No installed extension has settings.│ +││││ +╰────────────────────────╯╰──────────────────────────────────────────────────────────────────────── [ registries ]  ─╯ +▌i  Pick a URL and press Ctrl+R. +[Ctrl+R] Run   [Ctrl+C] Stop   [/] Search   [Ctrl+Y] Copy CLI   [Ctrl+L] Log   [Ctrl+O] Copy log   [?] Help + + + diff --git a/tests/visual/baseline/tui/08-extensions_120x40_mornye-light.svg b/tests/visual/baseline/tui/08-extensions_120x40_mornye-light.svg new file mode 100644 index 0000000..bc419b4 --- /dev/null +++ b/tests/visual/baseline/tui/08-extensions_120x40_mornye-light.svg @@ -0,0 +1,226 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + extensions 120x40 + + + + + + + + + + +MORNYE +                                                         v0.0.0 +╭─ * Modes ──────────────╮╭─ Extensions ─────────────────────────────────────────────────────────────────────────────╮ +││││ +│││Registry links. Providers install from these; without one there is nothing to download│ +│ v Download│││ +│││╭────────────────────────────────────────────────────────────────────────────────────╮│ +││││ Registry  Source  State ││ +│ ? Search││╰────────────────────────────────────────────────────────────────────────────────────╯│ +│││╭───────────────────────────────────────────────╮╭──────────────╮╭─────────────────╮│ +││││https://…/registry.json││ Add ││ Remove selected ││ +│ # Tracks││╰───────────────────────────────────────────────╯╰──────────────╯╰─────────────────╯│ +││││ +││││ +│ Q Queue││No registry links configured.│ +││││ +│││Extension settings│ +│ = Live│││ +│││╭────────────────────────────────────────────────────────────────────────────────────╮│ +││││Choose an extension…▼││ +│ h History││╰────────────────────────────────────────────────────────────────────────────────────╯│ +││││ +││││ +│ @ Session│││ +││││ +││││ +│ - Library│││ +││││ +│█│││ +│█ + Extensions│││ +│█▂││╭──────────────╮╭───────────────────╮│ +││││ Save ││ Reset to defaults ││ +│ ! Health││╰──────────────╯╰───────────────────╯│ +││││ +│││No installed extension has settings.│ +││││ +╰────────────────────────╯╰──────────────────────────────────────────────────────────────────────── [ registries ]  ─╯ +▌i  Pick a URL and press Ctrl+R. +[Ctrl+R] Run   [Ctrl+C] Stop   [/] Search   [Ctrl+Y] Copy CLI   [Ctrl+L] Log   [Ctrl+O] Copy log   [?] Help + + + diff --git a/tests/visual/baseline/tui/08-extensions_80x24_mornye-dark.svg b/tests/visual/baseline/tui/08-extensions_80x24_mornye-dark.svg new file mode 100644 index 0000000..6096657 --- /dev/null +++ b/tests/visual/baseline/tui/08-extensions_80x24_mornye-dark.svg @@ -0,0 +1,160 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + extensions 80x24 + + + + + + + + + + +MORNYE +                                     v0.0.0 +╭─ * Modes ──────────╮╭─ Extensions ─────────────────────────────────────────╮ +│ v Download│││ +│ ? Search││Registry links. Providers install from these; wit│ +│ # Tracks│││ +│ Q Queue││╭───────────────────────────────────────────────╮│ +│ = Live│││ Registry  Source  State ││ +│ h History││╰───────────────────────────────────────────────╯│ +│ @ Session││╭──────────╮╭──────────────╮╭─────────────────╮│ +│ - Library│││https:││ Add ││ Remove selected ││ +│█ + Extensions││╰──────────╯╰──────────────╯╰─────────────────╯│ +│ ! Health│││ +│ - Signed││▁│ +│ $ Command││No registry links configured.│ +││││ +│││Extension settings│ +││││ +│││╭───────────────────────────────────────────────╮│ +││││ +╰────────────────────╯╰──────────────────────────────────── [ registries ]  ─╯ +▌i  Pick a URL and press Ctrl+R. +[Ctrl+R] Run   [Ctrl+C] Stop   [/] Search   [Ctrl+Y] Copy CLI + + + diff --git a/tests/visual/baseline/tui/08-extensions_80x24_mornye-light.svg b/tests/visual/baseline/tui/08-extensions_80x24_mornye-light.svg new file mode 100644 index 0000000..f53475e --- /dev/null +++ b/tests/visual/baseline/tui/08-extensions_80x24_mornye-light.svg @@ -0,0 +1,160 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + extensions 80x24 + + + + + + + + + + +MORNYE +                                     v0.0.0 +╭─ * Modes ──────────╮╭─ Extensions ─────────────────────────────────────────╮ +│ v Download│││ +│ ? Search││Registry links. Providers install from these; wit│ +│ # Tracks│││ +│ Q Queue││╭───────────────────────────────────────────────╮│ +│ = Live│││ Registry  Source  State ││ +│ h History││╰───────────────────────────────────────────────╯│ +│ @ Session││╭──────────╮╭──────────────╮╭─────────────────╮│ +│ - Library│││https:││ Add ││ Remove selected ││ +│█ + Extensions││╰──────────╯╰──────────────╯╰─────────────────╯│ +│ ! Health│││ +│ - Signed││▁│ +│ $ Command││No registry links configured.│ +││││ +│││Extension settings│ +││││ +│││╭───────────────────────────────────────────────╮│ +││││ +╰────────────────────╯╰──────────────────────────────────── [ registries ]  ─╯ +▌i  Pick a URL and press Ctrl+R. +[Ctrl+R] Run   [Ctrl+C] Stop   [/] Search   [Ctrl+Y] Copy CLI + + + diff --git a/tests/visual/baseline/tui/09-health_120x40_mornye-dark.svg b/tests/visual/baseline/tui/09-health_120x40_mornye-dark.svg new file mode 100644 index 0000000..ef126eb --- /dev/null +++ b/tests/visual/baseline/tui/09-health_120x40_mornye-dark.svg @@ -0,0 +1,223 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + health 120x40 + + + + + + + + + + +MORNYE +                                                         v0.0.0 +╭─ * Modes ──────────────╮╭─ Health ─────────────────────────────────────────────────────────────────────────────────╮ +││││ +│││Lyrics providers, probed directly. One that is down is why its lyrics came back empty.│ +│ v Download│││ +│││╭──────────────╮│ +││││ Check now ││ +│ ? Search││╰──────────────╯│ +││││ +│││Not checked yet.│ +│ # Tracks│││ +│││╭────────────────────────────────────────────────────────────────────────────────────╮│ +││││ Provider  Status  Latency  Detail ││ +│ Q Queue││╰────────────────────────────────────────────────────────────────────────────────────╯│ +││││ +││││ +│ = Live│││ +││││ +││││ +│ h History│││ +││││ +││││ +│ @ Session│││ +││││ +││││ +│ - Library│││ +││││ +││││ +│ + Extensions│││ +│▂│││ +│█│││ +│█ ! Health│││ +│█│││ +││││ +││││ +╰────────────────────────╯╰───────────────────────────────────────────────────────────────────────── [ providers ]  ─╯ +▌i  Pick a URL and press Ctrl+R. +[Ctrl+R] Run   [Ctrl+C] Stop   [/] Search   [Ctrl+Y] Copy CLI   [Ctrl+L] Log   [Ctrl+O] Copy log   [?] Help + + + diff --git a/tests/visual/baseline/tui/09-health_120x40_mornye-light.svg b/tests/visual/baseline/tui/09-health_120x40_mornye-light.svg new file mode 100644 index 0000000..a89d0e6 --- /dev/null +++ b/tests/visual/baseline/tui/09-health_120x40_mornye-light.svg @@ -0,0 +1,223 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + health 120x40 + + + + + + + + + + +MORNYE +                                                         v0.0.0 +╭─ * Modes ──────────────╮╭─ Health ─────────────────────────────────────────────────────────────────────────────────╮ +││││ +│││Lyrics providers, probed directly. One that is down is why its lyrics came back empty.│ +│ v Download│││ +│││╭──────────────╮│ +││││ Check now ││ +│ ? Search││╰──────────────╯│ +││││ +│││Not checked yet.│ +│ # Tracks│││ +│││╭────────────────────────────────────────────────────────────────────────────────────╮│ +││││ Provider  Status  Latency  Detail ││ +│ Q Queue││╰────────────────────────────────────────────────────────────────────────────────────╯│ +││││ +││││ +│ = Live│││ +││││ +││││ +│ h History│││ +││││ +││││ +│ @ Session│││ +││││ +││││ +│ - Library│││ +││││ +││││ +│ + Extensions│││ +│▂│││ +│█│││ +│█ ! Health│││ +│█│││ +││││ +││││ +╰────────────────────────╯╰───────────────────────────────────────────────────────────────────────── [ providers ]  ─╯ +▌i  Pick a URL and press Ctrl+R. +[Ctrl+R] Run   [Ctrl+C] Stop   [/] Search   [Ctrl+Y] Copy CLI   [Ctrl+L] Log   [Ctrl+O] Copy log   [?] Help + + + diff --git a/tests/visual/baseline/tui/09-health_80x24_mornye-dark.svg b/tests/visual/baseline/tui/09-health_80x24_mornye-dark.svg new file mode 100644 index 0000000..b47a744 --- /dev/null +++ b/tests/visual/baseline/tui/09-health_80x24_mornye-dark.svg @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + health 80x24 + + + + + + + + + + +MORNYE +                                     v0.0.0 +╭─ * Modes ──────────╮╭─ Health ─────────────────────────────────────────────╮ +│ v Download│││ +│ ? Search││Lyrics providers, probed directly. One that is dow│ +│ # Tracks│││ +│ Q Queue││╭──────────────╮│ +│ = Live│││ Check now ││ +│ h History││╰──────────────╯│ +│ @ Session│││ +│ - Library││Not checked yet.│ +│ + Extensions│││ +│█ ! Health││╭────────────────────────────────────────────────╮│ +│ - Signed│││ Provider  Status  Latency  Detail ││ +│ $ Command││╰────────────────────────────────────────────────╯│ +││││ +││││ +││││ +││││ +││││ +╰────────────────────╯╰───────────────────────────────────── [ providers ]  ─╯ +▌i  Pick a URL and press Ctrl+R. +[Ctrl+R] Run   [Ctrl+C] Stop   [/] Search   [Ctrl+Y] Copy CLI + + + diff --git a/tests/visual/baseline/tui/09-health_80x24_mornye-light.svg b/tests/visual/baseline/tui/09-health_80x24_mornye-light.svg new file mode 100644 index 0000000..19545f1 --- /dev/null +++ b/tests/visual/baseline/tui/09-health_80x24_mornye-light.svg @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + health 80x24 + + + + + + + + + + +MORNYE +                                     v0.0.0 +╭─ * Modes ──────────╮╭─ Health ─────────────────────────────────────────────╮ +│ v Download│││ +│ ? Search││Lyrics providers, probed directly. One that is dow│ +│ # Tracks│││ +│ Q Queue││╭──────────────╮│ +│ = Live│││ Check now ││ +│ h History││╰──────────────╯│ +│ @ Session│││ +│ - Library││Not checked yet.│ +│ + Extensions│││ +│█ ! Health││╭────────────────────────────────────────────────╮│ +│ - Signed│││ Provider  Status  Latency  Detail ││ +│ $ Command││╰────────────────────────────────────────────────╯│ +││││ +││││ +││││ +││││ +││││ +╰────────────────────╯╰───────────────────────────────────── [ providers ]  ─╯ +▌i  Pick a URL and press Ctrl+R. +[Ctrl+R] Run   [Ctrl+C] Stop   [/] Search   [Ctrl+Y] Copy CLI + + + diff --git a/tests/visual/baseline/tui/10-signed_120x40_mornye-dark.svg b/tests/visual/baseline/tui/10-signed_120x40_mornye-dark.svg new file mode 100644 index 0000000..b9f3dd0 --- /dev/null +++ b/tests/visual/baseline/tui/10-signed_120x40_mornye-dark.svg @@ -0,0 +1,224 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + signed 120x40 + + + + + + + + + + +MORNYE +                                                         v0.0.0 +╭─ * Modes ──────────────╮╭─ Signed sessions ────────────────────────────────────────────────────────────────────────╮ +││││ +│││Verified sessions extensions use for their gateway. An expired one is renewed with a n│ +│▃│││ +│ ? Search││╭──────────────╮╭────────────────╮╭─────────────────╮│ +││││ Refresh ││ Clear selected ││ Remove orphaned ││ +│││╰──────────────╯╰────────────────╯╰─────────────────╯│ +│ # Tracks│││ +││││ +│││Could not read the sessions — The optional utilities extension is not installed; 'morn│ +│ Q Queue│││ +│││╭────────────────────────────────────────────────────────────────────────────────────╮│ +││││ Session  State  Expires  Detail ││ +│ = Live││╰────────────────────────────────────────────────────────────────────────────────────╯│ +││││ +││││ +│ h History│││ +││││ +││││ +│ @ Session│││ +││││ +││││ +│ - Library│││ +││││ +││││ +│ + Extensions│││ +││││ +││││ +│ ! Health│││ +││││ +│█▅│││ +│█ - Signed│││ +│█│││ +││││ +╰────────────────────────╯╰───────────────────────────────────────────────────────────────── [ --signed-sessions ]  ─╯ +▌i  Pick a URL and press Ctrl+R. +[Ctrl+R] Run   [Ctrl+C] Stop   [/] Search   [Ctrl+Y] Copy CLI   [Ctrl+L] Log   [Ctrl+O] Copy log   [?] Help + + + diff --git a/tests/visual/baseline/tui/10-signed_120x40_mornye-light.svg b/tests/visual/baseline/tui/10-signed_120x40_mornye-light.svg new file mode 100644 index 0000000..a73da74 --- /dev/null +++ b/tests/visual/baseline/tui/10-signed_120x40_mornye-light.svg @@ -0,0 +1,224 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + signed 120x40 + + + + + + + + + + +MORNYE +                                                         v0.0.0 +╭─ * Modes ──────────────╮╭─ Signed sessions ────────────────────────────────────────────────────────────────────────╮ +││││ +│││Verified sessions extensions use for their gateway. An expired one is renewed with a n│ +│▃│││ +│ ? Search││╭──────────────╮╭────────────────╮╭─────────────────╮│ +││││ Refresh ││ Clear selected ││ Remove orphaned ││ +│││╰──────────────╯╰────────────────╯╰─────────────────╯│ +│ # Tracks│││ +││││ +│││Could not read the sessions — The optional utilities extension is not installed; 'morn│ +│ Q Queue│││ +│││╭────────────────────────────────────────────────────────────────────────────────────╮│ +││││ Session  State  Expires  Detail ││ +│ = Live││╰────────────────────────────────────────────────────────────────────────────────────╯│ +││││ +││││ +│ h History│││ +││││ +││││ +│ @ Session│││ +││││ +││││ +│ - Library│││ +││││ +││││ +│ + Extensions│││ +││││ +││││ +│ ! Health│││ +││││ +│█▅│││ +│█ - Signed│││ +│█│││ +││││ +╰────────────────────────╯╰───────────────────────────────────────────────────────────────── [ --signed-sessions ]  ─╯ +▌i  Pick a URL and press Ctrl+R. +[Ctrl+R] Run   [Ctrl+C] Stop   [/] Search   [Ctrl+Y] Copy CLI   [Ctrl+L] Log   [Ctrl+O] Copy log   [?] Help + + + diff --git a/tests/visual/baseline/tui/10-signed_80x24_mornye-dark.svg b/tests/visual/baseline/tui/10-signed_80x24_mornye-dark.svg new file mode 100644 index 0000000..c33572a --- /dev/null +++ b/tests/visual/baseline/tui/10-signed_80x24_mornye-dark.svg @@ -0,0 +1,157 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + signed 80x24 + + + + + + + + + + +MORNYE +                                     v0.0.0 +╭─ * Modes ──────────╮╭─ Signed sessions ────────────────────────────────────╮ +│ v Download│││ +│ ? Search││Verified sessions extensions use for their gateway│ +│ # Tracks│││ +│ Q Queue││╭──────────────╮╭────────────────╮╭─────────────│ +│ = Live│││ Refresh ││ Clear selected ││ Remove orpha│ +│ h History││╰──────────────╯╰────────────────╯╰─────────────│ +│ @ Session│││ +│ - Library│││ +│ + Extensions││Could not read the sessions — The optional utiliti│ +│ ! Health│││ +│█ - Signed││╭────────────────────────────────────────────────╮│ +│ $ Command│││ Session  State  Expires  Detail ││ +│││╰────────────────────────────────────────────────╯│ +││││ +││││ +││││ +││││ +╰────────────────────╯╰───────────────────────────── [ --signed-sessions ]  ─╯ +▌i  Pick a URL and press Ctrl+R. +[Ctrl+R] Run   [Ctrl+C] Stop   [/] Search   [Ctrl+Y] Copy CLI + + + diff --git a/tests/visual/baseline/tui/10-signed_80x24_mornye-light.svg b/tests/visual/baseline/tui/10-signed_80x24_mornye-light.svg new file mode 100644 index 0000000..16ff7e0 --- /dev/null +++ b/tests/visual/baseline/tui/10-signed_80x24_mornye-light.svg @@ -0,0 +1,157 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + signed 80x24 + + + + + + + + + + +MORNYE +                                     v0.0.0 +╭─ * Modes ──────────╮╭─ Signed sessions ────────────────────────────────────╮ +│ v Download│││ +│ ? Search││Verified sessions extensions use for their gateway│ +│ # Tracks│││ +│ Q Queue││╭──────────────╮╭────────────────╮╭─────────────│ +│ = Live│││ Refresh ││ Clear selected ││ Remove orpha│ +│ h History││╰──────────────╯╰────────────────╯╰─────────────│ +│ @ Session│││ +│ - Library│││ +│ + Extensions││Could not read the sessions — The optional utiliti│ +│ ! Health│││ +│█ - Signed││╭────────────────────────────────────────────────╮│ +│ $ Command│││ Session  State  Expires  Detail ││ +│││╰────────────────────────────────────────────────╯│ +││││ +││││ +││││ +││││ +╰────────────────────╯╰───────────────────────────── [ --signed-sessions ]  ─╯ +▌i  Pick a URL and press Ctrl+R. +[Ctrl+R] Run   [Ctrl+C] Stop   [/] Search   [Ctrl+Y] Copy CLI + + + diff --git a/tests/visual/baseline/tui/11-command_120x40_mornye-dark.svg b/tests/visual/baseline/tui/11-command_120x40_mornye-dark.svg new file mode 100644 index 0000000..8ff0002 --- /dev/null +++ b/tests/visual/baseline/tui/11-command_120x40_mornye-dark.svg @@ -0,0 +1,220 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + command 120x40 + + + + + + + + + + +MORNYE +                                                         v0.0.0 +╭─ * Modes ──────────────╮╭─ Equivalent command ─────────────────────────────────────────────────────────────────────╮ +││││ +│││The same run, as a command you can script or schedule:│ +││││ +│ # Tracks││    mornye https://open.spotify.com/album/example /Music/Mornye \│ +│││    -s tidal \│ +│▆││    --lyrics-providers apple binilyrics lrclib \│ +│ Q Queue││    --enrich-providers deezer apple qobuz tidal \│ +│││    --timeout 180 \│ +│││    --include-featuring│ +│ = Live│││ +│││Ctrl+Y copies it.│ +││││ +│ h History│││ +││╰──────────────────────────────────────────────────────────────────── [ Ctrl+Y to copy ]  ─╯ +││ +│ @ Session│ +││ +││ +│ - Library│ +││ +││ +│ + Extensions│ +││ +││ +│ ! Health│ +││ +││ +│ - Signed│ +││ +│█│ +│█ $ Command│ +│█│ +││ +╰────────────────────────╯ +▌i  Pick a URL and press Ctrl+R. +[Ctrl+R] Run   [Ctrl+C] Stop   [/] Search   [Ctrl+Y] Copy CLI   [Ctrl+L] Log   [Ctrl+O] Copy log   [?] Help + + + diff --git a/tests/visual/baseline/tui/11-command_120x40_mornye-light.svg b/tests/visual/baseline/tui/11-command_120x40_mornye-light.svg new file mode 100644 index 0000000..c2fbd05 --- /dev/null +++ b/tests/visual/baseline/tui/11-command_120x40_mornye-light.svg @@ -0,0 +1,220 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + command 120x40 + + + + + + + + + + +MORNYE +                                                         v0.0.0 +╭─ * Modes ──────────────╮╭─ Equivalent command ─────────────────────────────────────────────────────────────────────╮ +││││ +│││The same run, as a command you can script or schedule:│ +││││ +│ # Tracks││    mornye https://open.spotify.com/album/example /Music/Mornye \│ +│││    -s tidal \│ +│▆││    --lyrics-providers apple binilyrics lrclib \│ +│ Q Queue││    --enrich-providers deezer apple qobuz tidal \│ +│││    --timeout 180 \│ +│││    --include-featuring│ +│ = Live│││ +│││Ctrl+Y copies it.│ +││││ +│ h History│││ +││╰──────────────────────────────────────────────────────────────────── [ Ctrl+Y to copy ]  ─╯ +││ +│ @ Session│ +││ +││ +│ - Library│ +││ +││ +│ + Extensions│ +││ +││ +│ ! Health│ +││ +││ +│ - Signed│ +││ +│█│ +│█ $ Command│ +│█│ +││ +╰────────────────────────╯ +▌i  Pick a URL and press Ctrl+R. +[Ctrl+R] Run   [Ctrl+C] Stop   [/] Search   [Ctrl+Y] Copy CLI   [Ctrl+L] Log   [Ctrl+O] Copy log   [?] Help + + + diff --git a/tests/visual/baseline/tui/11-command_80x24_mornye-dark.svg b/tests/visual/baseline/tui/11-command_80x24_mornye-dark.svg new file mode 100644 index 0000000..05d90e5 --- /dev/null +++ b/tests/visual/baseline/tui/11-command_80x24_mornye-dark.svg @@ -0,0 +1,154 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + command 80x24 + + + + + + + + + + +MORNYE +                                     v0.0.0 +╭─ * Modes ──────────╮╭─ Equivalent command ─────────────────────────────────╮ +│ v Download│││ +│ ? Search││The same run, as a command you can script or│ +│ # Tracks││schedule:│ +│ Q Queue│││ +│ = Live││    mornye https://open.spotify.com/album/example│ +│ h History││/Music/Mornye \│ +│ @ Session││    -s tidal \│ +│ - Library││    --lyrics-providers apple binilyrics lrclib \│ +│ + Extensions││    --enrich-providers deezer apple qobuz tidal \│ +│ ! Health││    --timeout 180 \│ +│ - Signed││    --include-featuring│ +│█ $ Command│││ +│││Ctrl+Y copies it.│ +││││ +││││ +││╰──────────────────────────────── [ Ctrl+Y to copy ]  ─╯ +││ +╰────────────────────╯ +▌i  Pick a URL and press Ctrl+R. +[Ctrl+R] Run   [Ctrl+C] Stop   [/] Search   [Ctrl+Y] Copy CLI + + + diff --git a/tests/visual/baseline/tui/11-command_80x24_mornye-light.svg b/tests/visual/baseline/tui/11-command_80x24_mornye-light.svg new file mode 100644 index 0000000..f9c8e16 --- /dev/null +++ b/tests/visual/baseline/tui/11-command_80x24_mornye-light.svg @@ -0,0 +1,154 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + command 80x24 + + + + + + + + + + +MORNYE +                                     v0.0.0 +╭─ * Modes ──────────╮╭─ Equivalent command ─────────────────────────────────╮ +│ v Download│││ +│ ? Search││The same run, as a command you can script or│ +│ # Tracks││schedule:│ +│ Q Queue│││ +│ = Live││    mornye https://open.spotify.com/album/example│ +│ h History││/Music/Mornye \│ +│ @ Session││    -s tidal \│ +│ - Library││    --lyrics-providers apple binilyrics lrclib \│ +│ + Extensions││    --enrich-providers deezer apple qobuz tidal \│ +│ ! Health││    --timeout 180 \│ +│ - Signed││    --include-featuring│ +│█ $ Command│││ +│││Ctrl+Y copies it.│ +││││ +││││ +││╰──────────────────────────────── [ Ctrl+Y to copy ]  ─╯ +││ +╰────────────────────╯ +▌i  Pick a URL and press Ctrl+R. +[Ctrl+R] Run   [Ctrl+C] Stop   [/] Search   [Ctrl+Y] Copy CLI + + + diff --git a/tests/visual/capture_gui.py b/tests/visual/capture_gui.py new file mode 100644 index 0000000..4a39e74 --- /dev/null +++ b/tests/visual/capture_gui.py @@ -0,0 +1,210 @@ +"""Screenshot every GUI view: the visual baseline for the redesign. + +Fase 0, voce 1 of ``docs/redesign-plan.md``. Starts ``mornye --web`` against +an empty, throw-away data folder (nothing from this machine reaches a +picture), opens it in Chrome through Playwright, and saves the ten views in +the dark and the light theme at three widths: a desktop window, 768 and 375. + +Needs ``pip install playwright`` and Google Chrome (``channel="chrome"``, so +Playwright downloads no browser of its own). Not part of the test suite: +the pictures are compared by eye, or by name with ``--compare``, which only +reports which files differ — pixels move with fonts and anti-aliasing. + + python tests/visual/capture_gui.py # → tests/visual/out/gui + python tests/visual/capture_gui.py --views home settings --widths 375 +""" + +from __future__ import annotations + +import argparse +import contextlib +import hashlib +import os +import socket +import subprocess +import sys +import tempfile +import time +from pathlib import Path + +HERE = Path(__file__).resolve().parent +ROOT = HERE.parents[1] + +VIEWS: tuple[str, ...] = ( + "home", + "explore", + "player", + "queue", + "history", + "local", + "following", + "stats", + "logs", + "settings", +) +#: name → (width, height). "desktop" is the default pywebview window. +WIDTHS: dict[str, tuple[int, int]] = { + "desktop": (1280, 800), + "768": (768, 1024), + "375": (375, 812), +} +THEMES: tuple[str, ...] = ("dark", "light") + + +def _free_port() -> int: + with socket.socket() as sock: + sock.bind(("127.0.0.1", 0)) + return int(sock.getsockname()[1]) + + +def _wait_for(port: int, proc: subprocess.Popen, timeout: float = 60.0) -> None: + deadline = time.monotonic() + timeout + while time.monotonic() < deadline: + if proc.poll() is not None: + raise SystemExit(f"mornye --web exited early ({proc.returncode})") + with ( + contextlib.suppress(OSError), + socket.create_connection(("127.0.0.1", port), timeout=1), + ): + return + time.sleep(0.3) + raise SystemExit("mornye --web did not start in time") + + +@contextlib.contextmanager +def _server(home: Path): + port = _free_port() + env = { + **os.environ, + "HOME": str(home), + "USERPROFILE": str(home), + "MORNYE_DATA_DIR": str(home / ".mornye"), + "MORNYE_CACHE_DIR": str(home / ".mornye" / ".cache"), + "MORNYE_DOWNLOAD_DIR": "/Music/Mornye", + "MORNYE_EXT_AUTO_INSTALL": "0", + } + proc = subprocess.Popen( + [sys.executable, "-m", "mornye", "--web", "--port", str(port)], + cwd=ROOT, + env=env, + stdout=subprocess.DEVNULL, + stderr=subprocess.DEVNULL, + ) + try: + _wait_for(port, proc) + yield f"http://127.0.0.1:{port}/" + finally: + proc.terminate() + with contextlib.suppress(subprocess.TimeoutExpired): + proc.wait(timeout=10) + + +def _capture(url: str, out: Path, views, widths, themes) -> list[Path]: + from playwright.sync_api import sync_playwright + + written: list[Path] = [] + with sync_playwright() as pw: + browser = pw.chromium.launch(channel="chrome", headless=True) + try: + for width_name in widths: + width, height = WIDTHS[width_name] + for theme in themes: + page = browser.new_page( + viewport={"width": width, "height": height}, + color_scheme=theme, # type: ignore[arg-type] + reduced_motion="reduce", + ) + page.add_init_script( + f"try {{ localStorage.setItem('mornye-theme-mode', '{theme}'); }}" + " catch (e) {}" + ) + page.goto(url, wait_until="networkidle") + page.wait_for_function("typeof switchView === 'function'") + # The URL box types its example links out one character + # at a time; freeze it, or every Home picture differs. + page.evaluate( + "() => { clearTimeout(phTimeout); runTypewriter = () => {};" + " $('urlInput').placeholder = 'open.spotify.com/track/…'; }" + ) + for view in views: + page.evaluate( + "([v, t]) => { switchView(v); applyTheme(t); }", + [view, theme], + ) + page.wait_for_timeout(600) + path = out / f"{view}_{width_name}_{theme}.png" + page.screenshot(path=str(path), full_page=False) + written.append(path) + page.close() + finally: + browser.close() + return written + + +#: Per-channel difference below which a pixel counts as unchanged. Two runs +#: of the same page differ by a pixel or two of anti-aliasing (measured: at +#: most 16 of 255); a real change of colour or layout is far above it. +_NOISE = 16 +#: How many pixels may exceed it before a picture counts as changed. +_NOISY_PIXELS = 20 + + +def _differs(a: Path, b: Path) -> bool: + if a.read_bytes() == b.read_bytes(): + return False + try: + from PIL import Image, ImageChops + except ImportError: + return ( + hashlib.sha256(a.read_bytes()).digest() + != hashlib.sha256(b.read_bytes()).digest() + ) + with Image.open(a) as left, Image.open(b) as right: + if left.size != right.size: + return True + diff = ImageChops.difference(left.convert("RGB"), right.convert("RGB")) + red, green, blue = diff.split() + # Per pixel, the largest of its three channel differences. + worst = ImageChops.lighter(ImageChops.lighter(red, green), blue) + # A stray anti-aliased pixel or two is noise; a change moves many. + return sum(worst.histogram()[_NOISE + 1 :]) > _NOISY_PIXELS + + +def _compare(out: Path, baseline: Path) -> int: + changed = [] + for path in sorted(out.glob("*.png")): + ref = baseline / path.name + if not ref.exists(): + changed.append(f"new {path.name}") + elif _differs(ref, path): + changed.append(f"changed {path.name}") + for ref in sorted(baseline.glob("*.png")): + if not (out / ref.name).exists(): + changed.append(f"missing {ref.name}") + print("\n".join(changed) or "identical to the baseline") + return 1 if changed else 0 + + +def main(argv: list[str] | None = None) -> int: + parser = argparse.ArgumentParser(description=(__doc__ or "").split("\n\n")[0]) + parser.add_argument("--out", type=Path, default=HERE / "out" / "gui") + parser.add_argument("--views", nargs="+", choices=VIEWS, default=list(VIEWS)) + parser.add_argument( + "--widths", nargs="+", choices=list(WIDTHS), default=list(WIDTHS) + ) + parser.add_argument("--themes", nargs="+", choices=THEMES, default=list(THEMES)) + parser.add_argument("--compare", type=Path, help="baseline folder to diff against") + args = parser.parse_args(argv) + + args.out.mkdir(parents=True, exist_ok=True) + for old in args.out.glob("*.png"): + old.unlink() + with tempfile.TemporaryDirectory(prefix="mornye-visual-") as tmp: + with _server(Path(tmp)) as url: + written = _capture(url, args.out, args.views, args.widths, args.themes) + print(f"{len(written)} screenshots in {args.out}") + return _compare(args.out, args.compare) if args.compare else 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/tests/visual/capture_tui.py b/tests/visual/capture_tui.py new file mode 100644 index 0000000..2e0a38e --- /dev/null +++ b/tests/visual/capture_tui.py @@ -0,0 +1,123 @@ +"""Draw every TUI panel to SVG: the visual baseline for the redesign. + +Fase 0, voce 2 of ``docs/redesign-plan.md``. Each of the twelve panels is +opened through the sidebar and exported with ``App.export_screenshot`` at +80×24 (the compact layout) and 120×40, in the default theme and in +``mornye-light``. The result is a folder of SVGs to compare before and after +a change — by eye, or with ``--compare`` against a saved baseline. + +The app runs against an empty, throw-away home so that nothing from this +machine — history, installed extensions, saved sessions, paths — ends up in +a picture that may be committed. + + python tests/visual/capture_tui.py # → tests/visual/out/tui + python tests/visual/capture_tui.py --out DIR + python tests/visual/capture_tui.py --compare tests/visual/baseline/tui +""" + +from __future__ import annotations + +import argparse +import asyncio +import os +import re +import sys +import tempfile +from pathlib import Path + +HERE = Path(__file__).resolve().parent +ROOT = HERE.parents[1] + +SIZES: tuple[tuple[int, int], ...] = ((80, 24), (120, 40)) +THEMES: tuple[str, ...] = ("mornye-dark", "mornye-light") + +#: Settling cycles after switching panel. The slowest panels in the suite +#: (extensions, tracklist) need 15; a picture taken earlier is half drawn. +_SETTLE = 15 + + +def _isolate(home: Path) -> None: + """Point every path Mornye reads at an empty home, before it is imported.""" + os.environ["HOME"] = str(home) + os.environ["USERPROFILE"] = str(home) + os.environ["MORNYE_DATA_DIR"] = str(home / ".mornye") + os.environ["MORNYE_CACHE_DIR"] = str(home / ".mornye" / ".cache") + # Shown in the Configuration panel; fixed so it reads the same anywhere. + os.environ["MORNYE_DOWNLOAD_DIR"] = "/Music/Mornye" + os.environ.pop("NO_COLOR", None) + + +def _normalise(svg: str, home: Path) -> str: + """Strip what changes between runs without the look changing.""" + svg = svg.replace(str(home), "~") + # The banner shows the release; a version bump is not a change of look. + svg = re.sub(r"v\d+\.\d+\.\d+", "v0.0.0", svg) + # Textual names the SVG's classes after a hash of the content. + return re.sub(r"terminal-\d+", "terminal", svg) + + +async def _capture(out: Path, home: Path) -> list[Path]: + from mornye.tui.app import MODES, MornyeTui + from mornye.tui.config_state import ConfigState + + written: list[Path] = [] + for width, height in SIZES: + for theme in THEMES: + state = ConfigState( + url="https://open.spotify.com/album/example", + output_dir="/Music/Mornye", + services=["tidal"], + ) + app = MornyeTui(state) + async with app.run_test(size=(width, height)) as pilot: + app.theme = theme + for _ in range(_SETTLE): + await pilot.pause() + sidebar = app.query_one("#sidebar") + for index, (key, _label) in enumerate(MODES): + sidebar.index = index # type: ignore[attr-defined] + for _ in range(_SETTLE): + await pilot.pause() + name = f"{index:02d}-{key}_{width}x{height}_{theme}.svg" + path = out / name + svg = app.export_screenshot(title=f"{key} {width}x{height}") + path.write_text(_normalise(svg, home), encoding="utf-8") + written.append(path) + return written + + +def _compare(out: Path, baseline: Path) -> int: + changed = [] + for path in sorted(out.glob("*.svg")): + ref = baseline / path.name + if not ref.exists(): + changed.append(f"new {path.name}") + elif ref.read_text(encoding="utf-8") != path.read_text(encoding="utf-8"): + changed.append(f"changed {path.name}") + for ref in sorted(baseline.glob("*.svg")): + if not (out / ref.name).exists(): + changed.append(f"missing {ref.name}") + print("\n".join(changed) or "identical to the baseline") + return 1 if changed else 0 + + +def main(argv: list[str] | None = None) -> int: + parser = argparse.ArgumentParser(description=(__doc__ or "").split("\n\n")[0]) + parser.add_argument("--out", type=Path, default=HERE / "out" / "tui") + parser.add_argument("--compare", type=Path, help="baseline folder to diff against") + args = parser.parse_args(argv) + + args.out.mkdir(parents=True, exist_ok=True) + for old in args.out.glob("*.svg"): + old.unlink() + with tempfile.TemporaryDirectory(prefix="mornye-visual-") as tmp: + home = Path(tmp) + _isolate(home) + sys.path.insert(0, str(ROOT)) + written = asyncio.run(_capture(args.out, home)) + print(f"{len(written)} snapshots in {args.out}") + return _compare(args.out, args.compare) if args.compare else 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/uv.lock b/uv.lock index 7dfc85e..24d90cd 100644 --- a/uv.lock +++ b/uv.lock @@ -1465,7 +1465,7 @@ wheels = [ [[package]] name = "mornye" -version = "2.0.5" +version = "2.0.6" source = { editable = "." } dependencies = [ { name = "aiofiles" },