Updated API calls and Library View
This commit is contained in:
@@ -7,27 +7,73 @@
|
||||
|
||||
import SwiftUI
|
||||
|
||||
enum LibraryTab: String, CaseIterable {
|
||||
case artists = "Artists"
|
||||
case albums = "Albums"
|
||||
case playlists = "Playlists"
|
||||
case radio = "Radio"
|
||||
}
|
||||
|
||||
struct LibraryView: View {
|
||||
@Environment(MAService.self) private var service
|
||||
|
||||
@State private var selectedTab: LibraryTab = .artists
|
||||
@State private var refreshError: String?
|
||||
@State private var showError = false
|
||||
|
||||
private var isRefreshing: Bool {
|
||||
switch selectedTab {
|
||||
case .artists: return service.libraryManager.isLoadingArtists
|
||||
case .albums: return service.libraryManager.isLoadingAlbums
|
||||
case .playlists: return service.libraryManager.isLoadingPlaylists
|
||||
case .radio: return false
|
||||
}
|
||||
}
|
||||
|
||||
private var lastRefresh: Date? {
|
||||
switch selectedTab {
|
||||
case .artists: return service.libraryManager.lastArtistsRefresh
|
||||
case .albums: return service.libraryManager.lastAlbumsRefresh
|
||||
case .playlists: return service.libraryManager.lastPlaylistsRefresh
|
||||
case .radio: return nil
|
||||
}
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
NavigationStack {
|
||||
TabView {
|
||||
Tab("Artists", systemImage: "music.mic") {
|
||||
ArtistsView()
|
||||
}
|
||||
|
||||
Tab("Albums", systemImage: "square.stack") {
|
||||
AlbumsView()
|
||||
}
|
||||
|
||||
Tab("Playlists", systemImage: "music.note.list") {
|
||||
PlaylistsView()
|
||||
Group {
|
||||
switch selectedTab {
|
||||
case .artists: ArtistsView()
|
||||
case .albums: AlbumsView()
|
||||
case .playlists: PlaylistsView()
|
||||
case .radio: RadiosView()
|
||||
}
|
||||
}
|
||||
.tabViewStyle(.page(indexDisplayMode: .always))
|
||||
.navigationTitle("Library")
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
.toolbar {
|
||||
ToolbarItem(placement: .navigationBarLeading) {
|
||||
Button {
|
||||
Task { await refresh() }
|
||||
} label: {
|
||||
if isRefreshing {
|
||||
ProgressView()
|
||||
} else {
|
||||
Image(systemName: "arrow.clockwise")
|
||||
}
|
||||
}
|
||||
.disabled(isRefreshing || selectedTab == .radio)
|
||||
.help(lastRefreshLabel)
|
||||
}
|
||||
|
||||
ToolbarItem(placement: .principal) {
|
||||
Picker("Library", selection: $selectedTab) {
|
||||
ForEach(LibraryTab.allCases, id: \.self) { tab in
|
||||
Text(tab.rawValue).tag(tab)
|
||||
}
|
||||
}
|
||||
.pickerStyle(.segmented)
|
||||
.frame(maxWidth: 360)
|
||||
}
|
||||
|
||||
ToolbarItem(placement: .primaryAction) {
|
||||
NavigationLink {
|
||||
SearchView()
|
||||
@@ -36,6 +82,37 @@ struct LibraryView: View {
|
||||
}
|
||||
}
|
||||
}
|
||||
.navigationDestination(for: MAArtist.self) { ArtistDetailView(artist: $0) }
|
||||
.navigationDestination(for: MAAlbum.self) { AlbumDetailView(album: $0) }
|
||||
.navigationDestination(for: MAPlaylist.self) { PlaylistDetailView(playlist: $0) }
|
||||
.alert("Refresh Failed", isPresented: $showError) {
|
||||
Button("OK", role: .cancel) { }
|
||||
} message: {
|
||||
if let refreshError { Text(refreshError) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Helpers
|
||||
|
||||
private var lastRefreshLabel: String {
|
||||
guard let date = lastRefresh else { return "Never refreshed" }
|
||||
let formatter = RelativeDateTimeFormatter()
|
||||
formatter.unitsStyle = .full
|
||||
return "Last refreshed \(formatter.localizedString(for: date, relativeTo: .now))"
|
||||
}
|
||||
|
||||
private func refresh() async {
|
||||
do {
|
||||
switch selectedTab {
|
||||
case .artists: try await service.libraryManager.loadArtists(refresh: true)
|
||||
case .albums: try await service.libraryManager.loadAlbums(refresh: true)
|
||||
case .playlists: try await service.libraryManager.loadPlaylists(refresh: true)
|
||||
case .radio: break
|
||||
}
|
||||
} catch {
|
||||
refreshError = error.localizedDescription
|
||||
showError = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user