The section_map plugin pins a ~20px clickable bar (#section-map, z-index:5)
to the top of #player. The v3 left-rail hover-catcher (.v3-railzone::before)
is full-height at z-index:30 with pointer-events:auto, so its top-left
corner swallowed every click on the section map's first section — the
left-most section was never clickable on the v3 desktop (macOS/Windows) UI.
Drop the catcher below the 20px bar when the section map is present,
mirroring the existing #section-map ~ #player-hud special-case in
static/style.css. The rail still reveals from anywhere below the bar.
Adds a Playwright regression test (hit-test of the top-left corner) with a
negative control that re-raises the catcher to reproduce the bug.
Fixes#616
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* Fix list/tree view: select mode, parts visibility, song actions
Bring the v3 list/tree view to parity with the grid card:
- Select mode now renders a per-row checkbox + selected-ring, preserves
expanded artist groups across re-render, and a capture-phase guard
makes a row/chip click select the song instead of starting playback.
- Always-on favourite / save-for-later / overflow-menu cluster on each
row, same actions as the grid card.
Rebuild static/tailwind.min.css so the new utilities are compiled in -
notably .sm:flex behind the arrangement chips' "hidden sm:flex" wrapper.
Without it the chips (and #582's badges) render display:none on the
Docker build, which serves the committed CSS; the desktop build looked
fine only because it rebuilds Tailwind from source at bundle time.
Signed-off-by: Sin <deathlysin@outlook.com>
* fix(v3): regenerate tailwind.min.css from source + add tree select tests + CHANGELOG
The committed tailwind.min.css was over-built: 135,578 bytes / 1,428
selectors, with 294 selectors (accent-amber-400, bg-cyan-500,
animate-spin, after:bg-gray-400, …) used in zero core source files —
bloat from a local build scanning outside the repo's content globs. It
would fail CI's rebuild-and-diff and violates the byte-stable rule in
scripts/build-tailwind.sh.
Regenerate via `scripts/build-tailwind.sh` (pinned tailwindcss@3.4.19):
111,491 bytes / 1,134 selectors, byte-identical to a clean rebuild,
still containing the .sm\:flex fix plus every new tree class
(ring-fb-primary, accent-fb-primary, pointer-events-none, …). Docker
chips now render and CI stays green.
Add tests/browser/v3-tree-select.spec.ts:
- select mode keeps expanded artist groups open across the tree
re-render (fails without loadTree's openArtists capture/restore)
- clicking a row in select mode selects instead of playing
Record the fix under CHANGELOG [Unreleased] -> Fixed.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Signed-off-by: Sin <deathlysin@outlook.com>
Co-authored-by: byrongamatos <xasiklas@gmail.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* chore(hotkeys): remove sloppak-convert library hotkey
Removes the 'c' keyboard shortcut for converting library entries to
.sloppak. The shortcut was defined in two places:
- The no-op registerShortcut() entry that only existed to show in the
? help panel (the Sloppak Converter plugin handles conversion and
can register its own shortcut via window.registerShortcut).
- The c dispatch in the library-entry keydown handler
({ c: 'button.sloppak-convert-btn', ... }) that triggered the
plugin button.
* test+docs: update tests & CHANGELOG for removed `c` convert hotkey
The previous commit removed the `c` library hotkey but left three
assertions in tests/browser/keyboard-shortcuts.spec.ts that require it,
which fail deterministically (the two registry tests read window._panels
directly, independent of environment):
- should list all registered shortcuts (required {key:'c',scope:'library'})
- should have correct shortcut scopes (expected library::c)
- should show library shortcuts in help modal (Convert library entry / c)
Drop those assertions and record the removal under CHANGELOG
[Unreleased] -> Removed.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: byrongamatos <xasiklas@gmail.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix(player): Space bar play/pause when focus is on sidebar or rail buttons
When any <button> in the player rail (viz, audio, mixer, etc.), a sidebar
nav link, or a popover control has keyboard focus, pressing Space was
blocked by _shortcutDispatchBlocked → _isInsideInteractiveControl, which
returns true for BUTTON elements. The Space shortcut never reached the
shortcut dispatcher and togglePlay() was never called.
The fix extends the same carve-out pattern already used for the section
practice bar: when the player screen is active, Space is always dispatched
through the shortcut system. The shortcut handler's preventDefault() stops
the focused element from also activating, so this is not a double-trigger.
* test(player): cover Space play/pause carve-out + add CHANGELOG entry
Adds two Playwright regression tests for #593 in
tests/browser/keyboard-shortcuts.spec.ts:
- Space toggles play/pause when a player rail <button> has focus, and
the focused button does NOT also activate (dispatcher preventDefault).
Fails on base (Space blocked, played=0), passes with the carve-out.
- Space in a player-screen text input still types a space and never
reaches play/pause (locks the _isTextInput exemption ordering).
Also records the fix under CHANGELOG [Unreleased] -> Fixed, per the
project workflow that every PR updates the changelog.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix(player): don't override Space inside modal dialogs over the player
The player-screen Space carve-out keyed off the active *screen*, so it
also hijacked Space inside a true modal dialog layered over the player
(e.g. the keyboard-shortcuts help modal, edit modal): Space toggled
playback behind the modal and preventDefault blocked the modal's focused
control (Close) from activating — contradicting aria-modal semantics.
Narrow the carve-out to skip focus inside a modal
(role="dialog" aria-modal="true" or .feedBack-modal). Non-modal player
popovers/toasts (loop A/B, arrangement pin, role=dialog aria-modal=false)
are not dialogs and stay covered, so the original fix is unchanged for
the cases it targeted. Adds a Playwright regression test (Space inside a
modal reaches the modal's button, not play/pause) and updates the
CHANGELOG entry.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: byrongamatos <xasiklas@gmail.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace the single long scrolling v3 settings screen with a horizontal tab
bar (Gameplay / Audio / Graphics / Keybinds / Progression / Mic / Plugins /
System) over card rows (icon + title + description, control on the right) with
a per-category Reset.
- static/v3/index.html: tab bar + card-row markup (ids keep hydrating through
the unchanged app.js loadSettings()/persistSetting() path).
- static/v3/settings.js (new): tab switching + active-tab persistence
(localStorage 'v3-settings-tab'), per-category reset, read-only Keybinds
reference from window.getAllShortcuts().
- static/v3/v3.css: plain CSS, no Tailwind rebuild.
- Per-plugin settings tab: new optional settings.category in plugin.json →
plugins/__init__.py surfaces settings_category; app.js mounts each plugin
<details> into #plugin-settings-<category> (fallback: Plugins tab).
highway_3d ships category: "graphics".
- New gameplay settings: countdown_before_song (wired end-to-end, default off);
miss_penalty + fail_behavior (persist-only stubs); "Note highway speed"
surfaces existing master_difficulty.
- New POST /api/settings/reset clears whitelisted keys back to defaults.
Tests: test_settings_api.py, test_plugins.py::test_settings_category_parsed_from_manifest,
tests/browser/settings-tabbed.spec.ts. 179 passed locally.
Ported from the pre-rename feat/v3-settings-tabbed WIP onto current main
(slopsmith→feedBack rename applied; settings-screen markup conflict resolved
in favour of the new tabbed layout — all prior setting ids preserved).
Closes#579
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* Update GitHub repo references from feedback* to feedBack*
* rename: slopsmith -> feedBack, byron -> got-feedBack
Renames across the entire codebase:
- slopsmith/Slopsmith/SLOPSMITH/SlopSmith -> feedBack/FeedBack/FEEDBACK/FeedBack
- byron/Byron/Byrongamatos -> got-feedBack/got-feedBack/got-feedBack
- /home/byron/ -> /opt/got-feedBack/
- byron@ougsoft.com -> hi@got-feedBack.org
- github.com/byrongamatos/ -> github.com/got-feedback/
- com.byron. -> com.got-feedback.
- SLOPSMITH_ env vars -> FEEDBACK_ with backward-compat fallback
- Protocol/storage strings migrated with read-old/write-new pattern
- window.slopsmith JS API -> window.feedBack (canonical) + backward-compat alias
Refs: #rename-slopsmith
* rename: complete regen against current main + fix backward-compat alias
Regenerated the slopsmith->feedBack / byron->got-feedBack rename on top of
current main (3 commits had landed since the branch: #572/#554/#574),
resolving the four content conflicts in favour of main's newer content
(autoplay/auto-exit, accuracy-badge, Virtuoso re-home, feedpak badge).
Completion fixes on top of the mechanical rename:
- Re-apply rename to post-branch content the original rename never saw:
window.slopsmith(.Tour) consumers in lessons.js / notifications.js /
onboarding-tour.js, and the matching JS + python tests (autoplay_exit,
progression_*, test_feedpak_extension FEEDBACK_* env vars). The test env
vars now match server.py (which reads FEEDBACK_SYNC_STARTUP /
FEEDBACK_SKIP_STARTUP_TASKS), so the sync-startup test exercises the real
path again.
- Restore the window.slopsmith backward-compat alias dropped during conflict
resolution, and move the bus aliases to AFTER the _feedBackExisting merge
block so they reference the fully-assembled object (also fixes the
loop_api.test.js API-surface regex, which the original PR latently broke).
- Drop the stray empty data/web_library.db (runtime DB lives in CONFIG_DIR)
and gitignore it.
- Fix stale tone-source test: feed[dB]ack -> fee[dB]ack to match shipped
source labels.
Verified locally (org CI billing-blocked): JS 819/819 pass; pytest 1669
passed / 1683 collected with 0 import errors; zero residual slopsmith/byron
except the two intentional window.slopsmith aliases.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* rename: implement advertised backward-compat + prune dead community plugins
Address gaps where PR #537's "Backward compatibility" section was advertised
but not implemented, and clean up the community plugin list.
Env vars (FEEDBACK_* canonical, legacy SLOPSMITH_* honoured):
- New lib/env_compat.py (getenv_compat / env_flag_compat) + tests. server.py
(_env_flag + all FEEDBACK_* reads), diagnostics_hardware, gp2midi and
tailwind_rebuild now resolve the legacy alias, so existing SLOPSMITH_UI /
SLOPSMITH_PLUGINS_DIR / etc. deployments keep working.
- Fix the rename collapsing plugins/__init__.py and minigames/routes.py from
`FEEDBACK_PLUGINS_DIR or SLOPSMITH_PLUGINS_DIR` into a redundant
`FEEDBACK_ or FEEDBACK_` (the fallback was silently lost).
Storage (app.js update-channel):
- Read feedBack-update-channel, fall back to legacy slopsmith-update-channel,
and clear the legacy key on write — so a user's update-channel preference
survives the rename instead of resetting to "stable".
Community plugin list (README): the rename rewrote third-party repo URLs we
don't own. Probed every one; their owners never renamed, so:
- Restore the 13 live community plugins to their real slopsmith-* names.
- Prune 6 that are 404 to the public (topkoa splitscreen/stems, OmikronApex
tuner, Jafz2001 nam-rig-builder, DeathlySin song-preview, Erikcb91 shuffle).
- Fix a pre-existing Guitar Theory clone-command typo (nam-tone -> guitar-theory).
Verified: env_compat 7/7, JS 819/819, pytest 1690 collected / 0 import errors,
rename-sensitive + startup suites green.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: byrongamatos <xasiklas@gmail.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Reword comments/docstrings/strings and rename identifiers that referenced
the external game and its file formats:
- format-id "psarc" -> "archive"; local vars psarc_path -> song_path,
psarc_base -> tone_base
- lyrics provenance value "sng" -> "notechart" (legacy "sng" still accepted)
- highway_3d fret-ghost scope value "rocksmith" -> "chords" (invalid/legacy
values fall back to the default, preserving behaviour)
- neutralise references in prose, test names/data, .gitattributes and docs
No functional change beyond the renamed identifiers; all Python compiles.