Skip to content

Background update check, music extension detection, and misc fixes#61

Merged
AeEn123 merged 4 commits into
AeEn123:mainfrom
AeEn123AI:feature/background-updater-and-fixes
Jul 15, 2026
Merged

Background update check, music extension detection, and misc fixes#61
AeEn123 merged 4 commits into
AeEn123:mainfrom
AeEn123AI:feature/background-updater-and-fixes

Conversation

@AeEn123AI

@AeEn123AI AeEn123AI commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Background update check — the update check is moved onto a background thread so the main window opens immediately instead of blocking on startup. An in-app UpdatePrompt widget surfaces the result when an update is found.
  • Music file extension detection — raw audio files (e.g. Roblox /sounds music stored without HTTP headers) now have their extension detected from magic bytes (OggS.ogg, ID3/frame-sync → .mp3), falling back to .ogg for the Music tab.
  • Asset lists backed by Arc (perf)FILE_LIST / FILTERED_FILE_LIST are now Mutex<Arc<Vec<AssetInfo>>>. The GUI takes a cheap Arc snapshot each frame (a refcount bump) instead of deep-cloning the whole Vec and all its Strings on every repaint. Writes use Arc::make_mut (copy-on-write): zero clones in the steady state, and at most one clone per frame during a refresh versus the old unconditional full clone every frame. Kept dependency-free (no arc-swap crate) since the lock is uncontended and the binary is size-constrained.
  • extract_bytes underflow fix — replaced direct subtraction with saturating_sub so a header found before the offset bytes cannot underflow the index and cause a slice panic.
  • Tab keyboard navigation panic fixegui::Key::from_name(...).expect(...) replaced with a from_name + continue guard so tabs beyond key 9 don't panic.
  • filter_file_list simplification — filter collects into a Vec once, then assigns under a single lock, removing repeated per-entry lock acquisitions.
  • Locale additions — new strings added across all supported locales (de-DE, en-GB, englifsh, ja-JP, pirate-speak, pl-PL, ru-RU, shakespearian-english, zh-CN).

Test plan

  • Launch the app — window should appear immediately without waiting for the update check
  • If an update is available, verify the in-app prompt appears
  • Extract music assets and confirm .ogg / .mp3 extensions are set correctly
  • Tab keyboard shortcuts (Ctrl/Alt + 1–9) work without panic
  • Search/filter in the file list returns correct results

Verification performed

  • cargo test — 22 passed (includes new test_file_list_arc_snapshot_and_filter covering the copy-on-write snapshot-stability guarantee the render loop relies on)
  • End-to-end CLI run against an isolated cache: --list --mode music lists all assets; --extract --mode music --extension produces byte-for-byte-identical files with correct .ogg/.mp3 extensions detected from magic bytes

🤖 Generated with Claude Code

AeEn123AI and others added 2 commits June 16, 2026 20:52
- Move update check to a background thread so the window opens
  immediately instead of blocking on startup
- Add in-app "update available" prompt (UpdatePrompt) surfaced from the
  background check result
- Detect .ogg / .mp3 extension from magic bytes for raw audio files
  (music stored without HTTP headers in /sounds)
- Fix potential index underflow in extract_bytes via saturating_sub
- Fix potential panic in tab keyboard navigation by using from_name +
  continue instead of expect
- Simplify filter_file_list to collect once under a single lock
- Various locale string additions across all supported languages

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Store FILE_LIST/FILTERED_FILE_LIST as Mutex<Arc<Vec<AssetInfo>>>. The GUI
now takes a cheap Arc snapshot each frame (a refcount bump) instead of
deep-cloning the whole Vec and all its Strings on every repaint.

Writes use Arc::make_mut (copy-on-write): zero clones in the steady
state, and at most one clone per frame during a refresh, versus the old
unconditional full clone every frame.

Kept dependency-free (Mutex<Arc<...>>) rather than the arc-swap crate
since the lock is uncontended and the binary is size-constrained.

Adds test_file_list_arc_snapshot_and_filter covering the copy-on-write
snapshot-stability guarantee the render loop relies on.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Comment thread src/logic.rs Outdated
extract_bytes(&header, bytes) // Extract between the header to the end of the file.
}
Err(_) => {
// No HTTP header was found. This is the normal case for music, which

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Weird workaround, actual bug in find_header

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: Check if all usages of find_header is okay with Music category including information

@AeEn123 AeEn123 Jul 12, 2026

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actual bug in get_headers*

get_headers usage fine with Music category including information:

  • cache_directory.rs:258 (splits logic for /sounds and /http)
  • rbx_storage_directory.rs:94 (early return for logic::Category::Music)
  • sql_database.rs:231 (early return for logic::Category::Music)
  • logic.rs:133 (find_header function, behavioural changes carry on)
    • logic.rs:337 (Fixes file extension logic)
    • logic.rs:406 (Will return Err if header not found, falls back to raw bytes, no behavioural differences)
  • logic.rs:695 (Additional check for MP3 should be excluded for Music tab)
  • logic.rs:735 (Multiple occurrences for sound data-types may show)
  • logic.rs:882 (does not check music)
  • logic.rs:883 (does not check music)
  • logic.rs:884 (test will fail with music containing data)

Comment thread src/logic.rs Outdated

pub fn get_file_list() -> Vec<AssetInfo> {
pub fn get_file_list() -> Arc<Vec<AssetInfo>> {
// Cheap snapshot: clones the `Arc` (a refcount bump), not the `Vec`.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unnecessary comment

Comment thread src/logic.rs
@@ -602,24 +649,23 @@ pub fn copy_assets(asset_a: AssetInfo, asset_b: AssetInfo) {

pub fn filter_file_list(query: String) {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note to myself: Filtering in gui/file_list.rs would probably be a better choice

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do in different PR

Comment thread src/updater.rs Outdated
}

/// Blocking update check used by the CLI (`--check-for-updates`,
/// `--download-new-update`). The CLI's whole job is this one request and the

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Too verbose in reasoning

AeEn123AI and others added 2 commits July 12, 2026 20:35
High-signal facts an agent would miss without reading multiple files:
build/test/lint commands, build.rs-generated locale_data.rs, generated
README.md, the Arc<Vec<AssetInfo>> COW snapshot contract, the required
User-Agent header for GitHub update checks, custom logging macros, and
the windows_subsystem debug-vs-release behavior.

Co-Authored-By: GLM 5.2 <noreply@z.ai>
…; simplify verbose AI comments

Instead of a separate detect_file_extension helper and a special Err-path
in extract_to_file, give Category::Music the same OggS/ID3 headers as
Sounds so find_header succeeds and the existing header->extension table
resolves the file extension naturally. determine_category and
get_headers(All) continue to skip Music to avoid shadowing Sounds.

Also trim the verbose AI-generated comments in logic.rs, updater.rs,
updater/gui.rs, and gui.rs to be shorter while still conveying the
intent.

Co-Authored-By: opencode <noreply@opencode.ai>
@AeEn123
AeEn123 merged commit a6e4d80 into AeEn123:main Jul 15, 2026
3 checks passed
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.

2 participants