Fixes #2083 - Expose options for overriding the system appearance in the advanced settings menu

This commit is contained in:
Stefan Ceriu
2023-11-15 10:48:00 +02:00
committed by Stefan Ceriu
parent 4b3a373782
commit eb6f7e0409
11 changed files with 106 additions and 22 deletions
@@ -88,12 +88,14 @@
"common_acceptable_use_policy" = "Acceptable use policy";
"common_advanced_settings" = "Advanced settings";
"common_analytics" = "Analytics";
"common_appearance" = "Appearance";
"common_audio" = "Audio";
"common_bubbles" = "Bubbles";
"common_chat_backup" = "Chat backup";
"common_copyright" = "Copyright";
"common_creating_room" = "Creating room…";
"common_current_user_left_room" = "Left room";
"common_dark" = "Dark";
"common_decryption_error" = "Decryption error";
"common_developer_options" = "Developer options";
"common_edited_suffix" = "(edited)";
@@ -111,6 +113,7 @@
"common_in_reply_to" = "In reply to %1$@";
"common_invite_unknown_profile" = "This Matrix ID can't be found, so the invite might not be received.";
"common_leaving_room" = "Leaving room";
"common_light" = "Light";
"common_link_copied_to_clipboard" = "Link copied to clipboard";
"common_loading" = "Loading…";
"common_message" = "Message";
@@ -156,6 +159,7 @@
"common_success" = "Success";
"common_suggestions" = "Suggestions";
"common_syncing" = "Syncing";
"common_system" = "System";
"common_text" = "Text";
"common_third_party_notices" = "Third-party notices";
"common_thread" = "Thread";
@@ -406,6 +410,7 @@
"screen_notification_settings_enable_notifications" = "Enable notifications on this device";
"screen_notification_settings_failed_fixing_configuration" = "The configuration has not been corrected, please try again.";
"screen_notification_settings_group_chats" = "Group chats";
"screen_notification_settings_mentions_only_disclaimer" = "Your homeserver does not support this option in encrypted rooms, you may not get notified in some rooms.";
"screen_notification_settings_mentions_section_title" = "Mentions";
"screen_notification_settings_mode_all" = "All";
"screen_notification_settings_mode_mentions" = "Mentions";
@@ -498,6 +503,7 @@
"screen_room_notification_settings_error_loading_settings" = "An error occurred while loading notification settings.";
"screen_room_notification_settings_error_restoring_default" = "Failed restoring the default mode, please try again.";
"screen_room_notification_settings_error_setting_mode" = "Failed setting the mode, please try again.";
"screen_room_notification_settings_mentions_only_disclaimer" = "Your homeserver does not support this option in encrypted rooms, you won't get notified in this room.";
"screen_room_notification_settings_mode_all_messages" = "All messages";
"screen_room_notification_settings_room_custom_settings_title" = "In this room, notify me for";
"screen_room_reactions_show_less" = "Show less";
@@ -167,6 +167,14 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationCoordinatorDelegate,
AnyView(
navigationRootCoordinator.toPresentable()
.environment(\.analyticsService, ServiceLocator.shared.analytics)
.onReceive(appSettings.$appAppearance) { [weak self] appAppearance in
guard let self else { return }
windowManager.windows.forEach { window in
// Unfortunately .preferredColorScheme doesn't propagate properly throughout the app when changed
window.overrideUserInterfaceStyle = appAppearance.interfaceStyle
}
}
)
}
@@ -36,6 +36,7 @@ final class AppSettings {
case otlpTracingEnabled
case viewSourceEnabled
case richTextEditorEnabled
case appAppearance
case elementCallBaseURL
case elementCallEncryptionEnabled
@@ -123,6 +124,9 @@ final class AppSettings {
// A URL where users can go read more about the chat backup.
let chatBackupDetailsURL: URL = "https://element.io/help#encryption5"
@UserPreference(key: UserDefaultsKeys.appAppearance, defaultValue: .system, storageType: .userDefaults(store))
var appAppearance: AppAppearance
// MARK: - Security
/// The app must be locked with a PIN code as part of the authentication flow.
@@ -36,6 +36,10 @@ class WindowManager {
/// A secondary window that can be presented instead of the main/overlay window combo.
private(set) var alternateWindow: UIWindow!
var windows: [UIWindow] {
[mainWindow, overlayWindow, alternateWindow]
}
/// Configures the window manager to operate on the supplied scene.
func configure(with windowScene: UIWindowScene) {
mainWindow = windowScene.keyWindow
+12
View File
@@ -194,6 +194,8 @@ public enum L10n {
public static var commonAdvancedSettings: String { return L10n.tr("Localizable", "common_advanced_settings") }
/// Analytics
public static var commonAnalytics: String { return L10n.tr("Localizable", "common_analytics") }
/// Appearance
public static var commonAppearance: String { return L10n.tr("Localizable", "common_appearance") }
/// Audio
public static var commonAudio: String { return L10n.tr("Localizable", "common_audio") }
/// Bubbles
@@ -206,6 +208,8 @@ public enum L10n {
public static var commonCreatingRoom: String { return L10n.tr("Localizable", "common_creating_room") }
/// Left room
public static var commonCurrentUserLeftRoom: String { return L10n.tr("Localizable", "common_current_user_left_room") }
/// Dark
public static var commonDark: String { return L10n.tr("Localizable", "common_dark") }
/// Decryption error
public static var commonDecryptionError: String { return L10n.tr("Localizable", "common_decryption_error") }
/// Developer options
@@ -244,6 +248,8 @@ public enum L10n {
public static var commonInviteUnknownProfile: String { return L10n.tr("Localizable", "common_invite_unknown_profile") }
/// Leaving room
public static var commonLeavingRoom: String { return L10n.tr("Localizable", "common_leaving_room") }
/// Light
public static var commonLight: String { return L10n.tr("Localizable", "common_light") }
/// Link copied to clipboard
public static var commonLinkCopiedToClipboard: String { return L10n.tr("Localizable", "common_link_copied_to_clipboard") }
/// Loading…
@@ -352,6 +358,8 @@ public enum L10n {
public static var commonSuggestions: String { return L10n.tr("Localizable", "common_suggestions") }
/// Syncing
public static var commonSyncing: String { return L10n.tr("Localizable", "common_syncing") }
/// System
public static var commonSystem: String { return L10n.tr("Localizable", "common_system") }
/// Text
public static var commonText: String { return L10n.tr("Localizable", "common_text") }
/// Third-party notices
@@ -992,6 +1000,8 @@ public enum L10n {
public static var screenNotificationSettingsFailedFixingConfiguration: String { return L10n.tr("Localizable", "screen_notification_settings_failed_fixing_configuration") }
/// Group chats
public static var screenNotificationSettingsGroupChats: String { return L10n.tr("Localizable", "screen_notification_settings_group_chats") }
/// Your homeserver does not support this option in encrypted rooms, you may not get notified in some rooms.
public static var screenNotificationSettingsMentionsOnlyDisclaimer: String { return L10n.tr("Localizable", "screen_notification_settings_mentions_only_disclaimer") }
/// Mentions
public static var screenNotificationSettingsMentionsSectionTitle: String { return L10n.tr("Localizable", "screen_notification_settings_mentions_section_title") }
/// All
@@ -1200,6 +1210,8 @@ public enum L10n {
public static var screenRoomNotificationSettingsErrorRestoringDefault: String { return L10n.tr("Localizable", "screen_room_notification_settings_error_restoring_default") }
/// Failed setting the mode, please try again.
public static var screenRoomNotificationSettingsErrorSettingMode: String { return L10n.tr("Localizable", "screen_room_notification_settings_error_setting_mode") }
/// Your homeserver does not support this option in encrypted rooms, you won't get notified in this room.
public static var screenRoomNotificationSettingsMentionsOnlyDisclaimer: String { return L10n.tr("Localizable", "screen_room_notification_settings_mentions_only_disclaimer") }
/// All messages
public static var screenRoomNotificationSettingsModeAllMessages: String { return L10n.tr("Localizable", "screen_room_notification_settings_mode_all_messages") }
/// Mentions and Keywords only
@@ -0,0 +1,35 @@
//
// Copyright 2023 New Vector Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
import SwiftUI
/// Used to specify the user's app specific appearance preference
enum AppAppearance: CaseIterable, Codable {
case system
case dark
case light
var interfaceStyle: UIUserInterfaceStyle {
switch self {
case .light:
return .light
case .dark:
return .dark
case .system:
return .unspecified
}
}
}
@@ -42,6 +42,7 @@ protocol AdvancedSettingsProtocol: AnyObject {
var timelineStyle: TimelineStyle { get set }
var viewSourceEnabled: Bool { get set }
var richTextEditorEnabled: Bool { get set }
var appAppearance: AppAppearance { get set }
}
extension AppSettings: AdvancedSettingsProtocol { }
@@ -23,6 +23,10 @@ struct AdvancedSettingsScreen: View {
var body: some View {
Form {
Section {
ListRow(label: .plain(title: L10n.commonAppearance),
kind: .picker(selection: $context.appAppearance,
items: AppAppearance.allCases.map { (title: $0.name, tag: $0) }))
ListRow(label: .plain(title: L10n.commonMessageLayout),
kind: .picker(selection: $context.timelineStyle,
items: TimelineStyle.allCases.map { (title: $0.name, tag: $0) }))
@@ -51,6 +55,19 @@ private extension TimelineStyle {
}
}
private extension AppAppearance {
var name: String {
switch self {
case .system:
return L10n.commonSystem
case .light:
return L10n.commonLight
case .dark:
return L10n.commonDark
}
}
}
// MARK: - Previews
struct AdvancedSettingsScreen_Previews: PreviewProvider, TestablePreview {