// // LibraryView.swift // Mobile Music Assistant // // Created by Sven Hanold on 26.03.26. // 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 { Group { switch selectedTab { case .artists: ArtistsView() case .albums: AlbumsView() case .playlists: PlaylistsView() case .radio: RadiosView() } } .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() } label: { Label("Search", systemImage: "magnifyingglass") } } } .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 } } } #Preview { LibraryView() .environment(MAService()) }