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.
66 lines
2.1 KiB
Swift
66 lines
2.1 KiB
Swift
//
|
|
// ChaptersPanelPage.swift
|
|
// Yattee
|
|
//
|
|
// Details panel page listing video chapters; tapping seeks.
|
|
//
|
|
|
|
import SwiftUI
|
|
|
|
#if os(iOS) || os(macOS)
|
|
|
|
struct ChaptersPanelPage: View {
|
|
let context: PanelPageContext
|
|
var settings: ChaptersPageSettings = ChaptersPageSettings()
|
|
var scrollConfig: PanelScrollConfig = PanelScrollConfig()
|
|
|
|
private var appEnvironment: AppEnvironment? { context.appEnvironment }
|
|
private var playerService: PlayerService? { appEnvironment?.playerService }
|
|
private var playerState: PlayerState? { playerService?.state }
|
|
|
|
private var chapters: [VideoChapter] { playerState?.chapters ?? [] }
|
|
private var storyboard: Storyboard? { playerState?.preferredStoryboard }
|
|
|
|
var body: some View {
|
|
PanelPageScrollView(config: scrollConfig) {
|
|
LazyVStack(spacing: 0) {
|
|
ForEach(chapters) { chapter in
|
|
ChapterRow(
|
|
chapter: chapter,
|
|
isActive: isChapterActive(chapter),
|
|
storyboard: storyboard,
|
|
showThumbnail: settings.effectiveShowThumbnails,
|
|
onTap: {
|
|
Task {
|
|
await playerService?.seek(to: chapter.startTime)
|
|
}
|
|
}
|
|
)
|
|
}
|
|
}
|
|
.panelHorizontalPadding()
|
|
.padding(.top, 8)
|
|
}
|
|
.task(id: context.video.id) {
|
|
if settings.effectiveShowThumbnails {
|
|
await preloadChapterSheets()
|
|
}
|
|
}
|
|
}
|
|
|
|
private func isChapterActive(_ chapter: VideoChapter) -> Bool {
|
|
// Observes only chapter transitions, not per-tick currentTime updates.
|
|
playerState?.activeChapterID == chapter.id
|
|
}
|
|
|
|
private func preloadChapterSheets() async {
|
|
guard let storyboard else { return }
|
|
let service = StoryboardService.shared
|
|
for chapter in chapters {
|
|
await service.loadSheet(for: chapter.startTime, from: storyboard)
|
|
}
|
|
}
|
|
}
|
|
|
|
#endif
|