Improve settings

This commit is contained in:
Arkadiusz Fal 2021-11-04 23:01:27 +01:00
parent d50b136b38
commit dc9cbd34d0
9 changed files with 120 additions and 81 deletions

View File

@ -169,7 +169,7 @@ final class InvidiousAPI: Service, ObservableObject, VideosAPI {
func trending(country: Country, category: TrendingCategory?) -> Resource { func trending(country: Country, category: TrendingCategory?) -> Resource {
resource(baseURL: account.url, path: "\(InvidiousAPI.basePath)/trending") resource(baseURL: account.url, path: "\(InvidiousAPI.basePath)/trending")
.withParam("type", category!.name) .withParam("type", category?.name)
.withParam("region", country.rawValue) .withParam("region", country.rawValue)
} }

View File

@ -189,6 +189,9 @@
376B2E0726F920D600B1D64D /* SignInRequiredView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 376B2E0626F920D600B1D64D /* SignInRequiredView.swift */; }; 376B2E0726F920D600B1D64D /* SignInRequiredView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 376B2E0626F920D600B1D64D /* SignInRequiredView.swift */; };
376B2E0826F920D600B1D64D /* 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 */; }; 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 */; }; 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 */; }; 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 */; }; 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 = "<group>"; }; 376A33DF2720CAD6000C1D6B /* VideosApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideosApp.swift; sourceTree = "<group>"; };
376A33E32720CB35000C1D6B /* Account.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Account.swift; sourceTree = "<group>"; }; 376A33E32720CB35000C1D6B /* Account.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Account.swift; sourceTree = "<group>"; };
376B2E0626F920D600B1D64D /* SignInRequiredView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SignInRequiredView.swift; sourceTree = "<group>"; }; 376B2E0626F920D600B1D64D /* SignInRequiredView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SignInRequiredView.swift; sourceTree = "<group>"; };
376BE50627347B57009AD608 /* SettingsHeader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsHeader.swift; sourceTree = "<group>"; };
376CD21526FBE18D001E1AC1 /* Instance+Fixtures.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Instance+Fixtures.swift"; sourceTree = "<group>"; }; 376CD21526FBE18D001E1AC1 /* Instance+Fixtures.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Instance+Fixtures.swift"; sourceTree = "<group>"; };
37732FEF2703A26300F04329 /* AccountValidationStatus.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountValidationStatus.swift; sourceTree = "<group>"; }; 37732FEF2703A26300F04329 /* AccountValidationStatus.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountValidationStatus.swift; sourceTree = "<group>"; };
37732FF32703D32400F04329 /* Sidebar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Sidebar.swift; sourceTree = "<group>"; }; 37732FF32703D32400F04329 /* Sidebar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Sidebar.swift; sourceTree = "<group>"; };
@ -914,6 +918,7 @@
37484C1C26FC83A400287258 /* InstancesSettings.swift */, 37484C1C26FC83A400287258 /* InstancesSettings.swift */,
37484C1826FC837400287258 /* PlaybackSettings.swift */, 37484C1826FC837400287258 /* PlaybackSettings.swift */,
374C053427242D9F009BDDBE /* ServicesSettings.swift */, 374C053427242D9F009BDDBE /* ServicesSettings.swift */,
376BE50627347B57009AD608 /* SettingsHeader.swift */,
37B044B626F7AB9000E1419D /* SettingsView.swift */, 37B044B626F7AB9000E1419D /* SettingsView.swift */,
); );
path = Settings; path = Settings;
@ -1691,6 +1696,7 @@
37CC3F4C270CFE1700608308 /* PlayerQueueView.swift in Sources */, 37CC3F4C270CFE1700608308 /* PlayerQueueView.swift in Sources */,
37FFC440272734C3009FFD26 /* Throttle.swift in Sources */, 37FFC440272734C3009FFD26 /* Throttle.swift in Sources */,
3705B182267B4E4900704544 /* TrendingCategory.swift in Sources */, 3705B182267B4E4900704544 /* TrendingCategory.swift in Sources */,
376BE50927347B5F009AD608 /* SettingsHeader.swift in Sources */,
3700155F271B12DD0049C794 /* SiestaConfiguration.swift in Sources */, 3700155F271B12DD0049C794 /* SiestaConfiguration.swift in Sources */,
37EAD86F267B9ED100D9E01B /* Segment.swift in Sources */, 37EAD86F267B9ED100D9E01B /* Segment.swift in Sources */,
375168D62700FAFF008F96A6 /* Debounce.swift in Sources */, 375168D62700FAFF008F96A6 /* Debounce.swift in Sources */,
@ -1820,6 +1826,7 @@
37BA793C26DB8EE4002A0235 /* PlaylistVideosView.swift in Sources */, 37BA793C26DB8EE4002A0235 /* PlaylistVideosView.swift in Sources */,
378E510026FE8EEE00F49626 /* AccountsMenuView.swift in Sources */, 378E510026FE8EEE00F49626 /* AccountsMenuView.swift in Sources */,
37141670267A8ACC006CA35D /* TrendingView.swift in Sources */, 37141670267A8ACC006CA35D /* TrendingView.swift in Sources */,
376BE50727347B57009AD608 /* SettingsHeader.swift in Sources */,
37152EEB26EFEB95004FB96D /* LazyView.swift in Sources */, 37152EEB26EFEB95004FB96D /* LazyView.swift in Sources */,
377FC7E2267A084A00A6BBAF /* VideoCell.swift in Sources */, 377FC7E2267A084A00A6BBAF /* VideoCell.swift in Sources */,
37CC3F51270D010D00608308 /* VideoBanner.swift in Sources */, 37CC3F51270D010D00608308 /* VideoBanner.swift in Sources */,
@ -1975,6 +1982,7 @@
37BE0BD126A0E2D50092E2DB /* VideoPlayerView.swift in Sources */, 37BE0BD126A0E2D50092E2DB /* VideoPlayerView.swift in Sources */,
37AAF27E26737323007FC770 /* PopularView.swift in Sources */, 37AAF27E26737323007FC770 /* PopularView.swift in Sources */,
3743CA50270EFE3400E4D32B /* PlayerQueueRow.swift in Sources */, 3743CA50270EFE3400E4D32B /* PlayerQueueRow.swift in Sources */,
376BE50827347B57009AD608 /* SettingsHeader.swift in Sources */,
37A9966026D6F9B9006E3224 /* FavoritesView.swift in Sources */, 37A9966026D6F9B9006E3224 /* FavoritesView.swift in Sources */,
37001565271B1F250049C794 /* AccountsModel.swift in Sources */, 37001565271B1F250049C794 /* AccountsModel.swift in Sources */,
374C0541272472C0009BDDBE /* PlayerSponsorBlock.swift in Sources */, 374C0541272472C0009BDDBE /* PlayerSponsorBlock.swift in Sources */,

