Skip to content

fix: adapt to every board geometry - #1

Merged
jeffredodd merged 1 commit into
mainfrom
fix/board-geometry-adaptivity
Sep 26, 2026
Merged

jeffredodd merged 1 commit into
mainfrom
fix/board-geometry-adaptivity

Conversation

@jeffredodd

Copy link
Copy Markdown
Member

What was broken

  • layout_lines() (__init__.py:107-136 before this change) always returned exactly
    three lines and never read board.rows — only board.cols was read anywhere in the
    file. On a 30x12 FiestaPanel, 9 rows stayed blank; on the 120x24 max array, 21 did.
    The fix derives the line budget from board.rows and fills anything beyond the
    featured session's three lines with other active sessions, then playback detail —
    never more than board.rows, never fewer just because there was nothing left to add.
  • For Track sessions, middle = session["artist"] was returned unmodified as line_2
    at both return points, while bottom (album) was passed through ellipsize. An
    artist name longer than the board's width produced a row wider than the board —
    trivial on a 15-col Note. Now ellipsized the same way as the album.
  • Six manifest vars (title, show, artist, album, user, player, as both
    simple vars and their sessions.* mirrors) declared max_length: 22 — wider than a
    Note (15) can fit, and dishonest in the other direction too: this is verbatim,
    unbounded Plex metadata the code never truncates, so no fixed number is an honest
    promise. Removed the bound rather than fabricate one; the page editor's fit-checker
    no longer claims a false guarantee on either axis for these fields.
  • The only note_array preview was 2-wide x 1-tall (the WIDE case only) — it never
    exercised a tall array, which is exactly why the row bug went unnoticed. Added a
    "Note Array (tall)" preview (1 wide x 4 tall = 15x12): narrower than a Flagship but
    twice a Note's height, the exact trap called out in the audit.

What was already right and is unchanged: ellipsize, wrap_two_lines and accent are
all parameterised by cols derived from self.board, with no literal-width branches —
that width-adaptivity is preserved as-is.

What changed

  • __init__.py: layout_lines() gained rows and others parameters (both default
    to the old 3-line, no-extras behavior, so every existing 3-arg call site is
    unchanged); a new _extra_lines() helper fills the row budget with
    session_summary() (one line per other active session) then playback_detail_lines()
    (player, then minutes left). fetch_data() now reads board.rows (defaulting to the
    Flagship's 6 when unbound, matching the existing board.cols default of 22) and
    passes it through, and sets PluginResult.formatted_lines — previously never set, so
    placing this plugin directly on a board slot (rather than via a template) rendered
    nothing at all.
  • manifest.json: removed the six over/under-declared max_length values, added the
    tall note_array preview, bumped version 1.0.0 → 1.0.1.
  • tests/test_plugin.py: added the shared board-geometry conformance test
    (strict_growth=True — this plugin renders a session list — and
    require_note_array_preview=True), unit tests for the row-growth behavior and the
    Track ellipsize fix, a render-equality test for the new tall preview, and coverage
    for session_summary()'s three media-type branches.

Local test output

Run via the repo's own CI recipe (FiestaBoard core on PYTHONPATH, inside the dev
container):

........................................................................ [ 90%]
........                                                                 [100%]
================================ tests coverage ================================
_______________ coverage: platform linux, python 3.14.6-final-0 ________________

Name                       Stmts   Miss  Cover   Missing
--------------------------------------------------------
__init__.py                  154      0   100%
plugins/__init__.py            0      0   100%
tests/__init__.py              0      0   100%
tests/test_demo_pages.py      48      6    88%   33-36, 62, 64
tests/test_plugin.py         374      0   100%
--------------------------------------------------------
TOTAL                        576      6    99%
Required test coverage of 70% reached. Total coverage: 98.96%
80 passed in 0.15s

Vacuity check (the new conformance test is not vacuous)

Reverted the row fix only (rows = board.rows if board else DEFAULT_ROWS →
rows = 3, i.e. the original hardcoded behavior) and re-ran just the new test:

____________ TestBoardConformance.test_renders_on_every_board_shape ____________

>       assert_board_conformance(
            make_plugin,
            manifest=MANIFEST,
            strict_growth=True,
            require_note_array_preview=True,
        )

E       AssertionError:
E       Board-geometry conformance for plex:
E         1 violation(s):
E           [DID_NOT_GROW] 15x12: 15x3 was full (3/3 rows) but 15x12 still renders 3 rows -- output is capped independently of the board
E         non-blank rows: flagship 22x6=3, note 15x3=3, panel 30x12=3, tall-narrow 15x12=3, wide-short 120x3=3, max array 120x24=3, 15x3=3, 15x12=3, 15x24=3

FAILED tests/test_plugin.py::TestBoardConformance::test_renders_on_every_board_shape
1 failed, 79 deselected in 0.09s

Restored the fix; full suite is green again (output above).

Deliberately left alone

  • line_1/line_2/line_3 still declare max_length: 22 in the manifest. The audit
    scoped the six-var fix to title/show/artist/album/user/player specifically
    and excluded these; they aren't checked by the conformance suite either (only the
    top-level max_lengths dict feeds DECLARED_LENGTH_EXCEEDED, and it only ever held
    sessions.* keys), so left as-is rather than widening scope.
  • get_formatted_display() — this plugin never overrides it, so there was nothing to
    fix on that (dead) hook.
  • The width-adaptivity already in place (ellipsize/wrap_two_lines/accent
    parameterised by cols) is untouched, per the audit's note that it's the one part of
    this plugin that was already generic.

Do not merge — opening for review only.

🤖 Generated with Claude Code

layout_lines() always returned exactly three lines and never read
board.rows -- on a 30x12 panel 9 rows stayed blank, on 120x24, 21 did.
It now derives the line budget from board.rows and uses any rows
beyond the featured session's three to list other active sessions and
then playback detail, bounded by the board like every other plugin
list should be.

Also fixes a real overflow: for Track sessions the artist ("middle")
was returned unmodified while the album ("bottom") was correctly
ellipsized, so a long artist name produced a row wider than the board
(trivial on a 15-col Note). It is now ellipsized the same way.

Manifest: removed max_length: 22 from title/show/artist/album/user/
player (both as simple vars and their sessions.* mirrors) -- these are
verbatim, unbounded Plex metadata the code never truncates, so a fixed
bound narrower than what the code can emit and wider than a Note can
fit was dishonest in both directions. Added a "Note Array (tall)"
preview (1 wide x 4 tall, 15x12 -- the narrower-than-Flagship,
taller-than-Note trap) alongside the existing wide one. Bumped the
patch version.

Added the shared board-geometry conformance test with
strict_growth=True (this plugin renders a session list) and
require_note_array_preview=True, plus unit coverage for the new
row-growth behavior and the Track ellipsize fix.

Co-Authored-By: Claude <noreply@anthropic.com>
@jeffredodd
jeffredodd merged commit 6ec001c into main Sep 26, 2026
1 check passed
@jeffredodd
jeffredodd deleted the fix/board-geometry-adaptivity branch September 26, 2026 19:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant