Reorganize locations settings

This commit is contained in:
Arkadiusz Fal 2022-11-11 19:55:18 +01:00
parent 611bcde238
commit 4c2d473caa
5 changed files with 110 additions and 159 deletions

View File

@ -7,20 +7,30 @@ struct AdvancedSettings: View {
@Default(.mpvCacheSecs) private var mpvCacheSecs
@Default(.mpvCachePauseWait) private var mpvCachePauseWait
@Default(.mpvEnableLogging) private var mpvEnableLogging
@Default(.countryOfPublicInstances) private var countryOfPublicInstances
@Default(.instances) private var instances
@EnvironmentObject<AccountsModel> private var accounts
@EnvironmentObject<NavigationModel> private var navigation
@EnvironmentObject<PlayerModel> private var player
@EnvironmentObject<SettingsModel> private var settings
@State private var presentingShareSheet = false
@State private var countries = [String]()
@State private var filesToShare = [MPVClient.logFile]
@State private var presentingInstanceForm = false
@State private var presentingShareSheet = false
@State private var savedFormInstanceID: Instance.ID?
var body: some View {
VStack(alignment: .leading) {
#if os(macOS)
advancedSettings
locationsSettings
Spacer()
#else
List {
advancedSettings
locationsSettings
}
#if os(iOS)
.sheet(isPresented: $presentingShareSheet) {
@ -31,6 +41,16 @@ struct AdvancedSettings: View {
#endif
#endif
}
.onAppear(perform: loadCountries)
.onChange(of: countryOfPublicInstances) { newCountry in
InstancesManifest.shared.setPublicAccount(newCountry, accounts: accounts, asCurrent: accounts.current?.isPublic ?? true)
}
.onChange(of: instancesManifest) { _ in
countries.removeAll()
}
.sheet(isPresented: $presentingInstanceForm) {
InstanceForm(savedInstanceID: $savedFormInstanceID)
}
#if os(tvOS)
.frame(maxWidth: 1000)
#endif
@ -82,6 +102,8 @@ struct AdvancedSettings: View {
Section(header: manifestHeader) {
TextField("URL", text: $instancesManifest)
Button("Reload manifest", action: loadCountries)
.disabled(instancesManifest.isEmpty)
#if !os(macOS)
.keyboardType(.webSearch)
#endif
@ -112,7 +134,7 @@ struct AdvancedSettings: View {
}
var manifestHeader: some View {
SettingsHeader(text: "Public Manifest".localized())
SettingsHeader(text: "Locations Manifest".localized())
}
var showMPVPlaybackStatsToggle: some View {
@ -132,10 +154,85 @@ struct AdvancedSettings: View {
}
}
#endif
@ViewBuilder var locationsSettings: some View {
if !InstancesManifest.shared.manifestURL.isNil, !countries.isEmpty {
Section(header: SettingsHeader(text: "Public Locations".localized()), footer: countryFooter) {
Picker("Country", selection: $countryOfPublicInstances) {
Text("Don't use public locations").tag(String?.none)
ForEach(countries, id: \.self) { country in
Text(country).tag(Optional(country))
}
}
#if os(tvOS)
.pickerStyle(.inline)
#endif
.disabled(countries.isEmpty)
Button {
InstancesManifest.shared.changePublicAccount(accounts, settings: settings)
} label: {
if let account = accounts.current, account.isPublic {
Text("Switch to other public location")
} else {
Text("Switch to public locations")
}
}
.disabled(countryOfPublicInstances.isNil)
}
}
Section(header: SettingsHeader(text: "Custom Locations".localized())) {
#if os(macOS)
InstancesSettings()
.environmentObject(settings)
#else
ForEach(instances) { instance in
AccountsNavigationLink(instance: instance)
}
addInstanceButton
#endif
}
}
@ViewBuilder var countryFooter: some View {
if let account = accounts.current {
let locationType = account.isPublic ? (account.country ?? "Unknown") : "Custom".localized()
let description = account.isPublic ? account.url : account.instance?.description ?? "unknown".localized()
Text("Current: \(locationType)\n\(description)")
.foregroundColor(.secondary)
#if os(macOS)
.padding(.bottom, 10)
#endif
}
}
func loadCountries() {
InstancesManifest.shared.configure()
InstancesManifest.shared.instancesList?.load()
.onSuccess { response in
if let instances: [ManifestedInstance] = response.typedContent() {
self.countries = instances.map(\.country).unique().sorted()
}
}
.onFailure { _ in
settings.presentAlert(title: "Could not load locations manifest".localized())
}
}
private var addInstanceButton: some View {
Button {
presentingInstanceForm = true
} label: {
Label("Add Location...", systemImage: "plus")
}
}
}
struct AdvancedSettings_Previews: PreviewProvider {
static var previews: some View {
AdvancedSettings()
.injectFixtureEnvironmentObjects()
}
}

View File

@ -1,124 +0,0 @@
import Defaults
import SwiftUI
struct LocationsSettings: View {
@State private var countries = [String]()
@State private var presentingInstanceForm = false
@State private var savedFormInstanceID: Instance.ID?
@EnvironmentObject<AccountsModel> private var accounts
@EnvironmentObject<NavigationModel> private var navigation
@EnvironmentObject<SettingsModel> private var model
@Default(.countryOfPublicInstances) private var countryOfPublicInstances
@Default(.instances) private var instances
var body: some View {
VStack(alignment: .leading) {
#if os(macOS)
settings
Spacer()
#else
Group {
settings
}
#if os(iOS)
.listStyle(.insetGrouped)
#endif
#endif
}
.onAppear(perform: loadCountries)
.onChange(of: countryOfPublicInstances) { newCountry in
InstancesManifest.shared.setPublicAccount(newCountry, accounts: accounts, asCurrent: accounts.current?.isPublic ?? true)
}
.sheet(isPresented: $presentingInstanceForm) {
InstanceForm(savedInstanceID: $savedFormInstanceID)
}
#if os(tvOS)
.frame(maxWidth: 1000)
#endif
.navigationTitle("Locations")
}
@ViewBuilder var settings: some View {
if !InstancesManifest.shared.manifestURL.isNil {
Section(header: SettingsHeader(text: "Public Locations".localized()), footer: countryFooter) {
Picker("Country", selection: $countryOfPublicInstances) {
Text("Don't use public locations").tag(String?.none)
ForEach(countries, id: \.self) { country in
Text(country).tag(Optional(country))
}
}
#if os(tvOS)
.pickerStyle(.inline)
#endif
.disabled(countries.isEmpty)
Button {
InstancesManifest.shared.changePublicAccount(accounts, settings: model)
} label: {
if let account = accounts.current, account.isPublic {
Text("Switch to other public location")
} else {
Text("Switch to public locations")
}
}
.disabled(countryOfPublicInstances.isNil)
}
}
Section(header: SettingsHeader(text: "Custom Locations".localized())) {
#if os(macOS)
InstancesSettings()
.environmentObject(model)
#else
ForEach(instances) { instance in
AccountsNavigationLink(instance: instance)
}
addInstanceButton
#endif
}
}
@ViewBuilder var countryFooter: some View {
if let account = accounts.current {
let locationType = account.isPublic ? (account.country ?? "Unknown") : "Custom".localized()
let description = account.isPublic ? account.url : account.instance?.description ?? "unknown".localized()
Text("Current: \(locationType)\n\(description)")
.foregroundColor(.secondary)
#if os(macOS)
.padding(.bottom, 10)
#endif
}
}
func loadCountries() {
InstancesManifest.shared.configure()
InstancesManifest.shared.instancesList?.load()
.onSuccess { response in
if let instances: [ManifestedInstance] = response.typedContent() {
self.countries = instances.map(\.country).unique().sorted()
}
}
.onFailure { _ in
model.presentAlert(title: "Could not load locations manifest".localized())
}
}
private var addInstanceButton: some View {
Button {
presentingInstanceForm = true
} label: {
Label("Add Location...", systemImage: "plus")
}
}
}
struct LocationsSettings_Previews: PreviewProvider {
static var previews: some View {
LocationsSettings()
.environmentObject(AccountsModel())
.environmentObject(NavigationModel())
}
}

View File

@ -7,10 +7,10 @@ struct SettingsView: View {
#if os(macOS)
private enum Tabs: Hashable {
case locations, browsing, player, quality, history, sponsorBlock, advanced, help
case browsing, player, quality, history, sponsorBlock, advanced, help
}
@State private var selection = Tabs.locations
@State private var selection = Tabs.browsing
#endif
@Environment(\.colorScheme) private var colorScheme
@ -34,14 +34,6 @@ struct SettingsView: View {
var settings: some View {
#if os(macOS)
TabView(selection: $selection) {
Form {
LocationsSettings()
}
.tabItem {
Label("Locations", systemImage: "globe")
}
.tag(Tabs.locations)
Form {
BrowsingSettings()
}
@ -127,12 +119,6 @@ struct SettingsView: View {
}
#endif
NavigationLink {
LocationsSettings()
} label: {
Label("Locations", systemImage: "globe")
}
NavigationLink {
BrowsingSettings()
} label: {
@ -233,11 +219,9 @@ struct SettingsView: View {
case .history:
return 500
case .sponsorBlock:
return 660
case .locations:
return 480
return 700
case .advanced:
return 340
return 650
case .help:
return 600
}

View File

@ -20,13 +20,15 @@ import SwiftUI
func makeNSView(context _: Context) -> some NSView {
player.mpvBackend.client = client
let view = MPVOGLView()
if !YatteeApp.isForPreviews {
client.layer = layer
layer.client = client
let view = MPVOGLView()
view.layer = client.layer
view.wantsLayer = true
}
return view
}

View File

@ -510,9 +510,6 @@
377ABC48286E5887009C986F /* Sequence+Unique.swift in Sources */ = {isa = PBXBuildFile; fileRef = 377ABC47286E5887009C986F /* Sequence+Unique.swift */; };
377ABC49286E5887009C986F /* Sequence+Unique.swift in Sources */ = {isa = PBXBuildFile; fileRef = 377ABC47286E5887009C986F /* Sequence+Unique.swift */; };
377ABC4A286E5887009C986F /* Sequence+Unique.swift in Sources */ = {isa = PBXBuildFile; fileRef = 377ABC47286E5887009C986F /* Sequence+Unique.swift */; };
377ABC4C286E6A78009C986F /* LocationsSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 377ABC4B286E6A78009C986F /* LocationsSettings.swift */; };
377ABC4D286E6A78009C986F /* LocationsSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 377ABC4B286E6A78009C986F /* LocationsSettings.swift */; };
377ABC4E286E6A78009C986F /* LocationsSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 377ABC4B286E6A78009C986F /* LocationsSettings.swift */; };
377FC7D5267A080300A6BBAF /* SwiftyJSON in Frameworks */ = {isa = PBXBuildFile; productRef = 377FC7D4267A080300A6BBAF /* SwiftyJSON */; };
377FC7DB267A080300A6BBAF /* Logging in Frameworks */ = {isa = PBXBuildFile; productRef = 377FC7DA267A080300A6BBAF /* Logging */; };
377FC7DC267A081800A6BBAF /* PopularView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37AAF27D26737323007FC770 /* PopularView.swift */; };
@ -1178,7 +1175,6 @@
377ABC3F286E4AD5009C986F /* InstancesManifest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InstancesManifest.swift; sourceTree = "<group>"; };
377ABC43286E4B74009C986F /* ManifestedInstance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ManifestedInstance.swift; sourceTree = "<group>"; };
377ABC47286E5887009C986F /* Sequence+Unique.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Sequence+Unique.swift"; sourceTree = "<group>"; };
377ABC4B286E6A78009C986F /* LocationsSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationsSettings.swift; sourceTree = "<group>"; };
377FF88A291A60310028EB0B /* OpenVideosModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenVideosModel.swift; sourceTree = "<group>"; };
377FF88E291A99580028EB0B /* HistoryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HistoryView.swift; sourceTree = "<group>"; };
37824309291E58D6005DEC1C /* Open in Yattee.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "Open in Yattee.entitlements"; sourceTree = "<group>"; };
@ -1817,7 +1813,6 @@
37BC50A72778A84700510953 /* HistorySettings.swift */,
37484C2426FC83E000287258 /* InstanceForm.swift */,
37484C2C26FC844700287258 /* InstanceSettings.swift */,
377ABC4B286E6A78009C986F /* LocationsSettings.swift */,
37484C1826FC837400287258 /* PlayerSettings.swift */,
374C053427242D9F009BDDBE /* SponsorBlockSettings.swift */,
376BE50627347B57009AD608 /* SettingsHeader.swift */,
@ -2961,7 +2956,6 @@
37FEF11327EFD8580033912F /* PlaceholderCell.swift in Sources */,
37B2631A2735EAAB00FE0D40 /* FavoriteResourceObserver.swift in Sources */,
3748186E26A769D60084E870 /* DetailBadge.swift in Sources */,
377ABC4C286E6A78009C986F /* LocationsSettings.swift in Sources */,
3744A96028B99ADD005DE0A7 /* PlayerControlsLayout.swift in Sources */,
376BE50B27349108009AD608 /* BrowsingSettings.swift in Sources */,
3763C989290C7A50004D3B5F /* OpenVideosView.swift in Sources */,
@ -3041,7 +3035,6 @@
37CEE4C22677B697005A1EFE /* Stream.swift in Sources */,
37F7D82D289EB05F00E2B3D0 /* SettingsPickerModifier.swift in Sources */,
3751BA8427E6914F007B1A60 /* ReturnYouTubeDislikeAPI.swift in Sources */,
377ABC4D286E6A78009C986F /* LocationsSettings.swift in Sources */,
3782B95027553A6700990149 /* SearchSuggestions.swift in Sources */,
371B7E6B2759791900D21217 /* CommentsModel.swift in Sources */,
37192D5528B0D5D60012EEDD /* PlayerLayerView.swift in Sources */,
@ -3409,7 +3402,6 @@
375F7412289DC35A00747050 /* PlayerBackendView.swift in Sources */,
37EF5C242739D37B00B03725 /* MenuModel.swift in Sources */,
37C7A1D7267BFD9D0010EAD6 /* SponsorBlockSegment.swift in Sources */,
377ABC4E286E6A78009C986F /* LocationsSettings.swift in Sources */,
3756C2A82861131100E4B059 /* NetworkState.swift in Sources */,
376578932685490700D4EA09 /* PlaylistsView.swift in Sources */,
377FF891291A99580028EB0B /* HistoryView.swift in Sources */,