Wire FAAB schedule-events into master-api and admin IPTV settings, add Android TV Events UI, fix mobile ClearKey/stream playback (DASH + bump 1.0.23), and scaffold the Apple TV (VMCTV) client with docs/scripts.
75 lines
3.1 KiB
Swift
75 lines
3.1 KiB
Swift
import SwiftUI
|
|
|
|
struct WatchlistView: View {
|
|
@EnvironmentObject private var app: AppModel
|
|
@State private var loading = false
|
|
|
|
private let cols = [
|
|
GridItem(.adaptive(minimum: 168, maximum: 200), spacing: 24)
|
|
]
|
|
|
|
var body: some View {
|
|
VStack(alignment: .leading, spacing: 20) {
|
|
Text("Watchlist")
|
|
.font(TvFonts.title)
|
|
.foregroundStyle(TvColors.text)
|
|
.padding(.horizontal, 48)
|
|
.padding(.top, 12)
|
|
|
|
if loading && app.favorites.mediaItems.isEmpty {
|
|
ProgressView().tint(.white).frame(maxWidth: .infinity, maxHeight: .infinity)
|
|
} else if app.favorites.mediaItems.isEmpty {
|
|
VStack(spacing: 16) {
|
|
Image(systemName: "bookmark")
|
|
.font(.system(size: 56))
|
|
.foregroundStyle(TvColors.textDim)
|
|
Text("Nog geen favorieten")
|
|
.font(TvFonts.headline)
|
|
.foregroundStyle(TvColors.textDim)
|
|
Text("Voeg films of series toe vanaf de detailpagina.")
|
|
.font(TvFonts.body)
|
|
.foregroundStyle(TvColors.textDim.opacity(0.8))
|
|
}
|
|
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
|
} else {
|
|
ScrollView {
|
|
LazyVGrid(columns: cols, spacing: 28) {
|
|
ForEach(app.favorites.mediaItems) { item in
|
|
NavigationLink(value: item) {
|
|
PosterCard(item: item, width: 168)
|
|
}
|
|
.buttonStyle(FocusableCardStyle())
|
|
.contextMenu {
|
|
Button("Verwijderen uit watchlist", role: .destructive) {
|
|
Task {
|
|
_ = await app.favorites.toggle(
|
|
type: item.type,
|
|
id: item.id,
|
|
title: item.title,
|
|
year: item.year,
|
|
posterUrl: item.posterUrl,
|
|
backdropUrl: item.backdropUrl,
|
|
logoUrl: item.logoUrl,
|
|
api: app.api
|
|
)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
.padding(.horizontal, 48)
|
|
.padding(.bottom, 48)
|
|
}
|
|
.focusSection()
|
|
}
|
|
}
|
|
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
|
.background(TvColors.bg.ignoresSafeArea())
|
|
.navigationDestination(for: MediaItem.self) { MediaRouter(item: $0) }
|
|
.task {
|
|
loading = true
|
|
await app.favorites.refresh(using: app.api)
|
|
loading = false
|
|
}
|
|
}
|
|
}
|