Wire Play button in MovieDetailView

This commit is contained in:
Brendan Szymanski 2026-06-24 00:28:46 -04:00
parent cf16bb3c19
commit 4ff210cdde
4 changed files with 60 additions and 6 deletions

View file

@ -137,7 +137,7 @@ struct ContentView: View {
}
.navigationTitle(page.description)
case .movieDetail(let item):
MovieDetailView(for: item)
MovieDetailView(for: item, navigation: $stack)
.topToolbar {
ToolbarView()
}

View file

@ -30,6 +30,7 @@ struct EpisodeList: View {
var seasonId: String
var client: JellyfinClient
var userId: String
@Binding var navigation: NavigationStack<Page>
@State private var episodes: [BaseItemDto] = []
var view: Body {
@ -37,7 +38,8 @@ struct EpisodeList: View {
ForEach(episodes) { episode in
EpisodeRow(
episode: episode,
client: client
client: client,
navigation: $navigation
)
}
}
@ -62,10 +64,18 @@ struct EpisodeRow: View {
var episode: BaseItemDto
var client: JellyfinClient
@Binding var navigation: NavigationStack<Page>
@Injected(\.imageService) var imageService
@Injected(\.viewUpdateScheduler) var viewUpdateScheduler
@Injected(\.userId) var userId
@State private var imageData: Data?
init(episode: BaseItemDto, client: JellyfinClient, navigation: Binding<NavigationStack<Page>>) {
self.episode = episode
self.client = client
self._navigation = navigation
}
var view: Body {
HStack {
if let data = imageData {
@ -92,7 +102,27 @@ struct EpisodeRow: View {
}
.hexpand(true)
Button(icon: .default(icon: .mediaPlaybackStart)) {
Task {
guard let itemId = episode.id else { return }
guard let info = try? await client.getPlaybackInfo(
itemId: itemId, userId: userId
) else { return }
guard let mediaSource = info.mediaSources?.first,
let playSessionId = info.playSessionId else { return }
guard let streamURL = await client.streamURL(
itemId: itemId,
mediaSourceId: mediaSource.id ?? "",
playSessionId: playSessionId
) else { return }
let state = PlayerState(
itemId: itemId,
mediaSourceId: mediaSource.id ?? "",
playSessionId: playSessionId,
streamURL: streamURL,
serverBase: await client.serverURL.absoluteString
)
navigation.push(.player(state))
}
}
.flat()
}

View file

@ -27,6 +27,7 @@ import LuminateDI
public struct MovieDetailView: View {
var item: BaseItemDto
@Binding var navigation: NavigationStack<Page>
@Injected(\.client) private var client
@Injected(\.userId) private var userId
@Injected(\.imageService) private var imageService
@ -35,8 +36,9 @@ public struct MovieDetailView: View {
@State private var similarItems: [BaseItemDto] = []
@State private var backdropData: Data?
public init(for item: BaseItemDto) {
public init(for item: BaseItemDto, navigation: Binding<NavigationStack<Page>>) {
self.item = item
self._navigation = navigation
_isFavorite = .init(wrappedValue: item.userData?.value1.isFavorite ?? false)
_isPlayed = .init(wrappedValue: item.userData?.value1.played ?? false)
}
@ -71,7 +73,27 @@ public struct MovieDetailView: View {
.halign(.start)
HStack {
Button("Play", icon: .default(icon: .mediaPlaybackStart)) {
Task {
guard let itemId = item.id else { return }
guard let info = try? await client.getPlaybackInfo(
itemId: itemId, userId: userId
) else { return }
guard let mediaSource = info.mediaSources?.first,
let playSessionId = info.playSessionId else { return }
guard let streamURL = await client.streamURL(
itemId: itemId,
mediaSourceId: mediaSource.id ?? "",
playSessionId: playSessionId
) else { return }
let state = PlayerState(
itemId: itemId,
mediaSourceId: mediaSource.id ?? "",
playSessionId: playSessionId,
streamURL: streamURL,
serverBase: await client.serverURL.absoluteString
)
navigation.push(.player(state))
}
}
.suggested()
Button(icon: .default(icon: .bookmarkNew)) {

View file

@ -29,6 +29,7 @@ struct TVShowView: View {
var item: BaseItemDto
var client: JellyfinClient
var userId: String
@Binding var navigation: NavigationStack<Page>
@Injected(\.imageService) var imageService
@State private var seasons: [BaseItemDto] = []
@State private var selectedSeasonId: String?
@ -89,7 +90,8 @@ struct TVShowView: View {
seriesId: item.id ?? "",
seasonId: seasonId,
client: client,
userId: userId
userId: userId,
navigation: $navigation
)
}
}