mirror of
https://gitlab.opencode.de/bwi/bundesmessenger/clients/bundesmessenger-ios.git
synced 2026-04-22 17:42:45 +02:00
222f3292a2
# Conflicts: # .github/workflows/ci-build.yml # .github/workflows/ci-tests.yml # .github/workflows/release-alpha.yml # .github/workflows/triage-move-labelled.yml # .github/workflows/triage-priority-bugs.yml # .gitignore # CHANGES.md # Config/AppConfiguration.swift # Config/AppIdentifiers.xcconfig # Config/AppVersion.xcconfig # Config/BuildSettings.swift # Config/CommonConfiguration.swift # Gemfile # Gemfile.lock # IDETemplateMacros.plist # Podfile # Podfile.lock # README.md # Riot.xcodeproj/xcshareddata/xcschemes/Riot.xcscheme # Riot/Assets/Images.xcassets/Common/reveal_password_button.imageset/reveal_password_button.png # Riot/Assets/Images.xcassets/Common/reveal_password_button.imageset/reveal_password_button@2x.png # Riot/Assets/Images.xcassets/Common/reveal_password_button.imageset/reveal_password_button@3x.png # Riot/Assets/Images.xcassets/People/people_floating_action.imageset/Contents.json # Riot/Assets/Images.xcassets/Rooms/rooms_floating_action.imageset/Contents.json # Riot/Assets/Images.xcassets/Secrets/Recovery/secrets_recovery_key.imageset/Contents.json # Riot/Assets/Images.xcassets/Secrets/Recovery/secrets_recovery_passphrase.imageset/Contents.json # Riot/Assets/Images.xcassets/Secrets/Setup/secrets_setup_key.imageset/Contents.json # Riot/Assets/Images.xcassets/Secrets/Setup/secrets_setup_passphrase.imageset/Contents.json # Riot/Assets/Images.xcassets/TabBar/tab_people.imageset/Contents.json # Riot/Assets/Images.xcassets/TabBar/tab_rooms.imageset/Contents.json # Riot/Assets/SharedImages.xcassets/AppIcon.appiconset/Contents.json # Riot/Assets/SharedImages.xcassets/horizontal_logo.imageset/Contents.json # Riot/Assets/ar.lproj/InfoPlist.strings # Riot/Assets/cs.lproj/Vector.strings # Riot/Assets/de.lproj/InfoPlist.strings # Riot/Assets/de.lproj/Localizable.strings # Riot/Assets/de.lproj/Vector.strings # Riot/Assets/en.lproj/Localizable.strings # Riot/Assets/en.lproj/Untranslated.strings # Riot/Assets/en.lproj/Vector.strings # Riot/Assets/es.lproj/InfoPlist.strings # Riot/Assets/es.lproj/Vector.strings # Riot/Assets/et.lproj/InfoPlist.strings # Riot/Assets/et.lproj/Vector.strings # Riot/Assets/fr.lproj/InfoPlist.strings # Riot/Assets/fr.lproj/Vector.strings # Riot/Assets/hu.lproj/InfoPlist.strings # Riot/Assets/hu.lproj/Vector.strings # Riot/Assets/id.lproj/InfoPlist.strings # Riot/Assets/id.lproj/Vector.strings # Riot/Assets/is.lproj/InfoPlist.strings # Riot/Assets/is.lproj/Vector.strings # Riot/Assets/it.lproj/InfoPlist.strings # Riot/Assets/it.lproj/Vector.strings # Riot/Assets/ja.lproj/InfoPlist.strings # Riot/Assets/ja.lproj/Localizable.strings # Riot/Assets/ja.lproj/Vector.strings # Riot/Assets/nl.lproj/InfoPlist.strings # Riot/Assets/nl.lproj/Vector.strings # Riot/Assets/pl.lproj/InfoPlist.strings # Riot/Assets/pl.lproj/Vector.strings # Riot/Assets/pt_BR.lproj/InfoPlist.strings # Riot/Assets/pt_BR.lproj/Vector.strings # Riot/Assets/ru.lproj/InfoPlist.strings # Riot/Assets/ru.lproj/Vector.strings # Riot/Assets/sk.lproj/InfoPlist.strings # Riot/Assets/sk.lproj/Vector.strings # Riot/Assets/sq.lproj/InfoPlist.strings # Riot/Assets/sq.lproj/Vector.strings # Riot/Assets/sv.lproj/InfoPlist.strings # Riot/Assets/sv.lproj/Vector.strings # Riot/Assets/third_party_licenses.html # Riot/Assets/uk.lproj/InfoPlist.strings # Riot/Assets/uk.lproj/Vector.strings # Riot/Assets/zh_Hans.lproj/InfoPlist.strings # Riot/Assets/zh_Hans.lproj/Localizable.strings # Riot/Assets/zh_Hans.lproj/Vector.strings # Riot/Assets/zh_Hant.lproj/Vector.strings # Riot/Categories/MXKRoomBubbleTableViewCell+Riot.h # Riot/Categories/MXKRoomBubbleTableViewCell+Riot.m # Riot/Categories/MXRestClient+Async.swift # Riot/Categories/MXSession+Riot.m # Riot/Categories/NSAttributedString.swift # Riot/Categories/Publisher+Riot.swift # Riot/Categories/RoomBubbleCellData.swift # Riot/Categories/UILabel.swift # Riot/Categories/UIScrollView.swift # Riot/Categories/UIView.swift # Riot/Categories/UIViewController.swift # Riot/Generated/Images.swift # Riot/Generated/Strings.swift # Riot/Generated/UntranslatedStrings.swift # Riot/Managers/EncryptionKeyManager/EncryptionKeyManager.swift # Riot/Managers/LocalAuthentication/LocalAuthenticationService.swift # Riot/Managers/PushNotification/PushNotificationService.m # Riot/Managers/PushNotification/PushNotificationStore.swift # Riot/Managers/Settings/RiotSettings.swift # Riot/Managers/Settings/Shared/RiotSharedSettings.swift # Riot/Managers/Theme/Themes/DarkTheme.swift # Riot/Managers/Theme/Themes/DefaultTheme.swift # Riot/Managers/UISIAutoReporter/UISIAutoReporter.swift # Riot/Model/HomeserverConfiguration/HomeserverConfigurationBuilder.swift # Riot/Modules/Analytics/Analytics.swift # Riot/Modules/Analytics/AnalyticsUIElement.swift # Riot/Modules/Analytics/DecryptionFailureTracker.m # Riot/Modules/Application/AppCoordinator.swift # Riot/Modules/Application/LegacyAppDelegate.h # Riot/Modules/Application/LegacyAppDelegate.m # Riot/Modules/Authentication/AuthenticationCoordinatorProtocol.swift # Riot/Modules/Common/Avatar/AvatarView.swift # Riot/Modules/Common/Recents/DataSources/RecentsDataSource.h # Riot/Modules/Common/Recents/DataSources/RecentsDataSource.m # Riot/Modules/Common/Recents/RecentsViewController.h # Riot/Modules/Common/Recents/RecentsViewController.m # Riot/Modules/Common/Recents/Views/RecentTableViewCell.m # Riot/Modules/Common/SwiftUI/VectorHostingController.swift # Riot/Modules/Common/Toasts/RoundedToastView.swift # Riot/Modules/Common/Toasts/ToastViewState.swift # Riot/Modules/Common/UserIndicators/UserIndicatorPresenter.swift # Riot/Modules/Common/UserIndicators/UserIndicatorStore.swift # Riot/Modules/Common/UserIndicators/ViewPresenters/ToastViewPresenter.swift # Riot/Modules/Common/WebViewController/WebViewViewController.m # Riot/Modules/Communities/Home/GroupHomeViewController.m # Riot/Modules/Communities/Members/GroupParticipantsViewController.m # Riot/Modules/Communities/Rooms/GroupRoomsViewController.m # Riot/Modules/Contacts/ContactsTableViewController.m # Riot/Modules/Contacts/ContactsTableViewController.xib # Riot/Modules/Contacts/Details/ContactDetailsViewController.m # Riot/Modules/Contacts/Views/ContactTableViewCell.m # Riot/Modules/Contacts/Views/ContactTableViewCell.xib # Riot/Modules/ContextMenu/ActionProviders/RoomActionProvider.swift # Riot/Modules/ContextMenu/Services/RoomContextActionService.swift # Riot/Modules/CreateRoom/CreateRoomCoordinator.swift # Riot/Modules/CreateRoom/EnterNewRoomDetails/EnterNewRoomDetailsCoordinator.swift # Riot/Modules/CreateRoom/EnterNewRoomDetails/EnterNewRoomDetailsViewController.swift # Riot/Modules/CreateRoom/EnterNewRoomDetails/EnterNewRoomDetailsViewModel.swift # Riot/Modules/DeepLink/UniversalLinkParameters.swift # Riot/Modules/Favorites/FavouritesViewController.h # Riot/Modules/Favorites/FavouritesViewController.m # Riot/Modules/GlobalSearch/UnifiedSearchViewController.m # Riot/Modules/Home/HomeViewController.m # Riot/Modules/Home/Views/RoomCollectionViewCell.m # Riot/Modules/Integrations/WidgetPicker/WidgetPickerViewController.m # Riot/Modules/Integrations/Widgets/StickerPicker/StickerPickerViewController.m # Riot/Modules/KeyBackup/ManualExport/EncryptionKeysExportPresenter.swift # Riot/Modules/KeyVerification/Common/KeyVerificationCoordinator.swift # Riot/Modules/KeyVerification/Common/Verify/Scanning/KeyVerificationVerifyByScanningViewController.swift # Riot/Modules/KeyVerification/Device/SelfVerifyWait/KeyVerificationSelfVerifyWaitCoordinator.swift # Riot/Modules/KeyVerification/Device/SelfVerifyWait/KeyVerificationSelfVerifyWaitViewController.storyboard # Riot/Modules/KeyVerification/Device/SelfVerifyWait/KeyVerificationSelfVerifyWaitViewController.swift # Riot/Modules/KeyVerification/User/SessionStatus/UserVerificationSessionStatusViewController.swift # Riot/Modules/LocationSharing/LocationManager.swift # Riot/Modules/LocationSharing/UserLocationService.swift # Riot/Modules/LocationSharing/UserLocationServiceProvider.swift # Riot/Modules/MatrixKit/Categories/NSBundle+MatrixKit.m # Riot/Modules/MatrixKit/Controllers/MXKAccountDetailsViewController.m # Riot/Modules/MatrixKit/Controllers/MXKAuthenticationViewController.m # Riot/Modules/MatrixKit/Controllers/MXKRoomMemberDetailsViewController.h # Riot/Modules/MatrixKit/Controllers/MXKViewController.h # Riot/Modules/MatrixKit/Models/Account/MXKAccount.h # Riot/Modules/MatrixKit/Models/Account/MXKAccount.m # Riot/Modules/MatrixKit/Models/Account/MXKAccountManager.h # Riot/Modules/MatrixKit/Models/Account/MXKAccountManager.m # Riot/Modules/MatrixKit/Models/Contact/MXKContact.h # Riot/Modules/MatrixKit/Models/Room/MXKRoomBubbleCellData.h # Riot/Modules/MatrixKit/Models/Room/MXKRoomBubbleCellData.m # Riot/Modules/MatrixKit/Models/Room/MXKRoomBubbleCellDataStoring.h # Riot/Modules/MatrixKit/Models/Room/MXKRoomBubbleCellDataWithAppendingMode.m # Riot/Modules/MatrixKit/Models/Room/MXKRoomBubbleComponent.h # Riot/Modules/MatrixKit/Models/Room/MXKRoomBubbleComponent.m # Riot/Modules/MatrixKit/Models/Room/MXKRoomDataSource.m # Riot/Modules/MatrixKit/Models/Room/MXKSendReplyEventStringLocalizer.swift # Riot/Modules/MatrixKit/Utils/ErrorPresentation/MXKErrorPresentableBuilder.m # Riot/Modules/MatrixKit/Utils/EventFormatter/MXKEventFormatter.h # Riot/Modules/MatrixKit/Utils/EventFormatter/MXKEventFormatter.m # Riot/Modules/MatrixKit/Utils/MXKTools.h # Riot/Modules/MatrixKit/Utils/MXKTools.m # Riot/Modules/MatrixKit/Views/Account/MXKAccountTableViewCell.m # Riot/Modules/MatrixKit/Views/MXKTableViewCell/MXKTableViewCellWithLabelAndTextField.xib # Riot/Modules/MatrixKit/Views/MXKTableViewCell/MXKTableViewCellWithTextFieldAndButton.m # Riot/Modules/MatrixKit/Views/RoomInputToolbar/MXKRoomInputToolbarView.m # Riot/Modules/MatrixKit/Views/RoomMemberList/MXKRoomMemberTableViewCell.m # Riot/Modules/MediaPicker/MediaPickerViewController.m # Riot/Modules/MediaPicker/SingleImagePickerPresenter.swift # Riot/Modules/MediaPickerV2/MediaPickerPresenter.swift # Riot/Modules/Onboarding/OnboardingCoordinator.swift # Riot/Modules/Onboarding/OnboardingCoordinatorBridgePresenter.swift # Riot/Modules/Onboarding/OnboardingCoordinatorProtocol.swift # Riot/Modules/People/PeopleViewController.h # Riot/Modules/People/PeopleViewController.m # Riot/Modules/Pills/PillTextAttachment.swift # Riot/Modules/Pills/PillsFormatter.swift # Riot/Modules/QRCode/QRCodeGenerator.swift # Riot/Modules/Room/CellData/RoomBubbleCellData.m # Riot/Modules/Room/ContextualMenu/ReactionsMenu/ReactionsMenuViewModel.swift # Riot/Modules/Room/CreationModal/RoomCreationEventsModal/RoomCreationEventsModalCoordinator.swift # Riot/Modules/Room/CreationModal/RoomCreationEventsModal/RoomCreationEventsModalViewModel.swift # Riot/Modules/Room/CreationModal/RoomCreationModalCoordinatorBridgePresenter.swift # Riot/Modules/Room/DataSources/RoomDataSource.m # Riot/Modules/Room/DataSources/RoomDataSource.swift # Riot/Modules/Room/EditHistory/EditHistoryViewModel.swift # Riot/Modules/Room/Files/RoomFilesViewController.m # Riot/Modules/Room/Location/RoomTimelineLocationView.swift # Riot/Modules/Room/Location/RoomTimelineLocationView.xib # Riot/Modules/Room/MXKRoomViewController.h # Riot/Modules/Room/MXKRoomViewController.m # Riot/Modules/Room/Members/Detail/RoomMemberDetailsViewController.h # Riot/Modules/Room/Members/Detail/RoomMemberDetailsViewController.m # Riot/Modules/Room/Members/RoomParticipantsViewController.h # Riot/Modules/Room/Members/RoomParticipantsViewController.m # Riot/Modules/Room/ParticipantsInviteModal/ContactsPicker/ContactsPickerViewModel.swift # Riot/Modules/Room/RoomCoordinator.swift # Riot/Modules/Room/RoomInfo/RoomInfoCoordinator.swift # Riot/Modules/Room/RoomInfo/RoomInfoList/RoomInfoListViewAction.swift # Riot/Modules/Room/RoomInfo/RoomInfoList/RoomInfoListViewController.swift # Riot/Modules/Room/RoomInfo/RoomInfoList/RoomInfoListViewModel.swift # Riot/Modules/Room/RoomInfo/RoomInfoList/RoomInfoListViewModelType.swift # Riot/Modules/Room/RoomInfo/RoomInfoList/RoomInfoListViewState.swift # Riot/Modules/Room/RoomInfo/RoomInfoList/Views/RoomInfoBasicView.swift # Riot/Modules/Room/RoomViewController.m # Riot/Modules/Room/Settings/RoomSettingsViewController.m # Riot/Modules/Room/TimelineCells/BaseRoomCell/RoomCellContentView.xib # Riot/Modules/Room/TimelineCells/Common/MXKRoomBubbleTableViewCell.m # Riot/Modules/Room/TimelineCells/RoomCreationIntro/RoomCreationIntroCell.swift # Riot/Modules/Room/TimelineCells/RoomCreationIntro/RoomCreationIntroCellContentView.swift # Riot/Modules/Room/TimelineCells/RoomCreationIntro/RoomCreationIntroViewData.swift # Riot/Modules/Room/TimelineCells/RoomMembership/RoomMembershipCollapsedBubbleCell.m # Riot/Modules/Room/TimelineCells/RoomTimelineCellIdentifier.h # Riot/Modules/Room/TimelineCells/Styles/Bubble/BubbleRoomTimelineCellProvider.m # Riot/Modules/Room/TimelineCells/Styles/Bubble/BubbleRoomTimelineStyle.swift # Riot/Modules/Room/TimelineCells/Styles/Bubble/Cells/FileWithoutThumbnail/Common/FileWithoutThumbnailBaseBubbleCell.swift # Riot/Modules/Room/TimelineCells/Styles/Bubble/Cells/FileWithoutThumbnail/Common/FileWithoutThumbnailCellContentView.swift # Riot/Modules/Room/TimelineCells/Styles/Bubble/Cells/FileWithoutThumbnail/Common/FileWithoutThumbnailCellContentView.xib # Riot/Modules/Room/TimelineCells/Styles/Plain/Cells/FileAttachment/Incoming/Clear/RoomIncomingAttachmentBubbleCell.xib # Riot/Modules/Room/TimelineCells/Styles/Plain/Cells/FileAttachment/Incoming/Clear/RoomIncomingAttachmentWithPaginationTitleBubbleCell.xib # Riot/Modules/Room/TimelineCells/Styles/Plain/Cells/FileAttachment/Incoming/Encrypted/RoomIncomingEncryptedAttachmentBubbleCell.xib # Riot/Modules/Room/TimelineCells/Styles/Plain/Cells/FileAttachment/Incoming/Encrypted/RoomIncomingEncryptedAttachmentWithPaginationTitleBubbleCell.xib # Riot/Modules/Room/TimelineCells/Styles/Plain/Cells/FileAttachment/Outgoing/Clear/RoomOutgoingAttachmentBubbleCell.xib # Riot/Modules/Room/TimelineCells/Styles/Plain/Cells/FileAttachment/Outgoing/Clear/RoomOutgoingAttachmentWithPaginationTitleBubbleCell.xib # Riot/Modules/Room/TimelineCells/Styles/Plain/Cells/FileAttachment/Outgoing/Encrypted/RoomOutgoingEncryptedAttachmentBubbleCell.xib # Riot/Modules/Room/TimelineCells/Styles/Plain/Cells/FileAttachment/Outgoing/Encrypted/RoomOutgoingEncryptedAttachmentWithPaginationTitleBubbleCell.xib # Riot/Modules/Room/TimelineCells/Styles/Plain/Cells/Location/LocationPlainCell.swift # Riot/Modules/Room/TimelineCells/Styles/Plain/Cells/Poll/PollPlainCell.swift # Riot/Modules/Room/TimelineCells/Styles/Plain/Cells/Sticker/RoomSelectedStickerBubbleCell.xib # Riot/Modules/Room/TimelineCells/Styles/Plain/Cells/TextMessage/Incoming/Clear/RoomIncomingTextMsgBubbleCell.xib # Riot/Modules/Room/TimelineCells/Styles/Plain/Cells/TextMessage/Incoming/Clear/RoomIncomingTextMsgWithPaginationTitleBubbleCell.xib # Riot/Modules/Room/TimelineCells/Styles/Plain/Cells/TextMessage/Incoming/Encrypted/RoomIncomingEncryptedTextMsgBubbleCell.xib # Riot/Modules/Room/TimelineCells/Styles/Plain/Cells/TextMessage/Incoming/Encrypted/RoomIncomingEncryptedTextMsgWithPaginationTitleBubbleCell.xib # Riot/Modules/Room/TimelineCells/Styles/Plain/Cells/TextMessage/Outgoing/Clear/RoomOutgoingTextMsgBubbleCell.xib # Riot/Modules/Room/TimelineCells/Styles/Plain/Cells/TextMessage/Outgoing/Clear/RoomOutgoingTextMsgWithPaginationTitleBubbleCell.xib # Riot/Modules/Room/TimelineCells/Styles/Plain/Cells/TextMessage/Outgoing/Encrypted/RoomOutgoingEncryptedTextMsgBubbleCell.xib # Riot/Modules/Room/TimelineCells/Styles/Plain/Cells/TextMessage/Outgoing/Encrypted/RoomOutgoingEncryptedTextMsgWithPaginationTitleBubbleCell.xib # Riot/Modules/Room/TimelineCells/Styles/Plain/PlainRoomTimelineCellProvider.m # Riot/Modules/Room/TimelineCells/Styles/Plain/PlainRoomTimelineStyle.swift # Riot/Modules/Room/TimelineCells/Styles/RoomTimelineStyle.swift # Riot/Modules/Room/TimelineDecorations/Reactions/RoomReactionActionViewCell.swift # Riot/Modules/Room/TimelineDecorations/Reactions/RoomReactionActionViewCell.xib # Riot/Modules/Room/TimelineDecorations/Reactions/RoomReactionViewCell.xib # Riot/Modules/Room/TimelineDecorations/Reactions/RoomReactionsView.swift # Riot/Modules/Room/TimelineDecorations/Reactions/RoomReactionsViewModel.swift # Riot/Modules/Room/TimelineDecorations/Reactions/RoomReactionsViewModelType.swift # Riot/Modules/Room/TimelineDecorations/Threads/Summary/ThreadSummaryView.swift # Riot/Modules/Room/VoiceMessages/VoiceMessageAudioConverter.swift # Riot/Modules/Room/VoiceMessages/VoiceMessageAudioRecorder.swift # Riot/Modules/Room/VoiceMessages/VoiceMessagePlaybackView.swift # Riot/Modules/Room/VoiceMessages/VoiceMessagePlaybackView.xib # Riot/Modules/Room/VoiceMessages/VoiceMessageToolbarView.swift # Riot/Modules/Rooms/RoomsViewController.h # Riot/Modules/Rooms/ShowDirectory/Cells/Network/DirectoryNetworkTableHeaderFooterView.swift # Riot/Modules/Rooms/ShowDirectory/Cells/Room/DirectoryRoomTableViewCell.swift # Riot/Modules/Rooms/ShowDirectory/Cells/Room/DirectoryRoomTableViewCell.xib # Riot/Modules/Rooms/ShowDirectory/PublicRoomsDirectoryViewModel.swift # Riot/Modules/Rooms/ShowDirectory/ShowDirectoryViewController.swift # Riot/Modules/Rooms/ShowDirectory/ShowDirectoryViewModel.swift # Riot/Modules/Secrets/Recover/RecoverWithKey/SecretsRecoveryWithKeyCoordinator.swift # Riot/Modules/Secrets/Recover/RecoverWithKey/SecretsRecoveryWithKeyViewController.swift # Riot/Modules/Secrets/Recover/RecoverWithPassphrase/SecretsRecoveryWithPassphraseCoordinator.swift # Riot/Modules/Secrets/Recover/RecoverWithPassphrase/SecretsRecoveryWithPassphraseViewController.swift # Riot/Modules/Secrets/Recover/SecretsRecoveryCoordinator.swift # Riot/Modules/Secrets/Reset/SecretsResetViewController.storyboard # Riot/Modules/Secrets/Reset/SecretsResetViewController.swift # Riot/Modules/Secrets/Setup/RecoveryKey/SecretsSetupRecoveryKeyViewController.swift # Riot/Modules/Secrets/Setup/RecoveryPassphrase/SecretsSetupRecoveryPassphraseViewController.storyboard # Riot/Modules/Secrets/Setup/RecoveryPassphrase/SecretsSetupRecoveryPassphraseViewController.swift # Riot/Modules/SecureBackup/Setup/Intro/SecureBackupSetupIntroViewController.swift # Riot/Modules/SecureBackup/Setup/Intro/SecureBackupSetupIntroViewModel.swift # Riot/Modules/SecureBackup/Setup/Intro/SecureBackupSetupIntroViewModelType.swift # Riot/Modules/SecureBackup/Setup/SecureBackupSetupCoordinator.swift # Riot/Modules/SetPinCode/EnterPinCode/EnterPinCodeViewController.storyboard # Riot/Modules/SetPinCode/EnterPinCode/EnterPinCodeViewController.swift # Riot/Modules/SetPinCode/EnterPinCode/EnterPinCodeViewModel.swift # Riot/Modules/SetPinCode/PinCodePreferences.swift # Riot/Modules/SetPinCode/SetPinCoordinator.swift # Riot/Modules/SetPinCode/SetPinCoordinatorBridgePresenter.swift # Riot/Modules/SetPinCode/SetupBiometrics/BiometricsAuthenticationPresenter.swift # Riot/Modules/SetPinCode/SetupBiometrics/SetupBiometricsCoordinator.swift # Riot/Modules/SetPinCode/SetupBiometrics/SetupBiometricsViewController.swift # Riot/Modules/SetPinCode/SetupBiometrics/SetupBiometricsViewModel.swift # Riot/Modules/Settings/DeactivateAccount/DeactivateAccountViewController.m # Riot/Modules/Settings/Security/ManageSession/ManageSessionViewController.m # Riot/Modules/Settings/Security/SecurityViewController.m # Riot/Modules/Settings/SettingsViewController.m # Riot/Modules/SideMenu/SideMenuCoordinator.swift # Riot/Modules/SideMenu/SideMenuViewModel.swift # Riot/Modules/Spaces/SpaceList/SpaceListViewModel.swift # Riot/Modules/Spaces/SpaceMenu/SpaceMenuPresenter.swift # Riot/Modules/Spaces/SpaceMenu/SpaceMenuViewModel.swift # Riot/Modules/Spaces/SpaceRoomList/ExploreRoomCoordinator.swift # Riot/Modules/SplitView/SplitViewCoordinator.swift # Riot/Modules/SplitView/SplitViewCoordinatorType.swift # Riot/Modules/StartChat/StartChatViewController.m # Riot/Modules/TabBar/MasterTabBarController.h # Riot/Modules/TabBar/MasterTabBarController.m # Riot/Modules/TabBar/TabBarCoordinator.swift # Riot/Modules/TabBar/TabBarCoordinatorType.swift # Riot/Modules/Threads/ThreadList/ThreadListViewModel.swift # Riot/SupportingFiles/Info.plist # Riot/SupportingFiles/Riot-Bridging-Header.h # Riot/SupportingFiles/Riot.entitlements # Riot/Utils/EventFormatter+DTCoreTextFix.m # Riot/Utils/EventFormatter.m # Riot/Utils/Tools.h # Riot/Utils/Tools.m # Riot/Utils/URLValidator.swift # Riot/Utils/UniversalLink.h # Riot/Utils/UniversalLink.m # Riot/target.yml # RiotNSE/NotificationService.swift # RiotNSE/RiotNSE.entitlements # RiotNSE/target.yml # RiotShareExtension/Shared/View/ShareViewController.m # RiotShareExtension/SupportingFiles/Info.plist # RiotShareExtension/target.yml # RiotSwiftUI/Modules/AnalyticsPrompt/AnalyticsPromptViewModel.swift # RiotSwiftUI/Modules/AnalyticsPrompt/Coordinator/AnalyticsPromptCoordinator.swift # RiotSwiftUI/Modules/AnalyticsPrompt/Coordinator/AnalyticsPromptStrings.swift # RiotSwiftUI/Modules/AnalyticsPrompt/MockAnalyticsPromptScreenState.swift # RiotSwiftUI/Modules/AnalyticsPrompt/Test/UI/AnalyticsPromptUITests.swift # RiotSwiftUI/Modules/AnalyticsPrompt/View/AnalyticsPrompt.swift # RiotSwiftUI/Modules/AnalyticsPrompt/View/AnalyticsPromptCheckmarkItem.swift # RiotSwiftUI/Modules/Authentication/Common/AuthenticationHomeserverViewData.swift # RiotSwiftUI/Modules/Authentication/Common/AuthenticationModels.swift # RiotSwiftUI/Modules/Authentication/Common/AuthenticationServerInfoSection.swift # RiotSwiftUI/Modules/Authentication/Common/Service/MatrixSDK/AuthenticationRestClient.swift # RiotSwiftUI/Modules/Authentication/Common/Service/MatrixSDK/AuthenticationService.swift # RiotSwiftUI/Modules/Authentication/Common/Service/MatrixSDK/AuthenticationState.swift # RiotSwiftUI/Modules/Authentication/Common/Service/MatrixSDK/LoginModels.swift # RiotSwiftUI/Modules/Authentication/Common/Service/MatrixSDK/LoginParameters.swift # RiotSwiftUI/Modules/Authentication/Common/Service/MatrixSDK/LoginWizard.swift # RiotSwiftUI/Modules/Authentication/Common/Service/MatrixSDK/RegistrationParameters.swift # RiotSwiftUI/Modules/Authentication/Common/Service/MatrixSDK/RegistrationWizard.swift # RiotSwiftUI/Modules/Authentication/Common/Service/MatrixSDK/SessionCreator.swift # RiotSwiftUI/Modules/Authentication/Common/Service/MatrixSDK/ThreePIDModels.swift # RiotSwiftUI/Modules/Authentication/Login/AuthenticationLoginModels.swift # RiotSwiftUI/Modules/Authentication/Login/Coordinator/AuthenticationLoginCoordinator.swift # RiotSwiftUI/Modules/Authentication/Login/Test/UI/AuthenticationLoginUITests.swift # RiotSwiftUI/Modules/Authentication/Login/Test/Unit/AuthenticationLoginViewModelTests.swift # RiotSwiftUI/Modules/Authentication/Login/View/AuthenticationLoginScreen.swift # RiotSwiftUI/Modules/Authentication/ReCaptcha/Test/UI/AuthenticationReCaptchaUITests.swift # RiotSwiftUI/Modules/Authentication/ReCaptcha/View/AuthenticationReCaptchaScreen.swift # RiotSwiftUI/Modules/Authentication/ReCaptcha/View/AuthenticationReCaptchaWebView.swift # RiotSwiftUI/Modules/Authentication/Registration/AuthenticationRegistrationModels.swift # RiotSwiftUI/Modules/Authentication/Registration/AuthenticationRegistrationViewModel.swift # RiotSwiftUI/Modules/Authentication/Registration/AuthenticationRegistrationViewModelProtocol.swift # RiotSwiftUI/Modules/Authentication/Registration/Coordinator/AuthenticationRegistrationCoordinator.swift # RiotSwiftUI/Modules/Authentication/Registration/MockAuthenticationRegistrationScreenState.swift # RiotSwiftUI/Modules/Authentication/Registration/Test/UI/AuthenticationRegistrationUITests.swift # RiotSwiftUI/Modules/Authentication/Registration/Test/Unit/AuthenticationRegistrationViewModelTests.swift # RiotSwiftUI/Modules/Authentication/Registration/View/AuthenticationRegistrationScreen.swift # RiotSwiftUI/Modules/Authentication/ServerSelection/AuthenticationServerSelectionModels.swift # RiotSwiftUI/Modules/Authentication/ServerSelection/AuthenticationServerSelectionViewModel.swift # RiotSwiftUI/Modules/Authentication/ServerSelection/Coordinator/AuthenticationServerSelectionCoordinator.swift # RiotSwiftUI/Modules/Authentication/ServerSelection/MockAuthenticationServerSelectionScreenState.swift # RiotSwiftUI/Modules/Authentication/ServerSelection/Test/UI/AuthenticationServerSelectionUITests.swift # RiotSwiftUI/Modules/Authentication/ServerSelection/Test/Unit/AuthenticationServerSelectionViewModelTests.swift # RiotSwiftUI/Modules/Authentication/ServerSelection/View/AuthenticationServerSelectionScreen.swift # RiotSwiftUI/Modules/Authentication/Terms/AuthenticationTermsModels.swift # RiotSwiftUI/Modules/Authentication/Terms/AuthenticationTermsViewModel.swift # RiotSwiftUI/Modules/Authentication/Terms/Coordinator/AuthenticationTermsCoordinator.swift # RiotSwiftUI/Modules/Authentication/Terms/MockAuthenticationTermsScreenState.swift # RiotSwiftUI/Modules/Authentication/Terms/Test/UI/AuthenticationTermsUITests.swift # RiotSwiftUI/Modules/Authentication/Terms/View/AuthenticationTermsScreen.swift # RiotSwiftUI/Modules/Authentication/Terms/View/AuthenticationTermsToggleStyle.swift # RiotSwiftUI/Modules/Authentication/VerifyEmail/AuthenticationVerifyEmailModels.swift # RiotSwiftUI/Modules/Authentication/VerifyEmail/AuthenticationVerifyEmailViewModel.swift # RiotSwiftUI/Modules/Authentication/VerifyEmail/Coordinator/AuthenticationVerifyEmailCoordinator.swift # RiotSwiftUI/Modules/Authentication/VerifyEmail/MockAuthenticationVerifyEmailScreenState.swift # RiotSwiftUI/Modules/Authentication/VerifyEmail/Test/UI/AuthenticationVerifyEmailUITests.swift # RiotSwiftUI/Modules/Authentication/VerifyEmail/Test/Unit/AuthenticationVerifyEmailViewModelTests.swift # RiotSwiftUI/Modules/Authentication/VerifyEmail/View/AuthenticationVerifyEmailForm.swift # RiotSwiftUI/Modules/Authentication/VerifyEmail/View/AuthenticationVerifyEmailScreen.swift # RiotSwiftUI/Modules/Authentication/VerifyMsisdn/AuthenticationVerifyMsisdnModels.swift # RiotSwiftUI/Modules/Authentication/VerifyMsisdn/AuthenticationVerifyMsisdnViewModel.swift # RiotSwiftUI/Modules/Authentication/VerifyMsisdn/Coordinator/AuthenticationVerifyMsisdnCoordinator.swift # RiotSwiftUI/Modules/Authentication/VerifyMsisdn/MockAuthenticationVerifyMsisdnScreenState.swift # RiotSwiftUI/Modules/Authentication/VerifyMsisdn/Test/UI/AuthenticationVerifyMsisdnUITests.swift # RiotSwiftUI/Modules/Authentication/VerifyMsisdn/Test/Unit/AuthenticationVerifyMsisdnViewModelTests.swift # RiotSwiftUI/Modules/Authentication/VerifyMsisdn/View/AuthenticationVerifyMsisdnForm.swift # RiotSwiftUI/Modules/Common/ActivityIndicator/ActivityIndicator.swift # RiotSwiftUI/Modules/Common/ActivityIndicator/ActivityIndicatorModifier.swift # RiotSwiftUI/Modules/Common/Avatar/Service/MatrixSDK/AvatarService.swift # RiotSwiftUI/Modules/Common/Avatar/Service/Mock/MockAvatarService.swift # RiotSwiftUI/Modules/Common/Avatar/View/AvatarImage.swift # RiotSwiftUI/Modules/Common/Avatar/View/PlaceholderAvatarImage.swift # RiotSwiftUI/Modules/Common/Avatar/View/SpaceAvatarImage.swift # RiotSwiftUI/Modules/Common/Avatar/ViewModel/AvatarServiceProtocol.swift # RiotSwiftUI/Modules/Common/Avatar/ViewModel/AvatarViewModel.swift # RiotSwiftUI/Modules/Common/Bridging/VectorContentView.swift # RiotSwiftUI/Modules/Common/DependencyInjection/DependencyContainerKey.swift # RiotSwiftUI/Modules/Common/EffectsScene/EffectsScene.swift # RiotSwiftUI/Modules/Common/EffectsScene/EffectsView.swift # RiotSwiftUI/Modules/Common/Extensions/Publisher.swift # RiotSwiftUI/Modules/Common/Mock/MockAppScreens.swift # RiotSwiftUI/Modules/Common/Mock/MockScreenState.swift # RiotSwiftUI/Modules/Common/Mock/ScreenList.swift # RiotSwiftUI/Modules/Common/Mock/ScreenStateInfo.swift # RiotSwiftUI/Modules/Common/Mock/StateRenderer.swift # RiotSwiftUI/Modules/Common/Test/UI/MockScreenTest.swift # RiotSwiftUI/Modules/Common/Test/UI/XCUIApplication+Riot.swift # RiotSwiftUI/Modules/Common/Test/XCTestPublisherExtensions.swift # RiotSwiftUI/Modules/Common/Theme/ThemeIdentifierExtensions.swift # RiotSwiftUI/Modules/Common/Theme/ThemeKey.swift # RiotSwiftUI/Modules/Common/Theme/ThemePublisher.swift # RiotSwiftUI/Modules/Common/Theme/ThemeSwiftUI.swift # RiotSwiftUI/Modules/Common/Theme/ThemeUsersColorsExtension.swift # RiotSwiftUI/Modules/Common/Theme/Themes/DarkThemeSwiftUI.swift # RiotSwiftUI/Modules/Common/Theme/Themes/DefaultThemeSwiftUI.swift # RiotSwiftUI/Modules/Common/Util/BorderModifier.swift # RiotSwiftUI/Modules/Common/Util/BorderedInputFieldStyle.swift # RiotSwiftUI/Modules/Common/Util/ClearViewModifier.swift # RiotSwiftUI/Modules/Common/Util/InlineTextButton.swift # RiotSwiftUI/Modules/Common/Util/MultilineTextField.swift # RiotSwiftUI/Modules/Common/Util/OptionButton.swift # RiotSwiftUI/Modules/Common/Util/PrimaryActionButtonStyle.swift # RiotSwiftUI/Modules/Common/Util/RadioButton.swift # RiotSwiftUI/Modules/Common/Util/RoundedBorderTextEditor.swift # RiotSwiftUI/Modules/Common/Util/RoundedBorderTextField.swift # RiotSwiftUI/Modules/Common/Util/RoundedCornerShape.swift # RiotSwiftUI/Modules/Common/Util/SafeBindingCollectionEnumerator.swift # RiotSwiftUI/Modules/Common/Util/ScreenTrackerViewModifier.swift # RiotSwiftUI/Modules/Common/Util/SearchBar.swift # RiotSwiftUI/Modules/Common/Util/SecondaryActionButtonStyle.swift # RiotSwiftUI/Modules/Common/Util/StyledText.swift # RiotSwiftUI/Modules/Common/Util/ThemableButton.swift # RiotSwiftUI/Modules/Common/Util/ThemableNavigationBar.swift # RiotSwiftUI/Modules/Common/Util/ThemableTextEditor.swift # RiotSwiftUI/Modules/Common/Util/ThemableTextField.swift # RiotSwiftUI/Modules/Common/Util/WaitOverlay.swift # RiotSwiftUI/Modules/Common/ViewFrameReader/FramePreferenceKey.swift # RiotSwiftUI/Modules/Common/ViewFrameReader/ViewFrameReader.swift # RiotSwiftUI/Modules/Common/ViewModel/StateStoreViewModel.swift # RiotSwiftUI/Modules/Onboarding/Avatar/Coordinator/OnboardingAvatarCoordinator.swift # RiotSwiftUI/Modules/Onboarding/Avatar/MockOnboardingAvatarScreenState.swift # RiotSwiftUI/Modules/Onboarding/Avatar/Test/UI/OnboardingAvatarUITests.swift # RiotSwiftUI/Modules/Onboarding/Avatar/Test/Unit/OnboardingAvatarViewModelTests.swift # RiotSwiftUI/Modules/Onboarding/Celebration/Test/UI/OnboardingCelebrationUITests.swift # RiotSwiftUI/Modules/Onboarding/Celebration/View/OnboardingCelebrationScreen.swift # RiotSwiftUI/Modules/Onboarding/Common/OnboardingIcon.swift # RiotSwiftUI/Modules/Onboarding/Common/OnboardingMetrics.swift # RiotSwiftUI/Modules/Onboarding/Congratulations/OnboardingCongratulationsModels.swift # RiotSwiftUI/Modules/Onboarding/Congratulations/Test/UI/OnboardingCongratulationsUITests.swift # RiotSwiftUI/Modules/Onboarding/Congratulations/View/OnboardingCongratulationsScreen.swift # RiotSwiftUI/Modules/Onboarding/DisplayName/Coordinator/OnboardingDisplayNameCoordinator.swift # RiotSwiftUI/Modules/Onboarding/DisplayName/Test/UI/OnboardingDisplayNameUITests.swift # RiotSwiftUI/Modules/Onboarding/DisplayName/View/OnboardingDisplayNameScreen.swift # RiotSwiftUI/Modules/Onboarding/SplashScreen/OnboardingSplashScreenModels.swift # RiotSwiftUI/Modules/Onboarding/SplashScreen/View/OnboardingSplashScreen.swift # RiotSwiftUI/Modules/Onboarding/SplashScreen/View/OnboardingSplashScreenPage.swift # RiotSwiftUI/Modules/Onboarding/SplashScreen/View/OnboardingSplashScreenPageIndicator.swift # RiotSwiftUI/Modules/Onboarding/UseCase/Coordinator/OnboardingUseCaseSelectionCoordinator.swift # RiotSwiftUI/Modules/Onboarding/UseCase/OnboardingUseCaseModels.swift # RiotSwiftUI/Modules/Onboarding/UseCase/Test/UI/OnboardingUseCaseUITests.swift # RiotSwiftUI/Modules/Onboarding/UseCase/View/OnboardingUseCaseSelectionScreen.swift # RiotSwiftUI/Modules/Room/LiveLocationSharingViewer/Coordinator/LiveLocationSharingViewerCoordinator.swift # RiotSwiftUI/Modules/Room/LiveLocationSharingViewer/LiveLocationSharingViewerModels.swift # RiotSwiftUI/Modules/Room/LiveLocationSharingViewer/LiveLocationSharingViewerViewModel.swift # RiotSwiftUI/Modules/Room/LiveLocationSharingViewer/LiveLocationSharingViewerViewModelProtocol.swift # RiotSwiftUI/Modules/Room/LiveLocationSharingViewer/MockLiveLocationSharingViewerScreenState.swift # RiotSwiftUI/Modules/Room/LiveLocationSharingViewer/Service/LiveLocationSharingViewerServiceProtocol.swift # RiotSwiftUI/Modules/Room/LiveLocationSharingViewer/Service/MatrixSDK/LiveLocationSharingViewerService.swift # RiotSwiftUI/Modules/Room/LiveLocationSharingViewer/Service/Mock/MockLiveLocationSharingViewerService.swift # RiotSwiftUI/Modules/Room/LiveLocationSharingViewer/Test/UI/LiveLocationSharingViewerUITests.swift # RiotSwiftUI/Modules/Room/LiveLocationSharingViewer/Test/Unit/LiveLocationSharingViewerViewModelTests.swift # RiotSwiftUI/Modules/Room/LiveLocationSharingViewer/View/LiveLocationListItem.swift # RiotSwiftUI/Modules/Room/LiveLocationSharingViewer/View/LiveLocationSharingViewer.swift # RiotSwiftUI/Modules/Room/LocationSharing/Coordinator/LocationSharingCoordinator.swift # RiotSwiftUI/Modules/Room/LocationSharing/LocationSharingModels.swift # RiotSwiftUI/Modules/Room/LocationSharing/LocationSharingScreenState.swift # RiotSwiftUI/Modules/Room/LocationSharing/LocationSharingViewModel.swift # RiotSwiftUI/Modules/Room/LocationSharing/Service/MatrixSDK/LocationSharingService.swift # RiotSwiftUI/Modules/Room/LocationSharing/Service/Mock/MockLocationSharingService.swift # RiotSwiftUI/Modules/Room/LocationSharing/Test/UI/LocationSharingUITests.swift # RiotSwiftUI/Modules/Room/LocationSharing/Test/Unit/LocationSharingViewModelTests.swift # RiotSwiftUI/Modules/Room/LocationSharing/View/LocationSharingMapView.swift # RiotSwiftUI/Modules/Room/LocationSharing/View/LocationSharingMarkerView.swift # RiotSwiftUI/Modules/Room/LocationSharing/View/LocationSharingOptionButton.swift # RiotSwiftUI/Modules/Room/LocationSharing/View/LocationSharingView.swift # RiotSwiftUI/Modules/Room/LocationSharing/View/MapCreditsView.swift # RiotSwiftUI/Modules/Room/LocationSharing/View/UserLocationAnnotationView.swift # RiotSwiftUI/Modules/Room/NotificationSettings/Coordinator/RoomNotificationSettingsCoordinator.swift # RiotSwiftUI/Modules/Room/NotificationSettings/View/FormItemButtonStyle.swift # RiotSwiftUI/Modules/Room/NotificationSettings/View/FormPickerItem.swift # RiotSwiftUI/Modules/Room/NotificationSettings/View/FormSectionFooter.swift # RiotSwiftUI/Modules/Room/NotificationSettings/View/FormSectionHeader.swift # RiotSwiftUI/Modules/Room/NotificationSettings/View/RoomNotificationSettings.swift # RiotSwiftUI/Modules/Room/NotificationSettings/View/RoomNotificationSettingsHeader.swift # RiotSwiftUI/Modules/Room/NotificationSettings/View/VectorForm.swift # RiotSwiftUI/Modules/Room/NotificationSettings/ViewModel/RoomNotificationSettingsSwiftUIViewModel.swift # RiotSwiftUI/Modules/Room/PollEditForm/Coordinator/PollEditFormCoordinator.swift # RiotSwiftUI/Modules/Room/PollEditForm/PollEditFormScreenState.swift # RiotSwiftUI/Modules/Room/PollEditForm/PollEditFormViewModel.swift # RiotSwiftUI/Modules/Room/PollEditForm/Test/UI/PollEditFormUITests.swift # RiotSwiftUI/Modules/Room/PollEditForm/Test/Unit/PollEditFormViewModelTests.swift # RiotSwiftUI/Modules/Room/PollEditForm/View/PollEditForm.swift # RiotSwiftUI/Modules/Room/PollEditForm/View/PollEditFormAnswerOptionView.swift # RiotSwiftUI/Modules/Room/PollEditForm/View/PollEditFormTypePicker.swift # RiotSwiftUI/Modules/Room/RoomAccess/Coordinator/RoomAccessCoordinator.swift # RiotSwiftUI/Modules/Room/RoomAccess/Coordinator/RoomAccessCoordinatorBridgePresenter.swift # RiotSwiftUI/Modules/Room/RoomAccess/RoomAccessTypeChooser/Coordinator/RoomAccessTypeChooserCoordinator.swift # RiotSwiftUI/Modules/Room/RoomAccess/RoomAccessTypeChooser/MockRoomAccessTypeChooserScreenState.swift # RiotSwiftUI/Modules/Room/RoomAccess/RoomAccessTypeChooser/RoomAccessTypeChooserViewModel.swift # RiotSwiftUI/Modules/Room/RoomAccess/RoomAccessTypeChooser/RoomAccessTypeChooserViewModelProtocol.swift # RiotSwiftUI/Modules/Room/RoomAccess/RoomAccessTypeChooser/Service/MatrixSDK/RoomAccessTypeChooserService.swift # RiotSwiftUI/Modules/Room/RoomAccess/RoomAccessTypeChooser/Service/Mock/MockRoomAccessTypeChooserService.swift # RiotSwiftUI/Modules/Room/RoomAccess/RoomAccessTypeChooser/Service/RoomAccessTypeChooserServiceProtocol.swift # RiotSwiftUI/Modules/Room/RoomAccess/RoomAccessTypeChooser/Test/UI/RoomAccessTypeChooserUITests.swift # RiotSwiftUI/Modules/Room/RoomAccess/RoomAccessTypeChooser/Test/Unit/RoomAccessTypeChooserViewModelTests.swift # RiotSwiftUI/Modules/Room/RoomAccess/RoomAccessTypeChooser/View/RoomAccessTypeChooser.swift # RiotSwiftUI/Modules/Room/RoomAccess/RoomAccessTypeChooser/View/RoomAccessTypeChooserRow.swift # RiotSwiftUI/Modules/Room/RoomAccess/RoomRestrictedAccessSpaceChooser/Coordinator/RoomRestrictedAccessSpaceChooserViewProvider.swift # RiotSwiftUI/Modules/Room/RoomAccess/RoomRestrictedAccessSpaceChooser/View/RoomRestrictedAccessSpaceChooserSelector.swift # RiotSwiftUI/Modules/Room/RoomSuggestion/Coordinator/RoomSuggestionCoordinator.swift # RiotSwiftUI/Modules/Room/RoomSuggestion/Coordinator/RoomSuggestionCoordinatorBridgePresenter.swift # RiotSwiftUI/Modules/Room/RoomSuggestion/RoomSuggestionSpaceChooser/Coordinator/RoomSuggestionSpaceChooserViewProvider.swift # RiotSwiftUI/Modules/Room/RoomSuggestion/RoomSuggestionSpaceChooser/View/RoomSuggestionSpaceChooserSelector.swift # RiotSwiftUI/Modules/Room/RoomUpgrade/Coordinator/RoomUpgradeCoordinator.swift # RiotSwiftUI/Modules/Room/RoomUpgrade/MockRoomUpgradeScreenState.swift # RiotSwiftUI/Modules/Room/RoomUpgrade/RoomUpgradeViewModel.swift # RiotSwiftUI/Modules/Room/RoomUpgrade/RoomUpgradeViewModelProtocol.swift # RiotSwiftUI/Modules/Room/RoomUpgrade/Service/MatrixSDK/RoomUpgradeService.swift # RiotSwiftUI/Modules/Room/RoomUpgrade/Service/Mock/MockRoomUpgradeService.swift # RiotSwiftUI/Modules/Room/RoomUpgrade/Service/RoomUpgradeServiceProtocol.swift # RiotSwiftUI/Modules/Room/RoomUpgrade/Test/UI/RoomUpgradeUITests.swift # RiotSwiftUI/Modules/Room/RoomUpgrade/Test/Unit/RoomUpgradeViewModelTests.swift # RiotSwiftUI/Modules/Room/RoomUpgrade/View/RoomUpgrade.swift # RiotSwiftUI/Modules/Room/StaticLocationSharingViewer/Coordinator/StaticLocationViewingCoordinator.swift # RiotSwiftUI/Modules/Room/StaticLocationSharingViewer/MockStaticLocationViewingScreenState.swift # RiotSwiftUI/Modules/Room/StaticLocationSharingViewer/StaticLocationViewingModels.swift # RiotSwiftUI/Modules/Room/StaticLocationSharingViewer/StaticLocationViewingViewModel.swift # RiotSwiftUI/Modules/Room/StaticLocationSharingViewer/StaticLocationViewingViewModelProtocol.swift # RiotSwiftUI/Modules/Room/StaticLocationSharingViewer/Test/UI/StaticLocationViewingUITests.swift # RiotSwiftUI/Modules/Room/StaticLocationSharingViewer/Test/Unit/StaticLocationViewingViewModelTests.swift # RiotSwiftUI/Modules/Room/StaticLocationSharingViewer/View/StaticLocationView.swift # RiotSwiftUI/Modules/Room/TimelinePoll/Coordinator/TimelinePollCoordinator.swift # RiotSwiftUI/Modules/Room/TimelinePoll/Coordinator/TimelinePollProvider.swift # RiotSwiftUI/Modules/Room/TimelinePoll/Test/UI/TimelinePollUITests.swift # RiotSwiftUI/Modules/Room/TimelinePoll/Test/Unit/TimelinePollViewModelTests.swift # RiotSwiftUI/Modules/Room/TimelinePoll/TimelinePollScreenState.swift # RiotSwiftUI/Modules/Room/TimelinePoll/TimelinePollViewModel.swift # RiotSwiftUI/Modules/Room/TimelinePoll/TimelinePollViewModelProtocol.swift # RiotSwiftUI/Modules/Room/TimelinePoll/View/TimelinePollAnswerOptionButton.swift # RiotSwiftUI/Modules/Room/TimelinePoll/View/TimelinePollView.swift # RiotSwiftUI/Modules/Room/UserSuggestion/Coordinator/UserSuggestionCoordinator.swift # RiotSwiftUI/Modules/Room/UserSuggestion/Coordinator/UserSuggestionCoordinatorBridge.swift # RiotSwiftUI/Modules/Room/UserSuggestion/Service/UserSuggestionService.swift # RiotSwiftUI/Modules/Room/UserSuggestion/Service/UserSuggestionServiceProtocol.swift # RiotSwiftUI/Modules/Room/UserSuggestion/Test/UI/UserSuggestionUITests.swift # RiotSwiftUI/Modules/Room/UserSuggestion/Test/Unit/UserSuggestionServiceTests.swift # RiotSwiftUI/Modules/Room/UserSuggestion/UserSuggestionScreenState.swift # RiotSwiftUI/Modules/Room/UserSuggestion/UserSuggestionViewModel.swift # RiotSwiftUI/Modules/Room/UserSuggestion/View/UserSuggestionList.swift # RiotSwiftUI/Modules/Room/UserSuggestion/View/UserSuggestionListItem.swift # RiotSwiftUI/Modules/Room/UserSuggestion/View/UserSuggestionListWithInput.swift # RiotSwiftUI/Modules/Settings/Notifications/Coordinator/NotificationSettingsBridgePresenter.swift # RiotSwiftUI/Modules/Settings/Notifications/Coordinator/NotificationSettingsCoordinator.swift # RiotSwiftUI/Modules/Settings/Notifications/Model/NotificationSettingsScreen.swift # RiotSwiftUI/Modules/Settings/Notifications/Service/MatrixSDK/MXNotificationSettingsService.swift # RiotSwiftUI/Modules/Settings/Notifications/Service/Mock/MockNotificationSettingsService.swift # RiotSwiftUI/Modules/Settings/Notifications/Service/NotificationSettingsServiceType.swift # RiotSwiftUI/Modules/Settings/Notifications/View/Chip.swift # RiotSwiftUI/Modules/Settings/Notifications/View/Chips.swift # RiotSwiftUI/Modules/Settings/Notifications/View/ChipsInput.swift # RiotSwiftUI/Modules/Settings/Notifications/View/DefaultNotificationSettings.swift # RiotSwiftUI/Modules/Settings/Notifications/View/FormInputFieldStyle.swift # RiotSwiftUI/Modules/Settings/Notifications/View/MentionsAndKeywordNotificationSettings.swift # RiotSwiftUI/Modules/Settings/Notifications/View/NotificationSettings.swift # RiotSwiftUI/Modules/Settings/Notifications/View/NotificationSettingsKeywords.swift # RiotSwiftUI/Modules/Settings/Notifications/View/OtherNotificationSettings.swift # RiotSwiftUI/Modules/Settings/Notifications/ViewModel/NotificationSettingsViewModel.swift # RiotSwiftUI/Modules/Spaces/AddRoomSelector/Coordinator/AddRoomSelectorViewProvider.swift # RiotSwiftUI/Modules/Spaces/AddRoomSelector/View/AddRoomSelector.swift # RiotSwiftUI/Modules/Spaces/LeaveSpace/Coordinator/LeaveSpaceViewProvider.swift # RiotSwiftUI/Modules/Spaces/LeaveSpace/View/LeaveSpace.swift # RiotSwiftUI/Modules/Spaces/MatrixItemChooser/Coordinator/MatrixItemChooserCoordinator.swift # RiotSwiftUI/Modules/Spaces/MatrixItemChooser/MatrixItemChooserViewModel.swift # RiotSwiftUI/Modules/Spaces/MatrixItemChooser/MatrixItemChooserViewModelProtocol.swift # RiotSwiftUI/Modules/Spaces/MatrixItemChooser/MockMatrixItemChooserScreenState.swift # RiotSwiftUI/Modules/Spaces/MatrixItemChooser/Service/MatrixItemChooserServiceProtocol.swift # RiotSwiftUI/Modules/Spaces/MatrixItemChooser/Service/MatrixSDK/MatrixItemChooserService.swift # RiotSwiftUI/Modules/Spaces/MatrixItemChooser/Service/Mock/MockMatrixItemChooserService.swift # RiotSwiftUI/Modules/Spaces/MatrixItemChooser/Test/UI/MatrixItemChooserUITests.swift # RiotSwiftUI/Modules/Spaces/MatrixItemChooser/Test/Unit/MatrixItemChooserViewModelTests.swift # RiotSwiftUI/Modules/Spaces/MatrixItemChooser/View/MatrixItemChooser.swift # RiotSwiftUI/Modules/Spaces/MatrixItemChooser/View/MatrixItemChooserListRow.swift # RiotSwiftUI/Modules/Spaces/MatrixItemChooser/View/MatrixItemChooserSectionHeader.swift # RiotSwiftUI/Modules/Spaces/RoomAncestorSelector/Coordinator/RoomAncestorSelectorViewProvider.swift # RiotSwiftUI/Modules/Spaces/RoomAncestorSelector/View/RoomAncestorSelector.swift # RiotSwiftUI/Modules/Spaces/SpaceCreation/Coordinator/SpaceCreationCoordinator.swift # RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationEmailInvites/Coordinator/SpaceCreationEmailInvitesCoordinator.swift # RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationEmailInvites/Service/MatrixSDK/SpaceCreationEmailInvitesService.swift # RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationEmailInvites/Service/Mock/MockSpaceCreationEmailInvitesScreenState.swift # RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationEmailInvites/Service/Mock/MockSpaceCreationEmailInvitesService.swift # RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationEmailInvites/Service/SpaceCreationEmailInvitesServiceProtocol.swift # RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationEmailInvites/Test/UI/SpaceCreationEmailInvitesUITests.swift # RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationEmailInvites/Test/Unit/SpaceCreationEmailInvitesViewModelTests.swift # RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationEmailInvites/View/SpaceCreationEmailInvites.swift # RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationEmailInvites/ViewModel/SpaceCreationEmailInvitesViewModel.swift # RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationEmailInvites/ViewModel/SpaceCreationEmailInvitesViewModelProtocol.swift # RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationMatrixItemChooser/Coordinator/SpaceCreationMatrixItemChooserViewProvider.swift # RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationMatrixItemChooser/View/SpaceCreationMatrixItemChooser.swift # RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationMenu/Coordinator/SpaceCreationMenuCoordinator.swift # RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationMenu/Test/UI/SpaceCreationMenuUITests.swift # RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationMenu/Test/Unit/SpaceCreationMenuViewModelTests.swift # RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationMenu/View/SpaceCreationMenu.swift # RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationMenu/ViewModel/SpaceCreationMenuViewModel.swift # RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationMenu/ViewModel/SpaceCreationMenuViewModelProtocol.swift # RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationPostProcess/Coordinator/SpaceCreationPostProcessCoordinator.swift # RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationPostProcess/Service/MatrixSDK/SpaceCreationPostProcessService.swift # RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationPostProcess/Service/Mock/MockSpaceCreationPostProcessScreenState.swift # RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationPostProcess/Service/Mock/MockSpaceCreationPostProcessService.swift # RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationPostProcess/Service/SpaceCreationPostProcessServiceProtocol.swift # RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationPostProcess/Test/UI/SpaceCreationPostProcessUITests.swift # RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationPostProcess/Test/Unit/SpaceCreationPostProcessViewModelTests.swift # RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationPostProcess/View/SpaceCreationPostProcess.swift # RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationPostProcess/View/SpaceCreationPostProcessItem.swift # RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationPostProcess/ViewModel/SpaceCreationPostProcessViewModel.swift # RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationPostProcess/ViewModel/SpaceCreationPostProcessViewModelProtocol.swift # RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationRooms/Coordinator/SpaceCreationRoomsCoordinator.swift # RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationRooms/Service/Mock/MockSpaceCreationRoomsScreenState.swift # RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationRooms/Test/UI/SpaceCreationRoomsUITests.swift # RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationRooms/Test/Unit/SpaceCreationRoomsViewModelTests.swift # RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationRooms/View/SpaceCreationRooms.swift # RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationRooms/ViewModel/SpaceCreationRoomsViewModel.swift # RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationRooms/ViewModel/SpaceCreationRoomsViewModelProtocol.swift # RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationSettings/Coordinator/SpaceCreationSettingsCoordinator.swift # RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationSettings/Service/MatrixSDK/SpaceCreationSettingsService.swift # RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationSettings/Service/Mock/MockSpaceCreationSettingsScreenState.swift # RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationSettings/Service/Mock/MockSpaceCreationSettingsService.swift # RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationSettings/Service/SpaceCreationSettingsServiceProtocol.swift # RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationSettings/Test/UI/SpaceCreationSettingsUITests.swift # RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationSettings/Test/Unit/SpaceCreationSettingsViewModelTests.swift # RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationSettings/View/SpaceCreationSettings.swift # RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationSettings/ViewModel/SpaceCreationSettingsViewModel.swift # RiotSwiftUI/Modules/Spaces/SpaceSettings/Coordinator/SpaceSettingsModalCoordinator.swift # RiotSwiftUI/Modules/Spaces/SpaceSettings/Coordinator/SpaceSettingsModalCoordinatorBridgePresenter.swift # RiotSwiftUI/Modules/Spaces/SpaceSettings/SpaceSettings/Coordinator/SpaceSettingsCoordinator.swift # RiotSwiftUI/Modules/Spaces/SpaceSettings/SpaceSettings/MockSpaceSettingsScreenState.swift # RiotSwiftUI/Modules/Spaces/SpaceSettings/SpaceSettings/Service/MatrixSDK/SpaceSettingsService.swift # RiotSwiftUI/Modules/Spaces/SpaceSettings/SpaceSettings/Service/Mock/MockSpaceSettingsService.swift # RiotSwiftUI/Modules/Spaces/SpaceSettings/SpaceSettings/Service/SpaceSettingsServiceProtocol.swift # RiotSwiftUI/Modules/Spaces/SpaceSettings/SpaceSettings/SpaceSettingsViewModel.swift # RiotSwiftUI/Modules/Spaces/SpaceSettings/SpaceSettings/SpaceSettingsViewModelProtocol.swift # RiotSwiftUI/Modules/Spaces/SpaceSettings/SpaceSettings/Test/UI/SpaceSettingsUITests.swift # RiotSwiftUI/Modules/Spaces/SpaceSettings/SpaceSettings/Test/Unit/SpaceSettingsViewModelTests.swift # RiotSwiftUI/Modules/Spaces/SpaceSettings/SpaceSettings/View/SpaceSettings.swift # RiotSwiftUI/Modules/Spaces/SpaceSettings/SpaceSettings/View/SpaceSettingsOptionListItem.swift # RiotSwiftUI/Modules/Template/SimpleScreenExample/Test/UI/TemplateSimpleScreenUITests.swift # RiotSwiftUI/Modules/Template/SimpleUserProfileExample/Test/UI/TemplateUserProfileUITests.swift # RiotSwiftUI/Modules/Template/TemplateAdvancedRoomsExample/TemplateRoomChat/Test/UI/TemplateRoomChatUITests.swift # RiotSwiftUI/Modules/Template/TemplateAdvancedRoomsExample/TemplateRoomList/Test/UI/TemplateRoomListUITests.swift # RiotSwiftUI/RiotSwiftUIApp.swift # RiotSwiftUI/target.yml # RiotSwiftUI/targetUITests.yml # RiotTests/MatrixKitTests/MXKEventFormatter+Tests.h # RiotTests/MatrixKitTests/MXKEventFormatterTests.m # RiotTests/MatrixKitTests/MXKRoomDataSourceTests.swift # RiotTests/MatrixKitTests/MatrixKitTests-Bridging-Header.h # RiotTests/Modules/Authentication/AuthenticationServiceTests.swift # RiotTests/OnboardingTests.swift # RiotTests/PillsFormatterTests.swift # RiotTests/target.yml # SiriIntents/IntentHandler.m # SiriIntents/target.yml # Tools/SwiftGen/swiftgen-config.yml # Tools/Templates/buildable/SimpleScreenTemplate/SimpleScreenTemplateViewController.storyboard # fastlane/.env.default # fastlane/Fastfile # project.yml
1144 lines
40 KiB
Objective-C
1144 lines
40 KiB
Objective-C
/*
|
|
Copyright 2017 Vector Creations Ltd
|
|
Copyright 2018 New Vector Ltd
|
|
Copyright (c) 2021 BWI GmbH
|
|
|
|
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 "MasterTabBarController.h"
|
|
|
|
#import "RecentsDataSource.h"
|
|
#import "GroupsDataSource.h"
|
|
|
|
|
|
#import "MXRoom+Riot.h"
|
|
#import "MXSession+Riot.h"
|
|
|
|
#import "SettingsViewController.h"
|
|
#import "SecurityViewController.h"
|
|
|
|
#import "GeneratedInterface-Swift.h"
|
|
|
|
@interface MasterTabBarController () <UITabBarControllerDelegate>
|
|
{
|
|
// Array of `MXSession` instances.
|
|
NSMutableArray<MXSession*> *mxSessionArray;
|
|
|
|
// The recents data source shared between all the view controllers of the tab bar.
|
|
RecentsDataSource *recentsDataSource;
|
|
|
|
// Current alert (if any).
|
|
UIAlertController *currentAlert;
|
|
|
|
// Keep reference on the pushed view controllers to release them correctly
|
|
NSMutableArray *childViewControllers;
|
|
|
|
// Observe kThemeServiceDidChangeThemeNotification to handle user interface theme change.
|
|
id kThemeServiceDidChangeThemeNotificationObserver;
|
|
|
|
// The groups data source
|
|
GroupsDataSource *groupsDataSource;
|
|
|
|
// Custom title view of the navigation bar
|
|
MainTitleView *titleView;
|
|
|
|
id spaceNotificationCounterDidUpdateNotificationCountObserver;
|
|
}
|
|
|
|
@property(nonatomic,getter=isHidden) BOOL hidden;
|
|
|
|
@property (nonatomic, readwrite) OnboardingCoordinatorBridgePresenter *onboardingCoordinatorBridgePresenter;
|
|
|
|
// Tell whether the onboarding screen is preparing.
|
|
@property (nonatomic, readwrite) BOOL isOnboardingCoordinatorPreparing;
|
|
@property (nonatomic, readwrite) BOOL isOnboardingInProgress;
|
|
|
|
@property (nonatomic) BOOL reviewSessionAlertHasBeenDisplayed;
|
|
|
|
@end
|
|
|
|
@implementation MasterTabBarController
|
|
|
|
#pragma mark - Properties override
|
|
|
|
- (HomeViewController *)homeViewController
|
|
{
|
|
UIViewController *wrapperVC = [self viewControllerForClass:HomeViewControllerWithBannerWrapperViewController.class];
|
|
return [(HomeViewControllerWithBannerWrapperViewController *)wrapperVC homeViewController];
|
|
}
|
|
|
|
- (FavouritesViewController *)favouritesViewController
|
|
{
|
|
return (FavouritesViewController*)[self viewControllerForClass:FavouritesViewController.class];
|
|
}
|
|
|
|
- (PeopleViewController *)peopleViewController
|
|
{
|
|
return (PeopleViewController*)[self viewControllerForClass:PeopleViewController.class];
|
|
}
|
|
|
|
- (RoomsViewController *)roomsViewController
|
|
{
|
|
return (RoomsViewController*)[self viewControllerForClass:RoomsViewController.class];
|
|
}
|
|
|
|
- (GroupsViewController *)groupsViewController
|
|
{
|
|
return (GroupsViewController*)[self viewControllerForClass:GroupsViewController.class];
|
|
}
|
|
|
|
#pragma mark - Life cycle
|
|
|
|
- (void)viewDidLoad
|
|
{
|
|
[super viewDidLoad];
|
|
// Do any additional setup after loading the view, typically from a nib.
|
|
|
|
self.delegate = self;
|
|
|
|
self.isOnboardingInProgress = NO;
|
|
|
|
// Note: UITabBarViewController should not be embed in a UINavigationController (https://github.com/vector-im/riot-ios/issues/3086)
|
|
[self vc_removeBackTitle];
|
|
|
|
/**
|
|
* Remove unused ViewController Home & Groups from TabBarViewController array.
|
|
* In a later release it will be may be deactivated again and this code
|
|
* can be removed.
|
|
*
|
|
* Furthermore the code set the select viewcontroller to people.
|
|
*/
|
|
NSMutableArray *tbViewControllers = [NSMutableArray arrayWithArray:[self viewControllers]];
|
|
[tbViewControllers removeLastObject]; // remove GroupsViewController from tabbar
|
|
[tbViewControllers removeLastObject]; // remove HomeViewController from tabbar
|
|
self.viewControllers = tbViewControllers;
|
|
self.selectedIndex = TABBAR_PEOPLE_INDEX;
|
|
|
|
[self setupTitleView];
|
|
self.titleLabelText = [VectorL10n titleHome];
|
|
|
|
childViewControllers = [NSMutableArray array];
|
|
|
|
MXWeakify(self);
|
|
spaceNotificationCounterDidUpdateNotificationCountObserver = [[NSNotificationCenter defaultCenter] addObserverForName:MXSpaceNotificationCounter.didUpdateNotificationCount object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) {
|
|
MXStrongifyAndReturnIfNil(self);
|
|
[self updateSideMenuNotifcationIcon];
|
|
}];
|
|
}
|
|
|
|
- (void)userInterfaceThemeDidChange
|
|
{
|
|
id<Theme> theme = ThemeService.shared.theme;
|
|
[theme applyStyleOnNavigationBar:self.navigationController.navigationBar];
|
|
|
|
[theme applyStyleOnTabBar:self.tabBar];
|
|
|
|
self.view.backgroundColor = theme.backgroundColor;
|
|
[titleView updateWithTheme:theme];
|
|
|
|
[self setNeedsStatusBarAppearanceUpdate];
|
|
}
|
|
|
|
- (UIViewController *)childViewControllerForStatusBarStyle
|
|
{
|
|
return self.selectedViewController;
|
|
}
|
|
|
|
- (UIViewController *)childViewControllerForStatusBarHidden
|
|
{
|
|
return self.selectedViewController;
|
|
}
|
|
|
|
- (void)viewWillAppear:(BOOL)animated
|
|
{
|
|
[super viewWillAppear:animated];
|
|
|
|
// Show the tab bar view controller content only when a user is logged in.
|
|
self.hidden = ([MXKAccountManager sharedManager].accounts.count == 0);
|
|
|
|
if (!kThemeServiceDidChangeThemeNotificationObserver)
|
|
{
|
|
// Observe user interface theme change.
|
|
kThemeServiceDidChangeThemeNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kThemeServiceDidChangeThemeNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {
|
|
|
|
[self userInterfaceThemeDidChange];
|
|
|
|
}];
|
|
[self userInterfaceThemeDidChange];
|
|
}
|
|
}
|
|
|
|
- (void)viewDidAppear:(BOOL)animated
|
|
{
|
|
MXLogDebug(@"[MasterTabBarController] viewDidAppear");
|
|
[super viewDidAppear:animated];
|
|
|
|
if (BuildSettings.bwiShowMatomoInfoScreen) {
|
|
NSString *matomoInfoScreenShownKey = @"bwi_matomo_info_screen_shown";
|
|
if (![[NSUserDefaults standardUserDefaults] boolForKey: matomoInfoScreenShownKey]) {
|
|
[[NSUserDefaults standardUserDefaults] setBool:TRUE forKey: matomoInfoScreenShownKey];
|
|
[self bwiShowMatomoInfoScreen];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Display the splash screen only one time although
|
|
* the viewDidAppear is invoked multiple time in the
|
|
* startup workflow.
|
|
*/
|
|
|
|
// Check whether we're not logged in
|
|
BOOL authIsShown = NO;
|
|
if (![MXKAccountManager sharedManager].accounts.count)
|
|
{
|
|
[self showOnboardingFlow];
|
|
authIsShown = YES;
|
|
}
|
|
else if (![MXKAccountManager sharedManager].activeAccounts.count)
|
|
{
|
|
// Display a login screen if the account is soft logout
|
|
// Note: We support only one account
|
|
MXKAccount *account = [MXKAccountManager sharedManager].accounts.firstObject;
|
|
if (account.isSoftLogout)
|
|
{
|
|
[self showSoftLogoutOnboardingFlowWithCredentials:account.mxCredentials];
|
|
authIsShown = YES;
|
|
}
|
|
}
|
|
|
|
if (!authIsShown)
|
|
{
|
|
[self refreshTabBarBadges];
|
|
|
|
// Release properly pushed and/or presented view controller
|
|
if (childViewControllers.count)
|
|
{
|
|
for (id viewController in childViewControllers)
|
|
{
|
|
if ([viewController isKindOfClass:[UINavigationController class]])
|
|
{
|
|
UINavigationController *navigationController = (UINavigationController*)viewController;
|
|
for (id subViewController in navigationController.viewControllers)
|
|
{
|
|
if ([subViewController respondsToSelector:@selector(destroy)])
|
|
{
|
|
[subViewController destroy];
|
|
}
|
|
}
|
|
}
|
|
else if ([viewController respondsToSelector:@selector(destroy)])
|
|
{
|
|
[viewController destroy];
|
|
}
|
|
}
|
|
|
|
[childViewControllers removeAllObjects];
|
|
}
|
|
|
|
if ([[AppDelegate theDelegate] checkJailbreak]) {
|
|
[[AppDelegate theDelegate] checkIntegrity];
|
|
}
|
|
[[AppDelegate theDelegate] checkAppVersion];
|
|
}
|
|
}
|
|
|
|
- (void)viewDidDisappear:(BOOL)animated
|
|
{
|
|
[super viewDidDisappear:animated];
|
|
}
|
|
|
|
- (void)dealloc
|
|
{
|
|
mxSessionArray = nil;
|
|
|
|
if (currentAlert)
|
|
{
|
|
[currentAlert dismissViewControllerAnimated:NO completion:nil];
|
|
currentAlert = nil;
|
|
}
|
|
|
|
if (kThemeServiceDidChangeThemeNotificationObserver)
|
|
{
|
|
[[NSNotificationCenter defaultCenter] removeObserver:kThemeServiceDidChangeThemeNotificationObserver];
|
|
kThemeServiceDidChangeThemeNotificationObserver = nil;
|
|
}
|
|
|
|
if (spaceNotificationCounterDidUpdateNotificationCountObserver)
|
|
{
|
|
[[NSNotificationCenter defaultCenter] removeObserver:spaceNotificationCounterDidUpdateNotificationCountObserver];
|
|
spaceNotificationCounterDidUpdateNotificationCountObserver = nil;
|
|
}
|
|
|
|
childViewControllers = nil;
|
|
}
|
|
|
|
#pragma mark - Public
|
|
|
|
- (void)updateViewControllers:(NSArray<UIViewController*>*)viewControllers
|
|
{
|
|
self.viewControllers = viewControllers;
|
|
|
|
[self initializeDataSources];
|
|
|
|
// Need to be called in case of the controllers have been replaced
|
|
[self.selectedViewController viewWillAppear:NO];
|
|
|
|
// Adjust the display of the icons in the tabbar.
|
|
for (UITabBarItem *tabBarItem in self.tabBar.items)
|
|
{
|
|
if (@available(iOS 13.0, *))
|
|
{
|
|
// Fix iOS 13 misalignment tab bar images. Some titles are nil and other empty strings. Nil title behaves as if a non-empty title was set.
|
|
// Note: However no need to modify imageInsets property on iOS 13.
|
|
tabBarItem.title = @"";
|
|
}
|
|
else
|
|
{
|
|
tabBarItem.imageInsets = UIEdgeInsetsMake(5, 0, -5, 0);
|
|
}
|
|
}
|
|
|
|
self.titleLabelText = [self getTitleForItemViewController:self.selectedViewController];
|
|
// Need to be called in case of the controllers have been replaced
|
|
[self.selectedViewController viewDidAppear:NO];
|
|
}
|
|
|
|
- (void)removeTabAt:(MasterTabBarIndex)tag
|
|
{
|
|
NSInteger index = [self indexOfTabItemWithTag:tag];
|
|
if (index != NSNotFound) {
|
|
NSMutableArray<UIViewController*> *viewControllers = [NSMutableArray arrayWithArray:self.viewControllers];
|
|
[viewControllers removeObjectAtIndex:index];
|
|
self.viewControllers = viewControllers;
|
|
}
|
|
}
|
|
|
|
- (void)selectTabAtIndex:(MasterTabBarIndex)tabBarIndex
|
|
{
|
|
NSInteger index = [self indexOfTabItemWithTag:tabBarIndex];
|
|
self.selectedIndex = index;
|
|
|
|
self.titleLabelText = [self getTitleForItemViewController:self.selectedViewController];
|
|
}
|
|
|
|
#pragma mark -
|
|
|
|
- (NSArray<MXSession*>*)mxSessions
|
|
{
|
|
return [NSArray arrayWithArray:mxSessionArray];
|
|
}
|
|
|
|
- (void)initializeDataSources
|
|
{
|
|
MXSession *mainSession = mxSessionArray.firstObject;
|
|
|
|
if (mainSession)
|
|
{
|
|
MXLogDebug(@"[MasterTabBarController] initializeDataSources");
|
|
|
|
// Init the recents data source
|
|
RecentsListService *recentsListService = [[RecentsListService alloc] initWithSession:mainSession];
|
|
recentsDataSource = [[RecentsDataSource alloc] initWithMatrixSession:mainSession
|
|
recentsListService:recentsListService];
|
|
|
|
[self.homeViewController displayList:recentsDataSource];
|
|
[self.favouritesViewController displayList:recentsDataSource];
|
|
[self.peopleViewController displayList:recentsDataSource];
|
|
[self.roomsViewController displayList:recentsDataSource];
|
|
|
|
// Restore the right delegate of the shared recent data source.
|
|
id<MXKDataSourceDelegate> recentsDataSourceDelegate = self.peopleViewController;
|
|
RecentsDataSourceMode recentsDataSourceMode = RecentsDataSourceModePeople;
|
|
|
|
NSInteger tabItemTag = self.tabBar.items[self.selectedIndex].tag;
|
|
|
|
switch (tabItemTag)
|
|
{
|
|
case TABBAR_FAVOURITES_INDEX:
|
|
recentsDataSourceDelegate = self.favouritesViewController;
|
|
recentsDataSourceMode = RecentsDataSourceModeFavourites;
|
|
break;
|
|
case TABBAR_PEOPLE_INDEX:
|
|
recentsDataSourceDelegate = self.peopleViewController;
|
|
recentsDataSourceMode = RecentsDataSourceModePeople;
|
|
break;
|
|
case TABBAR_ROOMS_INDEX:
|
|
recentsDataSourceDelegate = self.roomsViewController;
|
|
recentsDataSourceMode = RecentsDataSourceModeRooms;
|
|
break;
|
|
case TABBAR_HOME_INDEX:
|
|
recentsDataSourceDelegate = self.homeViewController;
|
|
recentsDataSourceMode = RecentsDataSourceModeHome;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
[recentsDataSource setDelegate:recentsDataSourceDelegate andRecentsDataSourceMode:recentsDataSourceMode];
|
|
|
|
// Init the recents data source
|
|
groupsDataSource = [[GroupsDataSource alloc] initWithMatrixSession:mainSession];
|
|
[groupsDataSource finalizeInitialization];
|
|
[self.groupsViewController displayList:groupsDataSource];
|
|
|
|
// Check whether there are others sessions
|
|
NSArray<MXSession*>* mxSessions = self.mxSessions;
|
|
if (mxSessions.count > 1)
|
|
{
|
|
for (MXSession *mxSession in mxSessions)
|
|
{
|
|
if (mxSession != mainSession)
|
|
{
|
|
// Add the session to the recents data source
|
|
[recentsDataSource addMatrixSession:mxSession];
|
|
}
|
|
}
|
|
}
|
|
|
|
[self bwiCheckForPersonalNotesRoom];
|
|
}
|
|
}
|
|
|
|
- (void)addMatrixSession:(MXSession *)mxSession
|
|
{
|
|
if ([mxSessionArray containsObject:mxSession])
|
|
{
|
|
MXLogDebug(@"MasterTabBarController already has %@ in mxSessionArray", mxSession)
|
|
return;
|
|
}
|
|
|
|
// Check whether the controller's view is loaded into memory.
|
|
if (self.viewControllers)
|
|
{
|
|
// Check whether the data sources have been initialized.
|
|
if (!recentsDataSource)
|
|
{
|
|
// Add first the session. The updated sessions list will be used during data sources initialization.
|
|
mxSessionArray = [NSMutableArray array];
|
|
[mxSessionArray addObject:mxSession];
|
|
|
|
// Prepare data sources and return
|
|
[self initializeDataSources];
|
|
|
|
// Add matrix sessions observer on first added session
|
|
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onMatrixSessionStateDidChange:) name:kMXSessionStateDidChangeNotification object:nil];
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
// Add the session to the existing data sources
|
|
[recentsDataSource addMatrixSession:mxSession];
|
|
}
|
|
}
|
|
|
|
if (!mxSessionArray)
|
|
{
|
|
mxSessionArray = [NSMutableArray array];
|
|
|
|
// Add matrix sessions observer on first added session
|
|
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onMatrixSessionStateDidChange:) name:kMXSessionStateDidChangeNotification object:nil];
|
|
}
|
|
[mxSessionArray addObject:mxSession];
|
|
|
|
// @TODO: handle multi sessions for groups
|
|
}
|
|
|
|
- (void)removeMatrixSession:(MXSession *)mxSession
|
|
{
|
|
if (![mxSessionArray containsObject:mxSession])
|
|
{
|
|
MXLogDebug(@"MasterTabBarController does not contain %@ in mxSessionArray", mxSession)
|
|
return;
|
|
}
|
|
|
|
[recentsDataSource removeMatrixSession:mxSession];
|
|
|
|
// Check whether there are others sessions
|
|
if (!recentsDataSource.mxSessions.count)
|
|
{
|
|
// Remove matrix sessions observer
|
|
[[NSNotificationCenter defaultCenter] removeObserver:self name:kMXSessionStateDidChangeNotification object:nil];
|
|
|
|
[self.homeViewController displayList:nil];
|
|
[self.favouritesViewController displayList:nil];
|
|
[self.peopleViewController displayList:nil];
|
|
[self.roomsViewController displayList:nil];
|
|
|
|
[recentsDataSource destroy];
|
|
recentsDataSource = nil;
|
|
}
|
|
|
|
[mxSessionArray removeObject:mxSession];
|
|
|
|
// @TODO: handle multi sessions for groups
|
|
}
|
|
|
|
- (void)onMatrixSessionStateDidChange:(NSNotification *)notif
|
|
{
|
|
[self refreshTabBarBadges];
|
|
}
|
|
|
|
// TODO: Manage the onboarding coordinator at the AppCoordinator level
|
|
- (void)presentOnboardingFlow
|
|
{
|
|
MXLogDebug(@"[MasterTabBarController] presentOnboardingFlow");
|
|
|
|
MXWeakify(self);
|
|
OnboardingCoordinatorBridgePresenter *onboardingCoordinatorBridgePresenter = [[OnboardingCoordinatorBridgePresenter alloc] init];
|
|
onboardingCoordinatorBridgePresenter.completion = ^{
|
|
MXStrongifyAndReturnIfNil(self);
|
|
[self.onboardingCoordinatorBridgePresenter dismissWithAnimated:YES completion:nil];
|
|
self.onboardingCoordinatorBridgePresenter = nil;
|
|
|
|
self.isOnboardingInProgress = NO; // Must be set before calling didCompleteAuthentication
|
|
[self.masterTabBarDelegate masterTabBarControllerDidCompleteAuthentication:self];
|
|
};
|
|
|
|
[onboardingCoordinatorBridgePresenter presentFrom:self animated:NO];
|
|
|
|
self.onboardingCoordinatorBridgePresenter = onboardingCoordinatorBridgePresenter;
|
|
self.isOnboardingCoordinatorPreparing = NO;
|
|
}
|
|
|
|
- (void)showOnboardingFlow
|
|
{
|
|
MXLogDebug(@"[MasterTabBarController] showOnboardingFlow");
|
|
[self showOnboardingFlowAndResetSessionFlags:YES];
|
|
}
|
|
|
|
- (void)showSoftLogoutOnboardingFlowWithCredentials:(MXCredentials*)credentials;
|
|
{
|
|
MXLogDebug(@"[MasterTabBarController] showAuthenticationScreenAfterSoftLogout");
|
|
|
|
// This method can be called after the user chooses to clear their data as the MXSession
|
|
// is opened to call logout from. So we only set the credentials when authentication isn't
|
|
// in progress to prevent a second soft logout screen being shown.
|
|
if (!self.onboardingCoordinatorBridgePresenter && !self.isOnboardingCoordinatorPreparing)
|
|
{
|
|
AuthenticationService.shared.softLogoutCredentials = credentials;
|
|
|
|
[self showOnboardingFlowAndResetSessionFlags:NO];
|
|
}
|
|
}
|
|
|
|
- (void)showOnboardingFlowAndResetSessionFlags:(BOOL)resetSessionFlags
|
|
{
|
|
// Check whether an authentication screen is not already shown or preparing
|
|
if (!self.onboardingCoordinatorBridgePresenter && !self.isOnboardingCoordinatorPreparing)
|
|
{
|
|
self.isOnboardingCoordinatorPreparing = YES;
|
|
self.isOnboardingInProgress = YES;
|
|
|
|
if (resetSessionFlags)
|
|
{
|
|
[self resetReviewSessionsFlags];
|
|
}
|
|
|
|
[[AppDelegate theDelegate] restoreInitialDisplay:^{
|
|
|
|
[self presentOnboardingFlow];
|
|
}];
|
|
}
|
|
}
|
|
|
|
- (void)selectRoomWithParameters:(RoomNavigationParameters*)paramaters completion:(void (^)(void))completion
|
|
{
|
|
[self releaseSelectedItem];
|
|
|
|
_selectedRoomId = paramaters.roomId;
|
|
_selectedEventId = paramaters.eventId;
|
|
_selectedRoomSession = paramaters.mxSession;
|
|
|
|
[self.masterTabBarDelegate masterTabBarController:self didSelectRoomWithParameters:paramaters completion:completion];
|
|
|
|
[self refreshSelectedControllerSelectedCellIfNeeded];
|
|
}
|
|
|
|
- (void)selectRoomPreviewWithParameters:(RoomPreviewNavigationParameters*)parameters completion:(void (^)(void))completion
|
|
{
|
|
[self releaseSelectedItem];
|
|
|
|
RoomPreviewData *roomPreviewData = parameters.previewData;
|
|
|
|
_selectedRoomPreviewData = roomPreviewData;
|
|
_selectedRoomId = roomPreviewData.roomId;
|
|
_selectedRoomSession = roomPreviewData.mxSession;
|
|
|
|
[self.masterTabBarDelegate masterTabBarController:self didSelectRoomPreviewWithParameters:parameters completion:completion];
|
|
|
|
[self refreshSelectedControllerSelectedCellIfNeeded];
|
|
}
|
|
|
|
- (void)selectContact:(MXKContact*)contact
|
|
{
|
|
ScreenPresentationParameters *presentationParameters = [[ScreenPresentationParameters alloc] initWithRestoreInitialDisplay:YES stackAboveVisibleViews:NO];
|
|
|
|
[self selectContact:contact withPresentationParameters:presentationParameters];
|
|
}
|
|
|
|
- (void)selectContact:(MXKContact*)contact withPresentationParameters:(ScreenPresentationParameters*)presentationParameters
|
|
{
|
|
[self releaseSelectedItem];
|
|
|
|
_selectedContact = contact;
|
|
|
|
[self.masterTabBarDelegate masterTabBarController:self didSelectContact:contact withPresentationParameters:presentationParameters];
|
|
|
|
[self refreshSelectedControllerSelectedCellIfNeeded];
|
|
}
|
|
|
|
- (void)selectGroup:(MXGroup*)group inMatrixSession:(MXSession*)matrixSession
|
|
{
|
|
ScreenPresentationParameters *presentationParameters = [[ScreenPresentationParameters alloc] initWithRestoreInitialDisplay:YES stackAboveVisibleViews:NO];
|
|
|
|
[self selectGroup:group inMatrixSession:matrixSession presentationParameters:presentationParameters];
|
|
}
|
|
|
|
- (void)selectGroup:(MXGroup*)group inMatrixSession:(MXSession*)matrixSession presentationParameters:(ScreenPresentationParameters*)presentationParameters
|
|
{
|
|
[self releaseSelectedItem];
|
|
|
|
_selectedGroup = group;
|
|
_selectedGroupSession = matrixSession;
|
|
|
|
[self.masterTabBarDelegate masterTabBarController:self didSelectGroup:group inMatrixSession:matrixSession presentationParameters:presentationParameters];
|
|
|
|
[self refreshSelectedControllerSelectedCellIfNeeded];
|
|
}
|
|
|
|
- (void)releaseSelectedItem
|
|
{
|
|
_selectedRoomId = nil;
|
|
_selectedEventId = nil;
|
|
_selectedRoomSession = nil;
|
|
_selectedRoomPreviewData = nil;
|
|
|
|
_selectedContact = nil;
|
|
|
|
_selectedGroup = nil;
|
|
_selectedGroupSession = nil;
|
|
}
|
|
|
|
- (NSUInteger)missedDiscussionsCount
|
|
{
|
|
NSUInteger roomCount = 0;
|
|
|
|
// Considering all the current sessions.
|
|
for (MXSession *session in mxSessionArray)
|
|
{
|
|
roomCount += [session vc_missedDiscussionsCount];
|
|
}
|
|
|
|
return roomCount;
|
|
}
|
|
|
|
- (NSUInteger)missedHighlightDiscussionsCount
|
|
{
|
|
NSUInteger roomCount = 0;
|
|
|
|
for (MXSession *session in mxSessionArray)
|
|
{
|
|
roomCount += [session missedHighlightDiscussionsCount];
|
|
}
|
|
|
|
return roomCount;
|
|
}
|
|
|
|
- (UIViewController*)viewControllerForClass:(Class)klass
|
|
{
|
|
UIViewController *foundViewController;
|
|
|
|
NSInteger viewControllerIndex = [self.viewControllers indexOfObjectPassingTest:^BOOL(__kindof UIViewController * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
|
|
if ([obj isKindOfClass:klass])
|
|
{
|
|
*stop = YES;
|
|
return YES;
|
|
}
|
|
return NO;
|
|
}];
|
|
|
|
if (viewControllerIndex != NSNotFound)
|
|
{
|
|
foundViewController = self.viewControllers[viewControllerIndex];
|
|
}
|
|
|
|
return foundViewController;
|
|
}
|
|
|
|
- (void)filterRoomsWithParentId:(NSString*)roomParentId
|
|
inMatrixSession:(MXSession*)mxSession
|
|
{
|
|
if (roomParentId) {
|
|
NSString *parentName = [mxSession roomSummaryWithRoomId:roomParentId].displayname;
|
|
NSMutableArray<NSString *> *breadcrumbs = [[NSMutableArray alloc] initWithObjects:parentName, nil];
|
|
|
|
MXSpace *firstRootAncestor = roomParentId ? [mxSession.spaceService firstRootAncestorForRoomWithId:roomParentId] : nil;
|
|
NSString *rootName = nil;
|
|
if (firstRootAncestor)
|
|
{
|
|
rootName = [mxSession roomSummaryWithRoomId:firstRootAncestor.spaceId].displayname;
|
|
[breadcrumbs insertObject:rootName atIndex:0];
|
|
}
|
|
titleView.breadcrumbView.breadcrumbs = breadcrumbs;
|
|
}
|
|
else
|
|
{
|
|
titleView.breadcrumbView.breadcrumbs = @[];
|
|
}
|
|
|
|
recentsDataSource.currentSpace = [mxSession.spaceService getSpaceWithId:roomParentId];
|
|
[self updateSideMenuNotifcationIcon];
|
|
}
|
|
|
|
- (void)updateSideMenuNotifcationIcon
|
|
{
|
|
BOOL displayNotification = NO;
|
|
|
|
for (MXRoomSummary *summary in recentsDataSource.mxSession.spaceService.rootSpaceSummaries) {
|
|
if (summary.membership == MXMembershipInvite) {
|
|
displayNotification = YES;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!displayNotification) {
|
|
MXSpaceNotificationState *notificationState = [recentsDataSource.mxSession.spaceService.notificationCounter notificationStateForAllSpacesExcept: recentsDataSource.currentSpace.spaceId];
|
|
|
|
if (recentsDataSource.currentSpace)
|
|
{
|
|
MXSpaceNotificationState *homeNotificationState = recentsDataSource.mxSession.spaceService.notificationCounter.homeNotificationState;
|
|
displayNotification = notificationState.groupMissedDiscussionsCount > 0 || notificationState.groupMissedDiscussionsHighlightedCount > 0 || homeNotificationState.allCount > 0 || homeNotificationState.allHighlightCount > 0;
|
|
}
|
|
else
|
|
{
|
|
displayNotification = notificationState.groupMissedDiscussionsCount > 0 || notificationState.groupMissedDiscussionsHighlightedCount > 0;
|
|
}
|
|
}
|
|
|
|
[self.masterTabBarDelegate masterTabBarController:self needsSideMenuIconWithNotification:displayNotification];
|
|
}
|
|
|
|
#pragma mark -
|
|
|
|
-(void)setupTitleView
|
|
{
|
|
titleView = [MainTitleView new];
|
|
self.navigationItem.titleView = titleView;
|
|
}
|
|
|
|
-(void)setTitleLabelText:(NSString *)text
|
|
{
|
|
titleView.titleLabel.text = text;
|
|
self.navigationItem.backButtonTitle = text;
|
|
}
|
|
|
|
- (void)presentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion
|
|
{
|
|
// Keep ref on presented view controller
|
|
[childViewControllers addObject:viewControllerToPresent];
|
|
|
|
[super presentViewController:viewControllerToPresent animated:flag completion:completion];
|
|
}
|
|
|
|
- (void)refreshSelectedControllerSelectedCellIfNeeded
|
|
{
|
|
if (self.splitViewController)
|
|
{
|
|
// Refresh selected cell without scrolling the selected cell (We suppose it's visible here)
|
|
[self refreshCurrentSelectedCell:NO];
|
|
}
|
|
}
|
|
|
|
// Made the actual selected view controller update its selected cell.
|
|
- (void)refreshCurrentSelectedCell:(BOOL)forceVisible
|
|
{
|
|
UIViewController *selectedViewController = self.selectedViewController;
|
|
|
|
if ([selectedViewController respondsToSelector:@selector(refreshCurrentSelectedCell:)])
|
|
{
|
|
[(id)selectedViewController refreshCurrentSelectedCell:forceVisible];
|
|
}
|
|
}
|
|
|
|
- (void)setHidden:(BOOL)hidden
|
|
{
|
|
_hidden = hidden;
|
|
|
|
[self.view superview].backgroundColor = ThemeService.shared.theme.backgroundColor;
|
|
self.view.hidden = hidden;
|
|
self.navigationController.navigationBar.hidden = hidden;
|
|
}
|
|
|
|
- (NSString*)getTitleForItemViewController:(UIViewController*)itemViewController
|
|
{
|
|
if ([itemViewController conformsToProtocol:@protocol(MasterTabBarItemDisplayProtocol)])
|
|
{
|
|
UIViewController<MasterTabBarItemDisplayProtocol> *masterTabBarItem = (UIViewController<MasterTabBarItemDisplayProtocol>*)itemViewController;
|
|
return masterTabBarItem.masterTabBarItemTitle;
|
|
}
|
|
|
|
return nil;
|
|
}
|
|
|
|
#pragma mark -
|
|
|
|
- (void)refreshTabBarBadges
|
|
{
|
|
// Use a middle dot to signal missed notif in favourites
|
|
if (RiotSettings.shared.homeScreenShowFavouritesTab)
|
|
{
|
|
[self setMissedDiscussionsMark:(recentsDataSource.favoriteMissedDiscussionsCount.numberOfNotified ? @"\u00B7": nil)
|
|
onTabBarItem:TABBAR_FAVOURITES_INDEX
|
|
withBadgeColor:(recentsDataSource.favoriteMissedDiscussionsCount.hasHighlight ? ThemeService.shared.theme.noticeColor : ThemeService.shared.theme.noticeSecondaryColor)];
|
|
}
|
|
|
|
// Update the badge on People and Rooms tabs
|
|
if (RiotSettings.shared.homeScreenShowPeopleTab)
|
|
{
|
|
if (recentsDataSource.directMissedDiscussionsCount.hasUnsent)
|
|
{
|
|
[self setBadgeValue:@"!"
|
|
onTabBarItem:TABBAR_PEOPLE_INDEX
|
|
withBadgeColor:ThemeService.shared.theme.noticeColor];
|
|
}
|
|
else
|
|
{
|
|
[self setMissedDiscussionsCount:recentsDataSource.directMissedDiscussionsCount.numberOfNotified
|
|
onTabBarItem:TABBAR_PEOPLE_INDEX
|
|
withBadgeColor:(recentsDataSource.directMissedDiscussionsCount.hasHighlight ? ThemeService.shared.theme.noticeColor : ThemeService.shared.theme.noticeSecondaryColor)];
|
|
}
|
|
}
|
|
|
|
if (RiotSettings.shared.homeScreenShowRoomsTab)
|
|
{
|
|
if (recentsDataSource.groupMissedDiscussionsCount.hasUnsent)
|
|
{
|
|
[self setMissedDiscussionsCount:recentsDataSource.groupMissedDiscussionsCount.numberOfUnsent
|
|
onTabBarItem:TABBAR_ROOMS_INDEX
|
|
withBadgeColor:ThemeService.shared.theme.noticeColor];
|
|
}
|
|
else
|
|
{
|
|
[self setMissedDiscussionsCount:recentsDataSource.groupMissedDiscussionsCount.numberOfNotified
|
|
onTabBarItem:TABBAR_ROOMS_INDEX
|
|
withBadgeColor:(recentsDataSource.groupMissedDiscussionsCount.hasHighlight ? ThemeService.shared.theme.noticeColor : ThemeService.shared.theme.noticeSecondaryColor)];
|
|
}
|
|
}
|
|
}
|
|
|
|
- (void)setMissedDiscussionsCount:(NSUInteger)count onTabBarItem:(NSUInteger)index withBadgeColor:(UIColor*)badgeColor
|
|
{
|
|
[self setBadgeValue:count ? [self tabBarBadgeStringValue:count] : nil onTabBarItem:index withBadgeColor:badgeColor];
|
|
}
|
|
|
|
- (void)setBadgeValue:(NSString *)value onTabBarItem:(NSUInteger)index withBadgeColor:(UIColor*)badgeColor
|
|
{
|
|
NSInteger itemIndex = [self indexOfTabItemWithTag:index];
|
|
if (itemIndex != NSNotFound)
|
|
{
|
|
if (value)
|
|
{
|
|
self.tabBar.items[itemIndex].badgeValue = value;
|
|
|
|
self.tabBar.items[itemIndex].badgeColor = badgeColor;
|
|
|
|
[self.tabBar.items[itemIndex] setBadgeTextAttributes:@{
|
|
NSForegroundColorAttributeName: ThemeService.shared.theme.baseTextPrimaryColor
|
|
}
|
|
forState:UIControlStateNormal];
|
|
}
|
|
else
|
|
{
|
|
self.tabBar.items[itemIndex].badgeValue = nil;
|
|
}
|
|
}
|
|
}
|
|
|
|
- (void)setMissedDiscussionsMark:(NSString*)mark onTabBarItem:(NSUInteger)index withBadgeColor:(UIColor*)badgeColor
|
|
{
|
|
NSInteger itemIndex = [self indexOfTabItemWithTag:index];
|
|
if (itemIndex != NSNotFound)
|
|
{
|
|
if (mark)
|
|
{
|
|
self.tabBar.items[itemIndex].badgeValue = mark;
|
|
|
|
self.tabBar.items[itemIndex].badgeColor = badgeColor;
|
|
|
|
[self.tabBar.items[itemIndex] setBadgeTextAttributes:@{
|
|
NSForegroundColorAttributeName: ThemeService.shared.theme.baseTextPrimaryColor
|
|
}
|
|
forState:UIControlStateNormal];
|
|
}
|
|
else
|
|
{
|
|
self.tabBar.items[itemIndex].badgeValue = nil;
|
|
}
|
|
}
|
|
}
|
|
|
|
- (NSString*)tabBarBadgeStringValue:(NSUInteger)count
|
|
{
|
|
NSString *badgeValue;
|
|
|
|
if (count > 1000)
|
|
{
|
|
CGFloat value = count / 1000.0;
|
|
badgeValue = [VectorL10n largeBadgeValueKFormat:value];
|
|
}
|
|
else
|
|
{
|
|
badgeValue = [NSString stringWithFormat:@"%tu", count];
|
|
}
|
|
|
|
return badgeValue;
|
|
}
|
|
|
|
- (NSInteger)indexOfTabItemWithTag:(NSUInteger)tag
|
|
{
|
|
for (int i = 0 ; i < self.tabBar.items.count ; i++)
|
|
{
|
|
if (self.tabBar.items[i].tag == tag)
|
|
{
|
|
return i;
|
|
}
|
|
}
|
|
|
|
return NSNotFound;
|
|
}
|
|
|
|
#pragma mark - Review session
|
|
|
|
- (void)presentVerifyCurrentSessionAlertIfNeededWithSession:(MXSession*)session
|
|
{
|
|
if (RiotSettings.shared.hideVerifyThisSessionAlert
|
|
|| self.reviewSessionAlertHasBeenDisplayed
|
|
|| self.isOnboardingInProgress)
|
|
{
|
|
return;
|
|
}
|
|
|
|
self.reviewSessionAlertHasBeenDisplayed = YES;
|
|
|
|
// Force verification if required by the HS configuration
|
|
if (session.vc_homeserverConfiguration.encryption.isSecureBackupRequired)
|
|
{
|
|
NSLog(@"[MasterTabBarController] presentVerifyCurrentSessionAlertIfNeededWithSession: Force verification of the device");
|
|
[[AppDelegate theDelegate] presentCompleteSecurityForSession:session];
|
|
return;
|
|
}
|
|
|
|
[self presentVerifyCurrentSessionAlertWithSession:session];
|
|
}
|
|
|
|
- (void)presentVerifyCurrentSessionAlertWithSession:(MXSession*)session
|
|
{
|
|
MXLogDebug(@"[MasterTabBarController] presentVerifyCurrentSessionAlertWithSession");
|
|
|
|
[currentAlert dismissViewControllerAnimated:NO completion:nil];
|
|
|
|
UIAlertController *alert = [UIAlertController alertControllerWithTitle:[VectorL10n keyVerificationSelfVerifyCurrentSessionAlertTitle]
|
|
message:[VectorL10n keyVerificationSelfVerifyCurrentSessionAlertMessage]
|
|
preferredStyle:UIAlertControllerStyleAlert];
|
|
|
|
[alert addAction:[UIAlertAction actionWithTitle:[VectorL10n keyVerificationSelfVerifyCurrentSessionAlertValidateAction]
|
|
style:UIAlertActionStyleDefault
|
|
handler:^(UIAlertAction * action) {
|
|
[[AppDelegate theDelegate] presentCompleteSecurityForSession:session];
|
|
}]];
|
|
|
|
[alert addAction:[UIAlertAction actionWithTitle:[VectorL10n later]
|
|
style:UIAlertActionStyleCancel
|
|
handler:nil]];
|
|
|
|
[alert addAction:[UIAlertAction actionWithTitle:[VectorL10n doNotAskAgain]
|
|
style:UIAlertActionStyleDestructive
|
|
handler:^(UIAlertAction * action) {
|
|
RiotSettings.shared.hideVerifyThisSessionAlert = YES;
|
|
}]];
|
|
|
|
|
|
[self presentViewController:alert animated:YES completion:nil];
|
|
|
|
currentAlert = alert;
|
|
}
|
|
|
|
- (void)presentReviewUnverifiedSessionsAlertIfNeededWithSession:(MXSession*)session
|
|
{
|
|
if (RiotSettings.shared.hideReviewSessionsAlert || self.reviewSessionAlertHasBeenDisplayed)
|
|
{
|
|
return;
|
|
}
|
|
|
|
NSArray<MXDeviceInfo*> *devices = [session.crypto devicesForUser:session.myUserId].allValues;
|
|
|
|
BOOL isUserHasOneUnverifiedDevice = NO;
|
|
|
|
for (MXDeviceInfo *device in devices)
|
|
{
|
|
if (!device.trustLevel.isCrossSigningVerified)
|
|
{
|
|
isUserHasOneUnverifiedDevice = YES;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (isUserHasOneUnverifiedDevice)
|
|
{
|
|
self.reviewSessionAlertHasBeenDisplayed = YES;
|
|
[self presentReviewUnverifiedSessionsAlertWithSession:session];
|
|
}
|
|
}
|
|
|
|
- (void)presentReviewUnverifiedSessionsAlertWithSession:(MXSession*)session
|
|
{
|
|
MXLogDebug(@"[MasterTabBarController] presentReviewUnverifiedSessionsAlertWithSession");
|
|
|
|
[currentAlert dismissViewControllerAnimated:NO completion:nil];
|
|
|
|
UIAlertController *alert = [UIAlertController alertControllerWithTitle:[VectorL10n keyVerificationSelfVerifyUnverifiedSessionsAlertTitle]
|
|
message:[VectorL10n keyVerificationSelfVerifyUnverifiedSessionsAlertMessage]
|
|
preferredStyle:UIAlertControllerStyleAlert];
|
|
|
|
[alert addAction:[UIAlertAction actionWithTitle:[VectorL10n keyVerificationSelfVerifyUnverifiedSessionsAlertValidateAction]
|
|
style:UIAlertActionStyleDefault
|
|
handler:^(UIAlertAction * action) {
|
|
[self showSettingsSecurityScreenForSession:session];
|
|
}]];
|
|
|
|
if (!session.homeserverWellknown.backupRequired)
|
|
{
|
|
[alert addAction:[UIAlertAction actionWithTitle:[VectorL10n later]
|
|
style:UIAlertActionStyleCancel
|
|
handler:nil]];
|
|
|
|
[alert addAction:[UIAlertAction actionWithTitle:[VectorL10n doNotAskAgain]
|
|
style:UIAlertActionStyleDestructive
|
|
handler:^(UIAlertAction * action) {
|
|
RiotSettings.shared.hideReviewSessionsAlert = YES;
|
|
}]];
|
|
}
|
|
|
|
[self presentViewController:alert animated:YES completion:nil];
|
|
|
|
currentAlert = alert;
|
|
}
|
|
|
|
- (void)showSettingsSecurityScreenForSession:(MXSession*)session
|
|
{
|
|
SettingsViewController *settingsViewController = [SettingsViewController instantiate];
|
|
[settingsViewController loadViewIfNeeded];
|
|
SecurityViewController *securityViewController = [SecurityViewController instantiateWithMatrixSession:session];
|
|
|
|
[[AppDelegate theDelegate] restoreInitialDisplay:^{
|
|
self.navigationController.viewControllers = @[self, settingsViewController, securityViewController];
|
|
}];
|
|
}
|
|
|
|
- (void)resetReviewSessionsFlags
|
|
{
|
|
self.reviewSessionAlertHasBeenDisplayed = NO;
|
|
RiotSettings.shared.hideVerifyThisSessionAlert = NO;
|
|
RiotSettings.shared.hideReviewSessionsAlert = NO;
|
|
}
|
|
|
|
#pragma mark - UITabBarDelegate
|
|
|
|
- (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item
|
|
{
|
|
// Detect multi-tap on the current selected tab.
|
|
if (item.tag == self.selectedIndex)
|
|
{
|
|
// Scroll to the next room with missed notifications.
|
|
if (item.tag == TABBAR_ROOMS_INDEX)
|
|
{
|
|
[self.roomsViewController scrollToNextRoomWithMissedNotifications];
|
|
}
|
|
else if (item.tag == TABBAR_PEOPLE_INDEX)
|
|
{
|
|
[self.peopleViewController scrollToNextRoomWithMissedNotifications];
|
|
}
|
|
else if (item.tag == TABBAR_FAVOURITES_INDEX)
|
|
{
|
|
[self.favouritesViewController scrollToNextRoomWithMissedNotifications];
|
|
}
|
|
}
|
|
}
|
|
|
|
#pragma mark - UITabBarControllerDelegate
|
|
|
|
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController
|
|
{
|
|
self.titleLabelText = [self getTitleForItemViewController:viewController];
|
|
}
|
|
|
|
#pragma mark - bwi sync management
|
|
|
|
- (void) bwiOnUnlockedByPin {
|
|
NSInteger tabItemTag = self.tabBar.items[self.selectedIndex].tag;
|
|
|
|
switch (tabItemTag)
|
|
{
|
|
case TABBAR_FAVOURITES_INDEX:
|
|
[self.favouritesViewController setupTopBanner];
|
|
[self.favouritesViewController checkAppVersionOutdated];
|
|
break;
|
|
case TABBAR_PEOPLE_INDEX:
|
|
[self.peopleViewController setupTopBanner];
|
|
break;
|
|
case TABBAR_ROOMS_INDEX:
|
|
[self.roomsViewController setupTopBanner];
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
- (void) bwiCheckForPersonalNotesRoom {
|
|
PersonalNotesDefaultService *service = [PersonalNotesDefaultService service:self.mxSessions.firstObject];
|
|
if (BuildSettings.bwiResetPersonalNotesAccountData) {
|
|
[service resetPersonalNotesRoom];
|
|
}
|
|
if (BuildSettings.bwiPersonalNotesRoom) {
|
|
[service createPersonalNotesRoomIfNeeded];
|
|
}
|
|
if (BwiBuildSettings.bwiUseCustomPersonalNotesAvatar) {
|
|
MXSession *mainSession = mxSessionArray.firstObject;
|
|
|
|
if (mainSession) {
|
|
for (MXRoom* room in [mainSession roomsWithTag:PersonalNotesDefaultService.roomTag]) {
|
|
if ([room.summary.avatar length] > 0) {
|
|
[room setAvatar:@"" success:nil failure:nil];
|
|
}
|
|
}
|
|
|
|
MXRoom* room = [mainSession roomWithRoomId:[service personalNotesRoomId]];
|
|
if (room && [room.summary.avatar length] > 0) {
|
|
[room setAvatar:@"" success:nil failure:nil];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#pragma mark - bwi matomo tracking
|
|
|
|
- (void) bwiShowMatomoInfoScreen {
|
|
UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil
|
|
message:NSLocalizedStringFromTable(@"MATOMO_USER_INFO", @"Vector", nil)
|
|
preferredStyle:UIAlertControllerStyleAlert];
|
|
[alert addAction:[UIAlertAction actionWithTitle:[VectorL10n ok] style:UIAlertActionStyleDefault handler:nil]];
|
|
[self presentViewController:alert animated:YES completion:nil];
|
|
}
|
|
|
|
@end
|