mirror of
https://github.com/yattee/yattee.git
synced 2026-10-24 05:32:53 +00:00
The corner layout side column puts a 12pt resize grabber strip before the panel, and every page then added the standard 16pt horizontal padding, so content sat ~28pt from the left edge but 16pt from the right. Add a PanelHorizontalInsets environment value with a panelHorizontalPadding() modifier that the info, comments, related and chapters pages use instead of .padding(.horizontal). The side column trims the leading inset by the grabber width so content is 16pt from the column's outer edge on both sides; other hosts keep the defaults. Queue and tracks are List-backed and get the same leading delta as a scroll content margin. The page bar follows the same insets so the first pill lines up with the content.
98 lines
4.2 KiB
Swift
98 lines
4.2 KiB
Swift
//
|
|
// TracksPanelPage.swift
|
|
// Yattee
|
|
//
|
|
// Details panel page embedding the quality/audio/subtitles/rate selector.
|
|
//
|
|
|
|
import SwiftUI
|
|
|
|
#if os(iOS) || os(macOS)
|
|
|
|
struct TracksPanelPage: View {
|
|
let context: PanelPageContext
|
|
var settings: TracksPageSettings = TracksPageSettings()
|
|
var bottomInset: CGFloat = 0
|
|
|
|
private var appEnvironment: AppEnvironment? { context.appEnvironment }
|
|
private var playerService: PlayerService? { appEnvironment?.playerService }
|
|
private var playerState: PlayerState? { playerService?.state }
|
|
|
|
var body: some View {
|
|
if let playerService {
|
|
let supportedFormats = playerService.currentBackendType.supportedFormats
|
|
QualitySelectorView(
|
|
streams: playerService.availableStreams.filter { stream in
|
|
let format = StreamFormat.detect(from: stream)
|
|
// DASH is never offered for manual selection
|
|
if format == .dash {
|
|
return false
|
|
}
|
|
return supportedFormats.contains(format)
|
|
},
|
|
captions: playerService.availableCaptions,
|
|
currentStream: playerState?.currentStream,
|
|
currentAudioStream: playerState?.currentAudioStream,
|
|
currentCaption: playerService.currentCaption,
|
|
isLoading: playerService.availableStreams.isEmpty && playerState?.playbackState == .loading,
|
|
currentDownload: playerService.currentDownload,
|
|
isLoadingOnlineStreams: playerService.isLoadingOnlineStreams,
|
|
localCaptionURL: playerService.currentDownload.flatMap { download in
|
|
guard let path = download.localCaptionPath else { return nil }
|
|
return appEnvironment?.downloadManager.downloadsDirectory().appendingPathComponent(path)
|
|
},
|
|
currentRate: playerState?.rate ?? .x1,
|
|
isControlsLocked: playerState?.isControlsLocked ?? false,
|
|
isAudioMode: appEnvironment?.settingsManager.audioOnlyModeEnabled ?? false,
|
|
embeddedAudioTracks: playerService.embeddedAudioTracks,
|
|
embeddedSubtitleTracks: playerService.embeddedSubtitleTracks,
|
|
currentEmbeddedAudioTrackID: playerService.selectedEmbeddedAudioTrackID,
|
|
currentEmbeddedSubtitleTrackID: playerService.selectedEmbeddedSubtitleTrackID,
|
|
embeddedVideoTrack: playerService.primaryEmbeddedVideoTrack,
|
|
onStreamSelected: { stream, audioStream in
|
|
Task {
|
|
await playerService.selectStreamManually(stream, audioStream: audioStream)
|
|
}
|
|
},
|
|
onCaptionSelected: { caption in
|
|
playerService.loadCaption(caption)
|
|
},
|
|
onLoadOnlineStreams: {
|
|
Task {
|
|
await playerService.loadOnlineStreams()
|
|
}
|
|
},
|
|
onSwitchToOnlineStream: { stream, audioStream in
|
|
Task {
|
|
await playerService.switchToOnlineStream(stream, audioStream: audioStream)
|
|
}
|
|
},
|
|
onEmbeddedAudioTrackSelected: { trackID in
|
|
playerService.selectEmbeddedAudioTrack(trackID)
|
|
},
|
|
onEmbeddedSubtitleTrackSelected: { trackID in
|
|
playerService.selectEmbeddedSubtitleTrack(trackID)
|
|
},
|
|
onRateChanged: { rate in
|
|
playerState?.rate = rate
|
|
playerService.currentBackend?.rate = Float(rate.rawValue)
|
|
},
|
|
onLockToggled: { locked in
|
|
playerState?.isControlsLocked = locked
|
|
},
|
|
onAudioModeToggled: { enabled in
|
|
Task {
|
|
await playerService.setAudioMode(enabled)
|
|
}
|
|
},
|
|
isEmbedded: true,
|
|
visibleSections: settings
|
|
)
|
|
.safeAreaPadding(.bottom, bottomInset)
|
|
.panelListLeadingMargin()
|
|
}
|
|
}
|
|
}
|
|
|
|
#endif
|