Ants Projects Hub
← Album Builder

Changelog

Album Builder

Every release, newest first — 10 in total.

v0.9.3

0.9.3 — The window fits smaller screens

Theme: The window fits smaller screens.

Fixed

  • The window now fits on smaller screens. (MUSI-0381) On a 1280-pixel-wide screen the window used to spill off the right edge, hiding the menu and the tabs. It now fits, and a window saved on a bigger screen opens inside the current one.

v0.9.2

0.9.2 — The Windows download works again

Theme: The Windows download works again.

Fixed

  • The Windows download no longer closes itself right after starting. (MUSI-0379) On Windows the app crashed the first time it saved its settings, so it vanished a moment after opening. It now saves normally. Linux was not affected.

v0.9.1

0.9.1 — Better translations, and a smoother shutdown

Theme: Better translations, and a smoother shutdown.

Fixed

  • Closing the app no longer waits on your desktop's media controls. (MUSI-0367) The app now disconnects from the desktop's play/pause controls before it stops the music, so closing it cannot get stuck there.

  • The "WhisperX not installed" message now appears in your language. (MUSI-0370) It was the one message still shown in English. The install help still appears once, the first time lyrics syncing needs it.

  • Better wording in every translated language. A second proofread corrected words that read oddly or wrongly: the exported song links no longer share a name with keyboard shortcuts, Afrikaans says "pouseer" for pause, and Arabic calls a composer a composer. In Arabic and Hebrew, the lyrics status line now reads right to left. The translations are still AI drafts awaiting native speakers.

v0.9.0

0.9.0 — More languages including Arabic and Hebrew, a Player-tab library, and choosing your music folder

Theme: More languages including Arabic and Hebrew, a Player-tab library, and choosing your music folder.

Added

  • Choose your music folder from inside the app. (part of MUSI-0357) Use File > Choose Music Folder..., and your library reloads straight away. When no music is found, the library shows a friendly message with a button to pick the right folder, so a fresh install no longer opens to an empty window. No more editing settings files by hand.

  • The app now speaks eight languages, including Arabic and Hebrew. (MUSI-0368) English, Afrikaans, Arabic, Hebrew, Spanish, French, German and Portuguese. It follows your computer's language, or choose one under View > Language and reopen the app. Arabic and Hebrew mirror the whole window right to left; the play controls stay the usual way round. Approval reports come out in the chosen language too. The translations are AI drafts, not yet checked by native speakers.

  • The Player tab now has its own music library. (part of MUSI-0356) Search and browse your songs right in the Player, without switching to the Album Builder tab. Double-click a song, or press Enter, to play from there. Right-click for play next, add to queue and playlists. Both tabs show the same songs and update together. The song details now read Title, Artist, Album, like most music players.

  • You can now bring back an album you deleted. (part of MUSI-0357) Choose File > Restore Deleted Album, pick it from the list, and it returns exactly as it was, with its tracks, order and reports.

Fixed

  • No more dark boxes behind text. Song details, headings, the lyrics status line and the time readouts now sit cleanly on their panel instead of each drawing a dark strip.

v0.8.1

0.8.1 — The Linux download is back, plus display fixes

Theme: The Linux download is back, plus display fixes.

Fixed

  • The Linux download is back. The 0.8.0 Linux AppImage failed to build because a part it downloads had been replaced upstream, so 0.8.0 shipped with only the Windows download. This release has both.

  • Song titles now show in the library. (MUSI-0364) The Title column shrank to nothing unless the window was very wide. It now always has room, and the Composer column gives way instead.

  • Album-order rows no longer show their text twice. (MUSI-0365) Each track's number and name appeared twice, overlapping. Now each row reads once.

  • Small buttons now show their symbols. (MUSI-0366) The play button beside each album-order track, the - and + buttons for the track count, and the x that closes a notification were blank or cut to a thin line. They now show properly.

v0.8.0

0.8.0 — Many more music file types now work properly

Theme: Many more music file types now work properly.

