diff --git a/crates/qbz-qt/src/local_albums.rs b/crates/qbz-qt/src/local_albums.rs index e8b0b0cea..76228a16d 100644 --- a/crates/qbz-qt/src/local_albums.rs +++ b/crates/qbz-qt/src/local_albums.rs @@ -305,8 +305,17 @@ pub fn load_tracks_page_blocking(reset: bool) -> Result<(Vec, bool), S // make pagination over-report. let has_more = page.len() as u64 == TRACKS_PAGE; - if crate::local_plex::is_enabled() && offset == 0 { - let mut merged = crate::local_plex::search_tracks(&query); + if offset == 0 { + // Plex AND the media servers, in one merge. Page 0 only, for the same + // reason the Plex arm was page 0 only: these caches are bounded sets + // read whole, so re-merging them on every page would repeat every + // remote row once per page of local results. + let mut merged = if crate::local_plex::is_enabled() { + crate::local_plex::search_tracks(&query) + } else { + Vec::new() + }; + merged.extend(crate::media_servers_qt::search_tracks(&query, None)); if !merged.is_empty() { merged.append(&mut page); if sort != "default" { diff --git a/crates/qbz-qt/src/search_local.rs b/crates/qbz-qt/src/search_local.rs index 44b286caf..9ffaddb6e 100644 --- a/crates/qbz-qt/src/search_local.rs +++ b/crates/qbz-qt/src/search_local.rs @@ -426,12 +426,21 @@ pub(crate) async fn load_cortinilla_local( db.search_with_filter_page(q.trim(), 0, limit, true, exclude_network, "default") }) .unwrap_or_default(); - if plex_enabled { - // PREPEND so Plex content is visible without scrolling past a full - // local page. See the module header: this can starve the local-file - // tracks out of the track section, and that is the reference's - // behaviour, reproduced. - let mut merged = crate::local_plex::search_tracks(q.trim()); + // PREPEND so remote content is visible without scrolling past a full + // local page. See the module header: this can starve the local-file + // tracks out of the track section, and that is the reference's + // behaviour, reproduced — now for every remote source, not just Plex. + let mut merged = if plex_enabled { + crate::local_plex::search_tracks(q.trim()) + } else { + Vec::new() + }; + // BOUNDED, unlike the Plex arm. The Plex cache is read whole because + // it always was; a media-server mirror can hold 50k rows and this runs + // on every keystroke of the cortinilla, so it takes the same limit the + // caller asked the local query for. + merged.extend(crate::media_servers_qt::search_tracks(q.trim(), Some(limit as u32))); + if !merged.is_empty() { merged.append(&mut rows); rows = merged; }