From a3ed6a21f6f6d60537a0b379c4a76ad9206f15da Mon Sep 17 00:00:00 2001 From: Purnama S Rahayu Date: Fri, 27 Mar 2026 08:14:36 +0700 Subject: [PATCH 1/4] add conjugate Settings tab contents #609 --- .../Views/Tabs/Settings/SettingsTab.swift | 143 +++++++++++++++++- Scribe.xcodeproj/project.pbxproj | 93 ------------ 2 files changed, 139 insertions(+), 97 deletions(-) diff --git a/Conjugate/Views/Tabs/Settings/SettingsTab.swift b/Conjugate/Views/Tabs/Settings/SettingsTab.swift index 57468676..070f547b 100644 --- a/Conjugate/Views/Tabs/Settings/SettingsTab.swift +++ b/Conjugate/Views/Tabs/Settings/SettingsTab.swift @@ -3,11 +3,146 @@ import SwiftUI struct SettingsTab: View { + @State private var isDarkMode = false + @State private var isLargeText = false + @State private var isHighContrast = false + + var body: some View { + AppNavigation { + ZStack(alignment: .top) { + Color.scribeBlue + .ignoresSafeArea() + VStack(alignment: .leading) { + Text(NSLocalizedString( + "i18n.app.settings.menu.title", + value: "App settings", + comment: ""), + ) + .padding(.horizontal) + .padding(.top, 20) + .font(.title3.weight(.semibold)) + VStack(spacing: 20) { + SettingsNavigationRow( + title: NSLocalizedString( + "i18n.app.settings.menu.app_language", + value: "App language", + comment: "", + ), + caption: NSLocalizedString( + "i18n.app.settings.menu.app_language_description", + value: "Change which language the Scribe app is in.", + comment: "", + ), + ) + SettingsToggleRow( + title: NSLocalizedString( + "i18n.app.settings.menu.app_color_mode", + value: "Dark mode", + comment: "", + ), + caption: NSLocalizedString( + "i18n.app.settings.menu.app_color_mode_description", + value: "Change the application display to dark mode.", + comment: "", + ), + isOn: $isDarkMode, + ) + SettingsToggleRow( + title: NSLocalizedString( + "i18n.app.settings.menu.increase_text_size", + value: "Increase app text size", + comment: "" + ), + caption: NSLocalizedString( + "i18n.app.settings.menu.increase_text_size_description", + value: "Increase the size of menu texts for better readability.", + comment: "" + ), + isOn: $isLargeText, + ) + SettingsToggleRow( + title: NSLocalizedString( + "i18n.app.settings.menu.high_color_contrast", + value: "High color contrast", + comment: "", + ), + caption: NSLocalizedString( + "i18n.app.settings.menu.high_color_contrast_description", + value: "Increase color contrast for improved accessibility and a clearer viewing experience.", + comment: "" + ), + isOn: $isHighContrast, + ) + } + .padding() + .frame(maxWidth: .infinity) + .background(Color.white) + .cornerRadius(16) + .padding(.horizontal) + } + } + .navigationTitle(NSLocalizedString( + "i18n.app.settings.title", + value: "Settings", + comment: ""), + ) + } + } +} + +struct SettingsNavigationRow: View { + let title: String + let caption: String + + var body: some View { + VStack(alignment: .leading, spacing: 6) { + + HStack { + Text(title) + .font(.body) + + Spacer() + + HStack { + Text("English") + .font(.body) + .foregroundColor(.secondary) + + Image(systemName: "chevron.right") + .foregroundColor(.secondary) + } + } + + Text(caption) + .font(.caption) + .foregroundColor(.secondary) + } + } +} + +struct SettingsToggleRow: View { + let title: String + let caption: String + @Binding var isOn: Bool + var body: some View { - AppNavigation { - Text("Settings") - .font(.largeTitle) - .navigationTitle("Settings") + VStack(alignment: .leading, spacing: 6) { + + HStack { + Text(title) + .font(.body) + + Spacer() + + Toggle("", isOn: $isOn) + .labelsHidden() + .tint(Color.scribeCTA) } + + Text(caption) + .font(.caption) + .foregroundColor(.secondary) + } + } } diff --git a/Scribe.xcodeproj/project.pbxproj b/Scribe.xcodeproj/project.pbxproj index 2ad3e9d9..6868221e 100644 --- a/Scribe.xcodeproj/project.pbxproj +++ b/Scribe.xcodeproj/project.pbxproj @@ -673,7 +673,6 @@ E98034DE2F45AE1F006C1CDC /* LanguageData.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9F727382F4468960060B92D /* LanguageData.swift */; }; E98034DF2F45AE1F006C1CDC /* LanguageData.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9F727382F4468960060B92D /* LanguageData.swift */; }; E98034E42F45B88C006C1CDC /* ToastView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E98034E32F45B88C006C1CDC /* ToastView.swift */; }; - E98034E52F45B88C006C1CDC /* ToastView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E98034E32F45B88C006C1CDC /* ToastView.swift */; }; E996495A2E98A12100200F53 /* GRDB in Frameworks */ = {isa = PBXBuildFile; productRef = E99649592E98A12100200F53 /* GRDB */; }; E996495B2E98A31B00200F53 /* KeyboardProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 198369CB2C7980BA00C1B583 /* KeyboardProvider.swift */; }; E996495C2E98A32900200F53 /* KeyboardViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D190B2592742565500705659 /* KeyboardViewController.swift */; }; @@ -739,7 +738,6 @@ E9ED93872F2A3C45008D7451 /* DynamicConjugationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9ED937C2F2A3C32008D7451 /* DynamicConjugationViewController.swift */; }; E9ED93882F2A3C45008D7451 /* DynamicConjugationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9ED937C2F2A3C32008D7451 /* DynamicConjugationViewController.swift */; }; E9ED93892F2A3C45008D7451 /* DynamicConjugationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9ED937C2F2A3C32008D7451 /* DynamicConjugationViewController.swift */; }; - E9ED938A2F2A3C45008D7451 /* DynamicConjugationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9ED937C2F2A3C32008D7451 /* DynamicConjugationViewController.swift */; }; E9F7273D2F45A6CE0060B92D /* LanguageData.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9F727382F4468960060B92D /* LanguageData.swift */; }; E9F7273E2F45A6DE0060B92D /* LanguageDataService.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9F7273C2F45856C0060B92D /* LanguageDataService.swift */; }; E9F7273F2F45A6E60060B92D /* APIClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9F7273A2F457A7E0060B92D /* APIClient.swift */; }; @@ -1363,7 +1361,6 @@ /* Begin PBXFileSystemSynchronizedRootGroup section */ E943457E2F05638700DFDB20 /* Button */ = {isa = PBXFileSystemSynchronizedRootGroup; exceptions = (F7A17EA92F6A8BC90040B09B /* PBXFileSystemSynchronizedBuildFileExceptionSet */, ); explicitFileTypes = {}; explicitFolders = (); path = Button; sourceTree = ""; }; - E98E73BE2F20D8AA005EEDA3 /* Data */ = {isa = PBXFileSystemSynchronizedRootGroup; exceptions = (E98E74352F20EA5E005EEDA3 /* PBXFileSystemSynchronizedBuildFileExceptionSet */, E98E74362F20EA5E005EEDA3 /* PBXFileSystemSynchronizedBuildFileExceptionSet */, E98E74372F20EA5E005EEDA3 /* PBXFileSystemSynchronizedBuildFileExceptionSet */, E98E74382F20EA5E005EEDA3 /* PBXFileSystemSynchronizedBuildFileExceptionSet */, E98E74392F20EA5E005EEDA3 /* PBXFileSystemSynchronizedBuildFileExceptionSet */, E98E743A2F20EA5E005EEDA3 /* PBXFileSystemSynchronizedBuildFileExceptionSet */, E98E743B2F20EA5E005EEDA3 /* PBXFileSystemSynchronizedBuildFileExceptionSet */, E98E743C2F20EA5E005EEDA3 /* PBXFileSystemSynchronizedBuildFileExceptionSet */, E98E743D2F20EA5E005EEDA3 /* PBXFileSystemSynchronizedBuildFileExceptionSet */, E98E743E2F20EA5E005EEDA3 /* PBXFileSystemSynchronizedBuildFileExceptionSet */, E98E743F2F20EA5E005EEDA3 /* PBXFileSystemSynchronizedBuildFileExceptionSet */, E98E74402F20EA5E005EEDA3 /* PBXFileSystemSynchronizedBuildFileExceptionSet */, ); explicitFileTypes = {}; explicitFolders = (); path = Data; sourceTree = ""; }; E98E73BF2F20D8C3005EEDA3 /* DataContracts */ = {isa = PBXFileSystemSynchronizedRootGroup; explicitFileTypes = {}; explicitFolders = (); path = DataContracts; sourceTree = ""; }; E9B89DCD2F226757003E396F /* DataManager */ = {isa = PBXFileSystemSynchronizedRootGroup; exceptions = (E9B89DCE2F22676B003E396F /* PBXFileSystemSynchronizedBuildFileExceptionSet */, E9B89DCF2F22676B003E396F /* PBXFileSystemSynchronizedBuildFileExceptionSet */, E9B89DD02F22676B003E396F /* PBXFileSystemSynchronizedBuildFileExceptionSet */, E9B89DD12F22676B003E396F /* PBXFileSystemSynchronizedBuildFileExceptionSet */, E9B89DD22F22676B003E396F /* PBXFileSystemSynchronizedBuildFileExceptionSet */, E9B89DD32F22676B003E396F /* PBXFileSystemSynchronizedBuildFileExceptionSet */, E9B89DD42F22676B003E396F /* PBXFileSystemSynchronizedBuildFileExceptionSet */, E9B89DD52F22676B003E396F /* PBXFileSystemSynchronizedBuildFileExceptionSet */, E9B89DD62F22676B003E396F /* PBXFileSystemSynchronizedBuildFileExceptionSet */, E9B89DD72F22676B003E396F /* PBXFileSystemSynchronizedBuildFileExceptionSet */, E9B89DD82F22676B003E396F /* PBXFileSystemSynchronizedBuildFileExceptionSet */, E9B89DD92F22676B003E396F /* PBXFileSystemSynchronizedBuildFileExceptionSet */, E9B89DDA2F22676B003E396F /* PBXFileSystemSynchronizedBuildFileExceptionSet */, ); explicitFileTypes = {}; explicitFolders = (); path = DataManager; sourceTree = ""; }; E9DADB332EF3CF9B00702783 /* ConfirmDialog */ = {isa = PBXFileSystemSynchronizedRootGroup; exceptions = (F7A17EAA2F6A8BE30040B09B /* PBXFileSystemSynchronizedBuildFileExceptionSet */, ); explicitFileTypes = {}; explicitFolders = (); path = ConfirmDialog; sourceTree = ""; }; @@ -1954,7 +1951,6 @@ D1FECBC9270E1A1500C8BC60 /* Keyboards */ = { isa = PBXGroup; children = ( - E90EF8AD2F485B91007D967C /* Data */, D190B2452741B1FE00705659 /* KeyboardsBase */, D1CCA15B2742B9F700902744 /* LanguageKeyboards */, EDC364682AE408F20001E456 /* InterfaceConstants.swift */, @@ -2192,7 +2188,6 @@ 5A8FFB6D2C5A9D9C00F4B571 /* PBXTargetDependency */, ); fileSystemSynchronizedGroups = ( - E90EF8AD2F485B91007D967C /* Data */, E943457E2F05638700DFDB20 /* Button */, E9DADB332EF3CF9B00702783 /* ConfirmDialog */, ); @@ -2220,7 +2215,6 @@ dependencies = ( ); fileSystemSynchronizedGroups = ( - E90EF8AD2F485B91007D967C /* Data */, E98E73BF2F20D8C3005EEDA3 /* DataContracts */, ); name = German; @@ -2246,7 +2240,6 @@ dependencies = ( ); fileSystemSynchronizedGroups = ( - E90EF8AD2F485B91007D967C /* Data */, E98E73BF2F20D8C3005EEDA3 /* DataContracts */, ); name = French; @@ -2272,7 +2265,6 @@ dependencies = ( ); fileSystemSynchronizedGroups = ( - E90EF8AD2F485B91007D967C /* Data */, E98E73BF2F20D8C3005EEDA3 /* DataContracts */, ); name = Portuguese; @@ -2316,7 +2308,6 @@ dependencies = ( ); fileSystemSynchronizedGroups = ( - E90EF8AD2F485B91007D967C /* Data */, E98E73BF2F20D8C3005EEDA3 /* DataContracts */, ); name = Spanish; @@ -2342,7 +2333,6 @@ dependencies = ( ); fileSystemSynchronizedGroups = ( - E90EF8AD2F485B91007D967C /* Data */, E98E73BF2F20D8C3005EEDA3 /* DataContracts */, ); name = Russian; @@ -2368,7 +2358,6 @@ dependencies = ( ); fileSystemSynchronizedGroups = ( - E90EF8AD2F485B91007D967C /* Data */, E98E73BF2F20D8C3005EEDA3 /* DataContracts */, ); name = Swedish; @@ -2394,7 +2383,6 @@ dependencies = ( ); fileSystemSynchronizedGroups = ( - E90EF8AD2F485B91007D967C /* Data */, E98E73BF2F20D8C3005EEDA3 /* DataContracts */, ); name = Norwegian; @@ -2420,7 +2408,6 @@ dependencies = ( ); fileSystemSynchronizedGroups = ( - E90EF8AD2F485B91007D967C /* Data */, E98E73BF2F20D8C3005EEDA3 /* DataContracts */, ); name = English; @@ -2446,7 +2433,6 @@ dependencies = ( ); fileSystemSynchronizedGroups = ( - E90EF8AD2F485B91007D967C /* Data */, E98E73BF2F20D8C3005EEDA3 /* DataContracts */, ); name = Danish; @@ -2472,7 +2458,6 @@ dependencies = ( ); fileSystemSynchronizedGroups = ( - E90EF8AD2F485B91007D967C /* Data */, E98E73BF2F20D8C3005EEDA3 /* DataContracts */, ); name = Hebrew; @@ -2498,7 +2483,6 @@ dependencies = ( ); fileSystemSynchronizedGroups = ( - E90EF8AD2F485B91007D967C /* Data */, E98E73BF2F20D8C3005EEDA3 /* DataContracts */, ); name = Italian; @@ -2524,7 +2508,6 @@ dependencies = ( ); fileSystemSynchronizedGroups = ( - E90EF8AD2F485B91007D967C /* Data */, E98E73BF2F20D8C3005EEDA3 /* DataContracts */, ); name = Indonesian; @@ -2564,7 +2547,6 @@ F786BAC92F1E8F70003F7505 /* PBXTargetDependency */, ); fileSystemSynchronizedGroups = ( - E90EF8AD2F485B91007D967C /* Data */, E943457E2F05638700DFDB20 /* Button */, E9DADB332EF3CF9B00702783 /* ConfirmDialog */, ); @@ -3631,81 +3613,6 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - E97E65172F2CDD730070810A /* ESInterfaceVariables.swift in Sources */, - E9ED938A2F2A3C45008D7451 /* DynamicConjugationViewController.swift in Sources */, - F786BAD42F1E8F70003F7505 /* ThirdPartyLicense.swift in Sources */, - F786BAD52F1E8F70003F7505 /* (null) in Sources */, - F786BAD62F1E8F70003F7505 /* AppTextStyling.swift in Sources */, - E91980BE2F2F540A00B5852F /* NavigationStructure.swift in Sources */, - F786BAD72F1E8F70003F7505 /* ScribeColor.swift in Sources */, - F786BAD82F1E8F70003F7505 /* Conjugate.swift in Sources */, - F786BAD92F1E8F70003F7505 /* SettingsViewController.swift in Sources */, - F786BADA2F1E8F70003F7505 /* AboutTableData.swift in Sources */, - F786BADB2F1E8F70003F7505 /* DownloadStateManager.swift in Sources */, - F786BADC2F1E8F70003F7505 /* IDInterfaceVariables.swift in Sources */, - F786BADE2F1E8F70003F7505 /* ToolTipViewDatasource.swift in Sources */, - F786BADF2F1E8F70003F7505 /* Translate.swift in Sources */, - F786BAE32F1E8F70003F7505 /* ScribeKey.swift in Sources */, - F786BAE42F1E8F70003F7505 /* AppExtensions.swift in Sources */, - F786BAE62F1E8F70003F7505 /* FR-AZERTYInterfaceVariables.swift in Sources */, - F786BAE72F1E8F70003F7505 /* ENInterfaceVariables.swift in Sources */, - F786BAE82F1E8F70003F7505 /* InstallationVC.swift in Sources */, - F786BAE92F1E8F70003F7505 /* DEInterfaceVariables.swift in Sources */, - F786BAEA2F1E8F70003F7505 /* SettingsTableData.swift in Sources */, - F786BAEB2F1E8F70003F7505 /* InformationScreenVC.swift in Sources */, - F786BAEC2F1E8F70003F7505 /* InfoChildTableViewCell.swift in Sources */, - F786BAED2F1E8F70003F7505 /* AppUISymbols.swift in Sources */, - F786BAEE2F1E8F70003F7505 /* KeyboardViewController.swift in Sources */, - F786BAEF2F1E8F70003F7505 /* InstallationDownload.swift in Sources */, - F786BAF02F1E8F70003F7505 /* UIEdgeInsetsExtensions.swift in Sources */, - F786BAF12F1E8F70003F7505 /* (null) in Sources */, - F786BAF22F1E8F70003F7505 /* KeyboardStyling.swift in Sources */, - F786BAF32F1E8F70003F7505 /* Annotate.swift in Sources */, - F786BAF42F1E8F70003F7505 /* KeyboardBuilder.swift in Sources */, - F786BAF52F1E8F70003F7505 /* KeyboardProvider.swift in Sources */, - F786BAF62F1E8F70003F7505 /* UIColor+ScribeColors.swift in Sources */, - F786BAF72F1E8F70003F7505 /* SVInterfaceVariables.swift in Sources */, - F786BAF92F1E8F70003F7505 /* TableViewTemplateViewController.swift in Sources */, - F786BAFB2F1E8F70003F7505 /* AppDelegate.swift in Sources */, - F786BAFC2F1E8F70003F7505 /* ToolTipView.swift in Sources */, - F786BAFD2F1E8F70003F7505 /* ToolTipViewTheme.swift in Sources */, - F786BAFE2F1E8F70003F7505 /* RadioTableViewCell.swift in Sources */, - F786BAFF2F1E8F70003F7505 /* CommandVariables.swift in Sources */, - F786BB002F1E8F70003F7505 /* DownloadDataScreen.swift in Sources */, - F786BB012F1E8F70003F7505 /* Utilities.swift in Sources */, - F786BB022F1E8F70003F7505 /* BaseTableViewController.swift in Sources */, - E98034E52F45B88C006C1CDC /* ToastView.swift in Sources */, - F786BB032F1E8F70003F7505 /* DAInterfaceVariables.swift in Sources */, - F786BB052F1E8F70003F7505 /* UIDeviceExtensions.swift in Sources */, - E97E65222F2CDEC50070810A /* ESCommandVariables.swift in Sources */, - F786BB062F1E8F70003F7505 /* TipCardView.swift in Sources */, - F786BB072F1E8F70003F7505 /* InformationToolTipData.swift in Sources */, - F786BB082F1E8F70003F7505 /* ToolTipViewUpdatable.swift in Sources */, - F786BB092F1E8F70003F7505 /* RUInterfaceVariables.swift in Sources */, - F786BB0A2F1E8F70003F7505 /* ITInterfaceVariables.swift in Sources */, - F786BB0B2F1E8F70003F7505 /* PTInterfaceVariables.swift in Sources */, - F786BB0C2F1E8F70003F7505 /* HEInterfaceVariables.swift in Sources */, - F786BB0D2F1E8F70003F7505 /* AppStyling.swift in Sources */, - F786BB0E2F1E8F70003F7505 /* Plural.swift in Sources */, - F786BB0F2F1E8F70003F7505 /* InterfaceVariables.swift in Sources */, - F786BB102F1E8F70003F7505 /* CommandBar.swift in Sources */, - F786BB122F1E8F70003F7505 /* ViewThemeable.swift in Sources */, - F786BB132F1E8F70003F7505 /* ColorVariables.swift in Sources */, - F786BB142F1E8F70003F7505 /* SelectionViewTemplateViewController.swift in Sources */, - F786BB152F1E8F70003F7505 /* AboutTableViewCell.swift in Sources */, - F786BB162F1E8F70003F7505 /* InstallScreen.swift in Sources */, - F786BB182F1E8F70003F7505 /* KeyboardKeys.swift in Sources */, - F786BB192F1E8F70003F7505 /* ParentTableCellModel.swift in Sources */, - F786BB1A2F1E8F70003F7505 /* WrapperCell.swift in Sources */, - F786BB1B2F1E8F70003F7505 /* WikimediaAndScribe.swift in Sources */, - F786BB1C2F1E8F70003F7505 /* ToolTipViewDatasourceable.swift in Sources */, - F786BB1D2F1E8F70003F7505 /* KeyAltChars.swift in Sources */, - F786BB1E2F1E8F70003F7505 /* NBInterfaceVariables.swift in Sources */, - F786BB1F2F1E8F70003F7505 /* FR-QWERTYInterfaceVariables.swift in Sources */, - F786BB202F1E8F70003F7505 /* KeyAnimation.swift in Sources */, - F786BB212F1E8F70003F7505 /* AboutViewController.swift in Sources */, - F786BB222F1E8F70003F7505 /* Extensions.swift in Sources */, - F786BB232F1E8F70003F7505 /* InterfaceConstants.swift in Sources */, F7A17EBD2F6A8C230040B09B /* ContentView.swift in Sources */, F7A17EBC2F6A8C200040B09B /* ConjugateTab.swift in Sources */, F7A17EBB2F6A8C1C0040B09B /* AboutTab.swift in Sources */, From 61f9bdb7de68d825958279afb0ce4bde1db370d3 Mon Sep 17 00:00:00 2001 From: Purnama S Rahayu Date: Fri, 27 Mar 2026 08:31:39 +0700 Subject: [PATCH 2/4] enable Conjugate Settings dark mode feature #609 --- Conjugate/ConjugateApp.swift | 2 ++ Conjugate/Views/Tabs/Settings/SettingsTab.swift | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Conjugate/ConjugateApp.swift b/Conjugate/ConjugateApp.swift index cba393de..235bf2ce 100644 --- a/Conjugate/ConjugateApp.swift +++ b/Conjugate/ConjugateApp.swift @@ -4,9 +4,11 @@ import SwiftUI @main struct ConjugateApp: App { + @AppStorage("isDarkMode") private var isDarkMode = false var body: some Scene { WindowGroup { ContentView() + .preferredColorScheme(isDarkMode ? .dark : .light) } } } diff --git a/Conjugate/Views/Tabs/Settings/SettingsTab.swift b/Conjugate/Views/Tabs/Settings/SettingsTab.swift index 070f547b..f11d7db5 100644 --- a/Conjugate/Views/Tabs/Settings/SettingsTab.swift +++ b/Conjugate/Views/Tabs/Settings/SettingsTab.swift @@ -3,7 +3,7 @@ import SwiftUI struct SettingsTab: View { - @State private var isDarkMode = false + @AppStorage("isDarkMode") private var isDarkMode = false @State private var isLargeText = false @State private var isHighContrast = false @@ -76,7 +76,7 @@ struct SettingsTab: View { } .padding() .frame(maxWidth: .infinity) - .background(Color.white) + .background(Color(.systemBackground)) .cornerRadius(16) .padding(.horizontal) } From 578088df820029bef6a68abe72b95a19ecab29c4 Mon Sep 17 00:00:00 2001 From: Purnama S Rahayu Date: Fri, 27 Mar 2026 22:52:34 +0700 Subject: [PATCH 3/4] enable increase text size Conjugate Settings tab #609 --- Conjugate/ConjugateApp.swift | 2 ++ Conjugate/Views/Tabs/Settings/SettingsTab.swift | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Conjugate/ConjugateApp.swift b/Conjugate/ConjugateApp.swift index 235bf2ce..845c3039 100644 --- a/Conjugate/ConjugateApp.swift +++ b/Conjugate/ConjugateApp.swift @@ -5,10 +5,12 @@ import SwiftUI @main struct ConjugateApp: App { @AppStorage("isDarkMode") private var isDarkMode = false + @AppStorage("increaseTextSize") private var increaseTextSize = false var body: some Scene { WindowGroup { ContentView() .preferredColorScheme(isDarkMode ? .dark : .light) + .dynamicTypeSize(increaseTextSize ? .xLarge : .medium) } } } diff --git a/Conjugate/Views/Tabs/Settings/SettingsTab.swift b/Conjugate/Views/Tabs/Settings/SettingsTab.swift index f11d7db5..c7e683bc 100644 --- a/Conjugate/Views/Tabs/Settings/SettingsTab.swift +++ b/Conjugate/Views/Tabs/Settings/SettingsTab.swift @@ -4,7 +4,7 @@ import SwiftUI struct SettingsTab: View { @AppStorage("isDarkMode") private var isDarkMode = false - @State private var isLargeText = false + @AppStorage("increaseTextSize") private var increaseTextSize = false @State private var isHighContrast = false var body: some View { @@ -58,7 +58,7 @@ struct SettingsTab: View { value: "Increase the size of menu texts for better readability.", comment: "" ), - isOn: $isLargeText, + isOn: $increaseTextSize, ) SettingsToggleRow( title: NSLocalizedString( From 34f1cf69b226d0143af234ae21735fe1d80fba24 Mon Sep 17 00:00:00 2001 From: Purnama S Rahayu Date: Sat, 28 Mar 2026 00:45:11 +0700 Subject: [PATCH 4/4] enable App language Conjugate Settings #609 --- Conjugate/ConjugateApp.swift | 8 +- .../Views/Tabs/Settings/SettingsTab.swift | 252 ++++++++++-------- 2 files changed, 141 insertions(+), 119 deletions(-) diff --git a/Conjugate/ConjugateApp.swift b/Conjugate/ConjugateApp.swift index 845c3039..9df509cd 100644 --- a/Conjugate/ConjugateApp.swift +++ b/Conjugate/ConjugateApp.swift @@ -4,13 +4,13 @@ import SwiftUI @main struct ConjugateApp: App { - @AppStorage("isDarkMode") private var isDarkMode = false - @AppStorage("increaseTextSize") private var increaseTextSize = false + @AppStorage("isDarkMode") private var isDarkMode = false + @AppStorage("increaseTextSize") private var increaseTextSize = false var body: some Scene { WindowGroup { ContentView() - .preferredColorScheme(isDarkMode ? .dark : .light) - .dynamicTypeSize(increaseTextSize ? .xLarge : .medium) + .preferredColorScheme(isDarkMode ? .dark : .light) + .dynamicTypeSize(increaseTextSize ? .xLarge : .medium) } } } diff --git a/Conjugate/Views/Tabs/Settings/SettingsTab.swift b/Conjugate/Views/Tabs/Settings/SettingsTab.swift index c7e683bc..b052b18e 100644 --- a/Conjugate/Views/Tabs/Settings/SettingsTab.swift +++ b/Conjugate/Views/Tabs/Settings/SettingsTab.swift @@ -3,121 +3,143 @@ import SwiftUI struct SettingsTab: View { - @AppStorage("isDarkMode") private var isDarkMode = false - @AppStorage("increaseTextSize") private var increaseTextSize = false - @State private var isHighContrast = false - - var body: some View { - AppNavigation { - ZStack(alignment: .top) { - Color.scribeBlue - .ignoresSafeArea() - VStack(alignment: .leading) { - Text(NSLocalizedString( - "i18n.app.settings.menu.title", - value: "App settings", - comment: ""), - ) - .padding(.horizontal) - .padding(.top, 20) - .font(.title3.weight(.semibold)) - VStack(spacing: 20) { - SettingsNavigationRow( - title: NSLocalizedString( - "i18n.app.settings.menu.app_language", - value: "App language", - comment: "", - ), - caption: NSLocalizedString( - "i18n.app.settings.menu.app_language_description", - value: "Change which language the Scribe app is in.", - comment: "", - ), - ) - SettingsToggleRow( - title: NSLocalizedString( - "i18n.app.settings.menu.app_color_mode", - value: "Dark mode", - comment: "", - ), - caption: NSLocalizedString( - "i18n.app.settings.menu.app_color_mode_description", - value: "Change the application display to dark mode.", - comment: "", - ), - isOn: $isDarkMode, - ) - SettingsToggleRow( - title: NSLocalizedString( - "i18n.app.settings.menu.increase_text_size", - value: "Increase app text size", - comment: "" - ), - caption: NSLocalizedString( - "i18n.app.settings.menu.increase_text_size_description", - value: "Increase the size of menu texts for better readability.", - comment: "" - ), - isOn: $increaseTextSize, - ) - SettingsToggleRow( - title: NSLocalizedString( - "i18n.app.settings.menu.high_color_contrast", - value: "High color contrast", - comment: "", - ), - caption: NSLocalizedString( - "i18n.app.settings.menu.high_color_contrast_description", - value: "Increase color contrast for improved accessibility and a clearer viewing experience.", - comment: "" - ), - isOn: $isHighContrast, + @AppStorage("isDarkMode") private var isDarkMode = false + @AppStorage("increaseTextSize") private var increaseTextSize = false + @State private var isHighContrast = false + + var language: String { + let langId = Locale.preferredLanguages.first ?? "" + let langCode = langId.components(separatedBy: "-").first ?? "" + let langLocale = Locale(identifier: langCode) + + return langLocale.localizedString(forIdentifier: langCode)?.capitalized + ?? "" + } + + var body: some View { + AppNavigation { + ZStack(alignment: .top) { + Color.scribeBlue + .ignoresSafeArea() + VStack(alignment: .leading) { + Text( + NSLocalizedString( + "i18n.app.settings.menu.title", + value: "App settings", + comment: "" + ), + ) + .padding(.horizontal) + .padding(.top, 20) + .font(.title3.weight(.semibold)) + VStack(spacing: 20) { + SettingsNavigationRow( + title: NSLocalizedString( + "i18n.app.settings.menu.app_language", + value: "App language", + comment: "", + ), + caption: NSLocalizedString( + "i18n.app.settings.menu.app_language_description", + value: "Change which language the Scribe app is in.", + comment: "", + ), + value: language + ) + .onTapGesture { + if let url = URL(string: UIApplication.openSettingsURLString) { + UIApplication.shared.open(url) + } + } + SettingsToggleRow( + title: NSLocalizedString( + "i18n.app.settings.menu.app_color_mode", + value: "Dark mode", + comment: "", + ), + caption: NSLocalizedString( + "i18n.app.settings.menu.app_color_mode_description", + value: "Change the application display to dark mode.", + comment: "", + ), + isOn: $isDarkMode, + ) + SettingsToggleRow( + title: NSLocalizedString( + "i18n.app.settings.menu.increase_text_size", + value: "Increase app text size", + comment: "" + ), + caption: NSLocalizedString( + "i18n.app.settings.menu.increase_text_size_description", + value: + "Increase the size of menu texts for better readability.", + comment: "" + ), + isOn: $increaseTextSize, + ) + SettingsToggleRow( + title: NSLocalizedString( + "i18n.app.settings.menu.high_color_contrast", + value: "High color contrast", + comment: "", + ), + caption: NSLocalizedString( + "i18n.app.settings.menu.high_color_contrast_description", + value: + "Increase color contrast for improved accessibility and a clearer viewing experience.", + comment: "" + ), + isOn: $isHighContrast, + ) + } + .padding() + .frame(maxWidth: .infinity) + .background(Color(.systemBackground)) + .cornerRadius(16) + .padding(.horizontal) + } + } + .navigationTitle( + NSLocalizedString( + "i18n.app.settings.title", + value: "Settings", + comment: "" + ), ) - } - .padding() - .frame(maxWidth: .infinity) - .background(Color(.systemBackground)) - .cornerRadius(16) - .padding(.horizontal) } - } - .navigationTitle(NSLocalizedString( - "i18n.app.settings.title", - value: "Settings", - comment: ""), - ) } - } } struct SettingsNavigationRow: View { - let title: String - let caption: String + let title: String + let caption: String + let value: String - var body: some View { - VStack(alignment: .leading, spacing: 6) { + var body: some View { + VStack(alignment: .leading, spacing: 6) { - HStack { - Text(title) - .font(.body) + HStack { + Text(title) + .font(.body) - Spacer() + Spacer() - HStack { - Text("English") - .font(.body) - .foregroundColor(.secondary) + HStack { + Text(value) + .font(.body) + .foregroundColor(.secondary) - Image(systemName: "chevron.right") - .foregroundColor(.secondary) - } - } + Image(systemName: "chevron.right") + .foregroundColor(.secondary) + } + } - Text(caption) - .font(.caption) - .foregroundColor(.secondary) + Text(caption) + .font(.caption) + .foregroundColor(.secondary) + } } - } } struct SettingsToggleRow: View { @@ -126,23 +148,23 @@ struct SettingsToggleRow: View { @Binding var isOn: Bool var body: some View { - VStack(alignment: .leading, spacing: 6) { + VStack(alignment: .leading, spacing: 6) { - HStack { - Text(title) - .font(.body) + HStack { + Text(title) + .font(.body) - Spacer() + Spacer() - Toggle("", isOn: $isOn) - .labelsHidden() - .tint(Color.scribeCTA) - } + Toggle("", isOn: $isOn) + .labelsHidden() + .tint(Color.scribeCTA) + } - Text(caption) - .font(.caption) - .foregroundColor(.secondary) - } + Text(caption) + .font(.caption) + .foregroundColor(.secondary) + } } }