feat(discover): add Release Watch section to Home and For You

The Qobuz mobile client (v9.7) surfaces a 'Release Watch' /
'Radar de Novedades' feed in its Discover screens — new releases
from the artists, labels and award series the user follows. We
didn't have parity for it. This adds it as a module in both
Discover tabs.

Backend:
- qbz-qobuz: new ALBUMS_RELEASE_WATCH endpoint constant
  (/albums/releaseWatch, plural as in mobile) and signed_get_auth
  client method returning a SearchResultsPage<Album>. Signing
  method is 'albumsreleaseWatch' per the Qobuz secret protocol.
- qbz-core: passthrough get_release_watch on QbzCore.
- src-tauri: core_bridge wrapper, new v2_get_release_watch Tauri
  command registered in lib.rs. Filters through the artist
  blacklist like other album endpoints.

Frontend:
- HomeView: new renderable section 'releaseWatch' in the home tab
  (default visible, placed right after New Releases). Parallel
  fetch alongside the existing discover_index call; mapped via
  the existing toAlbumCard helper.
- ForYouTab: section appears ahead of 'Essentials' since followed
  artists/labels are typically more personal.
- homeSettingsStore: new HomeSectionId 'releaseWatch' in the type
  union and DEFAULT_SECTIONS so the user can toggle/reorder it
  from home customization.
- i18n: discover.releaseWatch.title + subtitle added to all five
  locales, using Qobuz's own translations where they exist
  ('Radar de Novedades' for Spanish, 'Release-Radar' for German)
  with the 'followed artists/labels/awards' subtitle copy adapted
  from the mobile app's strings.xml resources.

cc
This commit is contained in:
vicrodh committed 2026-04-13 22:33:59 -06:00
1 parent 808b9db0db
commit ea216adf0f
14 files changed
+307 -10

No files matched your search

+16
View File
@@ -760,6 +760,22 @@ impl<A: FrontendAdapter + Send + Sync + 'static> QbzCore<A> {
.map_err(CoreError::Api)
}
/// Get Release Watch — new releases from followed artists, labels and
/// awards (the "Radar de Novedades" feed in the Qobuz mobile client).
pub async fn get_release_watch(
&self,
limit: u32,
offset: u32,
) -> Result<SearchResultsPage<Album>, CoreError> {
let client = self.client.read().await;
let client = client.as_ref().ok_or(CoreError::NotInitialized)?;
client
.get_release_watch(limit, offset)
.await
.map_err(CoreError::Api)
}
/// Get artist page (full artist details with albums, tracks, similar)
pub async fn get_artist_page(
&self,