View File

@ -25,13 +25,13 @@ struct VideoPlayerView: View {
@EnvironmentObject<PlayerModel> private var player @EnvironmentObject<PlayerModel> private var player
var body: some View { var body: some View {
GeometryReader { geometry in #if os(macOS)
#if os(macOS) HSplitView {
HSplitView { content
content }
} .frame(idealWidth: 1000, maxWidth: 1100, minHeight: 700)
.frame(idealWidth: 1000, maxWidth: 1100, minHeight: 700) #else
#else GeometryReader { geometry in
HStack(spacing: 0) { HStack(spacing: 0) {
content content
} }
@ -42,8 +42,8 @@ struct VideoPlayerView: View {
self.playerSize = size self.playerSize = size
} }
.navigationBarHidden(true) .navigationBarHidden(true)
#endif }
} #endif
} }
var content: some View { var content: some View {
@ -168,9 +168,5 @@ struct VideoPlayerView_Previews: PreviewProvider {
static var previews: some View { static var previews: some View {
VideoPlayerView() VideoPlayerView()
.injectFixtureEnvironmentObjects() .injectFixtureEnvironmentObjects()
VideoPlayerView()
.injectFixtureEnvironmentObjects()
.previewInterfaceOrientation(.landscapeRight)
} }
} }

View File

@ -14,7 +14,7 @@ struct InstancesSettings: View {
var body: some View { var body: some View {
Group { Group {
Section(header: Text("Instances")) { Section(header: SettingsHeader(text: "Instances")) {
ForEach(instances) { instance in ForEach(instances) { instance in
Group { Group {
NavigationLink(instance.longDescription) { NavigationLink(instance.longDescription) {

View File

@ -15,79 +15,61 @@ struct PlaybackSettings: View {
#endif #endif
var body: some View { 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) #if os(macOS)
playerSection Section(header: SettingsHeader(text: "Sidebar")) {
#endif sidebarPicker
}
#endif
keywordsToggle
#endif
}
#if os(macOS) #if os(macOS)
Spacer() Spacer()
#endif #endif
} }
private var playerInstanceSection: some View { private var sourcePicker: some View {
Section(header: Text("Preferred playback source")) { Picker("Source", selection: $playerInstanceID) {
Picker("Source", selection: $playerInstanceID) { Text("Best available stream").tag(String?.none)
Text("Best available stream").tag(String?.none)
ForEach(instances) { instance in ForEach(instances) { instance in
Text(instance.longDescription).tag(Optional(instance.id)) 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 { private var qualityPicker: some View {
Section(header: Text("Quality")) { Picker("Quality", selection: $quality) {
Picker("Quality", selection: $quality) { ForEach(Stream.ResolutionSetting.allCases, id: \.self) { resolution in
ForEach(Stream.ResolutionSetting.allCases, id: \.self) { resolution in Text(resolution.description).tag(resolution)
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() .labelsHidden()
@ -97,4 +79,36 @@ struct PlaybackSettings: View {
.pickerStyle(.inline) .pickerStyle(.inline)
#endif #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()
}
} }

View File

@ -6,7 +6,7 @@ struct ServicesSettings: View {
@Default(.sponsorBlockCategories) private var sponsorBlockCategories @Default(.sponsorBlockCategories) private var sponsorBlockCategories
var body: some View { var body: some View {
Section(header: Text("SponsorBlock API")) { Section(header: SettingsHeader(text: "SponsorBlock API")) {
TextField( TextField(
"SponsorBlock API Instance", "SponsorBlock API Instance",
text: $sponsorBlockInstance, text: $sponsorBlockInstance,
@ -19,7 +19,7 @@ struct ServicesSettings: View {
#endif #endif
} }
Section(header: Text("Categories to Skip")) { Section(header: SettingsHeader(text: "Categories to Skip")) {
#if os(macOS) #if os(macOS)
List(SponsorBlockAPI.categories, id: \.self) { category in List(SponsorBlockAPI.categories, id: \.self) { category in
SponsorBlockCategorySelectionRow( SponsorBlockCategorySelectionRow(

View File

@ -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")
}
}

View File

@ -20,8 +20,8 @@ struct InstancesSettings: View {
@Default(.instances) private var instances @Default(.instances) private var instances
var body: some View { var body: some View {
Section { Group {
Text("Instance") SettingsHeader(text: "Instance")
if !instances.isEmpty { if !instances.isEmpty {
Picker("Instance", selection: $selectedInstanceID) { Picker("Instance", selection: $selectedInstanceID) {
@ -37,7 +37,8 @@ struct InstancesSettings: View {
} }
if !selectedInstance.isNil, selectedInstance.app.supportsAccounts { if !selectedInstance.isNil, selectedInstance.app.supportsAccounts {
Text("Accounts") SettingsHeader(text: "Accounts")
List(selection: $selectedAccount) { List(selection: $selectedAccount) {
if selectedInstanceAccounts.isEmpty { if selectedInstanceAccounts.isEmpty {
Text("You have no accounts for this instance") Text("You have no accounts for this instance")
@ -70,7 +71,7 @@ struct InstancesSettings: View {
} }
if selectedInstance != nil, selectedInstance.app.hasFrontendURL { if selectedInstance != nil, selectedInstance.app.hasFrontendURL {
Text("Frontend URL") SettingsHeader(text: "Frontend URL")
TextField("Frontend URL", text: $frontendURL, prompt: Text("Frontend URL")) TextField("Frontend URL", text: $frontendURL, prompt: Text("Frontend URL"))
.onAppear { .onAppear {

View File

@ -12,7 +12,7 @@ struct AccountSelectionView: View {
@Default(.instances) private var instances @Default(.instances) private var instances
var body: some View { var body: some View {
Section(header: Text(showHeader ? "Current Account" : "")) { Section(header: SettingsHeader(text: showHeader ? "Current Account" : "")) {
Button(accountButtonTitle(account: accountsModel.current, long: true)) { Button(accountButtonTitle(account: accountsModel.current, long: true)) {
if let account = nextAccount { if let account = nextAccount {
accountsModel.setCurrent(account) accountsModel.setCurrent(account)