Added

  • Five more kinds of music file. The library now picks up AAC, AIFF (.aiff and .aif), Ogg audio (.oga) and Windows Media (.wma) files, as well as the types it already read. (MUSI-0358)
  • A clearer drag when reordering an album. The track you are dragging fades to half strength, and a line in your theme's colour shows exactly where it will land. (MUSI-0361)

Fixed

  • Song details now show for every file type, not just MP3. FLAC, Ogg, Opus, M4A, WMA, WAV and AIFF files used to show "Unknown artist" with no title or album, even when the file had them. They now show the real title, artist, album and composer. AAC files are the one exception: that format has no place to store song details, so they show the file name instead. (MUSI-0359)
  • Album artwork now shows for every file type. Cover pictures stored inside FLAC, Ogg, Opus, M4A, WMA, WAV and AIFF files appear in the app, the approval report and your desktop's media controls. Before, only MP3 artwork appeared. (MUSI-0359, MUSI-0362)
  • Volume levelling now works for every file type. If you use volume levelling (ReplayGain), FLAC, Ogg, Opus, M4A, WMA, WAV and AIFF tracks are now evened out too, instead of playing louder or quieter than the rest of the album. Before, only MP3 was. (MUSI-0359, MUSI-0363)
  • Songs without any tags no longer show a length of 0:00. A file with no song details at all now shows its real length, so exported playlists and sorting by length are correct. (MUSI-0360)

v0.7.0

This release shipped without written notes.

v0.6.1

v0.6.1 - first downloadable AppImage

First downloadable build. Album Builder now ships as a single-file Linux AppImage - download AlbumBuilder-0.6.1-x86_64.AppImage below, chmod +x, and run it. No Python, no pip, no install script; runs on most Linux distributions from ~2022 onward (glibc 2.35+).

Built inside a pinned Ubuntu 22.04 container and verified to launch + render on a clean system (Phase Dist-2 / Spec 23). Lyric auto-alignment (WhisperX/torch) stays an optional source-install extra, kept out of the bundle to hold the download to a few hundred MB.

The .AppImage asset attaches automatically once the release build finishes (a few minutes).

v0.5.2

v0.5.2 — lyrics-pane fill + per-row pause + click-to-preview when idle

✅ v0.5.2 — UX fix-pass: lyrics-pane fill + row-button play/pause toggle (2026-04-30)

User-reported UX gaps spotted on the v0.5.1 build:

  1. Lyrics pane was small. LyricsPanel called setFixedHeight(150) and NowPlayingPane finished its QVBoxLayout with addStretch(1) after the panel — together those two pinned the lyrics block to ~150 px and let empty space accumulate underneath. On a tall window the lyrics area looked stranded in the upper third of the right pane.
  2. Per-row ▶ button was load-only. Clicking the row's preview-play button on the currently-playing row reloaded the source from scratch (set_source + play), instead of toggling pause as the transport bar's main play/pause button does. The transport's play/pause button worked correctly — only the per-row button lacked the toggle.

Spec amendments (signed off via 2-pass cold-eyes review, 7 → 0 findings):

  • Spec 06 §user-visible-behavior — per-row preview-play button is now a load-or-toggle control with explicit four-state glyph mapping (PLAYING-on-active-source → Glyphs.PAUSE; PAUSED / STOPPED / ERROR / non-active → Glyphs.PLAY). Adds an ERROR-state same-row-click bullet (re-runs set_source + play()) and an Errors-table row for "active source's file removed between load and a same-row click."
  • Spec 06 test contract — TC-06-15 amended to flag that it supersedes the v0.4.0 signal-only assertion in test_library_pane_emits_preview_play_request; new TC-06-17 (active+playing → pause without reload), TC-06-18 (active+paused → resume), TC-06-19 (per-row glyph mapping with library-pane vs album-order-pane a11y bifurcation + dataChanged-row-range observable for the perf claim).
  • Spec 07 §Lyrics panel — panel now fills the available right-pane height below now-playing metadata, with a 150 px minimum (the pre-amendment fixed value) enforced via setMinimumHeight instead of setFixedHeight. New TC-07-16 with a measurable qtbot assertion (resize(420, 800) → lyrics_panel.height() >= 300).

