|
|
|
@ -9,9 +9,11 @@ struct ContentView: View { |
|
|
|
var shazam: ShazamService |
|
|
|
var shazam: ShazamService |
|
|
|
var db: DatabaseService |
|
|
|
var db: DatabaseService |
|
|
|
@Binding var showNewPlaylistAlert: Bool |
|
|
|
@Binding var showNewPlaylistAlert: Bool |
|
|
|
|
|
|
|
@Binding var showSmartPlaylistBuilder: Bool |
|
|
|
var networkStatus: NetworkStatus? |
|
|
|
var networkStatus: NetworkStatus? |
|
|
|
@State private var showRenameAlert = false |
|
|
|
@State private var showRenameAlert = false |
|
|
|
@State private var showEditQueryAlert = false |
|
|
|
@State private var showEditQueryAlert = false |
|
|
|
|
|
|
|
@State private var smartPlaylistBuilderEditing: SmartPlaylist? |
|
|
|
@State private var playlistNameInput = "" |
|
|
|
@State private var playlistNameInput = "" |
|
|
|
@State private var editQueryInput = "" |
|
|
|
@State private var editQueryInput = "" |
|
|
|
@State private var itemToRename: (any PlaylistRepresentable)? |
|
|
|
@State private var itemToRename: (any PlaylistRepresentable)? |
|
|
|
@ -24,8 +26,11 @@ struct ContentView: View { |
|
|
|
@State private var totalDuration: Double = 0 |
|
|
|
@State private var totalDuration: Double = 0 |
|
|
|
@State private var monthlyAdditions: [MonthlyCount] = [] |
|
|
|
@State private var monthlyAdditions: [MonthlyCount] = [] |
|
|
|
|
|
|
|
|
|
|
|
var body: some View { |
|
|
|
/// The remote/streaming connection status banner. Extracted from `body` so the |
|
|
|
VStack(spacing: 0) { |
|
|
|
/// type-checker doesn't have to solve the whole (very large) view in one expression |
|
|
|
|
|
|
|
/// — without this, a clean build fails with "unable to type-check in reasonable time". |
|
|
|
|
|
|
|
@ViewBuilder |
|
|
|
|
|
|
|
private var networkBanner: some View { |
|
|
|
if let status = networkStatus { |
|
|
|
if let status = networkStatus { |
|
|
|
switch status.mode { |
|
|
|
switch status.mode { |
|
|
|
case .remote(let hostName): |
|
|
|
case .remote(let hostName): |
|
|
|
@ -70,6 +75,11 @@ struct ContentView: View { |
|
|
|
.background(Color.purple.opacity(0.08)) |
|
|
|
.background(Color.purple.opacity(0.08)) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var body: some View { |
|
|
|
|
|
|
|
VStack(spacing: 0) { |
|
|
|
|
|
|
|
networkBanner |
|
|
|
|
|
|
|
|
|
|
|
SearchBarView( |
|
|
|
SearchBarView( |
|
|
|
searchText: $searchText, |
|
|
|
searchText: $searchText, |
|
|
|
@ -239,6 +249,9 @@ struct ContentView: View { |
|
|
|
smartPlaylistToEdit = smart |
|
|
|
smartPlaylistToEdit = smart |
|
|
|
editQueryInput = smart.searchQuery |
|
|
|
editQueryInput = smart.searchQuery |
|
|
|
showEditQueryAlert = true |
|
|
|
showEditQueryAlert = true |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
onEditConditions: { smart in |
|
|
|
|
|
|
|
smartPlaylistBuilderEditing = smart |
|
|
|
} |
|
|
|
} |
|
|
|
) |
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
@ -327,6 +340,29 @@ struct ContentView: View { |
|
|
|
Text(error) |
|
|
|
Text(error) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
.sheet(isPresented: $showSmartPlaylistBuilder) { |
|
|
|
|
|
|
|
SmartPlaylistBuilderSheet( |
|
|
|
|
|
|
|
editingPlaylist: nil, |
|
|
|
|
|
|
|
onSave: { name, conditions in |
|
|
|
|
|
|
|
try? playlist.createSmartPlaylist(name: name, conditions: conditions) |
|
|
|
|
|
|
|
showSmartPlaylistBuilder = false |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
onCancel: { showSmartPlaylistBuilder = false } |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
.sheet(item: $smartPlaylistBuilderEditing) { smart in |
|
|
|
|
|
|
|
SmartPlaylistBuilderSheet( |
|
|
|
|
|
|
|
editingPlaylist: smart, |
|
|
|
|
|
|
|
onSave: { name, conditions in |
|
|
|
|
|
|
|
if name != smart.name { |
|
|
|
|
|
|
|
try? playlist.renameSmartPlaylist(smart, to: name) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
try? playlist.updateSmartPlaylistConditions(smart, to: conditions) |
|
|
|
|
|
|
|
smartPlaylistBuilderEditing = nil |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
onCancel: { smartPlaylistBuilderEditing = nil } |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private var playerControls: some View { |
|
|
|
private var playerControls: some View { |
|
|
|
|