From 041a28e7a0bdfade70e72710c037ecfd90bad8da Mon Sep 17 00:00:00 2001 From: Arkadiusz Fal Date: Sun, 13 Nov 2022 23:36:46 +0100 Subject: [PATCH] Video details toolbar and inspector settings --- Shared/Defaults.swift | 20 +++++++- .../Player/Video Details/InspectorView.swift | 2 +- .../Player/Video Details/VideoActions.swift | 3 +- .../Player/Video Details/VideoDetails.swift | 12 +++-- .../Video Details/VideoDetailsTool.swift | 3 +- .../Video Details/VideoDetailsToolbar.swift | 14 +++++- Shared/Settings/PlayerSettings.swift | 50 +++++++++++++++++++ Shared/Settings/SettingsView.swift | 2 +- 8 files changed, 97 insertions(+), 9 deletions(-) diff --git a/Shared/Defaults.swift b/Shared/Defaults.swift index 694e388d..4b19922a 100644 --- a/Shared/Defaults.swift +++ b/Shared/Defaults.swift @@ -100,7 +100,9 @@ extension Defaults.Keys { static let chargingNonCellularProfile = Key("chargingNonCellularProfile", default: chargingNonCellularProfileDefault) static let forceAVPlayerForLiveStreams = Key("forceAVPlayerForLiveStreams", default: true) - static let playerSidebar = Key("playerSidebar", default: PlayerSidebarSetting.defaultValue) + static let playerSidebar = Key("playerSidebar", default: .defaultValue) + static let showInspector = Key("showInspector", default: .onlyLocal) + static let detailsToolbarPosition = Key("detailsToolbarPosition", default: .center) static let playerInstanceID = Key("playerInstance") #if os(iOS) @@ -329,3 +331,19 @@ enum ThumbnailsQuality: String, CaseIterable, Defaults.Serializable { enum SystemControlsCommands: String, CaseIterable, Defaults.Serializable { 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 + } +} diff --git a/Shared/Player/Video Details/InspectorView.swift b/Shared/Player/Video Details/InspectorView.swift index fc9c53cf..5a0da584 100644 --- a/Shared/Player/Video Details/InspectorView.swift +++ b/Shared/Player/Video Details/InspectorView.swift @@ -75,7 +75,7 @@ struct InspectorView: View { Text(detail) .foregroundColor(.secondary) Spacer() - let value = Text(value) + let value = Text(value).lineLimit(1) if #available(iOS 15.0, macOS 12.0, *) { value #if !os(tvOS) diff --git a/Shared/Player/Video Details/VideoActions.swift b/Shared/Player/Video Details/VideoActions.swift index 4cf7dbf3..b21606c8 100644 --- a/Shared/Player/Video Details/VideoActions.swift +++ b/Shared/Player/Video Details/VideoActions.swift @@ -83,8 +83,9 @@ struct VideoActions: View { Text(name) .foregroundColor(.secondary) .font(.caption2) + .allowsTightening(true) } - .padding(.horizontal, 10) + .padding(.horizontal, 6) .padding(.vertical, 5) .contentShape(Rectangle()) } diff --git a/Shared/Player/Video Details/VideoDetails.swift b/Shared/Player/Video Details/VideoDetails.swift index da154480..0e05c7e5 100644 --- a/Shared/Player/Video Details/VideoDetails.swift +++ b/Shared/Player/Video Details/VideoDetails.swift @@ -31,6 +31,7 @@ struct VideoDetails: View { @EnvironmentObject private var recents @EnvironmentObject private var subscriptions + @Default(.detailsToolbarPosition) private var detailsToolbarPosition @Default(.playerSidebar) private var playerSidebar var video: Video? { @@ -56,12 +57,17 @@ struct VideoDetails: View { .transition(.fade) HStack(alignment: .center) { - Spacer() + if detailsToolbarPosition.needsLeftSpacer { Spacer() } + 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) - .offset(y: bottomPadding ? -SafeArea.insets.bottom : 0) + .offset(y: bottomPadding ? -SafeArea.insets.bottom : 0) #endif } .onChange(of: player.currentItem) { newItem in diff --git a/Shared/Player/Video Details/VideoDetailsTool.swift b/Shared/Player/Video Details/VideoDetailsTool.swift index 843f52b0..5db6ce2b 100644 --- a/Shared/Player/Video Details/VideoDetailsTool.swift +++ b/Shared/Player/Video Details/VideoDetailsTool.swift @@ -1,3 +1,4 @@ +import Defaults import Foundation struct VideoDetailsTool: Identifiable { @@ -18,7 +19,7 @@ struct VideoDetailsTool: Identifiable { case .info: return video != nil && !video!.isLocal case .inspector: - return false + return video == nil || Defaults[.showInspector] == .always || video!.isLocal case .chapters: return video != nil && !video!.chapters.isEmpty case .comments: diff --git a/Shared/Player/Video Details/VideoDetailsToolbar.swift b/Shared/Player/Video Details/VideoDetailsToolbar.swift index b1a01d31..a3a7af0c 100644 --- a/Shared/Player/Video Details/VideoDetailsToolbar.swift +++ b/Shared/Player/Video Details/VideoDetailsToolbar.swift @@ -2,7 +2,7 @@ import Defaults import SwiftUI struct VideoDetailsToolbar: View { - static let lowOpacity = 0.33 + static let lowOpacity = 0.5 var video: Video? @Binding var page: VideoDetails.DetailsPage var sidebarQueue: Bool @@ -123,6 +123,7 @@ struct VideoDetailsToolbar: View { { Text(tool.wrappedValue.name) .font(.system(size: 14).bold()) + .padding(.trailing, 4) .foregroundColor(.white) .allowsTightening(true) .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 { activeTool?.id ?? "queue" } } + +struct VideoDetailsToolbar_Previews: PreviewProvider { + static var previews: some View { + VideoDetailsToolbar(page: .constant(.queue), sidebarQueue: false) + .injectFixtureEnvironmentObjects() + } +} diff --git a/Shared/Settings/PlayerSettings.swift b/Shared/Settings/PlayerSettings.swift index 2e11437c..fba6a91f 100644 --- a/Shared/Settings/PlayerSettings.swift +++ b/Shared/Settings/PlayerSettings.swift @@ -6,6 +6,9 @@ struct PlayerSettings: View { @Default(.playerInstanceID) private var playerInstanceID @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(.fullScreenPlayerControlsLayout) private var fullScreenPlayerControlsLayout @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) Section(header: SettingsHeader(text: "Orientation".localized())) { 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 { Picker("Source", selection: $playerInstanceID) { Text("Instance of current account").tag(String?.none) @@ -172,6 +196,31 @@ struct PlayerSettings: View { .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 { Toggle("Seek with horizontal swipe on video", isOn: $horizontalPlayerGestureEnabled) } @@ -287,6 +336,7 @@ struct PlayerSettings_Previews: PreviewProvider { VStack(alignment: .leading) { PlayerSettings() } + .frame(minHeight: 800) .injectFixtureEnvironmentObjects() } } diff --git a/Shared/Settings/SettingsView.swift b/Shared/Settings/SettingsView.swift index 09e7040d..5c7f2858 100644 --- a/Shared/Settings/SettingsView.swift +++ b/Shared/Settings/SettingsView.swift @@ -223,7 +223,7 @@ struct SettingsView: View { case .browsing: return 580 case .player: - return 680 + return 850 case .quality: return 420 case .history: