diff --git a/CHANGES_BWI.md b/CHANGES_BWI.md index 084c082ba..ff89c4c9e 100644 --- a/CHANGES_BWI.md +++ b/CHANGES_BWI.md @@ -1,3 +1,13 @@ +Changes in BWI project 2.28.0 (2026-03-27) +=================================================== + +Improvements 🙌: +- MESSENGER-7555 add migration level 3 +- MESSENGER-7555 add migration with mdm + +Bugfix 🙌: +- MESSENGER-8170 fix login via full matrix id + Changes in BWI project 2.27.3 (2026-02-09) =================================================== diff --git a/Config/AppVersion.xcconfig b/Config/AppVersion.xcconfig index 210d4c2c8..1d0815f12 100644 --- a/Config/AppVersion.xcconfig +++ b/Config/AppVersion.xcconfig @@ -17,5 +17,5 @@ // Version -MARKETING_VERSION = 2.27.3 +MARKETING_VERSION = 2.28.0 CURRENT_PROJECT_VERSION = 20220714163152 diff --git a/Config/BWIBuildSettings.swift b/Config/BWIBuildSettings.swift index 9d3394813..3e2f54679 100644 --- a/Config/BWIBuildSettings.swift +++ b/Config/BWIBuildSettings.swift @@ -684,6 +684,15 @@ class BWIBuildSettings: NSObject { @UserDefault(key: UserDefaultsKeys.didBuMXMigrationInfoLevelKey, defaultValue: 0, storage: RiotSettings.defaults) var didShowBuMXMigrationInfoLevel + // Migration level already shown (BWI #8123) + var isManagedViaMDM: Bool { + guard let managedConfig = UserDefaults.standard.dictionary(forKey: "com.apple.configuration.managed"), + let value = managedConfig["install_bumx_via_mdm"] as? Bool else { + return false + } + + return value + } // shows the grey/green/red shield for the room avatar / user avatar var showEncryptionStatusBadgeOnAvatar = false @@ -724,4 +733,7 @@ class BWIBuildSettings: NSObject { // MARK: Enable Room Retention var enableRoomRetention = false + + // MARK: homeserver selection via full qualified matrix id + var allowMatrixIDForHomeserverSelection = false } diff --git a/Podfile b/Podfile index 883f53f8a..6b25cc1d2 100644 --- a/Podfile +++ b/Podfile @@ -51,7 +51,7 @@ def import_MatrixKit_pods pod 'libPhoneNumber-iOS', '~> 0.9.13' pod 'DTCoreText', '1.6.26' #pod 'DTCoreText/Extension', '~> 1.6.25' - pod 'Down', '~> 0.11.0' + pod 'Down', :git => 'https://github.com/vvorlov/Down.git', :branch => 'master' end def import_SwiftUI_pods diff --git a/Podfile.lock b/Podfile.lock index 4bdc79fc5..f50862bc5 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -80,7 +80,7 @@ PODS: - ZXingObjC/All (3.6.9) DEPENDENCIES: - - Down (~> 0.11.0) + - Down (from `https://github.com/vvorlov/Down.git`, branch `master`) - DSWaveformImage (~> 6.1.1) - DTCoreText (= 1.6.26) - DTTJailbreakDetection (~> 0.4.0) @@ -107,7 +107,6 @@ DEPENDENCIES: SPEC REPOS: https://github.com/CocoaPods/Specs.git: - AFNetworking - - Down - DSWaveformImage - DTCoreText - DTFoundation @@ -137,18 +136,24 @@ SPEC REPOS: - ZXingObjC EXTERNAL SOURCES: + Down: + :branch: master + :git: https://github.com/vvorlov/Down.git MatrixSDK: :git: https://dl-gitlab.example.com/bwmessenger/bundesmessenger/bundesmessenger-ios-sdk :tag: v2.26.0 CHECKOUT OPTIONS: + Down: + :commit: dbb02cc9d16363874b7a0c6c48b9efe09bd5b006 + :git: https://github.com/vvorlov/Down.git MatrixSDK: :git: https://dl-gitlab.example.com/bwmessenger/bundesmessenger/bundesmessenger-ios-sdk :tag: v2.26.0 SPEC CHECKSUMS: AFNetworking: 3bd23d814e976cd148d7d44c3ab78017b744cd58 - Down: b6ba1bc985c9d2f4e15e3b293d2207766fa12612 + Down: 10462c9cb3a6ef28e0996739329c4976b13870f7 DSWaveformImage: 3c718a0cf99291887ee70d1d0c18d80101d3d9ce DTCoreText: ec749e013f2e1f76de5e7c7634642e600a7467ce DTFoundation: 76b624967cf5bcaae6bb057d622c536c36ef36d0 @@ -162,7 +167,7 @@ SPEC CHECKSUMS: libbase58: 8abc2a53ac38cd37720c0acbc53ef3660e9016c2 libPhoneNumber-iOS: 0a32a9525cf8744fe02c5206eb30d571e38f7d75 MatomoTracker: 1d98ddc58322fd9d65e1a6886b8e41363047bd13 - MatrixSDK: 0c394a7a3928208797d403bcf5706b6628690a96 + MatrixSDK: 45f9f97e7424e5d8731bf6b207c728a71caa8eb1 MatrixSDKCrypto: e44608012cae9befc52f13cd8e56c6f51ac83702 ReadMoreTextView: 19147adf93abce6d7271e14031a00303fe28720d Realm: 9ca328bd7e700cc19703799785e37f77d1a130f2 @@ -178,6 +183,6 @@ SPEC CHECKSUMS: zxcvbn-ios: fef98b7c80f1512ff0eec47ac1fa399fc00f7e3c ZXingObjC: 8898711ab495761b2dbbdec76d90164a6d7e14c5 -PODFILE CHECKSUM: 34582260e0e8275df7a07d3947cdac7794125b8e +PODFILE CHECKSUM: 92b7ae8a330216932c5a690e48743b4d7b1bdea8 -COCOAPODS: 1.15.2 +COCOAPODS: 1.16.2 diff --git a/Riot.xcodeproj/xcshareddata/xcschemes/Riot.xcscheme b/Riot.xcodeproj/xcshareddata/xcschemes/Riot.xcscheme index e1775adc4..73493e419 100644 --- a/Riot.xcodeproj/xcshareddata/xcschemes/Riot.xcscheme +++ b/Riot.xcodeproj/xcshareddata/xcschemes/Riot.xcscheme @@ -1,13 +1,13 @@ + shouldUseLaunchSchemeArgsEnv = "YES"> - - - - - - - - +
+

