From a657075ef92f38d515f6d7e5bdc4a77fc837c309 Mon Sep 17 00:00:00 2001 From: Laurent Date: Tue, 26 May 2026 09:33:08 +0200 Subject: [PATCH] feat: integrate HomeView as default view in ContentView Co-Authored-By: Claude Opus 4.6 --- Music/ContentView.swift | 118 ++++++++++++++++++++++++++++------------ Music/MusicApp.swift | 1 + 2 files changed, 83 insertions(+), 36 deletions(-) diff --git a/Music/ContentView.swift b/Music/ContentView.swift index aa32f61..f04988d 100644 --- a/Music/ContentView.swift +++ b/Music/ContentView.swift @@ -8,6 +8,7 @@ struct ContentView: View { var audio: AudioService var playlist: PlaylistViewModel var shazam: ShazamService + var db: DatabaseService @Binding var showNewPlaylistAlert: Bool @State private var showRenameAlert = false @State private var showEditQueryAlert = false @@ -17,6 +18,10 @@ struct ContentView: View { @State private var smartPlaylistToEdit: SmartPlaylist? @State private var scrollToPlayingTrigger = UUID() @State private var searchText = "" + @State private var showHome = true + @State private var recentTracks: [Track] = [] + @State private var totalDuration: Double = 0 + @State private var monthlyAdditions: [MonthlyCount] = [] var body: some View { VStack(spacing: 0) { @@ -24,6 +29,11 @@ struct ContentView: View { searchText: $searchText, trackCount: playlist.selectedItem != nil ? playlist.playlistTracks.count : library.trackCount, onSearch: { text in + if text.isEmpty { + showHome = true + } else { + showHome = false + } library.search(text) if playlist.selectedPlaylist != nil { playlist.search(text) @@ -52,6 +62,7 @@ struct ContentView: View { Button(action: { playlist.deselectPlaylist() searchText = "" + showHome = true }) { HStack(spacing: 2) { Image(systemName: "chevron.left") @@ -75,43 +86,60 @@ struct ContentView: View { .frame(maxWidth: .infinity, alignment: .leading) } - TrackTableView( - tracks: playlist.selectedItem != nil ? playlist.playlistTracks : library.tracks, - playingTrackId: player.currentTrack?.id, - sortColumn: library.sortColumn, - sortAscending: library.sortAscending, - onSort: { column in - if playlist.selectedItem == nil { - library.sort(by: column) + if showHome && playlist.selectedItem == nil && searchText.isEmpty { + HomeView( + recentTracks: recentTracks, + trackCount: library.trackCount, + totalDuration: totalDuration, + monthlyAdditions: monthlyAdditions, + onTrackDoubleClick: { track in + player.setQueue(recentTracks) + player.play(track) + }, + onShowAll: { + showHome = false } - }, - onDoubleClick: { track in - let trackList = playlist.selectedItem != nil ? playlist.playlistTracks : library.tracks - player.setQueue(trackList) - player.play(track) - }, - onPlayPause: { audio.togglePlayPause() }, - playlists: playlist.playlists, - lastUsedPlaylistName: playlist.lastUsedPlaylistName, - selectedPlaylist: playlist.selectedPlaylist, - onAddToPlaylist: { track, targetPlaylist in - try? playlist.addTrack(track, to: targetPlaylist) - }, - onAddToLastPlaylist: { track in - try? playlist.addTrackToLastUsedPlaylist(track) - }, - onRemoveFromPlaylist: playlist.selectedPlaylist != nil ? { track in - if let selected = playlist.selectedPlaylist { - try? playlist.removeTrack(track, from: selected) - } - } : nil, - onReorder: playlist.selectedPlaylist != nil ? { from, to in - if let selected = playlist.selectedPlaylist { - try? playlist.moveTrack(in: selected, from: from, to: to) - } - } : nil, - scrollToPlayingTrigger: scrollToPlayingTrigger - ) + ) + .onAppear { loadHomeData() } + } else { + TrackTableView( + tracks: playlist.selectedItem != nil ? playlist.playlistTracks : library.tracks, + playingTrackId: player.currentTrack?.id, + sortColumn: library.sortColumn, + sortAscending: library.sortAscending, + onSort: { column in + if playlist.selectedItem == nil { + library.sort(by: column) + } + }, + onDoubleClick: { track in + let trackList = playlist.selectedItem != nil ? playlist.playlistTracks : library.tracks + player.setQueue(trackList) + player.play(track) + }, + onPlayPause: { audio.togglePlayPause() }, + playlists: playlist.playlists, + lastUsedPlaylistName: playlist.lastUsedPlaylistName, + selectedPlaylist: playlist.selectedPlaylist, + onAddToPlaylist: { track, targetPlaylist in + try? playlist.addTrack(track, to: targetPlaylist) + }, + onAddToLastPlaylist: { track in + try? playlist.addTrackToLastUsedPlaylist(track) + }, + onRemoveFromPlaylist: playlist.selectedPlaylist != nil ? { track in + if let selected = playlist.selectedPlaylist { + try? playlist.removeTrack(track, from: selected) + } + } : nil, + onReorder: playlist.selectedPlaylist != nil ? { from, to in + if let selected = playlist.selectedPlaylist { + try? playlist.moveTrack(in: selected, from: from, to: to) + } + } : nil, + scrollToPlayingTrigger: scrollToPlayingTrigger + ) + } PlaylistBarView( playlists: playlist.allPlaylists, @@ -126,6 +154,7 @@ struct ContentView: View { onDeselect: { playlist.deselectPlaylist() searchText = "" + showHome = true }, onRename: { item in itemToRename = item @@ -148,6 +177,14 @@ struct ContentView: View { playerControls } + .onKeyPress(.leftArrow) { + player.previous() + return .handled + } + .onKeyPress(.rightArrow) { + player.next() + return .handled + } .onDrop(of: [.fileURL], isTargeted: nil) { providers in handleDrop(providers) return true @@ -155,6 +192,9 @@ struct ContentView: View { .onChange(of: audio.currentTime) { _, _ in player.checkHalfway() } + .onChange(of: library.trackCount) { _, _ in + if showHome { loadHomeData() } + } .alert("New Playlist", isPresented: $showNewPlaylistAlert) { TextField("Playlist name", text: $playlistNameInput) Button("Cancel", role: .cancel) { playlistNameInput = "" } @@ -241,6 +281,12 @@ struct ContentView: View { ) } + private func loadHomeData() { + recentTracks = (try? db.fetchRecentlyAdded(limit: 50)) ?? [] + totalDuration = (try? db.totalDuration()) ?? 0 + monthlyAdditions = (try? db.fetchMonthlyAdditions(months: 12)) ?? [] + } + private func handleDrop(_ providers: [NSItemProvider]) { for provider in providers { provider.loadItem(forTypeIdentifier: "public.file-url") { data, _ in diff --git a/Music/MusicApp.swift b/Music/MusicApp.swift index 587fd16..78afca5 100644 --- a/Music/MusicApp.swift +++ b/Music/MusicApp.swift @@ -27,6 +27,7 @@ struct MusicApp: App { audio: audioService, playlist: playlist, shazam: shazamService, + db: db, showNewPlaylistAlert: $showNewPlaylistAlert ) } else if let error = initError {