feat: integrate HomeView as default view in ContentView

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
feat/music-streaming
Laurent 1 month ago
parent 09be0460d4
commit a657075ef9
  1. 118
      Music/ContentView.swift
  2. 1
      Music/MusicApp.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

@ -27,6 +27,7 @@ struct MusicApp: App {
audio: audioService,
playlist: playlist,
shazam: shazamService,
db: db,
showNewPlaylistAlert: $showNewPlaylistAlert
)
} else if let error = initError {

Loading…
Cancel
Save