Release 0.5.0 — VibeUI frontend, games, and the Keyboard Hero visual overhaul#5
Merged
Conversation
… enhanced orb visualizer - Replace library grid views with a proper data table (sortable columns, search, pagination) - Add metadata editor filename display and all editable fields - Add spacebar play/pause global shortcut - Keys game now detects actual chords from FFT audio analysis instead of cycling fixed patterns - Orb visualizer pulses dramatically harder on bass hits with increased bloom and camera dynamics - Bump version to 0.4.0
Use chord detection to drive orb bloom pulses on chord changes instead of raw FFT spikes. Added extra smoothing layer for bass/mid/ treble to reduce spastic movement while keeping musical responsiveness.
- Lower analyser smoothingTimeConstant from 0.8 to 0.5 for snappier FFT - Boost energy values with 2-2.5x multiplier so bass actually hits hard - Faster attack rates in main smoothing loop (0.5 attack vs 0.25) - Bass pulse: scale multiplier 0.7 (was 0.5), inflate 0.8 (was 0.6) - Chord deformation: morph amp up to 0.7 (was 0.5), noise speed 0.6 - Camera pull-in 1.2x bass (was 0.9), lerp rate 0.15 (was 0.1) - Shader pulse: bass multiplier 1.2 (was 0.7), bloom 0.8 (was 0.6) - Vertex lerp rate back to 0.18 for responsive shape changes
collect_media_dir now tracks visited canonical paths in a HashSet so a self- or mutually-referencing directory symlink is entered only once, preventing unbounded recursion. Adds a unix symlink-cycle regression test that asserts the scan terminates and counts each file exactly once. Addresses code-review finding C5.
Introduces asset_scope_roots(), combining the configured library directories with the playlists directory (deduped), to be used as the runtime allowlist for Tauri's asset: protocol instead of the wildcard filesystem scope. Pure combine_asset_roots is unit-tested for inclusion and dedup. Part of code-review finding C6.
Replaces the wildcard asset: protocol scope ("**") with an empty static
scope and grants directory access at runtime in setup() via
asset_protocol_scope().allow_directory for each asset_scope_roots() entry.
This prevents the frontend (and any XSS) from reading arbitrary files such
as ~/.ssh/id_rsa through the asset: protocol.
Closes code-review finding C6 / S1.
…utput emptyOutDir during the Vite build wiped the vendored visualizer libraries (three, audiomotion, butterchurn) that lived in the tracked dist/vendor. Move them to frontend/public/vendor so Vite copies them back into dist/vendor on every build (same runtime path, zero behavior change), then gitignore the dist/ build output and untrack the legacy dist/index.html on this epic branch. Keeps the working tree clean across subsequent builds.
types.ts defines Source/Track/NativeStatus (snake_case to match the Rust NativeAudioRuntimeStatus). api/tauri.ts is the single invoke() boundary: typed native-audio wrappers that normalize failures into TauriError so errors are never silently swallowed. Tests mock @tauri-apps/api/core.
Isolates the HTMLAudioElement behind a typed interface (isLoaded/isPaused/ pause/resume) so the player store can delegate web-source playback and tests can mock it deterministically.
…A/H-B) Single source of truth for playback. togglePlayback decides on authoritative source/isPlaying state (not a transient native-status read), so the legacy fall-through that silently no-op'd or restarted the track is gone (H-A). An inFlight lock released in finally prevents concurrent transitions from rapid clicks wedging the buttons (H-B). Tested: native/web pause/resume truth table, the desync case (never silent), and re-entrancy.
Prev/Next emit events up; play/pause calls the player store. The icon binds to player.isPlaying, so the manual setToggleIcon drift from the legacy UI is gone by construction. Tested: click dispatches the action, icon tracks state.
…dial/LumiBars), persisted
…track near end, with a duration selector (Off/2/4/6/8/12s)
… embedded cover art (lofty Picture)
…similar tracks (metadata-based, no deps), persisted toggle
…/accuracy logic (TDD)
…ed notes, hit judging, combo/score HUD, end-of-song results; selectable from the visualizer
…ns, beat-reactive highway, x2/x4 combo multiplier, screen flash; misses no longer end the game (only the song's end does)
…h a music-reactive backdrop (EQ silhouette, bass pulse, beat flash, energy-scaled explosions); games now claim the keyboard so transport shortcuts don't fire
…s on perfects, comet note-trails, chord spawns, FEVER overdrive at x4 (gold tint + double particles), camera punch/FOV-kick on milestones
…ooms ~20% on bass for a gentle beat pulse
…); add sweeping spotlight beams, laser fan, lightning strikes on hard bass, and sky confetti pops on the beat
…rack + duration) drives a steady, position-synced note stream; each song is its own repeatable level; misses no longer interrupt the flow; Play Again restarts the song
- dispose note geometry+material on hit/miss/reset (was unbounded GPU leak) - judge + animate notes off player.positionSecs (one clock, no hit/visual drift) - ResizeObserver keeps WebGL viewport matched on fullscreen toggle - dispose whole scene graph + disconnect observer on unmount - claim keyboard only after init succeeds (no stuck transport-shortcut suppression)
- ResizeObserver matches canvas backing-store aspect to host (no fullscreen stretch); re-lays level + clamps bird in-bounds - boost EQ-silhouette backdrop alpha/height so the spectrum reads again
…updates - propagate malformed-row errors instead of filter_map(.ok()) - updated += execute(...)? so the count reflects writes and failures aren't swallowed
- new read_audio_signal_properties() pulls sample rate/bit depth/channels/bitrate from the container header - read_track_signal_details no longer opens + decodes the whole file per track change; bit depth/bitrate keep estimate fallbacks
- set_track_artwork rejects non-files, caps size (32MB), and verifies magic bytes match the claimed image type - Chicken Lander claims the keyboard only after canvas init succeeds
- store + clear the setTimeout that clears `crossfading` so rapid track changes don't stack timers - revert Chicken keyboard claim to mount (2D canvas can't fail in the webview the way KH WebGL can; the claim-after-init contract is covered by KH where it matters)
- highway strips, hit flashes, hit bar, notes/glow/trail: depthTest off + high renderOrder so they always paint over the EDC rig - dim + recede spectrum wall, spotlights, lasers, grid so the playfield reads clearly (was too chaotic)
- faceted icosahedron mirror ball on a hanging rod, global color multiply tints/pulses the facets to the music - scattered additive fleck field = the light it reflects; twinkles + grows with treble/bass - spin rate tracks estimated BPM (smoothed beat-interval tracker from onset gaps)
- whole palette shifted warm: dusk-plum backdrop/fog, warm grid/stars, pastel lanes (amber/coral/peach/gold/lavender), warm hit line + flash - soft radial sun glow on the horizon that breathes slowly with the bass - drifting warm bokeh 'fireflies' rising through the scene for calm, alive ambience - spotlight/laser/spectrum hues folded into a warm band; sweeps slowed (gentle, not strobe) - aggressive lightning softened to a rare warm shimmer - dispose the shared sun texture on teardown
- ACES filmic tone mapping so additive neon blooms warm instead of clipping white - fake bloom: soft radial light-pools under notes + a glowing hit-line halo (no post-processing addons; vendored three is core-only) - classic gem notes (spinning diamonds) replace the boxes; soft ease-in at spawn, no hard pop - tempo-driven scrolling beat lines on the highway (classic GH cue, fed by the BPM tracker) - cinematic DOM overlays: edge vignette + subtle film grain (reduced-motion aware) - HUD juice + warm palette: combo punches on increment, milestone messages animate in, warm mult/combo colors, animated warm results panel
- painted dusk-gradient sky background (deep plum -> peach horizon) replaces the flat clear color - volumetric god-rays fanning from the sun, swaying + shimmering with the music - glossy-floor reflections: dim mirrored gems under the deck, fading as notes near the camera - refined gem: white-hot inner core inside the diamond for a jewel read - per-lane hit BEAMS that shoot up + brighten on a hit (replacing the flat flash) - sleek song-progress bar + subtle now-playing label in the HUD - target fidelity ~6-7/10 (stylized-premium, Tetris-Effect lane), gameplay untouched (hits+combos)
- replace low-poly octahedron notes with flat rectangular gem PADS (wider than tall): per-lane canvas texture with gradient fill, top shine, and a bright gradient border (gemstone look), normal-blended over the additive glow pool - pad base colour = lane key colour (same LANE_COLORS the key labels use) so notes match the keys exactly - FIX choppy sliding: notes were driven by player.positionSecs (updates a few times/sec) so they stepped. Add a smoothed visual clock advanced by real frame time each frame and gently re-synced to the true position (snaps on seek). Judge on the same smoothed clock so feel stays consistent - pads + reflection slide flat (no gem tumble); dispose shared pad textures on teardown
- spotlights: 6->4, pushed far back to the horizon (z-66), tall + faint, slow narrow sway only, no cross-field drift, opacity capped — distant ambience, not raking searchlights. Lasers slowed + dimmed, no flicker - add warm hemisphere + directional lighting so structural geometry reads with real form - glossy lit stage deck grounds the highway; raised 3D side rails frame the lane channel - streaming roadside pylons (lit 3D posts) flow toward the camera at note speed = calm parallax groove + dimension - disco ball -> lit MeshStandard (real facet form); spectrum bars -> thin boxes for depth
- gitignore frontend build output (coreamp-app/dist, frontend/dist) and scratch reference assets (/images, *.dep) - remove stray root cruft (duplicate Chicken Lander source, sprites.png, deprecated todolist.old.dep) - rustfmt reflow in library.rs test imports
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Brings the Vue 3 + Pinia + VibeUI frontend to feature parity with the legacy UI and well beyond, adds two in-visualizer games, and lands a major Keyboard Hero visual overhaul. Backend hardened from a full code-review pass. Version bumped to 0.5.0.
Highlights
Player / library
Games (visualizer modes)
Keyboard Hero look (the big visual work)
Backend hardening (code-review fixes)
set_track_artwork; crossfade timer cleanupRelease housekeeping
Verification
cargo test: 39 pass ·clippy: cleanvitest: 352 pass.app+.dmgbundle built (CoreAmp_0.5.0_aarch64.dmg)🤖 Generated with Claude Code