Skip to content

Replace section glasses with the shared difficulty tier rail (#14) - #18

Merged
cchacs merged 2 commits into
mainfrom
pullfrog/14-difficulty-tier-rail
Oct 17, 2026
Merged

cchacs merged 2 commits into
mainfrom
pullfrog/14-difficulty-tier-rail

Conversation

@pullfrog

@pullfrog pullfrog Bot commented Oct 17, 2026

Copy link
Copy Markdown

Closes #14.

Section Map's per-section indicator was a glass whose fill percentage and glass size came from Difficulty Ladder's v2 payload. That metaphor encoded difficulty as size and could only ever show a fraction. This replaces it with the semantic tier rail the peer's own guide draws: one fixed-size segment per tier, the first current + 1 lit, and an outline on the tier a section plays in full. Difficulty is now shown by how many segments are lit, never by a segment's size.

What changed

  • v3 is preferred. When the peer advertises window._ddCapabilities.sectionsSchema === 'difficulty_ladder.sections.v3', Section Map subscribes to difficulty:sections-updated-v3 and renders current_tier / top_tier / max_tier / has_chart_content directly. Feature-detected via the capability marker, never version-pinned — the payload's own schema field is deliberately ignored.
  • v2 is a bounded-transition fallback. A peer that predates v3 still gets difficulty:sections-updated; Section Map reconstructs a coarse rail from fillPercentage (topTier = maxTier = maxDifficulty, currentTier = round(fill × topTier)) and discards glassSize entirely. Delete the fallback when the peer's transition policy drops v2.
  • Payloads are normalized, not trusted. Entries without finite numeric tiers (v3) or fillPercentage (v2) are dropped; an unreadable container is ignored so the last good state survives, while a well-formed payload with nothing renderable clears the rails. current_tier: null is "unknown" (an unlit rail), not a zero tier.
  • Responsive + accessible. A block too narrow for its segments collapses to a single marker; a resize listener invalidates the per-section signatures so the width-dependent form is re-decided. The readable detail Section name · tier X of Y · full detail at Z is the same wording in the block title and aria-label, and only tier-bearing blocks are focus stops — managed in both the full-render and in-place-update paths (so no phantom focus stop when data disappears).
  • In-place updates. Rails repaint from the peer's events via a per-section signature; no full _smRender() per event.
  • Glass code deleted (_smRenderGlassFilling, .sm-glass, SM_GLASS_SIZES, glassSize handling); state renamed to _smSectionTiers.
  • Tests: tier-model/tier-suffix/rail-markup units, responsive collapse, keyboard a11y, late-provider and v2/v3 subscription, malformed-payload, narrow-section, in-place update and resize. node tests/screen.test.js → 44/44.
  • Bumps plugin.json to 1.4.0 and updates README.md / CLAUDE.md / the capabilities block.

Standalone behavior

Unchanged: section colors, labels, click-to-seek and wheel nudging all work with no peer installed. The rail is the only dependent feature, gated on the capability marker — absent peer means no rails, never an error.

Pullfrog  | View workflow run | via Pullfrog | Using big-pickle (free) | 𝕏

Section Map's per-section indicator was a glass whose fill percentage and
glass size came from Difficulty Ladder's v2 payload. That metaphor encoded
difficulty as size and could only show a fraction. Replace it with the
semantic tier rail the peer's own guide draws: one fixed-size segment per
tier, the first current+1 lit, and an outline on the tier a section plays in
full. Difficulty is now shown by how many segments are lit, never by a
segment's size.

- Prefer the render-neutral difficulty:sections-updated-v3 payload
  (current_tier / top_tier / max_tier / has_chart_content), feature-detected
  via window._ddCapabilities.sectionsSchema ===
  'difficulty_ladder.sections.v3'. The payload's own schema field is ignored;
  the capability marker is the contract.
- Keep the frozen v2 event as a bounded-transition fallback: reconstruct a
  coarse rail from fillPercentage (topTier = maxTier = maxDifficulty,
  currentTier = round(fill x topTier)) and discard glassSize entirely. The
  fallback is deleted once the peer's transition policy drops v2.
- Normalize both payload shapes before rendering. Entries without finite
  numeric tiers (v3) or fillPercentage (v2) are dropped; a container that
  isn't readable is ignored so the last good state survives, while a
  well-formed payload with nothing renderable clears the rails. current_tier
  null is 'unknown' (an unlit rail), not a zero tier.
- Collapse a block too narrow for its segments to a single marker; a resize
  listener invalidates the per-section signatures so the width-dependent form
  is re-decided. The readable detail 'Section name · tier X of Y · full detail
  at Z' is the same wording in the block title and aria-label, and only
  tier-bearing blocks are focus stops (managed in both the full-render and
  in-place-update paths).
- Repaint rails in place from the peer's events via a per-section signature;
  no full _smRender() per event.
- Delete the glass code (_smRenderGlassFilling, .sm-glass, SM_GLASS_SIZES,
  glassSize handling) and rename the state to _smSectionTiers.
- Add tier-rail, responsive-collapse, a11y, late-provider, malformed-payload
  and narrow-section tests; bump to 1.4.0.
@pullfrog

pullfrog Bot commented Oct 17, 2026 •

Copy link
Copy Markdown
Author

Fixed the check suite failure on PR #18 (CodeFactor: "Complex Method" on screen.js L659–L701).

Diagnosis: the failed check was CodeFactor flagging _smUpdateTierRails for cognitive complexity. Tests and compliance checks all passed locally (node tests/screen.test.js → 44/44).

Fix: split the rail DOM update and the block attribute/title update out of _smUpdateTierRails into _smUpdateBlockRail and _smUpdateBlockAttributes, leaving the loop as signature check → width math → two helper calls. No behavior change; all 44 tests still pass.

Pushed as d324285 to pullfrog/14-difficulty-tier-rail; working tree clean.

Pullfrog  | View workflow run | via Pullfrog | Using big-pickle (free) | 𝕏

@kilo-code-bot

kilo-code-bot Bot commented Oct 17, 2026 •

Copy link
Copy Markdown

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Files Reviewed (5 files)
  • screen.js
  • tests/screen.test.js
  • plugin.json
  • README.md
  • CLAUDE.md

Reviewed by efficient · Input: 62K · Output: 13.7K · Cached: 346.1K

@cchacs
cchacs self-requested a review October 17, 2026 12:12
@cchacs
cchacs merged commit c82b767 into main Oct 17, 2026
10 checks passed
@cchacs
cchacs deleted the pullfrog/14-difficulty-tier-rail branch October 17, 2026 12:13
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.

Replace section glasses with the shared difficulty tier rail

1 participant