diff --git a/Config/BuildSettings.swift b/Config/BuildSettings.swift index 8fcabf42b..5695d6723 100644 --- a/Config/BuildSettings.swift +++ b/Config/BuildSettings.swift @@ -90,6 +90,12 @@ final class BuildSettings: NSObject { static let applicationWebAppUrlString = "https://app.element.io" + // MARK: - Localization + + /// Whether to allow the app to use a right to left layout or force left to right for all languages + static let disableRightToLeftLayout = true + + // MARK: - Server configuration // Default servers proposed on the authentication screen @@ -290,7 +296,11 @@ final class BuildSettings: NSObject { static let settingsSecurityScreenShowAdvancedUnverifiedDevices:Bool = true // MARK: - Timeline settings - static let roomInputToolbarCompressionMode = MXKRoomInputToolbarCompressionModePrompt + static let roomInputToolbarCompressionMode: MediaCompressionMode = .prompt + + enum MediaCompressionMode { + case prompt, small, medium, large, none + } // MARK: - Room Creation Screen diff --git a/Riot/Modules/Application/LegacyAppDelegate.m b/Riot/Modules/Application/LegacyAppDelegate.m index 136f3508b..80de56871 100644 --- a/Riot/Modules/Application/LegacyAppDelegate.m +++ b/Riot/Modules/Application/LegacyAppDelegate.m @@ -394,6 +394,11 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni [NSBundle mxk_setLanguage:language]; [NSBundle mxk_setFallbackLanguage:@"en"]; + if (BuildSettings.disableRightToLeftLayout) + { + [[UIView appearance] setSemanticContentAttribute:UISemanticContentAttributeForceLeftToRight]; + } + // Set app info now as Mac (Designed for iPad) accesses it before didFinishLaunching is called self.appInfo = AppInfo.current; diff --git a/Riot/Utils/MediaCompressionHelper.swift b/Riot/Utils/MediaCompressionHelper.swift index 143321d94..c25bfb275 100644 --- a/Riot/Utils/MediaCompressionHelper.swift +++ b/Riot/Utils/MediaCompressionHelper.swift @@ -22,11 +22,29 @@ class MediaCompressionHelper: NSObject { /// and the `showMediaCompressionPrompt` Riot setting. @objc static var defaultCompressionMode: MXKRoomInputToolbarCompressionMode { // When the compression mode build setting hasn't been customised, use the media compression prompt setting to determine what to do. - if BuildSettings.roomInputToolbarCompressionMode == MXKRoomInputToolbarCompressionModePrompt { + if BuildSettings.roomInputToolbarCompressionMode == .prompt { return RiotSettings.shared.showMediaCompressionPrompt ? MXKRoomInputToolbarCompressionModePrompt : MXKRoomInputToolbarCompressionModeNone } else { // Otherwise use the compression mode defined in the build settings. - return BuildSettings.roomInputToolbarCompressionMode + return BuildSettings.roomInputToolbarCompressionMode.mxkCompressionMode + } + } +} + +extension BuildSettings.MediaCompressionMode { + /// The compression mode as an `MXKRoomInputToolbarCompressionMode` value. + var mxkCompressionMode: MXKRoomInputToolbarCompressionMode { + switch self { + case .prompt: + return MXKRoomInputToolbarCompressionModePrompt + case .small: + return MXKRoomInputToolbarCompressionModeSmall + case .medium: + return MXKRoomInputToolbarCompressionModeMedium + case .large: + return MXKRoomInputToolbarCompressionModeLarge + case .none: + return MXKRoomInputToolbarCompressionModeNone } } } diff --git a/Riot/target.yml b/Riot/target.yml index 8f2d95d2c..76014eb44 100644 --- a/Riot/target.yml +++ b/Riot/target.yml @@ -67,96 +67,7 @@ targets: - path: . excludes: - "Modules/Room/EmojiPicker/Data/EmojiMart/EmojiJSONStore.swift" - - "**/*.strings" # Exclude all strings files - path: ../RiotShareExtension/Shared - path: Modules/MatrixKit excludes: - "**/*.md" # excludes all files with the .md extension - - # Add separately localizable files - # Once a language has enough translations (>80%), it must be declared here - - path: Assets/bg.lproj/InfoPlist.strings - - path: Assets/bg.lproj/Localizable.strings - - path: Assets/bg.lproj/Vector.strings - - path: Assets/ca.lproj/InfoPlist.strings - - path: Assets/ca.lproj/Localizable.strings - - path: Assets/ca.lproj/Vector.strings - - path: Assets/cy.lproj/InfoPlist.strings - - path: Assets/cy.lproj/Localizable.strings - - path: Assets/cy.lproj/Vector.strings - - path: Assets/de.lproj/InfoPlist.strings - - path: Assets/de.lproj/Localizable.strings - - path: Assets/de.lproj/Vector.strings - - path: Assets/en.lproj/InfoPlist.strings - - path: Assets/en.lproj/Localizable.strings - - path: Assets/en.lproj/Vector.strings - - path: Assets/en.lproj/Untranslated.strings - - path: Assets/eo.lproj/InfoPlist.strings - - path: Assets/eo.lproj/Localizable.strings - - path: Assets/eo.lproj/Vector.strings - - path: Assets/es.lproj/InfoPlist.strings - - path: Assets/es.lproj/Localizable.strings - - path: Assets/es.lproj/Vector.strings - - path: Assets/et.lproj/InfoPlist.strings - - path: Assets/et.lproj/Localizable.strings - - path: Assets/et.lproj/Vector.strings - - path: Assets/eu.lproj/InfoPlist.strings - - path: Assets/eu.lproj/Localizable.strings - - path: Assets/eu.lproj/Vector.strings - - path: Assets/fr.lproj/InfoPlist.strings - - path: Assets/fr.lproj/Localizable.strings - - path: Assets/fr.lproj/Vector.strings - - path: Assets/hu.lproj/InfoPlist.strings - - path: Assets/hu.lproj/Localizable.strings - - path: Assets/hu.lproj/Vector.strings - - path: Assets/id.lproj/InfoPlist.strings - - path: Assets/id.lproj/Localizable.strings - - path: Assets/id.lproj/Vector.strings - - path: Assets/is.lproj/InfoPlist.strings - - path: Assets/is.lproj/Localizable.strings - - path: Assets/is.lproj/Vector.strings - - path: Assets/it.lproj/InfoPlist.strings - - path: Assets/it.lproj/Localizable.strings - - path: Assets/it.lproj/Vector.strings - - path: Assets/ja.lproj/InfoPlist.strings - - path: Assets/ja.lproj/Localizable.strings - - path: Assets/ja.lproj/Vector.strings - - path: Assets/kab.lproj/InfoPlist.strings - - path: Assets/kab.lproj/Localizable.strings - - path: Assets/kab.lproj/Vector.strings - - path: Assets/nb-NO.lproj/InfoPlist.strings - - path: Assets/nb-NO.lproj/Localizable.strings - - path: Assets/nb-NO.lproj/Vector.strings - - path: Assets/nl.lproj/InfoPlist.strings - - path: Assets/nl.lproj/Localizable.strings - - path: Assets/nl.lproj/Vector.strings - - path: Assets/pl.lproj/InfoPlist.strings - - path: Assets/pl.lproj/Localizable.strings - - path: Assets/pl.lproj/Vector.strings - - path: Assets/pt_BR.lproj/InfoPlist.strings - - path: Assets/pt_BR.lproj/Localizable.strings - - path: Assets/pt_BR.lproj/Vector.strings - - path: Assets/ru.lproj/InfoPlist.strings - - path: Assets/ru.lproj/Localizable.strings - - path: Assets/ru.lproj/Vector.strings - - path: Assets/sk.lproj/InfoPlist.strings - - path: Assets/sk.lproj/Localizable.strings - - path: Assets/sk.lproj/Vector.strings - - path: Assets/sq.lproj/InfoPlist.strings - - path: Assets/sq.lproj/Localizable.strings - - path: Assets/sq.lproj/Vector.strings - - path: Assets/sv.lproj/InfoPlist.strings - - path: Assets/sv.lproj/Localizable.strings - - path: Assets/sv.lproj/Vector.strings - - path: Assets/uk.lproj/InfoPlist.strings - - path: Assets/uk.lproj/Localizable.strings - - path: Assets/uk.lproj/Vector.strings - - path: Assets/vi.lproj/InfoPlist.strings - - path: Assets/vi.lproj/Localizable.strings - - path: Assets/vi.lproj/Vector.strings - - path: Assets/zh_Hans.lproj/InfoPlist.strings - - path: Assets/zh_Hans.lproj/Localizable.strings - - path: Assets/zh_Hans.lproj/Vector.strings - - path: Assets/zh_Hant.lproj/InfoPlist.strings - - path: Assets/zh_Hant.lproj/Localizable.strings - - path: Assets/zh_Hant.lproj/Vector.strings diff --git a/RiotSwiftUI/Modules/Common/Bridging/VectorContentView.swift b/RiotSwiftUI/Modules/Common/Bridging/VectorContentView.swift index 449042d78..73f565dbd 100644 --- a/RiotSwiftUI/Modules/Common/Bridging/VectorContentView.swift +++ b/RiotSwiftUI/Modules/Common/Bridging/VectorContentView.swift @@ -23,10 +23,18 @@ import SwiftUI struct VectorContentModifier: ViewModifier { @ObservedObject private var themePublisher = ThemePublisher.shared + @Environment(\.layoutDirection) private var defaultLayoutDirection + + /// The layout direction to use, taking into account the build settings. SwiftUI generally + /// handles RTL well enough, but we match the behaviour used in UIKit to avoid mixed layouts. + var layoutDirection: LayoutDirection { + BuildSettings.disableRightToLeftLayout ? .leftToRight : defaultLayoutDirection + } func body(content: Content) -> some View { content .theme(themePublisher.theme) + .environment(\.layoutDirection, layoutDirection) } } diff --git a/RiotSwiftUI/target.yml b/RiotSwiftUI/target.yml index 0c270c460..58f3e74f3 100644 --- a/RiotSwiftUI/target.yml +++ b/RiotSwiftUI/target.yml @@ -46,6 +46,8 @@ targets: - path: ../Riot/Generated/Images.swift - path: ../Riot/Managers/Theme/ - path: ../Riot/Managers/Locale/LocaleProviderType.swift + - path: ../Config/BuildSettings.swift + - path: ../Riot/Modules/Room/TimelineCells/Styles/RoomTimelineStyleIdentifier.swift - path: ../Riot/Categories/String.swift - path: ../Riot/Categories/Character.swift - path: ../Riot/Categories/UIColor.swift diff --git a/RiotSwiftUI/targetUITests.yml b/RiotSwiftUI/targetUITests.yml index 612f09230..324fcb0d0 100644 --- a/RiotSwiftUI/targetUITests.yml +++ b/RiotSwiftUI/targetUITests.yml @@ -54,6 +54,8 @@ targets: - path: ../Riot/Generated/Images.swift - path: ../Riot/Managers/Theme/ - path: ../Riot/Managers/Locale/LocaleProviderType.swift + - path: ../Config/BuildSettings.swift + - path: ../Riot/Modules/Room/TimelineCells/Styles/RoomTimelineStyleIdentifier.swift - path: ../Riot/Categories/String.swift - path: ../Riot/Categories/Character.swift - path: ../Riot/Categories/UIColor.swift diff --git a/SiriIntents/IntentHandler.m b/SiriIntents/IntentHandler.m index 94d120a4f..65681525a 100644 --- a/SiriIntents/IntentHandler.m +++ b/SiriIntents/IntentHandler.m @@ -17,6 +17,7 @@ #import "IntentHandler.h" #import "GeneratedInterface-Swift.h" +#import "MXKAccountManager.h" #if __has_include() #define CALL_STACK_JINGLE diff --git a/changelog.d/5935.i18n b/changelog.d/5935.i18n new file mode 100644 index 000000000..1d306244d --- /dev/null +++ b/changelog.d/5935.i18n @@ -0,0 +1 @@ +Translations: Enable all languages rather than waiting for an 80% translation.