Skip to content

Commit

Permalink
[app] Clean up preferences UI a bit; add locale setting
Browse files Browse the repository at this point in the history
  • Loading branch information
kirb committed Mar 22, 2022
1 parent 8f96284 commit 2e78f76
Show file tree
Hide file tree
Showing 15 changed files with 202 additions and 27 deletions.
13 changes: 12 additions & 1 deletion App/Controllers/SettingsSceneDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,13 @@ private extension NSToolbarItem.Identifier {
static let general = NSToolbarItem.Identifier("general")
static let interface = NSToolbarItem.Identifier("interface")
static let performance = NSToolbarItem.Identifier("performance")
static let advanced = NSToolbarItem.Identifier("advanced")
}

extension SettingsSceneDelegate: NSToolbarDelegate {

func toolbarDefaultItemIdentifiers(_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] {
[ .general, .interface, .performance ]
[ .general, .interface, .performance, .advanced ]
}

func toolbarAllowedItemIdentifiers(_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] {
Expand Down Expand Up @@ -107,6 +108,12 @@ extension SettingsSceneDelegate: NSToolbarDelegate {
icon: "hare",
action: #selector(selectPerformanceTab))

case .advanced:
return makeToolbarItem(itemIdentifier: itemIdentifier,
label: "Advanced",
icon: "sparkles",
action: #selector(selectAdvancedTab))

default:
return nil
}
Expand Down Expand Up @@ -152,5 +159,9 @@ extension SettingsSceneDelegate: NSToolbarDelegate {
switchTab(rootView: SettingsPerformanceView(), size: CGSize(width: 600, height: 500))
}

@objc private func selectAdvancedTab() {
switchTab(rootView: SettingsAdvancedView(), size: CGSize(width: 600, height: 500))
}

}
#endif
2 changes: 1 addition & 1 deletion App/UI/Settings/Mac/SettingsGeneralView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ struct SettingsGeneralView: View {
header: Text("Settings Sync"),
footer: Text("Keep your NewTerm settings in sync between your Mac, iPhone, and iPad by selecting iCloud sync. If you just want to keep a backup with a service such as Dropbox, select custom folder sync.")
) {
Picker("Sync app settings:", selection: preferences.$preferencesSyncService) {
PreferencesPicker(selection: preferences.$preferencesSyncService, label: "Sync app settings:") {
Text("Don’t sync")
.tag(PreferencesSyncService.none)
Text("via iCloud")
Expand Down
13 changes: 4 additions & 9 deletions App/UI/Settings/Mac/SettingsInterfaceView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -67,19 +67,14 @@ struct SettingsInterfaceView: View {
)
.padding([.top, .bottom, .leading], 20)

let themes = Picker("Theme", selection: preferences.$themeName) {
ForEach(sortedThemes, id: \.key) { key, value in
Button(
action: {
preferences.themeName = key
},
label: { Text(key) }
)
let themes = PreferencesPicker(selection: preferences.$themeName, label: "Theme") {
ForEach(sortedThemes, id: \.key) { key, _ in
Text(key)
}
}
.pickerStyle(MenuPickerStyle())

let fonts = Picker("Font", selection: preferences.$fontName) {
let fonts = PreferencesPicker(selection: preferences.$fontName, label: "Font") {
Text("Default (SF Mono)")
.id("SF Mono")
HStack {
Expand Down
1 change: 0 additions & 1 deletion App/UI/Settings/PreferencesGroup.swift
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ struct PreferencesGroup<Header: View, Footer: View, Content: View>: View {
) {
content
}
.pickerStyle(InlinePickerStyle())
#endif
}

Expand Down
2 changes: 1 addition & 1 deletion App/UI/Settings/PreferencesList.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ struct PreferencesList<Content: View>: View {
}
.navigationBarTitleDisplayMode(.inline)
#else
List {
Form {
content
}
.listStyle(InsetGroupedListStyle())
Expand Down
51 changes: 51 additions & 0 deletions App/UI/Settings/PreferencesPicker.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
//
// PreferencesPicker.swift
// NewTerm (iOS)
//
// Created by Adam Demasi on 5/12/21.
//

import SwiftUI

struct PreferencesPicker<Label: View, SelectionValue: Hashable, Content: View>: View {

var label: Label
var selectionBinding: Binding<SelectionValue>
var content: Content

init(selection: Binding<SelectionValue>, label: Label, @ViewBuilder content: () -> Content) {
self.label = label
self.selectionBinding = selection
self.content = content()
}

var body: some View {
#if targetEnvironment(macCatalyst)
Picker(
selection: selectionBinding,
content: { content },
label: { label }
)
#else
Section(
header: label
) {
Picker(
selection: selectionBinding,
content: { content },
label: { label }
)
}
.pickerStyle(InlinePickerStyle())
#endif
}

}

extension PreferencesPicker where Label == Text {
init(selection: Binding<SelectionValue>, label: String, @ViewBuilder content: () -> Content) {
self.label = Text(label)
self.selectionBinding = selection
self.content = content()
}
}
96 changes: 96 additions & 0 deletions App/UI/Settings/SettingsAdvancedView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
//
// SettingsAdvancedView.swift
// NewTerm (iOS)
//
// Created by Adam Demasi on 16/9/21.
//

import SwiftUI

struct SettingsAdvancedView: View {

private struct LocaleItem: Identifiable, Comparable {
let locale: Locale
let name: String
var id: String { locale == .autoupdatingCurrent ? "" : locale.identifier }

static func < (lhs: Self, rhs: Self) -> Bool {
lhs.name < rhs.name
}
}

private var systemLocale: LocaleItem {
let mainLocale = Locale.autoupdatingCurrent
let name = String(format: .localize("LOCALE_SYSTEM"),
mainLocale.localizedString(forIdentifier: mainLocale.identifier) ?? mainLocale.identifier)
return LocaleItem(locale: mainLocale, name: name)
}

private let locales: [LocaleItem] = {
let mainLocale = Locale.autoupdatingCurrent
let items = try! FileManager.default.contentsOfDirectory(at: URL(fileURLWithPath: "/usr/share/locale"),
includingPropertiesForKeys: [],
options: .skipsSubdirectoryDescendants)
return items
.compactMap { item in
guard let code = item.pathComponents.last,
code.hasSuffix(".UTF-8") else {
return nil
}
let locale = Locale(identifier: code)
return LocaleItem(locale: locale,
name: mainLocale.localizedString(forIdentifier: locale.identifier) ?? locale.identifier)
}
.sorted()
}()

@ObservedObject var preferences = Preferences.shared

var body: some View {
let systemLocale = self.systemLocale
let list = ForEach(locales) { item in
Text(item.name)
}

return PreferencesList {
#if !targetEnvironment(macCatalyst)
PreferencesGroup {
NavigationLink(
destination: SettingsPerformanceView(),
label: { Text("Performance") }
)
}
#endif

PreferencesGroup(
header: Text("Locale"),
footer: Text("NewTerm will ask terminal programs to use this locale. Not all programs support this. This will not apply to currently open tabs, and may be overridden by shell startup scripts.")
) {
PreferencesPicker(
selection: preferences.$preferredLocale,
label: Text("Language")
) {
Text(systemLocale.name)
.tag(systemLocale.id)
Divider()
list
}
#if targetEnvironment(macCatalyst)
.pickerStyle(MenuPickerStyle())
#else
.pickerStyle(RadioGroupPickerStyle())
#endif
}
}
.navigationBarTitle("Advanced")
}

}

struct SettingsAdvancedView_Previews: PreviewProvider {
static var previews: some View {
NavigationView {
SettingsAdvancedView()
}
}
}
4 changes: 2 additions & 2 deletions App/UI/Settings/SettingsPerformanceView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ struct SettingsPerformanceView: View {
? AnyView(EmptyView())
: AnyView(Text("The Performance setting is recommended."))
) {
Picker(
PreferencesPicker(
selection: preferences.$refreshRateOnAC,
label: EmptyView()
) {
Expand All @@ -88,7 +88,7 @@ struct SettingsPerformanceView: View {
footer: Text("A lower refresh rate improves \(UIDevice.current.deviceModel) battery life, but may cause the terminal display to feel sluggish.\nThe Performance setting is recommended.")
.fixedSize(horizontal: false, vertical: true)
) {
Picker(
PreferencesPicker(
selection: preferences.$refreshRateOnBattery,
label: EmptyView()
) {
Expand Down
2 changes: 1 addition & 1 deletion App/UI/Settings/iOS/SettingsFontView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ struct SettingsFontView: View {

PreferencesList {
PreferencesGroup(header: Text("Font")) {
Picker(selection: preferences.$fontName, label: EmptyView()) {
PreferencesPicker(selection: preferences.$fontName, label: EmptyView()) {
ForEach(sortedFonts, id: \.key) { key, value in
HStack(alignment: .center) {
if value.previewFont == nil {
Expand Down
2 changes: 1 addition & 1 deletion App/UI/Settings/iOS/SettingsThemeView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ struct SettingsThemeView: View {

PreferencesList {
PreferencesGroup(header: Text("Built in Themes")) {
Picker(selection: preferences.$themeName, label: EmptyView()) {
PreferencesPicker(selection: preferences.$themeName, label: EmptyView()) {
ForEach(sortedThemes, id: \.key) { item in Text(item.key) }
}
}
Expand Down
4 changes: 2 additions & 2 deletions App/UI/Settings/iOS/SettingsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ struct SettingsView: View {
#if !targetEnvironment(macCatalyst)
Section {
NavigationLink(
destination: SettingsPerformanceView(),
label: { Text("Performance") }
destination: SettingsAdvancedView(),
label: { Text("Advanced") }
)
}

Expand Down
5 changes: 5 additions & 0 deletions Common/Controllers/Preferences.swift
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,11 @@ public class Preferences: NSObject, ObservableObject {
willSet { objectWillChange.send() }
}

@AppStorage("preferredLocale")
public var preferredLocale: String = "" {
willSet { objectWillChange.send() }
}

@AppStorage("lastVersion")
public var lastVersion: Int = 0 {
willSet { objectWillChange.send() }
Expand Down
12 changes: 10 additions & 2 deletions Common/Controllers/SubProcess.swift
Original file line number Diff line number Diff line change
Expand Up @@ -149,9 +149,17 @@ class SubProcess: NSObject {
// instance, a phone set to Simplified Chinese but a region of Australia will only have the
// language zh_AU… which isn’t a thing. But gettext only has languages in country pairs, no
// safe generic fallbacks exist, like zh-Hans in this case.
for language in Locale.preferredLanguages {
var languages = Locale.preferredLanguages
let preferredLocale = Preferences.shared.preferredLocale
if preferredLocale != "",
Locale(identifier: preferredLocale).languageCode != nil {
languages.insert(preferredLocale, at: 0)
}

for language in languages {
let locale = Locale(identifier: language)
if let languageCode = locale.languageCode, let regionCode = locale.regionCode {
if let languageCode = locale.languageCode,
let regionCode = locale.regionCode {
let identifier = "\(languageCode)_\(regionCode).UTF-8"
let url = URL(fileURLWithPath: "/usr/share/locale").appendingPathComponent(identifier)
if (try? url.checkResourceIsReachable()) == true {
Expand Down
Loading

0 comments on commit 2e78f76

Please sign in to comment.