Shipped:

  • ✅ Step 3 — failing tests for TC-06-17/18/19 + TC-07-16 (10 of 11 red on the implementation-side, 1 already passing as the existing cross-row case).
  • ✅ Step 4 — implementation (lifted setFixedHeight(150) → setMinimumHeight(150), dropped competing addStretch after the lyrics panel, added LibraryPane.set_active_play_state + AlbumOrderPane.set_active_play_state, routed Player.state_changed + source-swap into both panes from MainWindow, added load-or-toggle dispatch in _on_preview_play).
  • ✅ Step 5/6 — /audit + /indie-review in parallel (1 audit + 5 review findings, all L). Round 1 folded inline: pyright None-guard on album_order_pane.py:173, spec-06 PAUSED-vs-STOPPED split (PAUSED→toggle, STOPPED→fresh-load+restart), TC-06-15 marker disambiguation on the v0.4.0 test, and 2 new TC-06-19 tests for the album-order pane (set_album re-render preservation + set_active call-count observable). Round 2 convergence confirmed clean.
  • ✅ Step 8/9 — flipped status to ✅; commit pending; push pending user OK.

Convergence trace: spec amendments 1-pass cold-eyes review (7 → 0 findings), implementation, post-implementation /audit + /indie-review (6 → 0 findings). 471 → 484 passing tests (+13: 11 new TC-06-17/18/19 + TC-07-16 contracts and 2 round-1-fold-out additions). Ruff clean. Manual smoke-launch on the Tracks/ corpus completed without error.

v0.5.2 follow-up — click-to-preview-when-idle (2026-04-30)

