From 47530b2f19640872cb8b3bef58873670163c82f9 Mon Sep 17 00:00:00 2001 From: Frank Rotermund Date: Thu, 5 Mar 2026 07:35:35 +0100 Subject: [PATCH 1/8] fix: login via matrix id should not change the homeserver (MESSENGER-8170) --- Config/BWIBuildSettings.swift | 3 ++ Podfile | 2 +- Podfile.lock | 17 +++++---- .../xcshareddata/swiftpm/Package.resolved | 4 +-- .../AuthenticationLoginCoordinator.swift | 36 ++++++++++--------- 5 files changed, 37 insertions(+), 25 deletions(-) diff --git a/Config/BWIBuildSettings.swift b/Config/BWIBuildSettings.swift index 9d3394813..1c9d1de09 100644 --- a/Config/BWIBuildSettings.swift +++ b/Config/BWIBuildSettings.swift @@ -724,4 +724,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.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Riot.xcworkspace/xcshareddata/swiftpm/Package.resolved index d4b165eca..b769e2fe1 100644 --- a/Riot.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Riot.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -105,8 +105,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/element-hq/matrix-rich-text-editor-swift", "state" : { - "revision" : "b6583a47b5d14d2dc8405a0303ebd4041b877707", - "version" : "2.37.12" + "revision" : "5f703d05bbf39f3026cc3c0697aab753a71fd83b", + "version" : "2.41.0" } }, { 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) + } } } } From 585f4a852d27fb4290bd83f144cad58321b3ebcd Mon Sep 17 00:00:00 2001 From: Arnfried Griesert Date: Tue, 17 Mar 2026 13:55:15 +0000 Subject: [PATCH 2/8] Feature/7555 migration part 3 --- Config/BWIBuildSettings.swift | 9 ++ .../xcshareddata/xcschemes/Riot.xcscheme | 28 +--- Riot/Assets/de.lproj/Bwi.strings | 13 +- Riot/Assets/en.lproj/Bwi.strings | 28 ++-- Riot/Generated/BWIStrings.swift | 58 ++++++-- .../KeyValueStorage/Extensions/Keychain.swift | 30 ++-- .../PushNotificationService.m | 14 +- .../Home/AllChats/AllChatsCoordinator.swift | 7 + .../AllChats/AllChatsViewController.swift | 18 ++- .../View/AuthenticationLoginScreen.swift | 12 ++ bwi/FeatureBanner/FeatureBannerView.swift | 11 +- bwi/FeatureBanner/MigrationInfoView.swift | 128 ++++++++++++++++-- .../MigrationAssistant.swift | 6 + project.yml | 5 + 14 files changed, 283 insertions(+), 84 deletions(-) diff --git a/Config/BWIBuildSettings.swift b/Config/BWIBuildSettings.swift index 1c9d1de09..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 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"> - - - - - - - - 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 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,30 @@ 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, welche dir von deinem Admin zur Verfügung gestellt wird + public static var bwiMobileDialogM3MoreText1: String { + return BWIL10n.tr("Bwi", "bwi_mobile_dialog_m3_more_text_1") + } + /// 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 +411,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/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..ed6c69e6c 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 !username.isEmpty || getUserName != nil { + 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.bwiMobileDialogM3MoreText1) + + 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) } @@ -246,7 +301,7 @@ struct MigrationInfoViewTwo: View { HStack() { Text("1.") Button(action: { - UIPasteboard.general.string = username + UIPasteboard.general.string = lazyLoadedUserName ?? "" guard !showSuccessToast else { return } withAnimation { showSuccessToast = true @@ -311,3 +366,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 From fbb133f4ce9a08484caceef97d20b0cb775fd576 Mon Sep 17 00:00:00 2001 From: Frank Rotermund Date: Thu, 19 Mar 2026 14:52:20 +0100 Subject: [PATCH 3/8] fix: Fix Appstore Page on Login and Texts (MESSENGER-7555) --- bwi/FeatureBanner/MigrationInfoView.swift | 79 +++++++++++++---------- 1 file changed, 45 insertions(+), 34 deletions(-) diff --git a/bwi/FeatureBanner/MigrationInfoView.swift b/bwi/FeatureBanner/MigrationInfoView.swift index ed6c69e6c..de49869d8 100644 --- a/bwi/FeatureBanner/MigrationInfoView.swift +++ b/bwi/FeatureBanner/MigrationInfoView.swift @@ -36,10 +36,8 @@ struct MigrationInfoView: View { } else { MigrationInfoViewOne() .tag(1) - if !username.isEmpty || getUserName != nil { - MigrationInfoViewTwo(username: username, getUserName: getUserName) + MigrationInfoViewTwo(username: username, getUserName: getUserName) .tag(2) - } } } .id(redrawKey) @@ -185,7 +183,7 @@ struct MigrationInfoViewOne: View { Text(BWIL10n.bwiMobileDialogM1MoreText2).bold() + Text(BWIL10n.bwiMobileDialogM1MoreText3) } else { - Text(BWIL10n.bwiMobileDialogM3MoreText1) + + Text(BWIL10n.bwiMobileDialogM1MoreText1) + Text(BWIL10n.bwiMobileDialogM1MoreText2).bold() + Text(BWIL10n.bwiMobileDialogM1MoreText3) } @@ -298,38 +296,51 @@ struct MigrationInfoViewTwo: View { .padding(.bottom, 20) } VStack(alignment: .leading) { - HStack() { - Text("1.") - Button(action: { - UIPasteboard.general.string = lazyLoadedUserName ?? "" - 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) + } } } } From 0ae1896cf59770cba7a0f90ae5dbcc95dc287381 Mon Sep 17 00:00:00 2001 From: Frank Rotermund Date: Thu, 19 Mar 2026 15:27:58 +0100 Subject: [PATCH 4/8] fix: wording mdm (MESSENGER-7555) --- Riot/Assets/en.lproj/Bwi.strings | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Riot/Assets/en.lproj/Bwi.strings b/Riot/Assets/en.lproj/Bwi.strings index 6c1291e52..70c0a4864 100644 --- a/Riot/Assets/en.lproj/Bwi.strings +++ b/Riot/Assets/en.lproj/Bwi.strings @@ -676,7 +676,7 @@ // Sheet page 1 "bwi_mobile_dialog_m_more_title" = "BundesMessengerX"; "bwi_mobile_dialog_m1_more_text_1" = "BuM will soon be switched off and replaced by BumX. This is a new, technically optimized app "; -"bwi_mobile_dialog_m3_more_text_1" = "BuM has been switched off and replaced by BumX. This is a new, technically optimized app "; +"bwi_mobile_dialog_m3_more_text_1" = "BuM has been switched off and replaced by BumX. This is a new, technically optimized app, which will soon be made available by your administrator "; "bwi_mobile_dialog_m1_more_text_2" = "(all your contacts and messages will be retained)."; "bwi_mobile_dialog_m1_more_text_3" = "\n\nYou can expect:"; From d2410313f62a7a7055be32ed501f5e1c883aa2ea Mon Sep 17 00:00:00 2001 From: Frank Rotermund Date: Fri, 20 Mar 2026 07:08:47 +0100 Subject: [PATCH 5/8] fix: more wording mdm (MESSENGER-7555) --- Riot/Assets/de.lproj/Bwi.strings | 5 +++-- Riot/Assets/en.lproj/Bwi.strings | 3 ++- Riot/Generated/BWIStrings.swift | 8 ++++++-- bwi/FeatureBanner/MigrationInfoView.swift | 4 ++-- 4 files changed, 13 insertions(+), 7 deletions(-) diff --git a/Riot/Assets/de.lproj/Bwi.strings b/Riot/Assets/de.lproj/Bwi.strings index 886748caa..c1cc44edd 100644 --- a/Riot/Assets/de.lproj/Bwi.strings +++ b/Riot/Assets/de.lproj/Bwi.strings @@ -763,8 +763,9 @@ // Sheet page 1 "bwi_mobile_dialog_m_more_title" = "BundesMessengerX"; -"bwi_mobile_dialog_m1_more_text_1" = "Der BuM wird bald abgeschaltet und durch durch den BuMX ersetzt. Dies ist eine neue, technisch optimierte App "; -"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 "; +"bwi_mobile_dialog_m1_more_text_1" = "Der BuM wird bald abgeschaltet und durch den BuMX ersetzt. Dies ist eine neue, technisch optimierte App "; +"bwi_mobile_dialog_m3_more_text_1" = "Der BuM wurde nun abgeschaltet und durch den BuMX ersetzt. Dies ist eine neue, technisch optimierte App "; +"bwi_mobile_dialog_m3_more_text_1_mdm" = "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 "; "bwi_mobile_dialog_m1_more_text_2" = "(alle deine Kontakte und Nachrichten bleiben erhalten)."; "bwi_mobile_dialog_m1_more_text_3" = "\n\nDich erwartet u.a.:"; "bwi_mobile_dialog_m1_more_text_bullet_1" = "schnellere Performance"; diff --git a/Riot/Assets/en.lproj/Bwi.strings b/Riot/Assets/en.lproj/Bwi.strings index 70c0a4864..52200f89e 100644 --- a/Riot/Assets/en.lproj/Bwi.strings +++ b/Riot/Assets/en.lproj/Bwi.strings @@ -676,7 +676,8 @@ // Sheet page 1 "bwi_mobile_dialog_m_more_title" = "BundesMessengerX"; "bwi_mobile_dialog_m1_more_text_1" = "BuM will soon be switched off and replaced by BumX. This is a new, technically optimized app "; -"bwi_mobile_dialog_m3_more_text_1" = "BuM has been switched off and replaced by BumX. This is a new, technically optimized app, which will soon be made available by your administrator "; +"bwi_mobile_dialog_m3_more_text_1" = "BuM has been switched off and replaced by BumX. This is a new, technically optimized app "; +"bwi_mobile_dialog_m3_more_text_1_mdm" = "BuM has been switched off and replaced by BumX. This is a new, technically optimized app, which will soon be made available by your administrator "; "bwi_mobile_dialog_m1_more_text_2" = "(all your contacts and messages will be retained)."; "bwi_mobile_dialog_m1_more_text_3" = "\n\nYou can expect:"; diff --git a/Riot/Generated/BWIStrings.swift b/Riot/Generated/BWIStrings.swift index 0061066b1..e05b828a8 100644 --- a/Riot/Generated/BWIStrings.swift +++ b/Riot/Generated/BWIStrings.swift @@ -319,7 +319,7 @@ public class BWIL10n: NSObject { public static var bwiMobileDialogM1BannerTextPrefix: String { return BWIL10n.tr("Bwi", "bwi_mobile_dialog_m1_banner_text_prefix") } - /// Der BuM wird bald abgeschaltet und durch durch den BuMX ersetzt. Dies ist eine neue, technisch optimierte App + /// 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") } @@ -359,10 +359,14 @@ public class BWIL10n: NSObject { 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, welche dir von deinem Admin zur Verfügung gestellt wird + /// 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") diff --git a/bwi/FeatureBanner/MigrationInfoView.swift b/bwi/FeatureBanner/MigrationInfoView.swift index de49869d8..51bb39c7b 100644 --- a/bwi/FeatureBanner/MigrationInfoView.swift +++ b/bwi/FeatureBanner/MigrationInfoView.swift @@ -171,7 +171,7 @@ struct MigrationInfoViewOne: View { .padding(.bottom, 20) if BWIBuildSettings.shared.isManagedViaMDM { if BWIBuildSettings.shared.BuMXMigrationInfoLevel == 3 { - Text(BWIL10n.bwiMobileDialogM3MoreText1) + + Text(BWIL10n.bwiMobileDialogM3MoreText1Mdm) + Text(BWIL10n.bwiMobileDialogM1MoreText2).bold() + Text(BWIL10n.bwiMobileDialogM1MoreText3) } else { @@ -183,7 +183,7 @@ struct MigrationInfoViewOne: View { Text(BWIL10n.bwiMobileDialogM1MoreText2).bold() + Text(BWIL10n.bwiMobileDialogM1MoreText3) } else { - Text(BWIL10n.bwiMobileDialogM1MoreText1) + + Text(BWIL10n.bwiMobileDialogM3MoreText1) + Text(BWIL10n.bwiMobileDialogM1MoreText2).bold() + Text(BWIL10n.bwiMobileDialogM1MoreText3) } From 535035a08372e123828e248a43c2e8bde91014d3 Mon Sep 17 00:00:00 2001 From: Frank Rotermund Date: Fri, 20 Mar 2026 12:07:59 +0100 Subject: [PATCH 6/8] fix: mdm no second page (MESSENGER-7555) --- bwi/FeatureBanner/MigrationInfoView.swift | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/bwi/FeatureBanner/MigrationInfoView.swift b/bwi/FeatureBanner/MigrationInfoView.swift index 51bb39c7b..3e973b110 100644 --- a/bwi/FeatureBanner/MigrationInfoView.swift +++ b/bwi/FeatureBanner/MigrationInfoView.swift @@ -36,8 +36,10 @@ struct MigrationInfoView: View { } else { MigrationInfoViewOne() .tag(1) - MigrationInfoViewTwo(username: username, getUserName: getUserName) - .tag(2) + if !BWIBuildSettings.shared.isManagedViaMDM { + MigrationInfoViewTwo(username: username, getUserName: getUserName) + .tag(2) + } } } .id(redrawKey) From 56e02e71361278db5ca34b23a8ab64ac2ca18b33 Mon Sep 17 00:00:00 2001 From: Jan Niklas Grabowski Date: Fri, 27 Mar 2026 11:52:06 +0100 Subject: [PATCH 7/8] chore: update changelog (MESSENGER-8137) --- CHANGES_BWI.md | 10 ++++++++++ Config/AppVersion.xcconfig | 2 +- Riot/Assets/new_features.html | 14 ++++++++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) 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/Riot/Assets/new_features.html b/Riot/Assets/new_features.html index 21ff34788..53691ee26 100644 --- a/Riot/Assets/new_features.html +++ b/Riot/Assets/new_features.html @@ -26,6 +26,20 @@ +
+

+ Version 2.28.0 +

+ +

+ Verbesserungen +

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

+ +

Version 2.27.3 From c92ef3961e30062b7d72c24858acb209ff7a797c Mon Sep 17 00:00:00 2001 From: Jan Niklas Grabowski Date: Tue, 31 Mar 2026 14:30:32 +0200 Subject: [PATCH 8/8] fix: remove share button (MESSENGER-8137) --- .../Controllers/MXKPreviewViewController.m | 38 +++++++++++++------ 1 file changed, 27 insertions(+), 11 deletions(-) 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