Started working on NowPlaying mini

This commit is contained in:
2025-06-11 13:32:34 -07:00
parent ca829dde4c
commit a98bcd5b66

View File

@@ -27,6 +27,10 @@ class MainViewModel
case favorites case favorites
case settings case settings
} }
func onAddButtonTapped() {
}
} }
struct MainView: View struct MainView: View
@@ -51,6 +55,8 @@ struct MainView: View
NavigationStack { NavigationStack {
MediaListView(model: model.playlistModel) MediaListView(model: model.playlistModel)
.displayingServerSelectionToolbar(model: $model.serverSelectionViewModel) .displayingServerSelectionToolbar(model: $model.serverSelectionViewModel)
.displayingNowPlayingMiniPlayer(model: $model.nowPlayingViewModel)
.withAddButton { model.onAddButtonTapped() }
.navigationTitle(.playlist) .navigationTitle(.playlist)
} }
} }
@@ -59,6 +65,8 @@ struct MainView: View
NavigationStack { NavigationStack {
MediaListView(model: model.favoritesModel) MediaListView(model: model.favoritesModel)
.displayingServerSelectionToolbar(model: $model.serverSelectionViewModel) .displayingServerSelectionToolbar(model: $model.serverSelectionViewModel)
.displayingNowPlayingMiniPlayer(model: $model.nowPlayingViewModel)
.withAddButton { model.onAddButtonTapped() }
.navigationTitle(.favorites) .navigationTitle(.favorites)
} }
} }
@@ -69,6 +77,7 @@ struct MainView: View
} }
#if false #if false
VStack { VStack {
if showConfigurationDialog { if showConfigurationDialog {
@@ -106,6 +115,51 @@ struct MainView: View
} }
} }
struct NowPlayingMiniPlayerModifier: ViewModifier
{
@Binding var model: NowPlayingViewModel
private let height = 64.0
func body(content: Content) -> some View {
let playPauseImageName = model.isPlaying ? "pause.fill" : "play.fill"
ZStack {
content
.safeAreaPadding(.bottom, height)
VStack {
Spacer()
HStack {
VStack(alignment: .leading) {
Text(model.title)
.bold()
Text(model.subtitle)
.foregroundStyle(.secondary)
}
Spacer()
Button(action: { model.onPlayPause(model) }) { Image(systemName: playPauseImageName) }
.imageScale(.large)
.padding(12.0)
}
.padding()
.frame(height: height)
.background(
RoundedRectangle(cornerRadius: 12)
.fill(.regularMaterial)
.stroke(.ultraThinMaterial, lineWidth: 1.0)
)
.shadow(color: .black.opacity(0.15), radius: 14.0, y: 2.0)
.padding()
}
}
}
}
struct ServerSelectionToolbarModifier: ViewModifier struct ServerSelectionToolbarModifier: ViewModifier
{ {
@Binding var model: ViewModel @Binding var model: ViewModel
@@ -113,7 +167,7 @@ struct ServerSelectionToolbarModifier: ViewModifier
func body(content: Content) -> some View { func body(content: Content) -> some View {
content content
.toolbar { .toolbar {
ToolbarItemGroup(placement: .topBarTrailing) { ToolbarItemGroup(placement: .topBarLeading) {
Menu { Menu {
Section { Section {
ForEach(model.selectableServers) { server in ForEach(model.selectableServers) { server in
@@ -164,9 +218,35 @@ struct ServerSelectionToolbarModifier: ViewModifier
} }
} }
struct AddButtonToolbarModifier: ViewModifier
{
let onAdd: () -> Void
func body(content: Content) -> some View {
content
.toolbar {
ToolbarItemGroup(placement: .topBarTrailing) {
Button {
onAdd()
} label: {
Image(systemName: "plus")
}
}
}
}
}
extension View { extension View {
func displayingServerSelectionToolbar(model: Binding<ServerSelectionToolbarModifier.ViewModel>) -> some View { func displayingServerSelectionToolbar(model: Binding<ServerSelectionToolbarModifier.ViewModel>) -> some View {
modifier(ServerSelectionToolbarModifier(model: model)) modifier(ServerSelectionToolbarModifier(model: model))
} }
func displayingNowPlayingMiniPlayer(model: Binding<NowPlayingViewModel>) -> some View {
modifier(NowPlayingMiniPlayerModifier(model: model))
}
func withAddButton(onAdd: @escaping () -> Void) -> some View {
modifier(AddButtonToolbarModifier(onAdd: onAdd))
}
} }