Same release wave; user feedback after the v0.5.2 commit: the running ~/.local-installed app was still v0.4.1 (the install.sh deploy hadn't been re-run after the v0.5.2 source-tree commit), so the lyrics-pane fill + per-row pause weren't observed. Triaged that as a deployment gap (re-run install.sh). Same round, the user requested a new behaviour: clicking a track row (anywhere outside the play / toggle column) should populate the now-playing pane with that track's metadata + lyrics, but only when nothing is playing.

Spec amendments (signed off via 1-pass cold-eyes review, 10 → 0 findings):

  • Spec 06 §user-visible-behavior — new top bullet "Row body click previews-without-playing when idle" with sub-bullets for: hit-zones (library = non-_play / non-_toggle columns; album-order = label area only, drag-handle and play button excluded), keyboard-navigation parity (preview is mouse-click only — Enter routes through a separate _on_table_activated slot that handles only _play/_toggle), app-start state (STOPPED on launch, preview enabled from first click; restored last_played_track_path is not mutated by preview), Player.source() decoupling during preview, hover affordance (PointingHand cursor when STOPPED, Arrow otherwise — applies to both panes' viewports).
  • Spec 06 Errors table — new row for "late state_changed(STOPPED) arrives after preview populated the now-playing pane" (preview metadata wins; state_changed only repaints row glyphs, not the now-playing block).
  • Spec 06 test contract — TC-06-20 (STOPPED → preview), TC-06-21 (PLAYING/PAUSED/ERROR → no-op), TC-06-22 (album-order pane parity), TC-06-23 (last_played_track_path not mutated), TC-06-24 (late STOPPED clobber), TC-06-25 (keyboard nav inert), TC-06-26 (cursor mapping for all four states).

Code changes:

  • LibraryPane — new row_body_clicked signal; _on_table_clicked emits it for non-_play/_toggle columns; new _on_table_activated slot handles keyboard activation (no row-body branch); new set_row_body_cursor_for_state(stopped=) method.
  • _OrderRowWidget — new body_clicked signal; overridden mousePressEvent captures press position; overridden mouseReleaseEvent emits body_clicked only when the press → release delta is within QApplication.startDragDistance() (so genuine drags don't fire previews); label has WA_TransparentForMouseEvents so clicks fall through to the row widget.
  • AlbumOrderPane — new row_body_clicked signal; set_album connects each row's body_clicked to re-emit the row's path; new set_row_body_cursor_for_state(stopped=) mirroring the library pane.
  • MainWindow — new _on_row_body_clicked(path) handler gates on Player.state() == STOPPED, then set_track + _sync_lyrics_for_track; missing-track shows toast (mirroring _on_preview_play); _on_player_state_changed_for_rows flips both panes' cursors and is now also called once at end of __init__ so the construction-time cursor is correct without waiting for a state-change emission.

Audit/review trace: post-implementation /audit + /indie-review (12 → 0 findings, all H+M folded inline). 484 → 500 passing tests (+16: 9 initial TC-06-20..26 contracts + 7 round-1-fold-out additions covering ERROR-state no-op, PAUSED+ERROR cursor, real-mousePress plumbing, play-button-negative case, fresh-LRC lyrics population, Enter-doesn't-preview, construction-time cursor). Ruff clean. Manual smoke pending on ~/.local install (gated on the running v0.4.1 instance being closed first).


v0.5.1

v0.5.1 — outstanding-roadmap sweep

Same-day follow-up to v0.5.0 (Phase 4: Export & Approval) closing every actionable 📋 item still surviving in ROADMAP.md.

This is also the first true tagged release since v0.4.2 — v0.5.0 (Phase 4 ship) shipped as a feat: commit without a release tag, so v0.5.1 bundles Phase 4 + the sweep.

Phase 4 (v0.5.0) recap

M3U + symlink folder per album, hard-lock approval state, PDF + HTML report generation via WeasyPrint. Specs: 02 / 08 / 09 / 10 / 11. Convergence trace: 4-round pre-implementation spec sweep (39 → 17 → 3 → 0 actionable findings) + 3-round post-implementation /audit + /indie-review (40 → 3 → 0 findings) + full-codebase audit (ruff / bandit / semgrep / gitleaks all clean).

v0.5.1 sweep — 8 items

Audit tooling

  • pyrightconfig.json at repo root pointing pyright at .venv (recovers the 4 mutagen unresolved-import diagnostics on every /audit run).
  • .gitleaks.toml with extends.useDefault = true + path-regexp allowlist for .venv/, __pycache__/, gitignored data dirs (Tracks/, Albums/, .album-builder/).

Code

  • ACCENT_ROLE = Qt.ItemDataRole.UserRole + 2 extracted as module-level constant in library_pane.py — closes the v0.2.1 Tier 2 L6-M2 deferral; mirrors MISSING_ROLE / TITLE_ROLE in album_order_pane.py.
  • _write_settings(data) helper in persistence/settings.py stamps SETTINGS_SCHEMA_VERSION = 1 at every write site so a hand-rolled settings.json lacking schema_version self-heals on next save (closes the final piece of Theme B recurrence; +4 regression tests).

Docs

  • README §Status promoted from v0.2.0 to v0.5.0 prose.
  • README §System dependencies adds WeasyPrint runtime-library install commands (Pango / Cairo / GDK-PixBuf) for openSUSE + Debian/Ubuntu.
  • ROADMAP cross-cutting summary 📋 → ✅ flips for Themes A-H (2026-04-28 indie-review) and Themes B/F/I/J/K/L recurrence (2026-04-30 indie-review), each citing the per-item Tier fix that actually closed it.
  • Phase 4 prep round-1/2/3 section headers flipped 📝 → ✅ to match round-4's already-✅ marker.

Verification

  • 467 → 471 passing tests (+4 schema_version regression tests in tests/persistence/test_settings.py).
  • Ruff clean.
  • 11 skipped (audio integration gates).

Outstanding

Two genuine 📋 deferrals remain in the roadmap, both intentional:

  • DebouncedWriter._timers unbounded growth — bounded by album count today; revisit when high-cardinality keys land.
  • Stale-segment recovery TOCTOU — microsecond race window during owner shutdown; accepted as v1 design.

The §Future / deferred section lists 7 explicit non-v1 features (group-by-artist tabs, tap-along LRC editor, multi-project, album cover compositing, bulk pre-alignment scheduler, light-theme support, recursive subfolder scanning).

Phases 1–4 are feature-complete and hardened.