import Adwaita import Foundation import LuminateCore public struct PlayerView: View { public var item: Components.Schemas.BaseItemDto public var client: JellyfinClient public var userId: String public var mediaSourceId: String public var playSessionId: String public var streamURL: URL @State private var isPlaying = true @State private var position: Double = 0 @State private var duration: Double = 0 @State private var showControls = true public var onClose: () -> Void public init( item: Components.Schemas.BaseItemDto, client: JellyfinClient, userId: String, mediaSourceId: String, playSessionId: String, streamURL: URL, onClose: @escaping () -> Void ) { self.item = item self.client = client self.userId = userId self.mediaSourceId = mediaSourceId self.playSessionId = playSessionId self.streamURL = streamURL self.onClose = onClose } public var view: Body { VStack { VideoPlayerWidget( url: streamURL.absoluteString, isPlaying: $isPlaying, position: $position, duration: $duration ) .hexpand(true) .vexpand(true) if showControls { PlayerControls( isPlaying: $isPlaying, position: $position, duration: $duration, onTogglePlay: { isPlaying.toggle() }, onSeekBack: { position = max(0, position - 10) }, onSeekForward: { position = min(duration, position + 10) }, onFullscreen: {}, onClose: { stopPlayback() onClose() } ) } } } private func startPlayback() { Task { try? await client.reportPlaybackStart( info: .init( itemId: item.id, mediaSourceId: mediaSourceId, playSessionId: playSessionId ) ) } } private func stopPlayback() { Task { try? await client.reportPlaybackStopped( info: .init( itemId: item.id, mediaSourceId: mediaSourceId, positionTicks: Int64(position * 10_000_000), playSessionId: playSessionId ) ) } } }