Rework tvOS player controls and settings sheet

Replace the tvOS bottom action bar with Settings / Info / Comments /
Next / Close. Settings reuses QualitySelectorView (video, audio,
subtitles, speed); Comments opens TVDetailsPanel directly on the
comments tab; Close stops playback and dismisses.

Debug button is hidden by default and can be re-enabled via a new
tvOS-only Advanced Settings > Developer toggle.

Present the settings sheet as a fullScreenCover with a centered
material card, fix the "Normal" hyphenation, and restyle row selection
throughout the quality selector on tvOS: per-row rounded backgrounds
with focus tint + stroke, vertical spacing instead of dividers, and a
focusable speed-rate menu.
This commit is contained in:
Arkadiusz Fal
2026-04-14 17:34:20 +02:00
parent 4f9285686a
commit c7942ef555
11 changed files with 443 additions and 169 deletions

View File

@@ -7,6 +7,13 @@
import SwiftUI
#if os(tvOS)
/// Padding used inside selection row buttons so the tvOS focus background
/// fills the whole row.
private let tvRowVerticalPadding: CGFloat = 14
private let tvRowHorizontalPadding: CGFloat = 20
#endif
// MARK: - Adaptive Stream Row
/// Row view for HLS/DASH adaptive streams.
@@ -61,9 +68,18 @@ struct AdaptiveStreamRowView: View {
.foregroundStyle(.tint)
}
}
#if os(tvOS)
.padding(.vertical, tvRowVerticalPadding)
.padding(.horizontal, tvRowHorizontalPadding)
.frame(maxWidth: .infinity, alignment: .leading)
#endif
.contentShape(Rectangle())
}
#if os(tvOS)
.buttonStyle(TVSettingsRowButtonStyle())
#else
.buttonStyle(.plain)
#endif
}
}
@@ -97,9 +113,18 @@ struct VideoStreamRowView: View {
}
}
.frame(minHeight: showAdvancedDetails ? nil : 36)
#if os(tvOS)
.padding(.vertical, tvRowVerticalPadding)
.padding(.horizontal, tvRowHorizontalPadding)
.frame(maxWidth: .infinity, alignment: .leading)
#endif
.contentShape(Rectangle())
}
#if os(tvOS)
.buttonStyle(TVSettingsRowButtonStyle())
#else
.buttonStyle(.plain)
#endif
}
@ViewBuilder
@@ -251,9 +276,18 @@ struct AudioStreamRowView: View {
}
}
.frame(minHeight: showAdvancedDetails ? nil : 36)
#if os(tvOS)
.padding(.vertical, tvRowVerticalPadding)
.padding(.horizontal, tvRowHorizontalPadding)
.frame(maxWidth: .infinity, alignment: .leading)
#endif
.contentShape(Rectangle())
}
#if os(tvOS)
.buttonStyle(TVSettingsRowButtonStyle())
#else
.buttonStyle(.plain)
#endif
}
@ViewBuilder
@@ -341,9 +375,18 @@ struct CaptionRowView: View {
}
}
.frame(minHeight: 36)
#if os(tvOS)
.padding(.vertical, tvRowVerticalPadding)
.padding(.horizontal, tvRowHorizontalPadding)
.frame(maxWidth: .infinity, alignment: .leading)
#endif
.contentShape(Rectangle())
}
#if os(tvOS)
.buttonStyle(TVSettingsRowButtonStyle())
#else
.buttonStyle(.plain)
#endif
}
@ViewBuilder