@ -60,90 +60,93 @@ struct ContentView: View {
. padding ( . vertical , 4 )
. padding ( . vertical , 4 )
}
}
if showHome || playlist . selectedItem != nil {
VStack ( spacing : 0 ) {
HStack ( spacing : 4 ) {
if showHome || playlist . selectedItem != nil {
Button ( action : {
HStack ( spacing : 4 ) {
playlist . deselectPlaylist ( )
Button ( action : {
searchText = " "
playlist . deselectPlaylist ( )
showHome = false
searchText = " "
} ) {
showHome = false
HStack ( spacing : 2 ) {
} ) {
Image ( systemName : " chevron.left " )
HStack ( spacing : 2 ) {
. font ( . system ( size : 10 ) )
Image ( systemName : " chevron.left " )
Text ( " Library " )
. font ( . system ( size : 10 ) )
. font ( . system ( size : 12 ) )
Text ( " Library " )
. font ( . system ( size : 12 ) )
}
. foregroundStyle ( . secondary )
}
}
. foregroundStyle ( . secondary )
. buttonStyle ( . plain )
}
. buttonStyle ( . plain )
Text ( " / " )
Text ( " / " )
. font ( . system ( size : 12 ) )
. font ( . system ( size : 12 ) )
. foregroundStyle ( . quaternary )
. foregroundStyle ( . quaternary )
Text ( showHome ? " Home " : ( playlist . selectedItem ? . name ? ? " " ) )
Text ( showHome ? " Home " : ( playlist . selectedItem ? . name ? ? " " ) )
. font ( . system ( size : 12 , weight : . medium ) )
. font ( . system ( size : 12 , weight : . medium ) )
}
. padding ( . horizontal , 12 )
. padding ( . vertical , 4 )
. frame ( maxWidth : . infinity , alignment : . leading )
}
}
. padding ( . horizontal , 12 )
. padding ( . vertical , 4 )
. frame ( maxWidth : . infinity , alignment : . leading )
}
if showHome && playlist . selectedItem = = nil {
if showHome && playlist . selectedItem = = nil {
HomeView (
HomeView (
recentTracks : recentTracks ,
recentTracks : recentTracks ,
trackCount : library . trackCount ,
trackCount : library . trackCount ,
totalDuration : totalDuration ,
totalDuration : totalDuration ,
monthlyAdditions : monthlyAdditions ,
monthlyAdditions : monthlyAdditions ,
onTrackDoubleClick : { track in
onTrackDoubleClick : { track in
player . setQueue ( recentTracks )
player . setQueue ( recentTracks )
player . play ( track )
player . play ( track )
} ,
} ,
onShowAll : {
onShowAll : {
showHome = false
showHome = false
}
)
. onAppear { loadHomeData ( ) }
} else {
TrackTableView (
tracks : playlist . selectedItem != nil ? playlist . playlistTracks : library . tracks ,
playingTrackId : player . currentTrack ? . id ,
sortColumn : playlist . selectedSmartPlaylist != nil ? playlist . sortColumn : library . sortColumn ,
sortAscending : playlist . selectedSmartPlaylist != nil ? playlist . sortAscending : library . sortAscending ,
onSort : { column in
if playlist . selectedSmartPlaylist != nil {
playlist . sort ( by : column )
} else if playlist . selectedItem = = nil {
library . sort ( by : column )
}
}
} ,
)
onDoubleClick : { track in
. onAppear { loadHomeData ( ) }
let trackList = playlist . selectedItem != nil ? playlist . playlistTracks : library . tracks
} else {
player . setQueue ( trackList )
TrackTableView (
player . play ( track )
tracks : playlist . selectedItem != nil ? playlist . playlistTracks : library . tracks ,
} ,
playingTrackId : player . currentTrack ? . id ,
playlists : playlist . playlists ,
sortColumn : playlist . selectedSmartPlaylist != nil ? playlist . sortColumn : library . sortColumn ,
lastUsedPlaylistName : playlist . lastUsedPlaylistName ,
sortAscending : playlist . selectedSmartPlaylist != nil ? playlist . sortAscending : library . sortAscending ,
selectedPlaylist : playlist . selectedPlaylist ,
onSort : { column in
onAddToPlaylist : { track , targetPlaylist in
if playlist . selectedSmartPlaylist != nil {
try ? playlist . addTrack ( track , to : targetPlaylist )
playlist . sort ( by : column )
} ,
} else if playlist . selectedItem = = nil {
onAddToLastPlaylist : { track in
library . sort ( by : column )
try ? playlist . addTrackToLastUsedPlaylist ( track )
}
} ,
} ,
onRemoveFromPlaylist : playlist . selectedPlaylist != nil ? { track in
onDoubleClick : { track in
if let selected = playlist . selectedPlaylist {
let trackList = playlist . selectedItem != nil ? playlist . playlistTracks : library . tracks
try ? playlist . removeTrack ( track , from : selected )
player . setQueue ( trackList )
}
player . play ( track )
} : nil ,
} ,
onReorder : playlist . selectedPlaylist != nil ? { from , to in
playlists : playlist . playlists ,
if let selected = playlist . selectedPlaylist {
lastUsedPlaylistName : playlist . lastUsedPlaylistName ,
try ? playlist . moveTrack ( in : selected , from : from , to : to )
selectedPlaylist : playlist . selectedPlaylist ,
}
onAddToPlaylist : { track , targetPlaylist in
} : nil ,
try ? playlist . addTrack ( track , to : targetPlaylist )
scrollToPlayingTrigger : scrollToPlayingTrigger
} ,
)
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
)
}
}
}
. frame ( maxHeight : . infinity )
PlaylistBarView (
PlaylistBarView (
playlists : playlist . allPlaylists ,
playlists : playlist . allPlaylists ,
@ -280,7 +283,17 @@ struct ContentView: View {
duration : audio . duration ,
duration : audio . duration ,
volume : audio . volume ,
volume : audio . volume ,
isShuffled : player . isShuffled ,
isShuffled : player . isShuffled ,
onPlayPause : { audio . togglePlayPause ( ) } ,
onPlayPause : {
if player . currentTrack = = nil {
let trackList = playlist . selectedItem != nil ? playlist . playlistTracks : library . tracks
if let first = trackList . first {
player . setQueue ( trackList )
player . play ( first )
}
} else {
audio . togglePlayPause ( )
}
} ,
onNext : { player . next ( ) } ,
onNext : { player . next ( ) } ,
onPrevious : { player . previous ( ) } ,
onPrevious : { player . previous ( ) } ,
onSeek : { audio . seek ( to : $0 ) } ,
onSeek : { audio . seek ( to : $0 ) } ,
@ -294,7 +307,7 @@ struct ContentView: View {
}
}
private func installKeyboardMonitor ( ) {
private func installKeyboardMonitor ( ) {
keyMonitor = NSEvent . addLocalMonitorForEvents ( matching : . keyDown ) { [ audio , player ] event in
keyMonitor = NSEvent . addLocalMonitorForEvents ( matching : . keyDown ) { [ audio , player , library , playlist ] event in
guard event . modifierFlags . intersection ( [ . command , . control , . option , . shift ] ) . isEmpty else {
guard event . modifierFlags . intersection ( [ . command , . control , . option , . shift ] ) . isEmpty else {
return event
return event
}
}
@ -304,7 +317,15 @@ struct ContentView: View {
}
}
switch event . keyCode {
switch event . keyCode {
case 49 : // s p a c e
case 49 : // s p a c e
audio . togglePlayPause ( )
if player . currentTrack = = nil {
let trackList = playlist . selectedItem != nil ? playlist . playlistTracks : library . tracks
if let first = trackList . first {
player . setQueue ( trackList )
player . play ( first )
}
} else {
audio . togglePlayPause ( )
}
return nil
return nil
case 123 : // l e f t a r r o w
case 123 : // l e f t a r r o w
player . previous ( )
player . previous ( )