import Adwaita import LuminateCore struct PlayerView: View { var item: Components.Schemas.BaseItemDto var client: JellyfinClient var userId: String var mediaSourceId: String var playSessionId: String 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 var onClose: () -> Void 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() } ) } } .onAppear { startPlayback() } .onDisappear { stopPlayback() } } private func startPlayback() { Task { try? await client.reportPlaybackStart( info: .init( ItemId: item.Id, PlaySessionId: playSessionId, MediaSourceId: mediaSourceId ) ) } } private func stopPlayback() { Task { try? await client.reportPlaybackStopped( info: .init( ItemId: item.Id, PlaySessionId: playSessionId, MediaSourceId: mediaSourceId, PositionTicks: Int64(position * 10_000_000) ) ) } } }