feat(android): swipe between Erkunden sub-tabs (Bibliothek ↔ Global)

Wrap the Erkunden content in a HorizontalPager so a left/right swipe switches
between the Bibliothek and Global search tabs, two-way synced with the TabRow: a
chip tap animates the pager; a settled swipe updates the selected tab (and stops
any preview, like a tap). Removes the idea from the backlog now that it's built.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
HoneyandClaude Opus 4.8 committed 2026-08-16 21:52:11 +02:00
1 parent 87ee8cd097
commit 7f5d25a03b
2 files changed
+38 -21

No files matched your search

-1
View File
@@ -453,7 +453,6 @@ Primary causes identified:
- **New-release alerts:** periodic check for new albums/singles by followed artists (sources: iTunes lookup / MusicBrainz / Last.fm), surfaced in the existing in-app notification bell (and optionally push). - **New-release alerts:** periodic check for new albums/singles by followed artists (sources: iTunes lookup / MusicBrainz / Last.fm), surfaced in the existing in-app notification bell (and optionally push).
- **Concert alerts:** reuse the existing **Ticketmaster** events integration to notify when a followed artist has nearby/upcoming shows. - **Concert alerts:** reuse the existing **Ticketmaster** events integration to notify when a followed artist has nearby/upcoming shows.
- Ties into the importer: a "download this new release" action straight from the notification. - Ties into the importer: a "download this new release" action straight from the notification.
- **Android** — **Swipe between Erkunden sub-tabs** — a left/right swipe gesture on the Erkunden tab to switch between "Bibliothek" and "Global" search (instead of only tapping the chips). A fun, natural pager-style gesture (e.g. HorizontalPager).
- **Android** — Playlist drag-and-drop / sort order - **Android** — Playlist drag-and-drop / sort order
- **Android** — Artist page iTunes fallback (for artists not in Navidrome) - **Android** — Artist page iTunes fallback (for artists not in Navidrome)
- **Android** — Romaji / Japanese sort support - **Android** — Romaji / Japanese sort support
@@ -3,6 +3,8 @@ package com.novasonic.app.ui.screen
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
import androidx.compose.foundation.pager.HorizontalPager
import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyRow import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.items
@@ -148,6 +150,17 @@ fun ExploreScreen(
return return
} }
// Swipe left/right to switch between the Bibliothek and Erkunden sub-tabs, kept in sync with the
// TabRow: a chip tap animates the pager; a settled swipe updates the selected tab.
val pagerState = rememberPagerState(initialPage = state.tab.ordinal) { ExploreTab.values().size }
LaunchedEffect(state.tab) {
if (pagerState.currentPage != state.tab.ordinal) pagerState.animateScrollToPage(state.tab.ordinal)
}
LaunchedEffect(pagerState.settledPage) {
val t = ExploreTab.values()[pagerState.settledPage]
if (t != state.tab) { vm.selectTab(t); vm.stopPreview() }
}
Column(Modifier.fillMaxSize()) { Column(Modifier.fillMaxSize()) {
// ── Tabs ───────────────────────────────────────────────────────────── // ── Tabs ─────────────────────────────────────────────────────────────
TabRow( TabRow(
@@ -230,26 +243,31 @@ fun ExploreScreen(
} }
} }
// ── Content ────────────────────────────────────────────────────────── // ── Content (swipeable) ────────────────────────────────────────────────
when (state.tab) { HorizontalPager(
ExploreTab.LIBRARY -> LibrarySearchContent( state = pagerState,
query = state.query, modifier = Modifier.weight(1f),
coverUrl = coverUrl, ) { page ->
playerState = playerState, when (page) {
onSongPlay = onSongPlay, ExploreTab.LIBRARY.ordinal -> LibrarySearchContent(
onAlbumClick = onAlbumClick, query = state.query,
onArtistClick = onArtistClick, coverUrl = coverUrl,
onShowContextMenu = onShowContextMenu, playerState = playerState,
) onSongPlay = onSongPlay,
ExploreTab.GLOBAL -> GlobalExploreContent( onAlbumClick = onAlbumClick,
state = state, onArtistClick = onArtistClick,
vm = vm, onShowContextMenu = onShowContextMenu,
coverUrl = coverUrl, )
playerState = playerState, else -> GlobalExploreContent(
onAlbumClick = onAlbumClick, state = state,
onSongPlay = onSongPlay, vm = vm,
onDownload = vm::showDownloadSheet, coverUrl = coverUrl,
) playerState = playerState,
onAlbumClick = onAlbumClick,
onSongPlay = onSongPlay,
onDownload = vm::showDownloadSheet,
)
}
} }
} }
} }