+ Version 2.28.0 +

+ +

+ Verbesserungen +

    +
  • Die neuesten Sicherheitsupdates wurden eingespielt. +
  • Kleinere Fehlerkorrekturen. +
+

+ +

Version 2.27.3 diff --git a/Riot/Generated/BWIStrings.swift b/Riot/Generated/BWIStrings.swift index b817f63d0..e05b828a8 100644 --- a/Riot/Generated/BWIStrings.swift +++ b/Riot/Generated/BWIStrings.swift @@ -131,10 +131,6 @@ public class BWIL10n: NSObject { public static var bumAutheticationTitle: String { return BWIL10n.tr("Bwi", "bum_authetication_title") } - /// Ansicht schließen - public static var bwiA11yCloseButton: String { - return BWIL10n.tr("Bwi", "bwi_a11y_close_button") - } /// Barrierefreiheitserklärung public static var bwiAccessibilityDeclarationButtonTitle: String { return BWIL10n.tr("Bwi", "bwi_accessibility_declaration_button_title") @@ -143,6 +139,14 @@ public class BWIL10n: NSObject { public static var bwiActivateLabsAlertTitle: String { return BWIL10n.tr("Bwi", "bwi_activate_labs_alert_title") } + /// Schließen + public static var bwiAllCommonClose: String { + return BWIL10n.tr("Bwi", "bwi_all_common_close") + } + /// Verstanden + public static var bwiAllCommonGotIt: String { + return BWIL10n.tr("Bwi", "bwi_all_common_got_it") + } /// Wir brauchen Deine Hilfe, um Fehler im %@ besser analysieren zu können. Dazu würden wir gerne anonymisierte Diagnosedaten erfassen. Es werden keine Daten an Dritte übermittelt. Details findest Du in der Datenschutzerklärung.\n\nFalls Du nicht mehr mithelfen möchtest, kannst Du dies in den Einstellungen jederzeit wieder deaktivieren.\n\nMöchtest du bei der Fehler-Analyse unterstützen? public static func bwiAnalyticsAlertBody(_ p1: String) -> String { return BWIL10n.tr("Bwi", "bwi_analytics_alert_body", p1) @@ -307,7 +311,15 @@ public class BWIL10n: NSObject { public static var bwiMdmLogoutMessage: String { return BWIL10n.tr("Bwi", "bwi_mdm_logout_message") } - /// Diese App wird bald abgeschaltet und durch eine neue technisch optimierte App ersetzt + /// Alle deine Kontakte und Nachrichten bleiben dabei erhalten. + public static var bwiMobileDialogM1BannerTextBold: String { + return BWIL10n.tr("Bwi", "bwi_mobile_dialog_m1_banner_text_bold") + } + /// Das ist eine neue, technisch optimierte App vom BuM. Du kannst sie jetzt schon ausprobieren, bevor bald alle wechseln müssen. + public static var bwiMobileDialogM1BannerTextPrefix: String { + return BWIL10n.tr("Bwi", "bwi_mobile_dialog_m1_banner_text_prefix") + } + /// Der BuM wird bald abgeschaltet und durch den BuMX ersetzt. Dies ist eine neue, technisch optimierte App public static var bwiMobileDialogM1MoreText1: String { return BWIL10n.tr("Bwi", "bwi_mobile_dialog_m1_more_text_1") } @@ -335,6 +347,34 @@ public class BWIL10n: NSObject { public static var bwiMobileDialogM1MoreTextBullet4: String { return BWIL10n.tr("Bwi", "bwi_mobile_dialog_m1_more_text_bullet_4") } + /// wenige Tage + public static var bwiMobileDialogM2BannerTextBold: String { + return BWIL10n.tr("Bwi", "bwi_mobile_dialog_m2_banner_text_bold") + } + /// Das ist eine neue, technisch optimierte App vom BuM. Du hast nur noch + public static var bwiMobileDialogM2BannerTextPrefix: String { + return BWIL10n.tr("Bwi", "bwi_mobile_dialog_m2_banner_text_prefix") + } + /// Zeit zu wechseln. Alle deine Kontakte und Nachrichten bleiben dabei erhalten. + public static var bwiMobileDialogM2BannerTextSuffix: String { + return BWIL10n.tr("Bwi", "bwi_mobile_dialog_m2_banner_text_suffix") + } + /// Der BuM wurde nun abgeschaltet und durch den BuMX ersetzt. Dies ist eine neue, technisch optimierte App + public static var bwiMobileDialogM3MoreText1: String { + return BWIL10n.tr("Bwi", "bwi_mobile_dialog_m3_more_text_1") + } + /// Der BuM wurde nun abgeschaltet und durch den BuMX ersetzt. Dies ist eine neue, technisch optimierte App, welche dir von deinem Admin zur Verfügung gestellt wird + public static var bwiMobileDialogM3MoreText1Mdm: String { + return BWIL10n.tr("Bwi", "bwi_mobile_dialog_m3_more_text_1_mdm") + } + /// Wechsel erfolgreich 🎉 + public static var bwiMobileDialogM3SuccessChangeTitle: String { + return BWIL10n.tr("Bwi", "bwi_mobile_dialog_m3_success_change_title") + } + /// Diese App kannst du nun löschen. + public static var bwiMobileDialogM3SuccessText: String { + return BWIL10n.tr("Bwi", "bwi_mobile_dialog_m3_success_text") + } /// Später erinnern public static var bwiMobileDialogMBannerButton1: String { return BWIL10n.tr("Bwi", "bwi_mobile_dialog_m_banner_button1") @@ -375,13 +415,13 @@ public class BWIL10n: NSObject { public static var bwiMobileDialogMMoreTitle: String { return BWIL10n.tr("Bwi", "bwi_mobile_dialog_m_more_title") } - /// Das ist eine neue, technisch optimierte App vom BuM. Du kannst sie jetzt schon ausprobieren, bevor bald alle wechseln müssen. - public static var bwiMobileMdialogM1BannerText: String { - return BWIL10n.tr("Bwi", "bwi_mobileMdialog_m1_banner_text") + /// Alle deine Kontakte und Nachrichten bleiben dabei bestehen, halte dafür deine Login Daten bereit. + public static var bwiMobileDialogMdmBannerTextBold: String { + return BWIL10n.tr("Bwi", "bwi_mobile_dialog_mdm_banner_text_bold") } - /// Alle deine Kontakte und Nachrichten bleiben dabei erhalten. - public static var bwiMobileMdialogM1BannerTextBold: String { - return BWIL10n.tr("Bwi", "bwi_mobileMdialog_m1_banner_text_bold") + /// Das ist eine neue, technisch optimierte App vom BuM, welche dir bald von deinem Admin zur Verfügung gestellt wird. + public static var bwiMobileDialogMdmBannerTextPrefix: String { + return BWIL10n.tr("Bwi", "bwi_mobile_dialog_mdm_banner_text_prefix") } /// Meine Notizen public static var bwiNotesRoomTitle: String { diff --git a/Riot/Managers/KeyValueStorage/Extensions/Keychain.swift b/Riot/Managers/KeyValueStorage/Extensions/Keychain.swift index 7701d5812..3221509b4 100644 --- a/Riot/Managers/KeyValueStorage/Extensions/Keychain.swift +++ b/Riot/Managers/KeyValueStorage/Extensions/Keychain.swift @@ -9,18 +9,20 @@ import Foundation import KeychainAccess /// Extension on Keychain to get/set booleans +#if !S_BUM_APP extension Keychain { - - public func set(_ value: Bool, key: String, ignoringAttributeSynchronizable: Bool = true) throws { - try set(value.description, key: key, ignoringAttributeSynchronizable: ignoringAttributeSynchronizable) - } - - public func getBool(_ key: String, ignoringAttributeSynchronizable: Bool = true) throws -> Bool? { - guard let value = try getString(key, ignoringAttributeSynchronizable: ignoringAttributeSynchronizable) else { - return nil - } - guard value == true.description || value == false.description else { return nil } - return value == true.description - } - -} + + public func set(_ value: Bool, key: String, ignoringAttributeSynchronizable: Bool = true) throws { + try set(value.description, key: key, ignoringAttributeSynchronizable: ignoringAttributeSynchronizable) + } + + public func getBool(_ key: String, ignoringAttributeSynchronizable: Bool = true) throws -> Bool? { + guard let value = try getString(key, ignoringAttributeSynchronizable: ignoringAttributeSynchronizable) else { + return nil + } + guard value == true.description || value == false.description else { return nil } + return value == true.description + } + + } +#endif diff --git a/Riot/Managers/PushNotification/PushNotificationService.m b/Riot/Managers/PushNotification/PushNotificationService.m index 17039e74c..5170e5420 100644 --- a/Riot/Managers/PushNotification/PushNotificationService.m +++ b/Riot/Managers/PushNotification/PushNotificationService.m @@ -90,9 +90,17 @@ Matrix session observer used to detect new opened sessions. { self.registrationForRemoteNotificationsCompletion = completion; - dispatch_async(dispatch_get_main_queue(), ^{ - [[UIApplication sharedApplication] registerForRemoteNotifications]; - }); + + // BWI #7555 migration part 3 + if([[BWIBuildSettings shared] BuMXMigrationInfoLevel] < 2) { + dispatch_async(dispatch_get_main_queue(), ^{ + // Even after we unregistered from Apples push service we must make sure that + // the app will not register again. After reaching migration level 3 this app should neither show + // remote notifications any more nor register for new notifications. + [[UIApplication sharedApplication] registerForRemoteNotifications]; + }); + } + // BWI #7555 END } - (void)didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken diff --git a/Riot/Modules/Home/AllChats/AllChatsCoordinator.swift b/Riot/Modules/Home/AllChats/AllChatsCoordinator.swift index b27dc860a..4f5d0a268 100644 --- a/Riot/Modules/Home/AllChats/AllChatsCoordinator.swift +++ b/Riot/Modules/Home/AllChats/AllChatsCoordinator.swift @@ -775,6 +775,13 @@ class AllChatsCoordinator: NSObject, SplitViewMasterCoordinatorProtocol { // BWI #7564 add migration level if let migrationLevel = wellknown?.migrationInfoLevel() { BWIBuildSettings.shared.BuMXMigrationInfoLevel = migrationLevel + + // BWI #7555 migration part 3 + if migrationLevel == 3 { + // Inform Apple that this app on this device can be ignored + UIApplication.shared.unregisterForRemoteNotifications() + } + // BWI #7564 END } // BWI #7564 END self.bwiCheckForMatomoPromt() diff --git a/Riot/Modules/Home/AllChats/AllChatsViewController.swift b/Riot/Modules/Home/AllChats/AllChatsViewController.swift index ff5901520..f0c621804 100644 --- a/Riot/Modules/Home/AllChats/AllChatsViewController.swift +++ b/Riot/Modules/Home/AllChats/AllChatsViewController.swift @@ -249,7 +249,7 @@ class AllChatsViewController: HomeViewController { roomFilterButton?.isSelected = !AllChatsLayoutSettingsManager.shared.allChatLayoutSettings.filters.isEmpty } - + override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) @@ -285,6 +285,21 @@ class AllChatsViewController: HomeViewController { NotificationCenter.default.addObserver(self, selector: #selector(self.spaceListDidChange), name: MXSpaceService.didBuildSpaceGraph, object: nil) set(tableHeadeView: self.bannerView) + + // BWI #7555 migration part 3 + if BWIBuildSettings.shared.BuMXMigrationInfoLevel == 3 { + let migrationInfoView = MigrationInfoView(username: "") { + return self.mainSession.myUser.username() + }.environmentObject(BWIThemeService.shared).interactiveDismissDisabled(true) + let hostingViewController = UIHostingController(rootView: migrationInfoView) + if hostingViewController.popoverPresentationController != nil { + hostingViewController.modalPresentationStyle = .popover + } + hostingViewController.isModalInPresentation = true + self.navigationController?.present(hostingViewController, animated: false, completion: nil) + } + // BWI #7555 END + } override func viewDidAppear(_ animated: Bool) { @@ -317,6 +332,7 @@ class AllChatsViewController: HomeViewController { } AppDelegate.theDelegate().checkAppVersion() + } func presentFederationIntroductionSheet() { diff --git a/Riot/Modules/MatrixKit/Controllers/MXKPreviewViewController.m b/Riot/Modules/MatrixKit/Controllers/MXKPreviewViewController.m index 75ef50f4b..37d125792 100644 --- a/Riot/Modules/MatrixKit/Controllers/MXKPreviewViewController.m +++ b/Riot/Modules/MatrixKit/Controllers/MXKPreviewViewController.m @@ -9,7 +9,10 @@ Please see LICENSE in the repository root for full details. #import "MXKPreviewViewController.h" @import QuickLook; -@interface MXKPreviewViewController () +@interface MXKPreviewViewController () { + // BWI #8137 remove share button + NSTimer *removeShareButtonTimer; +} /// A specialized view controller for previewing an item. @property (nonatomic, weak) QLPreviewController *previewController; @@ -63,22 +66,20 @@ Please see LICENSE in the repository root for full details. if (!self.allowActions) { - NSMutableArray *items = [NSMutableArray arrayWithArray: self.previewController.navigationItem.rightBarButtonItems]; - if (items.count > 0) - { - [items removeObjectAtIndex:0]; - } - self.previewController.navigationItem.rightBarButtonItems = items; - // bwi: no toolbar items to disallow share files - self.previewController.toolbarItems = nil; - // bwi: no title to disallow sharing/printing - self.previewController.navigationItem.title = @""; + // BWI #8137 remove share button + [removeShareButtonTimer invalidate]; + removeShareButtonTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 repeats:YES block:^(NSTimer * _Nonnull timer) { + [self removeShareButtons]; + }]; } } - (IBAction)doneAction:(id)sender { + // BWI #8137 remove share button + [removeShareButtonTimer invalidate]; + removeShareButtonTimer = nil; [self dismissViewControllerAnimated:YES completion:^{ if ([self.previewDelegate respondsToSelector:@selector(previewViewControllerDidEndPreview:)]) { [self.previewDelegate previewViewControllerDidEndPreview:self]; @@ -86,6 +87,21 @@ Please see LICENSE in the repository root for full details. }]; } +// BWI #8137 remove share button +- (void)removeShareButtons +{ + NSMutableArray *items = [NSMutableArray arrayWithArray: self.previewController.navigationItem.rightBarButtonItems]; + if (items.count > 0) + { + [items removeObjectAtIndex:0]; + } + self.previewController.navigationItem.rightBarButtonItems = items; + // bwi: no toolbar items to disallow share files + self.previewController.toolbarItems = nil; + // bwi: no title to disallow sharing/printing + self.previewController.navigationItem.title = @""; +} + #pragma mark - QLPreviewControllerDataSource - (NSInteger)numberOfPreviewItemsInPreviewController:(nonnull QLPreviewController *)controller diff --git a/RiotSwiftUI/Modules/Authentication/Login/Coordinator/AuthenticationLoginCoordinator.swift b/RiotSwiftUI/Modules/Authentication/Login/Coordinator/AuthenticationLoginCoordinator.swift index 12109cba9..9ff7d76f7 100644 --- a/RiotSwiftUI/Modules/Authentication/Login/Coordinator/AuthenticationLoginCoordinator.swift +++ b/RiotSwiftUI/Modules/Authentication/Login/Coordinator/AuthenticationLoginCoordinator.swift @@ -206,23 +206,27 @@ final class AuthenticationLoginCoordinator: Coordinator, Presentable { } @MainActor private func parseUsername(_ username: String) { - guard MXTools.isMatrixUserIdentifier(username) else { return } - let domain = username.components(separatedBy: ":")[1] - let homeserverAddress = HomeserverAddress.sanitized(domain) - startLoading(isInteractionBlocking: false) - - currentTask = Task { [weak self] in - do { - try await authenticationService.startFlow(.login, for: homeserverAddress) - - guard !Task.isCancelled else { return } - - updateViewModel() - self?.stopLoading() - } catch { - self?.stopLoading() - self?.handleError(error) + // bwi #8170 no homeserver over matrix ID ch + if BWIBuildSettings.shared.allowMatrixIDForHomeserverSelection { + guard MXTools.isMatrixUserIdentifier(username) else { return } + let domain = username.components(separatedBy: ":")[1] + let homeserverAddress = HomeserverAddress.sanitized(domain) + + startLoading(isInteractionBlocking: false) + + currentTask = Task { [weak self] in + do { + try await authenticationService.startFlow(.login, for: homeserverAddress) + + guard !Task.isCancelled else { return } + + updateViewModel() + self?.stopLoading() + } catch { + self?.stopLoading() + self?.handleError(error) + } } } } diff --git a/RiotSwiftUI/Modules/Authentication/Login/View/AuthenticationLoginScreen.swift b/RiotSwiftUI/Modules/Authentication/Login/View/AuthenticationLoginScreen.swift index 4476b39a1..e681b815e 100644 --- a/RiotSwiftUI/Modules/Authentication/Login/View/AuthenticationLoginScreen.swift +++ b/RiotSwiftUI/Modules/Authentication/Login/View/AuthenticationLoginScreen.swift @@ -21,6 +21,10 @@ struct AuthenticationLoginScreen: View { /// This must be manually set back to `false` when the text field finishes editing. @State private var isPasswordFocused = false + // BWI #7555 migration part 3 + @State private var showMigrationView = BWIBuildSettings.shared.BuMXMigrationInfoLevel == 3 + // BWI #7555 END + // MARK: Public @ObservedObject var viewModel: AuthenticationLoginViewModel.Context @@ -110,6 +114,13 @@ struct AuthenticationLoginScreen: View { .background(theme.colors.background.ignoresSafeArea()) .alert(item: $viewModel.alertInfo) { $0.alert } .accentColor(theme.colors.accent) + // BWI #7555 migration part 3 + .sheet(isPresented: $showMigrationView) { + MigrationInfoView(username: "", getUserName: nil) + .environmentObject(BWIThemeService.shared) + .interactiveDismissDisabled(true) + } + // BWI #7555 END } /// The header containing a Welcome Back title. @@ -163,6 +174,7 @@ struct AuthenticationLoginScreen: View { Button(action: submit) { Text(getCustomText(text: .submit)) } + .disabled(BWIBuildSettings.shared.BuMXMigrationInfoLevel > 2) // BWI #7555 migration part 3 .buttonStyle(PrimaryActionButtonStyle()) .disabled(!viewModel.viewState.canSubmit) .accessibilityIdentifier("nextButton") diff --git a/bwi/FeatureBanner/FeatureBannerView.swift b/bwi/FeatureBanner/FeatureBannerView.swift index fee450f9a..d419ad088 100644 --- a/bwi/FeatureBanner/FeatureBannerView.swift +++ b/bwi/FeatureBanner/FeatureBannerView.swift @@ -91,11 +91,12 @@ protocol FeatureBannerDelegate { } func didPressShowDetails() { - let migrationInfoView = MigrationInfoView(username: username).environmentObject(BWIThemeService.shared).interactiveDismissDisabled(true) + let migrationInfoView = MigrationInfoView(username: username, getUserName: nil).environmentObject(BWIThemeService.shared).interactiveDismissDisabled(true) let hostingViewController = UIHostingController(rootView: migrationInfoView) if hostingViewController.popoverPresentationController != nil { hostingViewController.modalPresentationStyle = .popover } + hostingViewController.isModalInPresentation = true hostingController.parent?.present(hostingViewController, animated: true, completion: nil) } @@ -155,8 +156,12 @@ struct FeatureBannerView: View { var advertisementText: some View { VStack { VStack { - if BWIBuildSettings.shared.BuMXMigrationInfoLevel == 1 { - Text(BWIL10n.bwiMobileDialogM1BannerText) + + if BWIBuildSettings.shared.isManagedViaMDM { + Text(BWIL10n.bwiMobileDialogMdmBannerTextPrefix) + + Text(BWIL10n.bwiMobileDialogMdmBannerTextBold) + .bold() + } else if BWIBuildSettings.shared.BuMXMigrationInfoLevel == 1 { + Text(BWIL10n.bwiMobileDialogM1BannerTextPrefix) + Text(BWIL10n.bwiMobileDialogM1BannerTextBold) .bold() } else { diff --git a/bwi/FeatureBanner/MigrationInfoView.swift b/bwi/FeatureBanner/MigrationInfoView.swift index 62e6e2b0b..3e973b110 100644 --- a/bwi/FeatureBanner/MigrationInfoView.swift +++ b/bwi/FeatureBanner/MigrationInfoView.swift @@ -23,15 +23,24 @@ struct MigrationInfoView: View { @State private var selectedTab = 1 @EnvironmentObject var themeService: BWIThemeService @State var redrawKey = UUID() + @State var migrationFinished = SharedKeychain.load(account: "migration_finished") == "true" let username: String + let getUserName: (() -> String?)? var body: some View { TabView(selection: $selectedTab) { - MigrationInfoViewOne() - .tag(1) - MigrationInfoViewTwo(username: username) - .tag(2) + if migrationFinished { + MigrationSuccessView() + .tag(1) + } else { + MigrationInfoViewOne() + .tag(1) + if !BWIBuildSettings.shared.isManagedViaMDM { + MigrationInfoViewTwo(username: username, getUserName: getUserName) + .tag(2) + } + } } .id(redrawKey) .tabViewStyle(.page) @@ -58,7 +67,8 @@ struct MigrationInfoView: View { .foregroundColor(Color(themeService.theme.colors.tertiaryContent)) .padding(20) } - .accessibilityLabel(BWIL10n.bwiA11yCloseButton) + .accessibilityLabel(BWIL10n.bwiAllCommonClose) + .isHidden(BWIBuildSettings.shared.BuMXMigrationInfoLevel > 2) } Spacer() HStack() { @@ -90,6 +100,18 @@ struct MigrationInfoView: View { } .opacity(selectedTab == 2 ? 0 : 1) } + .isHidden(migrationFinished || BWIBuildSettings.shared.isManagedViaMDM) + + if BWIBuildSettings.shared.isManagedViaMDM && BWIBuildSettings.shared.BuMXMigrationInfoLevel < 3 { + Button { + dismissView() + } label: { + Text(BWIL10n.bwiAllCommonGotIt) + .foregroundColor(Color(ThemeService.shared().theme.backgroundColor)) + } + .buttonStyle(PrimaryActionButtonStyle()) + .padding() + } } } .onAppear { @@ -149,10 +171,25 @@ struct MigrationInfoViewOne: View { .lineLimit(nil) .fixedSize(horizontal: false, vertical: true) .padding(.bottom, 20) - - Text(BWIL10n.bwiMobileDialogM1MoreText1) + - Text(BWIL10n.bwiMobileDialogM1MoreText2).bold() + - Text(BWIL10n.bwiMobileDialogM1MoreText3) + if BWIBuildSettings.shared.isManagedViaMDM { + if BWIBuildSettings.shared.BuMXMigrationInfoLevel == 3 { + Text(BWIL10n.bwiMobileDialogM3MoreText1Mdm) + + Text(BWIL10n.bwiMobileDialogM1MoreText2).bold() + + Text(BWIL10n.bwiMobileDialogM1MoreText3) + } else { + Text(BWIL10n.bwiMobileDialogM1MoreText3) + } + } else { + if BWIBuildSettings.shared.BuMXMigrationInfoLevel < 3 { + Text(BWIL10n.bwiMobileDialogM1MoreText1) + + Text(BWIL10n.bwiMobileDialogM1MoreText2).bold() + + Text(BWIL10n.bwiMobileDialogM1MoreText3) + } else { + Text(BWIL10n.bwiMobileDialogM3MoreText1) + + Text(BWIL10n.bwiMobileDialogM1MoreText2).bold() + + Text(BWIL10n.bwiMobileDialogM1MoreText3) + } + } VStack(alignment: .leading) { HStack(alignment: .top) { Text("•") @@ -178,15 +215,29 @@ struct MigrationInfoViewOne: View { .fixedSize(horizontal: false, vertical: true) .padding(EdgeInsets(top: 10, leading: 30, bottom: 0, trailing: 30)) .accessibilityElement(children: .ignore) - .accessibilityLabel( - BWIL10n.bwiMobileDialogMMoreTitle + ". " + + .accessibilityLabel(accessibilityLabel) + } + + var accessibilityLabel: String { + if BWIBuildSettings.shared.BuMXMigrationInfoLevel < 3 && !BWIBuildSettings.shared.isManagedViaMDM { + return BWIL10n.bwiMobileDialogMMoreTitle + ". " + BWIL10n.bwiMobileDialogM1MoreText1 + BWIL10n.bwiMobileDialogM1MoreText2 + BWIL10n.bwiMobileDialogM1MoreText3 + ", " + BWIL10n.bwiMobileDialogM1MoreTextBullet1 + ", " + BWIL10n.bwiMobileDialogM1MoreTextBullet2 + ", " + BWIL10n.bwiMobileDialogM1MoreTextBullet3 + ", " + - BWIL10n.bwiMobileDialogM1MoreTextBullet4) + BWIL10n.bwiMobileDialogM1MoreTextBullet4 + } else { + return BWIL10n.bwiMobileDialogMMoreTitle + ". " + + BWIL10n.bwiMobileDialogM3MoreText1 + + BWIL10n.bwiMobileDialogM1MoreText2 + + BWIL10n.bwiMobileDialogM1MoreText3 + ", " + + BWIL10n.bwiMobileDialogM1MoreTextBullet1 + ", " + + BWIL10n.bwiMobileDialogM1MoreTextBullet2 + ", " + + BWIL10n.bwiMobileDialogM1MoreTextBullet3 + ", " + + BWIL10n.bwiMobileDialogM1MoreTextBullet4 + } } } @@ -194,6 +245,8 @@ struct MigrationInfoViewOne: View { // MARK: Migraion Info View two struct MigrationInfoViewTwo: View { let username: String + let getUserName: (() -> String?)? + @State var lazyLoadedUserName: String? = nil @State var showSuccessToast: Bool = false @EnvironmentObject var themeService: BWIThemeService @@ -228,7 +281,9 @@ struct MigrationInfoViewTwo: View { } .frame(minHeight: geo.size.height) .frame(width: geo.size.width) - + .onAppear { + lazyLoadedUserName = username.isEmpty ? getUserName?() : username + } } .frame(width: geo.size.width, height: geo.size.height) } @@ -243,38 +298,51 @@ struct MigrationInfoViewTwo: View { .padding(.bottom, 20) } VStack(alignment: .leading) { - HStack() { - Text("1.") - Button(action: { - UIPasteboard.general.string = username - guard !showSuccessToast else { return } - withAnimation { - showSuccessToast = true + VStack(alignment: .leading) { + HStack() { + if lazyLoadedUserName != nil { + Text("1.") + Button(action: { + UIPasteboard.general.string = lazyLoadedUserName ?? "" + guard !showSuccessToast else { return } + withAnimation { + showSuccessToast = true + } + DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) { + withAnimation { + showSuccessToast = false + } + } + }, label: { + Text(BWIL10n.bwiMobileDialogMMore2Text1) + .underline() + .foregroundColor(Color(themeService.theme.textPrimaryColor)) + Image(systemName: "square.on.square") + .resizable() + .foregroundColor(Color(themeService.theme.textPrimaryColor)) + .frame(width: 15, height: 15) + }) } - DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) { - withAnimation { - showSuccessToast = false - } + } + + HStack() { + // bwi #7555 I know, but its only legacy + if lazyLoadedUserName != nil { + Text("2.") + } else { + Text("1.") } - }, label: { - Text(BWIL10n.bwiMobileDialogMMore2Text1) - .underline() - .foregroundColor(Color(themeService.theme.textPrimaryColor)) - Image(systemName: "square.on.square") - .resizable() - .foregroundColor(Color(themeService.theme.textPrimaryColor)) - .frame(width: 15, height: 15) - }) - } - - HStack() { - Text("2.") - Text(BWIL10n.bwiMobileDialogMMore2Text2) - } - .padding(.bottom, 1) - HStack() { - Text("3.") - Text(BWIL10n.bwiMobileDialogMMore2Text3) + Text(BWIL10n.bwiMobileDialogMMore2Text2) + } + .padding(.bottom, 1) + HStack() { + if lazyLoadedUserName != nil { + Text("3.") + } else { + Text("2.") + } + Text(BWIL10n.bwiMobileDialogMMore2Text3) + } } } } @@ -311,3 +379,48 @@ struct MigrationInfoViewTwo: View { .transition(.opacity) } } + + +// MARK: Migraion Success View +struct MigrationSuccessView: View { + @EnvironmentObject var themeService: BWIThemeService + + var body: some View { + GeometryReader { geo in + ScrollView(.vertical) { + VStack(alignment: .center, spacing: 20) { + VStack() { + Image("bumx_logo") + .resizable() + .frame(width: 200, height: 200) + .clipShape(.rect(cornerRadius: 36)) + .overlay( + RoundedRectangle(cornerRadius: 36) + .stroke(.gray, lineWidth: 0.4) + ) + .accessibilityHidden(true) + } + .frame(height: geo.size.height * 0.35, alignment: .center) + .padding(EdgeInsets(top: 56, leading: 30, bottom: 10, trailing: 30)) + + VStack { + Text(BWIL10n.bwiMobileDialogM3SuccessChangeTitle) + .font(.title) + .bold() + .padding(.bottom, 20) + + Text(BWIL10n.bwiMobileDialogM3SuccessText) + .fixedSize(horizontal: false, vertical: true) + .padding(EdgeInsets(top: 10, leading: 30, bottom: 0, trailing: 30)) + } + + Spacer() + } + .frame(minHeight: geo.size.height) + .frame(width: geo.size.width) + + } + .frame(width: geo.size.width, height: geo.size.height) + } + } +} diff --git a/bwi/MigrationAssistent/MigrationAssistant.swift b/bwi/MigrationAssistent/MigrationAssistant.swift index f55434174..c56ba37ef 100644 --- a/bwi/MigrationAssistent/MigrationAssistant.swift +++ b/bwi/MigrationAssistent/MigrationAssistant.swift @@ -43,4 +43,10 @@ import MatrixSDK return returnValue } + + // BWI #7555 migration part 3 + func loadFinishedFlag() -> String? { + return SharedKeychain.load(account: "migration_finished") + } + // BWI #7555 END } diff --git a/project.yml b/project.yml index be1a146e0..7c436d67b 100644 --- a/project.yml +++ b/project.yml @@ -77,3 +77,8 @@ packages: SwiftJWT: url: https://github.com/Kitura/Swift-JWT version: 4.0.2 + +settings: + base: + SWIFT_ENABLE_EXPLICIT_MODULES: NO + _EXPERIMENTAL_SWIFT_EXPLICIT_MODULES: NO