ios: reorderable tab bar with more tabs, debug log export, AirPlay picker, more room above seeker

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
cdnutterandClaude Sonnet 5.5 committed 2026-10-20 14:11:58 -07:00
1 parent a0fe35a8d8
commit 926ad6ee99
10 files changed
+350 -10

No files matched your search

+10 -1
View File
@@ -9,7 +9,7 @@ struct RootView: View {
let s = g.settings
let p = Palette.of(s.theme, s.accent)
TabView(selection: Binding(get: { ui.tab }, set: { ui.selectTab($0) })) {
ForEach(Tab.allCases, id: \.self) { t in
ForEach(Tab.layout(s.tabLayout), id: \.self) { t in
NavigationStack(path: ui.path(t)) {
root(t).miniPlayerRoom()
.navigationDestination(for: Route.self) { destination($0).miniPlayerRoom() }
@@ -20,6 +20,7 @@ struct RootView: View {
}
}
.modifier(GlassMiniPlayerHost())
.onChange(of: s.tabLayout) { _, _ in ui.ensureValidTab() }
.sheet(isPresented: Binding(get: { ui.nowPlayingOpen }, set: { ui.nowPlayingOpen = $0 })) {
NowPlayingScreen()
.overlayHost(ui.overlays, level: 1)
@@ -41,6 +42,10 @@ struct RootView: View {
@ViewBuilder private func root(_ t: Tab) -> some View {
switch t {
case .Library: LibraryHome()
case .Songs: SongsScreen()
case .Albums: AlbumsScreen()
case .Artists: ArtistsScreen()
case .Genres: GenresScreen()
case .Playlists: PlaylistsScreen()
case .Search: SearchScreen()
case .Downloads: DownloadsScreen()
@@ -54,6 +59,10 @@ struct RootView: View {
case .Albums: AlbumsScreen()
case .Songs: SongsScreen()
case .Playlists: PlaylistsScreen()
case .Genres: GenresScreen()
case .Downloads: DownloadsScreen()
case .TabBar: TabBarScreen()
case .GenrePage(let g): GenreScreen(genre: g)
case .Eq: EqScreen()
case .EqFilters(let id): EqFiltersScreen(profileId: id)
case .EqFilterPage(let id, let f): EqFilterPage(profileId: id, filterId: f)