1
0
mirror of https://github.com/yattee/yattee.git synced 2024-12-13 13:50:32 +05:30
yattee/Shared/Settings/LocationsSettings.swift

145 lines
5.0 KiB
Swift
Raw Normal View History

2022-11-13 16:44:05 +05:30
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
@Default(.instancesManifest) private var instancesManifest
var body: some View {
VStack(alignment: .leading) {
#if os(macOS)
settings
Spacer()
#else
List {
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)
}
.onChange(of: instancesManifest) { _ in
countryOfPublicInstances = nil
if let account = accounts.current, account.isPublic {
accounts.setCurrent(nil)
}
countries.removeAll()
}
.sheet(isPresented: $presentingInstanceForm) {
InstanceForm(savedInstanceID: $savedFormInstanceID)
}
#if os(tvOS)
.frame(maxWidth: 1000)
#endif
.navigationTitle("Locations")
}
@ViewBuilder var settings: some View {
Section(header: SettingsHeader(text: "Locations Manifest".localized())) {
TextField("URL", text: $instancesManifest)
Button("Reload manifest", action: loadCountries)
.disabled(instancesManifest.isEmpty)
#if !os(macOS)
.keyboardType(.webSearch)
#endif
.disableAutocorrection(true)
}
.padding(.bottom, 4)
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())
.environmentObject(SettingsModel())
}
}