Background update check, music extension detection, and misc fixes#61
Merged
AeEn123 merged 4 commits intoJul 15, 2026
Merged
Conversation
- 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>
AeEn123
reviewed
Jul 10, 2026
| 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 |
Owner
There was a problem hiding this comment.
Weird workaround, actual bug in find_header
Owner
There was a problem hiding this comment.
TODO: Check if all usages of find_header is okay with Music category including information
Owner
There was a problem hiding this comment.
Actual bug in get_headers*
get_headers usage fine with Music category including information:
-
cache_directory.rs:258(splits logic for/soundsand/http) -
rbx_storage_directory.rs:94(early return forlogic::Category::Music) -
sql_database.rs:231(early return forlogic::Category::Music) -
logic.rs:133(find_headerfunction, behavioural changes carry on)-
logic.rs:337(Fixes file extension logic) -
logic.rs:406(Will returnErrif 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)
AeEn123
reviewed
Jul 10, 2026
|
|
||
| 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`. |
AeEn123
reviewed
Jul 11, 2026
| @@ -602,24 +649,23 @@ pub fn copy_assets(asset_a: AssetInfo, asset_b: AssetInfo) { | |||
|
|
|||
| pub fn filter_file_list(query: String) { | |||
Owner
There was a problem hiding this comment.
Note to myself: Filtering in gui/file_list.rs would probably be a better choice
AeEn123
reviewed
Jul 11, 2026
| } | ||
|
|
||
| /// Blocking update check used by the CLI (`--check-for-updates`, | ||
| /// `--download-new-update`). The CLI's whole job is this one request and the |
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>
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
UpdatePromptwidget surfaces the result when an update is found./soundsmusic stored without HTTP headers) now have their extension detected from magic bytes (OggS→.ogg,ID3/frame-sync →.mp3), falling back to.oggfor the Music tab.Arc(perf) —FILE_LIST/FILTERED_FILE_LISTare nowMutex<Arc<Vec<AssetInfo>>>. The GUI takes a cheapArcsnapshot each frame (a refcount bump) instead of deep-cloning the wholeVecand all itsStrings on every repaint. Writes useArc::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 (noarc-swapcrate) since the lock is uncontended and the binary is size-constrained.extract_bytesunderflow fix — replaced direct subtraction withsaturating_subso a header found before the offset bytes cannot underflow the index and cause a slice panic.egui::Key::from_name(...).expect(...)replaced with afrom_name+continueguard so tabs beyond key 9 don't panic.filter_file_listsimplification — filter collects into aVeconce, then assigns under a single lock, removing repeated per-entry lock acquisitions.Test plan
.ogg/.mp3extensions are set correctlyVerification performed
cargo test— 22 passed (includes newtest_file_list_arc_snapshot_and_filtercovering the copy-on-write snapshot-stability guarantee the render loop relies on)--list --mode musiclists all assets;--extract --mode music --extensionproduces byte-for-byte-identical files with correct.ogg/.mp3extensions detected from magic bytes🤖 Generated with Claude Code