mirror of
https://github.com/yattee/yattee.git
synced 2025-04-28 16:00:33 +05:30
Video details toolbar and inspector settings
This commit is contained in:
parent
7cc3cd950b
commit
041a28e7a0
@ -100,7 +100,9 @@ extension Defaults.Keys {
|
|||||||
static let chargingNonCellularProfile = Key<QualityProfile.ID>("chargingNonCellularProfile", default: chargingNonCellularProfileDefault)
|
static let chargingNonCellularProfile = Key<QualityProfile.ID>("chargingNonCellularProfile", default: chargingNonCellularProfileDefault)
|
||||||
static let forceAVPlayerForLiveStreams = Key<Bool>("forceAVPlayerForLiveStreams", default: true)
|
static let forceAVPlayerForLiveStreams = Key<Bool>("forceAVPlayerForLiveStreams", default: true)
|
||||||
|
|
||||||
static let playerSidebar = Key<PlayerSidebarSetting>("playerSidebar", default: PlayerSidebarSetting.defaultValue)
|
static let playerSidebar = Key<PlayerSidebarSetting>("playerSidebar", default: .defaultValue)
|
||||||
|
static let showInspector = Key<ShowInspectorSetting>("showInspector", default: .onlyLocal)
|
||||||
|
static let detailsToolbarPosition = Key<DetailsToolbarPositionSetting>("detailsToolbarPosition", default: .center)
|
||||||
static let playerInstanceID = Key<Instance.ID?>("playerInstance")
|
static let playerInstanceID = Key<Instance.ID?>("playerInstance")
|
||||||
|
|
||||||
#if os(iOS)
|
#if os(iOS)
|
||||||
@ -329,3 +331,19 @@ enum ThumbnailsQuality: String, CaseIterable, Defaults.Serializable {
|
|||||||
enum SystemControlsCommands: String, CaseIterable, Defaults.Serializable {
|
enum SystemControlsCommands: String, CaseIterable, Defaults.Serializable {
|
||||||
case seek, restartAndAdvanceToNext
|
case seek, restartAndAdvanceToNext
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum ShowInspectorSetting: String, Defaults.Serializable {
|
||||||
|
case always, onlyLocal
|
||||||
|
}
|
||||||
|
|
||||||
|
enum DetailsToolbarPositionSetting: String, CaseIterable, Defaults.Serializable {
|
||||||
|
case left, center, right
|
||||||
|
|
||||||
|
var needsLeftSpacer: Bool {
|
||||||
|
self == .center || self == .right
|
||||||
|
}
|
||||||
|
|
||||||
|
var needsRightSpacer: Bool {
|
||||||
|
self == .center || self == .left
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -75,7 +75,7 @@ struct InspectorView: View {
|
|||||||
Text(detail)
|
Text(detail)
|
||||||
.foregroundColor(.secondary)
|
.foregroundColor(.secondary)
|
||||||
Spacer()
|
Spacer()
|
||||||
let value = Text(value)
|
let value = Text(value).lineLimit(1)
|
||||||
if #available(iOS 15.0, macOS 12.0, *) {
|
if #available(iOS 15.0, macOS 12.0, *) {
|
||||||
value
|
value
|
||||||
#if !os(tvOS)
|
#if !os(tvOS)
|
||||||
|
@ -83,8 +83,9 @@ struct VideoActions: View {
|
|||||||
Text(name)
|
Text(name)
|
||||||
.foregroundColor(.secondary)
|
.foregroundColor(.secondary)
|
||||||
.font(.caption2)
|
.font(.caption2)
|
||||||
|
.allowsTightening(true)
|
||||||
}
|
}
|
||||||
.padding(.horizontal, 10)
|
.padding(.horizontal, 6)
|
||||||
.padding(.vertical, 5)
|
.padding(.vertical, 5)
|
||||||
.contentShape(Rectangle())
|
.contentShape(Rectangle())
|
||||||
}
|
}
|
||||||
|
@ -31,6 +31,7 @@ struct VideoDetails: View {
|
|||||||
@EnvironmentObject<RecentsModel> private var recents
|
@EnvironmentObject<RecentsModel> private var recents
|
||||||
@EnvironmentObject<SubscriptionsModel> private var subscriptions
|
@EnvironmentObject<SubscriptionsModel> private var subscriptions
|
||||||
|
|
||||||
|
@Default(.detailsToolbarPosition) private var detailsToolbarPosition
|
||||||
@Default(.playerSidebar) private var playerSidebar
|
@Default(.playerSidebar) private var playerSidebar
|
||||||
|
|
||||||
var video: Video? {
|
var video: Video? {
|
||||||
@ -56,12 +57,17 @@ struct VideoDetails: View {
|
|||||||
.transition(.fade)
|
.transition(.fade)
|
||||||
|
|
||||||
HStack(alignment: .center) {
|
HStack(alignment: .center) {
|
||||||
Spacer()
|
if detailsToolbarPosition.needsLeftSpacer { Spacer() }
|
||||||
|
|
||||||
VideoDetailsToolbar(video: video, page: $page, sidebarQueue: sidebarQueue)
|
VideoDetailsToolbar(video: video, page: $page, sidebarQueue: sidebarQueue)
|
||||||
Spacer()
|
|
||||||
|
if detailsToolbarPosition.needsRightSpacer { Spacer() }
|
||||||
}
|
}
|
||||||
|
.padding(.leading, detailsToolbarPosition == .left ? 10 : 0)
|
||||||
|
.padding(.trailing, detailsToolbarPosition == .right ? 10 : 0)
|
||||||
|
|
||||||
#if os(iOS)
|
#if os(iOS)
|
||||||
.offset(y: bottomPadding ? -SafeArea.insets.bottom : 0)
|
.offset(y: bottomPadding ? -SafeArea.insets.bottom : 0)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
.onChange(of: player.currentItem) { newItem in
|
.onChange(of: player.currentItem) { newItem in
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import Defaults
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
struct VideoDetailsTool: Identifiable {
|
struct VideoDetailsTool: Identifiable {
|
||||||
@ -18,7 +19,7 @@ struct VideoDetailsTool: Identifiable {
|
|||||||
case .info:
|
case .info:
|
||||||
return video != nil && !video!.isLocal
|
return video != nil && !video!.isLocal
|
||||||
case .inspector:
|
case .inspector:
|
||||||
return false
|
return video == nil || Defaults[.showInspector] == .always || video!.isLocal
|
||||||
case .chapters:
|
case .chapters:
|
||||||
return video != nil && !video!.chapters.isEmpty
|
return video != nil && !video!.chapters.isEmpty
|
||||||
case .comments:
|
case .comments:
|
||||||
|
@ -2,7 +2,7 @@ import Defaults
|
|||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
struct VideoDetailsToolbar: View {
|
struct VideoDetailsToolbar: View {
|
||||||
static let lowOpacity = 0.33
|
static let lowOpacity = 0.5
|
||||||
var video: Video?
|
var video: Video?
|
||||||
@Binding var page: VideoDetails.DetailsPage
|
@Binding var page: VideoDetails.DetailsPage
|
||||||
var sidebarQueue: Bool
|
var sidebarQueue: Bool
|
||||||
@ -123,6 +123,7 @@ struct VideoDetailsToolbar: View {
|
|||||||
{
|
{
|
||||||
Text(tool.wrappedValue.name)
|
Text(tool.wrappedValue.name)
|
||||||
.font(.system(size: 14).bold())
|
.font(.system(size: 14).bold())
|
||||||
|
.padding(.trailing, 4)
|
||||||
.foregroundColor(.white)
|
.foregroundColor(.white)
|
||||||
.allowsTightening(true)
|
.allowsTightening(true)
|
||||||
.lineLimit(1)
|
.lineLimit(1)
|
||||||
@ -136,7 +137,18 @@ struct VideoDetailsToolbar: View {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var visibleToolsCount: Int {
|
||||||
|
tools.filter { $0.isAvailable(for: video, sidebarQueue: sidebarQueue) }.count
|
||||||
|
}
|
||||||
|
|
||||||
var activeToolID: VideoDetailsTool.ID {
|
var activeToolID: VideoDetailsTool.ID {
|
||||||
activeTool?.id ?? "queue"
|
activeTool?.id ?? "queue"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct VideoDetailsToolbar_Previews: PreviewProvider {
|
||||||
|
static var previews: some View {
|
||||||
|
VideoDetailsToolbar(page: .constant(.queue), sidebarQueue: false)
|
||||||
|
.injectFixtureEnvironmentObjects()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -6,6 +6,9 @@ struct PlayerSettings: View {
|
|||||||
@Default(.playerInstanceID) private var playerInstanceID
|
@Default(.playerInstanceID) private var playerInstanceID
|
||||||
|
|
||||||
@Default(.playerSidebar) private var playerSidebar
|
@Default(.playerSidebar) private var playerSidebar
|
||||||
|
@Default(.playerDetailsPageButtonLabelStyle) private var playerDetailsPageButtonLabelStyle
|
||||||
|
@Default(.detailsToolbarPosition) private var detailsToolbarPosition
|
||||||
|
@Default(.showInspector) private var showInspector
|
||||||
@Default(.playerControlsLayout) private var playerControlsLayout
|
@Default(.playerControlsLayout) private var playerControlsLayout
|
||||||
@Default(.fullScreenPlayerControlsLayout) private var fullScreenPlayerControlsLayout
|
@Default(.fullScreenPlayerControlsLayout) private var fullScreenPlayerControlsLayout
|
||||||
@Default(.horizontalPlayerGestureEnabled) private var horizontalPlayerGestureEnabled
|
@Default(.horizontalPlayerGestureEnabled) private var horizontalPlayerGestureEnabled
|
||||||
@ -106,6 +109,19 @@ struct PlayerSettings: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !os(tvOS)
|
||||||
|
Section(header: SettingsHeader(text: "Video Details").padding(.bottom, videoDetailsHeaderPadding)) {
|
||||||
|
SettingsHeader(text: "Buttons labels".localized(), secondary: true)
|
||||||
|
detailsButtonLabelStylePicker
|
||||||
|
|
||||||
|
SettingsHeader(text: "Show Inspector".localized(), secondary: true)
|
||||||
|
showInspectorPicker
|
||||||
|
|
||||||
|
SettingsHeader(text: "Pages toolbar position".localized(), secondary: true)
|
||||||
|
detailsToolbarPositionPicker
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if os(iOS)
|
#if os(iOS)
|
||||||
Section(header: SettingsHeader(text: "Orientation".localized())) {
|
Section(header: SettingsHeader(text: "Orientation".localized())) {
|
||||||
if idiom == .pad {
|
if idiom == .pad {
|
||||||
@ -127,6 +143,14 @@ struct PlayerSettings: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private var videoDetailsHeaderPadding: Double {
|
||||||
|
#if os(macOS)
|
||||||
|
5.0
|
||||||
|
#else
|
||||||
|
0.0
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
private var sourcePicker: some View {
|
private var sourcePicker: some View {
|
||||||
Picker("Source", selection: $playerInstanceID) {
|
Picker("Source", selection: $playerInstanceID) {
|
||||||
Text("Instance of current account").tag(String?.none)
|
Text("Instance of current account").tag(String?.none)
|
||||||
@ -172,6 +196,31 @@ struct PlayerSettings: View {
|
|||||||
.modifier(SettingsPickerModifier())
|
.modifier(SettingsPickerModifier())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private var detailsButtonLabelStylePicker: some View {
|
||||||
|
Picker("Buttons labels", selection: $playerDetailsPageButtonLabelStyle) {
|
||||||
|
Text("Show only icons").tag(PlayerDetailsPageButtonLabelStyle.iconOnly)
|
||||||
|
Text("Show icons and text when space permits").tag(PlayerDetailsPageButtonLabelStyle.iconAndText)
|
||||||
|
}
|
||||||
|
.modifier(SettingsPickerModifier())
|
||||||
|
}
|
||||||
|
|
||||||
|
private var showInspectorPicker: some View {
|
||||||
|
Picker("Inspector visibility", selection: $showInspector) {
|
||||||
|
Text("Always").tag(ShowInspectorSetting.always)
|
||||||
|
Text("Only for local files and URLs").tag(ShowInspectorSetting.onlyLocal)
|
||||||
|
}
|
||||||
|
.modifier(SettingsPickerModifier())
|
||||||
|
}
|
||||||
|
|
||||||
|
private var detailsToolbarPositionPicker: some View {
|
||||||
|
Picker("Pages toolbar position", selection: $detailsToolbarPosition) {
|
||||||
|
ForEach(DetailsToolbarPositionSetting.allCases, id: \.self) { setting in
|
||||||
|
Text(setting.rawValue.capitalized).tag(setting)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.modifier(SettingsPickerModifier())
|
||||||
|
}
|
||||||
|
|
||||||
private var horizontalPlayerGestureEnabledToggle: some View {
|
private var horizontalPlayerGestureEnabledToggle: some View {
|
||||||
Toggle("Seek with horizontal swipe on video", isOn: $horizontalPlayerGestureEnabled)
|
Toggle("Seek with horizontal swipe on video", isOn: $horizontalPlayerGestureEnabled)
|
||||||
}
|
}
|
||||||
@ -287,6 +336,7 @@ struct PlayerSettings_Previews: PreviewProvider {
|
|||||||
VStack(alignment: .leading) {
|
VStack(alignment: .leading) {
|
||||||
PlayerSettings()
|
PlayerSettings()
|
||||||
}
|
}
|
||||||
|
.frame(minHeight: 800)
|
||||||
.injectFixtureEnvironmentObjects()
|
.injectFixtureEnvironmentObjects()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -223,7 +223,7 @@ struct SettingsView: View {
|
|||||||
case .browsing:
|
case .browsing:
|
||||||
return 580
|
return 580
|
||||||
case .player:
|
case .player:
|
||||||
return 680
|
return 850
|
||||||
case .quality:
|
case .quality:
|
||||||
return 420
|
return 420
|
||||||
case .history:
|
case .history:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user