mirror of
https://github.com/yattee/yattee.git
synced 2026-10-27 15:07:18 +00:00
Phase 5 of the player panels redesign: - Per-page element toggles now rendered and editable for every page: comments (author avatars), related (thumbnails), chapters (thumbnails), queue (previously played section), tracks (video/audio/subtitles/speed sections) - Page bar labels toggle (icons-only bar shows the selected page's name) - Layout mode schematic diagram in the details panel settings - NEW badge machinery for future page types (versionAdded on PanelPageType) - Typed per-page settings accessors on PanelPageConfiguration and VM update helpers for each page kind - Unit tests for per-page settings round-trip and accessor fallbacks The standalone quality selector sheet is unaffected: section gating defaults to everything visible and only the embedded tracks page passes preset settings through.
69 lines
2.3 KiB
Swift
69 lines
2.3 KiB
Swift
//
|
|
// RelatedPanelPage.swift
|
|
// Yattee
|
|
//
|
|
// Details panel page listing videos related to the current one.
|
|
//
|
|
|
|
import SwiftUI
|
|
|
|
#if os(iOS) || os(macOS)
|
|
|
|
struct RelatedPanelPage: View {
|
|
let context: PanelPageContext
|
|
var settings: RelatedPageSettings = RelatedPageSettings()
|
|
var scrollConfig: PanelScrollConfig = PanelScrollConfig()
|
|
|
|
private var relatedVideos: [Video] { context.video.relatedVideos ?? [] }
|
|
|
|
var body: some View {
|
|
PanelPageScrollView(config: scrollConfig) {
|
|
if relatedVideos.isEmpty {
|
|
emptyState
|
|
} else {
|
|
LazyVStack(spacing: 12) {
|
|
ForEach(Array(relatedVideos.enumerated()), id: \.element.id) { index, relatedVideo in
|
|
VideoRowView(
|
|
video: relatedVideo,
|
|
style: .regular,
|
|
showThumbnail: settings.effectiveShowThumbnails
|
|
)
|
|
.tappableVideo(
|
|
relatedVideo,
|
|
queueSource: .manual,
|
|
sourceLabel: String(localized: "videoInfo.section.relatedVideos"),
|
|
videoList: relatedVideos,
|
|
videoIndex: index,
|
|
loadMoreVideos: nil
|
|
)
|
|
|
|
if index < relatedVideos.count - 1 {
|
|
Divider()
|
|
.padding(.leading, settings.effectiveShowThumbnails
|
|
? VideoRowStyle.regular.thumbnailWidth + 12
|
|
: 0)
|
|
}
|
|
}
|
|
}
|
|
.padding(.horizontal)
|
|
.padding(.top, 8)
|
|
}
|
|
}
|
|
}
|
|
|
|
private var emptyState: some View {
|
|
VStack(spacing: 8) {
|
|
Image(systemName: "rectangle.stack.badge.play")
|
|
.font(.title2)
|
|
.foregroundStyle(.secondary)
|
|
Text(String(localized: "videoInfo.section.relatedVideos"))
|
|
.font(.subheadline)
|
|
.foregroundStyle(.secondary)
|
|
}
|
|
.frame(maxWidth: .infinity)
|
|
.padding(.vertical, 32)
|
|
}
|
|
}
|
|
|
|
#endif
|