From dc9cbd34d073f42d108f5a4f7b28383210a3bfef Mon Sep 17 00:00:00 2001 From: Arkadiusz Fal Date: Thu, 4 Nov 2021 23:01:27 +0100 Subject: [PATCH] Improve settings --- Model/Applications/InvidiousAPI.swift | 2 +- Pearvidious.xcodeproj/project.pbxproj | 8 ++ Shared/Player/VideoPlayerView.swift | 22 ++-- Shared/Settings/InstancesSettings.swift | 2 +- Shared/Settings/PlaybackSettings.swift | 132 +++++++++++++----------- Shared/Settings/ServicesSettings.swift | 4 +- Shared/Settings/SettingsHeader.swift | 20 ++++ macOS/Settings/InstancesSettings.swift | 9 +- tvOS/AccountSelectionView.swift | 2 +- 9 files changed, 120 insertions(+), 81 deletions(-) create mode 100644 Shared/Settings/SettingsHeader.swift diff --git a/Model/Applications/InvidiousAPI.swift b/Model/Applications/InvidiousAPI.swift index 0ed3c91b..04220eed 100644 --- a/Model/Applications/InvidiousAPI.swift +++ b/Model/Applications/InvidiousAPI.swift @@ -169,7 +169,7 @@ final class InvidiousAPI: Service, ObservableObject, VideosAPI { func trending(country: Country, category: TrendingCategory?) -> Resource { resource(baseURL: account.url, path: "\(InvidiousAPI.basePath)/trending") - .withParam("type", category!.name) + .withParam("type", category?.name) .withParam("region", country.rawValue) } diff --git a/Pearvidious.xcodeproj/project.pbxproj b/Pearvidious.xcodeproj/project.pbxproj index 6704f14f..2771db4f 100644 --- a/Pearvidious.xcodeproj/project.pbxproj +++ b/Pearvidious.xcodeproj/project.pbxproj @@ -189,6 +189,9 @@ 376B2E0726F920D600B1D64D /* SignInRequiredView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 376B2E0626F920D600B1D64D /* SignInRequiredView.swift */; }; 376B2E0826F920D600B1D64D /* SignInRequiredView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 376B2E0626F920D600B1D64D /* SignInRequiredView.swift */; }; 376B2E0926F920D600B1D64D /* SignInRequiredView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 376B2E0626F920D600B1D64D /* SignInRequiredView.swift */; }; + 376BE50727347B57009AD608 /* SettingsHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 376BE50627347B57009AD608 /* SettingsHeader.swift */; }; + 376BE50827347B57009AD608 /* SettingsHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 376BE50627347B57009AD608 /* SettingsHeader.swift */; }; + 376BE50927347B5F009AD608 /* SettingsHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 376BE50627347B57009AD608 /* SettingsHeader.swift */; }; 376CD21626FBE18D001E1AC1 /* Instance+Fixtures.swift in Sources */ = {isa = PBXBuildFile; fileRef = 376CD21526FBE18D001E1AC1 /* Instance+Fixtures.swift */; }; 376CD21726FBE18D001E1AC1 /* Instance+Fixtures.swift in Sources */ = {isa = PBXBuildFile; fileRef = 376CD21526FBE18D001E1AC1 /* Instance+Fixtures.swift */; }; 376CD21826FBE18D001E1AC1 /* Instance+Fixtures.swift in Sources */ = {isa = PBXBuildFile; fileRef = 376CD21526FBE18D001E1AC1 /* Instance+Fixtures.swift */; }; @@ -567,6 +570,7 @@ 376A33DF2720CAD6000C1D6B /* VideosApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideosApp.swift; sourceTree = ""; }; 376A33E32720CB35000C1D6B /* Account.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Account.swift; sourceTree = ""; }; 376B2E0626F920D600B1D64D /* SignInRequiredView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SignInRequiredView.swift; sourceTree = ""; }; + 376BE50627347B57009AD608 /* SettingsHeader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsHeader.swift; sourceTree = ""; }; 376CD21526FBE18D001E1AC1 /* Instance+Fixtures.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Instance+Fixtures.swift"; sourceTree = ""; }; 37732FEF2703A26300F04329 /* AccountValidationStatus.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountValidationStatus.swift; sourceTree = ""; }; 37732FF32703D32400F04329 /* Sidebar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Sidebar.swift; sourceTree = ""; }; @@ -914,6 +918,7 @@ 37484C1C26FC83A400287258 /* InstancesSettings.swift */, 37484C1826FC837400287258 /* PlaybackSettings.swift */, 374C053427242D9F009BDDBE /* ServicesSettings.swift */, + 376BE50627347B57009AD608 /* SettingsHeader.swift */, 37B044B626F7AB9000E1419D /* SettingsView.swift */, ); path = Settings; @@ -1691,6 +1696,7 @@ 37CC3F4C270CFE1700608308 /* PlayerQueueView.swift in Sources */, 37FFC440272734C3009FFD26 /* Throttle.swift in Sources */, 3705B182267B4E4900704544 /* TrendingCategory.swift in Sources */, + 376BE50927347B5F009AD608 /* SettingsHeader.swift in Sources */, 3700155F271B12DD0049C794 /* SiestaConfiguration.swift in Sources */, 37EAD86F267B9ED100D9E01B /* Segment.swift in Sources */, 375168D62700FAFF008F96A6 /* Debounce.swift in Sources */, @@ -1820,6 +1826,7 @@ 37BA793C26DB8EE4002A0235 /* PlaylistVideosView.swift in Sources */, 378E510026FE8EEE00F49626 /* AccountsMenuView.swift in Sources */, 37141670267A8ACC006CA35D /* TrendingView.swift in Sources */, + 376BE50727347B57009AD608 /* SettingsHeader.swift in Sources */, 37152EEB26EFEB95004FB96D /* LazyView.swift in Sources */, 377FC7E2267A084A00A6BBAF /* VideoCell.swift in Sources */, 37CC3F51270D010D00608308 /* VideoBanner.swift in Sources */, @@ -1975,6 +1982,7 @@ 37BE0BD126A0E2D50092E2DB /* VideoPlayerView.swift in Sources */, 37AAF27E26737323007FC770 /* PopularView.swift in Sources */, 3743CA50270EFE3400E4D32B /* PlayerQueueRow.swift in Sources */, + 376BE50827347B57009AD608 /* SettingsHeader.swift in Sources */, 37A9966026D6F9B9006E3224 /* FavoritesView.swift in Sources */, 37001565271B1F250049C794 /* AccountsModel.swift in Sources */, 374C0541272472C0009BDDBE /* PlayerSponsorBlock.swift in Sources */, diff --git a/Shared/Player/VideoPlayerView.swift b/Shared/Player/VideoPlayerView.swift index cb28c075..bc7e9e26 100644 --- a/Shared/Player/VideoPlayerView.swift +++ b/Shared/Player/VideoPlayerView.swift @@ -25,13 +25,13 @@ struct VideoPlayerView: View { @EnvironmentObject private var player var body: some View { - GeometryReader { geometry in - #if os(macOS) - HSplitView { - content - } - .frame(idealWidth: 1000, maxWidth: 1100, minHeight: 700) - #else + #if os(macOS) + HSplitView { + content + } + .frame(idealWidth: 1000, maxWidth: 1100, minHeight: 700) + #else + GeometryReader { geometry in HStack(spacing: 0) { content } @@ -42,8 +42,8 @@ struct VideoPlayerView: View { self.playerSize = size } .navigationBarHidden(true) - #endif - } + } + #endif } var content: some View { @@ -168,9 +168,5 @@ struct VideoPlayerView_Previews: PreviewProvider { static var previews: some View { VideoPlayerView() .injectFixtureEnvironmentObjects() - - VideoPlayerView() - .injectFixtureEnvironmentObjects() - .previewInterfaceOrientation(.landscapeRight) } } diff --git a/Shared/Settings/InstancesSettings.swift b/Shared/Settings/InstancesSettings.swift index e8fb4845..cb5bdf87 100644 --- a/Shared/Settings/InstancesSettings.swift +++ b/Shared/Settings/InstancesSettings.swift @@ -14,7 +14,7 @@ struct InstancesSettings: View { var body: some View { Group { - Section(header: Text("Instances")) { + Section(header: SettingsHeader(text: "Instances")) { ForEach(instances) { instance in Group { NavigationLink(instance.longDescription) { diff --git a/Shared/Settings/PlaybackSettings.swift b/Shared/Settings/PlaybackSettings.swift index 3fd74714..727a0190 100644 --- a/Shared/Settings/PlaybackSettings.swift +++ b/Shared/Settings/PlaybackSettings.swift @@ -15,79 +15,61 @@ struct PlaybackSettings: View { #endif var body: some View { - playerInstanceSection + Group { + #if os(iOS) + Section(header: SettingsHeader(text: "Player")) { + sourcePicker + qualityPicker + if idiom == .pad { + sidebarPicker + } + keywordsToggle + } + #else + Section(header: SettingsHeader(text: "Source")) { + sourcePicker + } - qualitySection + Section(header: SettingsHeader(text: "Quality")) { + qualityPicker + } - #if !os(tvOS) - playerSection - #endif + #if os(macOS) + Section(header: SettingsHeader(text: "Sidebar")) { + sidebarPicker + } + #endif + + keywordsToggle + #endif + } #if os(macOS) Spacer() #endif } - private var playerInstanceSection: some View { - Section(header: Text("Preferred playback source")) { - Picker("Source", selection: $playerInstanceID) { - Text("Best available stream").tag(String?.none) + private var sourcePicker: some View { + Picker("Source", selection: $playerInstanceID) { + Text("Best available stream").tag(String?.none) - ForEach(instances) { instance in - Text(instance.longDescription).tag(Optional(instance.id)) - } + ForEach(instances) { instance in + Text(instance.longDescription).tag(Optional(instance.id)) } - .labelsHidden() - #if os(iOS) - .pickerStyle(.automatic) - #elseif os(tvOS) - .pickerStyle(.inline) - #endif } + .labelsHidden() + #if os(iOS) + .pickerStyle(.automatic) + #elseif os(tvOS) + .pickerStyle(.inline) + #endif } - private var qualitySection: some View { - Section(header: Text("Quality")) { - Picker("Quality", selection: $quality) { - ForEach(Stream.ResolutionSetting.allCases, id: \.self) { resolution in - Text(resolution.description).tag(resolution) - } + private var qualityPicker: some View { + Picker("Quality", selection: $quality) { + ForEach(Stream.ResolutionSetting.allCases, id: \.self) { resolution in + Text(resolution.description).tag(resolution) } - .labelsHidden() - - #if os(iOS) - .pickerStyle(.automatic) - #elseif os(tvOS) - .pickerStyle(.inline) - #endif - } - } - - private var playerSection: some View { - Section(header: Text("Player")) { - #if os(iOS) - if idiom == .pad { - sidebarPicker - } - #elseif os(macOS) - sidebarPicker - #endif - - Toggle("Show video keywords", isOn: $showKeywords) - } - } - - private var sidebarPicker: some View { - Picker("Sidebar", selection: $playerSidebar) { - #if os(macOS) - Text("Show sidebar").tag(PlayerSidebarSetting.always) - #endif - - #if os(iOS) - Text("Show sidebar when space permits").tag(PlayerSidebarSetting.whenFits) - #endif - - Text("Hide sidebar").tag(PlayerSidebarSetting.never) } .labelsHidden() @@ -97,4 +79,36 @@ struct PlaybackSettings: View { .pickerStyle(.inline) #endif } + + private var sidebarPicker: some View { + Picker("Sidebar", selection: $playerSidebar) { + #if os(macOS) + Text("Show").tag(PlayerSidebarSetting.always) + #endif + + #if os(iOS) + Text("Show sidebar when space permits").tag(PlayerSidebarSetting.whenFits) + #endif + + Text("Hide").tag(PlayerSidebarSetting.never) + } + .labelsHidden() + + #if os(iOS) + .pickerStyle(.automatic) + #elseif os(tvOS) + .pickerStyle(.inline) + #endif + } + + private var keywordsToggle: some View { + Toggle("Show video keywords", isOn: $showKeywords) + } +} + +struct PlaybackSettings_Previews: PreviewProvider { + static var previews: some View { + PlaybackSettings() + .injectFixtureEnvironmentObjects() + } } diff --git a/Shared/Settings/ServicesSettings.swift b/Shared/Settings/ServicesSettings.swift index 7f622baf..46a41964 100644 --- a/Shared/Settings/ServicesSettings.swift +++ b/Shared/Settings/ServicesSettings.swift @@ -6,7 +6,7 @@ struct ServicesSettings: View { @Default(.sponsorBlockCategories) private var sponsorBlockCategories var body: some View { - Section(header: Text("SponsorBlock API")) { + Section(header: SettingsHeader(text: "SponsorBlock API")) { TextField( "SponsorBlock API Instance", text: $sponsorBlockInstance, @@ -19,7 +19,7 @@ struct ServicesSettings: View { #endif } - Section(header: Text("Categories to Skip")) { + Section(header: SettingsHeader(text: "Categories to Skip")) { #if os(macOS) List(SponsorBlockAPI.categories, id: \.self) { category in SponsorBlockCategorySelectionRow( diff --git a/Shared/Settings/SettingsHeader.swift b/Shared/Settings/SettingsHeader.swift new file mode 100644 index 00000000..201a8a3e --- /dev/null +++ b/Shared/Settings/SettingsHeader.swift @@ -0,0 +1,20 @@ +import SwiftUI + +struct SettingsHeader: View { + var text: String + + var body: some View { + Text(text) + #if os(macOS) || os(tvOS) + .font(.title3) + .foregroundColor(.secondary) + .focusable(false) + #endif + } +} + +struct SettingsHeader_Previews: PreviewProvider { + static var previews: some View { + SettingsHeader(text: "Header") + } +} diff --git a/macOS/Settings/InstancesSettings.swift b/macOS/Settings/InstancesSettings.swift index f3a92440..760b2dd5 100644 --- a/macOS/Settings/InstancesSettings.swift +++ b/macOS/Settings/InstancesSettings.swift @@ -20,8 +20,8 @@ struct InstancesSettings: View { @Default(.instances) private var instances var body: some View { - Section { - Text("Instance") + Group { + SettingsHeader(text: "Instance") if !instances.isEmpty { Picker("Instance", selection: $selectedInstanceID) { @@ -37,7 +37,8 @@ struct InstancesSettings: View { } if !selectedInstance.isNil, selectedInstance.app.supportsAccounts { - Text("Accounts") + SettingsHeader(text: "Accounts") + List(selection: $selectedAccount) { if selectedInstanceAccounts.isEmpty { Text("You have no accounts for this instance") @@ -70,7 +71,7 @@ struct InstancesSettings: View { } if selectedInstance != nil, selectedInstance.app.hasFrontendURL { - Text("Frontend URL") + SettingsHeader(text: "Frontend URL") TextField("Frontend URL", text: $frontendURL, prompt: Text("Frontend URL")) .onAppear { diff --git a/tvOS/AccountSelectionView.swift b/tvOS/AccountSelectionView.swift index 6f24d01f..978e32eb 100644 --- a/tvOS/AccountSelectionView.swift +++ b/tvOS/AccountSelectionView.swift @@ -12,7 +12,7 @@ struct AccountSelectionView: View { @Default(.instances) private var instances var body: some View { - Section(header: Text(showHeader ? "Current Account" : "")) { + Section(header: SettingsHeader(text: showHeader ? "Current Account" : "")) { Button(accountButtonTitle(account: accountsModel.current, long: true)) { if let account = nextAccount { accountsModel.setCurrent(account)