Merge commit '1f3f2160661f1d7d3550d53752c66165309e4bd5' into feature/basis_merge_1824

# 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
This commit is contained in:
Frank Rotermund
2022-09-19 11:31:20 +02:00
773 changed files with 15324 additions and 7024 deletions
@@ -44,13 +44,14 @@ final class LiveLocationSharingViewerCoordinator: Coordinator, Presentable {
// MARK: - Setup
@available(iOS 14.0, *)
init(parameters: LiveLocationSharingViewerCoordinatorParameters) {
self.parameters = parameters
let service = LiveLocationSharingViewerService(session: parameters.session, roomId: parameters.roomId)
let viewModel = LiveLocationSharingViewerViewModel(mapStyleURL: BuildSettings.tileServerMapStyleURL, service: service)
let viewModel = LiveLocationSharingViewerViewModel(
mapStyleURL: parameters.session.vc_homeserverConfiguration().tileServer.mapStyleURL,
service: service)
let view = LiveLocationSharingViewer(viewModel: viewModel.context)
.addDependency(AvatarService.instantiate(mediaManager: parameters.session.mediaManager))
liveLocationSharingViewerViewModel = viewModel
@@ -29,7 +29,6 @@ enum LiveLocationSharingViewerViewModelResult {
// MARK: View
@available(iOS 14, *)
struct LiveLocationSharingViewerViewState: BindableState {
/// Map style URL
@@ -57,6 +56,7 @@ struct LiveLocationSharingViewerViewState: BindableState {
struct LiveLocationSharingViewerViewStateBindings {
var alertInfo: AlertInfo<LocationSharingAlertType>?
var showMapCreditsSheet = false
}
enum LiveLocationSharingViewerViewAction {
@@ -64,4 +64,5 @@ enum LiveLocationSharingViewerViewAction {
case stopSharing
case tapListItem(_ userId: String)
case share(_ annotation: UserLocationAnnotation)
case mapCreditsDidTap
}
@@ -18,11 +18,9 @@ import SwiftUI
import Combine
import Mapbox
@available(iOS 14, *)
typealias LiveLocationSharingViewerViewModelType = StateStoreViewModel<LiveLocationSharingViewerViewState,
Never,
LiveLocationSharingViewerViewAction>
@available(iOS 14, *)
class LiveLocationSharingViewerViewModel: LiveLocationSharingViewerViewModelType, LiveLocationSharingViewerViewModelProtocol {
// MARK: - Properties
@@ -71,6 +69,8 @@ class LiveLocationSharingViewerViewModel: LiveLocationSharingViewerViewModelType
self.highlighAnnotation(with: userId)
case .share(let userLocationAnnotation):
completion?(.share(userLocationAnnotation.coordinate))
case .mapCreditsDidTap:
state.bindings.showMapCreditsSheet.toggle()
}
}
@@ -19,6 +19,5 @@ import Foundation
protocol LiveLocationSharingViewerViewModelProtocol {
var completion: ((LiveLocationSharingViewerViewModelResult) -> Void)? { get set }
@available(iOS 14, *)
var context: LiveLocationSharingViewerViewModelType.Context { get }
}
@@ -19,7 +19,6 @@ import SwiftUI
/// Using an enum for the screen allows you define the different state cases with
/// the relevant associated data for each case.
@available(iOS 14.0, *)
enum MockLiveLocationSharingViewerScreenState: MockScreenState, CaseIterable {
// A case for each state you want to represent
// with specific, minimal associated data that will allow you
@@ -18,7 +18,6 @@ import Foundation
import Combine
import CoreLocation
@available(iOS 14.0, *)
protocol LiveLocationSharingViewerServiceProtocol {
/// All shared users live location
@@ -18,7 +18,6 @@ import Foundation
import CoreLocation
import MatrixSDK
@available(iOS 14.0, *)
class LiveLocationSharingViewerService: LiveLocationSharingViewerServiceProtocol {
// MARK: - Properties
@@ -18,7 +18,6 @@ import Foundation
import Combine
import CoreLocation
@available(iOS 14.0, *)
class MockLiveLocationSharingViewerService: LiveLocationSharingViewerServiceProtocol {
// MARK: Properties
@@ -17,10 +17,6 @@
import XCTest
import RiotSwiftUI
@available(iOS 14.0, *)
class LiveLocationSharingViewerUITests: MockScreenTest {
override class var screenType: MockScreenState.Type {
return MockLiveLocationSharingViewerScreenState.self
}
class LiveLocationSharingViewerUITests: MockScreenTestCase {
// Tests to be implemented.
}
@@ -19,7 +19,6 @@ import Combine
@testable import RiotSwiftUI
@available(iOS 14.0, *)
class LiveLocationSharingViewerViewModelTests: XCTestCase {
var service: MockLiveLocationSharingViewerService!
@@ -29,7 +28,7 @@ class LiveLocationSharingViewerViewModelTests: XCTestCase {
override func setUpWithError() throws {
service = MockLiveLocationSharingViewerService()
viewModel = LiveLocationSharingViewerViewModel(mapStyleURL: BuildSettings.tileServerMapStyleURL, service: service)
viewModel = LiveLocationSharingViewerViewModel(mapStyleURL: BuildSettings.defaultTileServerMapStyleURL, service: service)
context = viewModel.context
}
}
@@ -16,7 +16,6 @@
import SwiftUI
@available(iOS 14.0, *)
struct LiveLocationListItem: View {
// MARK: - Properties
@@ -86,7 +85,7 @@ struct LiveLocationListItem: View {
Button(VectorL10n.locationSharingLiveListItemStopSharingAction) {
onStopSharingAction?()
}
.font(theme.fonts.caption1)
.font(theme.fonts.body)
.foregroundColor(theme.colors.alert)
}
}
@@ -121,7 +120,6 @@ struct LiveLocationListItem: View {
}
}
@available(iOS 14.0, *)
struct LiveLocationListPreview: View {
let liveLocationSharingViewerService: LiveLocationSharingViewerServiceProtocol = MockLiveLocationSharingViewerService()
@@ -181,7 +179,6 @@ struct LiveLocationListPreview: View {
}
}
@available(iOS 14.0, *)
struct LiveLocationListItem_Previews: PreviewProvider {
static var previews: some View {
Group {
@@ -17,7 +17,6 @@
import SwiftUI
import DSBottomSheet
@available(iOS 14.0, *)
struct LiveLocationSharingViewer: View {
// MARK: - Properties
@@ -26,9 +25,13 @@ struct LiveLocationSharingViewer: View {
@Environment(\.theme) private var theme: ThemeSwiftUI
@Environment(\.openURL) var openURL
var isBottomSheetVisible = true
@State private var isBottomSheetExpanded = false
var bottomSheetCollapsedHeight: CGFloat = 150.0
// MARK: Public
@ObservedObject var viewModel: LiveLocationSharingViewerViewModel.Context
@@ -51,20 +54,29 @@ struct LiveLocationSharingViewer: View {
errorSubject: viewModel.viewState.errorSubject)
VStack(alignment: .center) {
Spacer()
MapCreditsView()
.offset(y: -130)
MapCreditsView(action: {
viewModel.send(viewAction: .mapCreditsDidTap)
})
.offset(y: -(bottomSheetCollapsedHeight)) // Put the copyright action above the collapsed bottom sheet
.padding(.bottom, 10)
}
.ignoresSafeArea()
}
.navigationTitle(VectorL10n.locationSharingLiveViewerTitle)
.toolbar {
ToolbarItem(placement: .cancellationAction) {
Button(VectorL10n.cancel) {
Button(VectorL10n.close) {
viewModel.send(viewAction: .done)
}
}
}
.accentColor(theme.colors.accent)
.bottomSheet(sheet, if: isBottomSheetVisible)
.actionSheet(isPresented: $viewModel.showMapCreditsSheet) {
return MapCreditsActionSheet(openURL: { url in
openURL(url)
}).sheet
}
.alert(item: $viewModel.alertInfo) { info in
info.alert
}
@@ -86,11 +98,11 @@ struct LiveLocationSharingViewer: View {
}
.padding()
}
.background(theme.colors.background.ignoresSafeArea())
}
}
// MARK: - Bottom sheet
@available(iOS 14.0, *)
extension LiveLocationSharingViewer {
var sheetStyle: BottomSheetStyle {
@@ -109,7 +121,7 @@ extension LiveLocationSharingViewer {
var sheet: some BottomSheetView {
BottomSheet(
isExpanded: $isBottomSheetExpanded,
minHeight: .points(150),
minHeight: .points(bottomSheetCollapsedHeight),
maxHeight: .available,
style: sheetStyle) {
userLocationList
@@ -119,7 +131,6 @@ extension LiveLocationSharingViewer {
// MARK: - Previews
@available(iOS 14.0, *)
struct LiveLocationSharingViewer_Previews: PreviewProvider {
static let stateRenderer = MockLiveLocationSharingViewerScreenState.stateRenderer
static var previews: some View {
@@ -20,6 +20,7 @@ import SwiftUI
import MatrixSDK
struct LocationSharingCoordinatorParameters {
let session: MXSession
let roomDataSource: MXKRoomDataSource
let mediaManager: MXMediaManager
let avatarData: AvatarInputProtocol
@@ -73,18 +74,17 @@ final class LocationSharingCoordinator: Coordinator, Presentable {
// MARK: - Setup
@available(iOS 14.0, *)
init(parameters: LocationSharingCoordinatorParameters) {
self.parameters = parameters
let locationSharingService = LocationSharingService(session: parameters.roomDataSource.mxSession)
let locationSharingService = LocationSharingService(userLocationService: parameters.roomDataSource.mxSession.userLocationService)
let viewModel = LocationSharingViewModel(
mapStyleURL: parameters.session.vc_homeserverConfiguration().tileServer.mapStyleURL,
avatarData: parameters.avatarData,
isLiveLocationSharingEnabled: RiotSettings.shared.enableLiveLocationSharing,
service: locationSharingService)
let tileServerMapStyleURL = parameters.roomDataSource.mxSession.vc_homeserverConfiguration().tileServer.mapStyleURL
let viewModel = LocationSharingViewModel(mapStyleURL: tileServerMapStyleURL,
avatarData: parameters.avatarData,
isLiveLocationSharingEnabled: RiotSettings.shared.enableLiveLocationSharing, service: locationSharingService)
let view = LocationSharingView(context: viewModel.context)
.addDependency(AvatarService.instantiate(mediaManager: parameters.mediaManager))
@@ -94,11 +94,6 @@ final class LocationSharingCoordinator: Coordinator, Presentable {
// MARK: - Public
func start() {
guard #available(iOS 14.0, *) else {
MXLog.error("[LocationSharingCoordinator] start: Invalid iOS version, returning.")
return
}
locationSharingViewModel.completion = { [weak self] result in
guard let self = self else { return }
@@ -109,6 +104,8 @@ final class LocationSharingCoordinator: Coordinator, Presentable {
self.shareStaticLocation(latitude: latitude, longitude: longitude, coordinateType: coordinateType)
case .shareLiveLocation(let timeout):
self.startLiveLocationSharing(with: timeout)
case .checkLiveLocationCanBeStarted(let completion):
self.checkLiveLocationCanBeStarted(completion: completion)
}
}
}
@@ -168,6 +165,70 @@ final class LocationSharingCoordinator: Coordinator, Presentable {
}
}
private func checkLiveLocationCanBeStarted(completion: @escaping ((Result<Void, Error>) -> Void)) {
guard self.canShareLiveLocation() else {
completion(.failure(LiveLocationStartError.powerLevelNotHighEnough))
return
}
self.showLabFlagPromotionIfNeeded { labFlagEnabled in
if labFlagEnabled {
completion(.success(Void()))
} else {
completion(.failure(LiveLocationStartError.labFlagNotEnabled))
}
}
}
// Check if user can send beacon info state event
private func canShareLiveLocation() -> Bool {
guard let myUserId = self.parameters.roomDataSource.mxSession.myUserId else {
return false
}
let userPowerLevelRawValue = self.parameters.roomDataSource.roomState.powerLevels.powerLevelOfUser(withUserID: myUserId)
guard let userPowerLevel = RoomPowerLevel(rawValue: userPowerLevelRawValue) else {
return false
}
return userPowerLevel.rawValue >= RoomPowerLevel.moderator.rawValue
}
private func showLabFlagPromotionIfNeeded(completion: @escaping ((Bool) -> Void)) {
guard RiotSettings.shared.enableLiveLocationSharing == false else {
// Live location sharing lab flag is already enabled, do not present lab flag promotion screen
completion(true)
return
}
self.showLabFlagPromotion(completion: completion)
}
private func showLabFlagPromotion(completion: @escaping ((Bool) -> Void)) {
// TODO: Use a NavigationRouter instead of using NavigationView inside LocationSharingView
// In order to use `NavigationRouter.present`
let coordinator = LiveLocationLabPromotionCoordinator()
coordinator.start()
coordinator.completion = { [weak self, weak coordinator] enableLiveLocation in
guard let self = self, let coordinator = coordinator else { return }
completion(enableLiveLocation)
coordinator.toPresentable().dismiss(animated: true) {
self.remove(childCoordinator: coordinator)
}
}
self.locationSharingHostingController.present(coordinator.toPresentable(), animated: true)
self.add(childCoordinator: coordinator)
}
// MARK: - Presentable
func toPresentable() -> UIViewController {
@@ -40,12 +40,19 @@ enum LocationSharingViewAction {
case startLiveSharing
case shareLiveLocation(timeout: LiveLocationSharingTimeout)
case userDidPan
case mapCreditsDidTap
}
enum LocationSharingViewModelResult {
case cancel
case share(latitude: Double, longitude: Double, coordinateType: LocationSharingCoordinateType)
case shareLiveLocation(timeout: TimeInterval)
case checkLiveLocationCanBeStarted(_ completion: ((Result<Void, Error>) -> Void))
}
enum LiveLocationStartError: Error {
case powerLevelNotHighEnough
case labFlagNotEnabled
}
enum LocationSharingViewError {
@@ -55,7 +62,6 @@ enum LocationSharingViewError {
case failedSharingLocation
}
@available(iOS 14, *)
struct LocationSharingViewState: BindableState {
/// Map style URL
@@ -78,7 +84,7 @@ struct LocationSharingViewState: BindableState {
/// True to indicate to show and follow current user location
var showsUserLocation: Bool = false
/// Used to hide live location sharing features until is finished
/// Used to hide live location sharing features
var isLiveLocationSharingEnabled: Bool = false
var shareButtonEnabled: Bool {
@@ -95,6 +101,7 @@ struct LocationSharingViewStateBindings {
var userLocation: CLLocationCoordinate2D?
var pinLocation: CLLocationCoordinate2D?
var showingTimerSelector = false
var showMapCreditsSheet = false
}
enum LocationSharingAlertType {
@@ -103,4 +110,5 @@ enum LocationSharingAlertType {
case authorizationError
case locationSharingError
case stopLocationSharingError
case locationSharingPowerLevelError
}
@@ -18,7 +18,6 @@ import Foundation
import SwiftUI
import CoreLocation
@available(iOS 14.0, *)
enum MockLocationSharingScreenState: MockScreenState, CaseIterable {
case shareUserLocation
@@ -18,11 +18,9 @@ import SwiftUI
import Combine
import CoreLocation
@available(iOS 14, *)
typealias LocationSharingViewModelType = StateStoreViewModel<LocationSharingViewState,
Never,
LocationSharingViewAction>
@available(iOS 14, *)
class LocationSharingViewModel: LocationSharingViewModelType, LocationSharingViewModelProtocol {
// MARK: - Properties
@@ -88,6 +86,8 @@ class LocationSharingViewModel: LocationSharingViewModelType, LocationSharingVie
case .userDidPan:
state.showsUserLocation = false
state.isPinDropSharing = true
case .mapCreditsDidTap:
state.bindings.showMapCreditsSheet.toggle()
}
}
@@ -101,10 +101,23 @@ class LocationSharingViewModel: LocationSharingViewModelType, LocationSharingVie
state.showLoadingIndicator = false
if let error = error {
state.bindings.alertInfo = AlertInfo(id: error,
title: VectorL10n.locationSharingPostFailureTitle,
message: VectorL10n.locationSharingPostFailureSubtitle(AppInfo.current.displayName),
primaryButton: (VectorL10n.ok, nil))
let alertInfo: AlertInfo<LocationSharingAlertType>
switch error {
case .locationSharingPowerLevelError:
alertInfo = AlertInfo(id: error,
title: VectorL10n.locationSharingInvalidPowerLevelTitle,
message: VectorL10n.locationSharingInvalidPowerLevelMessage,
primaryButton: (VectorL10n.ok, nil))
default:
alertInfo = AlertInfo(id: error,
title: VectorL10n.locationSharingPostFailureTitle,
message: VectorL10n.locationSharingPostFailureSubtitle(AppInfo.current.displayName),
primaryButton: (VectorL10n.ok, nil))
}
state.bindings.alertInfo = alertInfo
}
}
@@ -140,7 +153,7 @@ class LocationSharingViewModel: LocationSharingViewModelType, LocationSharingVie
}
}
private func startLiveLocationSharing() {
private func checkLocationAuthorizationAndPresentTimerSelector() {
self.locationSharingService.requestAuthorization { [weak self] authorizationStatus in
@@ -160,11 +173,30 @@ class LocationSharingViewModel: LocationSharingViewModelType, LocationSharingVie
self.state.bindings.alertInfo = AlertInfo(id: .userLocatingError,
title: VectorL10n.locationSharingAllowBackgroundLocationTitle,
message: VectorL10n.locationSharingAllowBackgroundLocationMessage,
primaryButton: (VectorL10n.locationSharingAllowBackgroundLocationCancelAction, { [weak self] in self?.state.bindings.showingTimerSelector = true }),
primaryButton: (VectorL10n.locationSharingAllowBackgroundLocationCancelAction, {}),
secondaryButton: (VectorL10n.locationSharingAllowBackgroundLocationValidateAction, { UIApplication.shared.vc_openSettings() }))
case .authorizedAlways:
self.state.bindings.showingTimerSelector = true
}
}
}
private func startLiveLocationSharing() {
guard let completion = completion else {
return
}
completion(.checkLiveLocationCanBeStarted({ result in
switch result {
case .success:
self.checkLocationAuthorizationAndPresentTimerSelector()
case .failure(let error):
if case LiveLocationStartError.powerLevelNotHighEnough = error {
self.stopLoading(error: .locationSharingPowerLevelError)
}
}
}))
}
}
@@ -0,0 +1,37 @@
//
// Copyright 2022 New Vector Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
import SwiftUI
struct MapCreditsActionSheet {
// Open URL action
let openURL: (URL) -> Void
// Map credits action sheet
var sheet: ActionSheet {
ActionSheet(title: Text(VectorL10n.locationSharingMapCreditsTitle),
buttons: [
.default(Text("© MapTiler")) {
openURL(URL(string: "https://www.maptiler.com/copyright/")!)
},
.default(Text("© OpenStreetMap")) {
openURL(URL(string: "https://www.openstreetmap.org/copyright")!)
},
.cancel()
])
}
}
@@ -24,20 +24,26 @@ class LocationSharingService: LocationSharingServiceProtocol {
// MARK: Private
private let userLocationService: UserLocationServiceProtocol?
private let session: MXSession
private var userLocationService: UserLocationServiceProtocol? {
return self.session.userLocationService
}
// MARK: Public
// MARK: - Setup
init(userLocationService: UserLocationServiceProtocol?) {
self.userLocationService = userLocationService
init(session: MXSession) {
self.session = session
}
// MARK: - Public
func requestAuthorization(_ handler: @escaping LocationAuthorizationHandler) {
guard let userLocationService = self.userLocationService else {
MXLog.error("[LocationSharingService] No userLocationService found for the current session")
handler(LocationAuthorizationStatus.unknown)
return
}
@@ -18,7 +18,6 @@ import Foundation
import Combine
import CoreLocation
@available(iOS 14.0, *)
class MockLocationSharingService: LocationSharingServiceProtocol {
func requestAuthorization(_ handler: @escaping LocationAuthorizationHandler) {
handler(.authorizedAlways)
@@ -17,18 +17,7 @@
import XCTest
import RiotSwiftUI
@available(iOS 14.0, *)
class LocationSharingUITests: XCTestCase {
private var app: XCUIApplication!
override func setUp() {
continueAfterFailure = false
app = XCUIApplication()
app.launch()
}
class LocationSharingUITests: MockScreenTestCase {
func testInitialUserLocation() {
goToScreenWithIdentifier(MockLocationSharingScreenState.shareUserLocation.title)
@@ -20,7 +20,6 @@ import CoreLocation
@testable import RiotSwiftUI
@available(iOS 14.0, *)
class LocationSharingViewModelTests: XCTestCase {
var cancellables = Set<AnyCancellable>()
@@ -51,6 +50,8 @@ class LocationSharingViewModelTests: XCTestCase {
expectation.fulfill()
case .shareLiveLocation:
XCTFail()
case .checkLiveLocationCanBeStarted:
XCTFail()
}
}
@@ -18,13 +18,12 @@ import SwiftUI
import Combine
import Mapbox
@available(iOS 14, *)
struct LocationSharingMapView: UIViewRepresentable {
// MARK: - Constants
private struct Constants {
static let mapZoomLevel = 13.0
static let mapZoomLevel = 15.0
}
// MARK: - Properties
@@ -86,7 +85,6 @@ struct LocationSharingMapView: UIViewRepresentable {
if self.showsUserLocation {
mapView.showsUserLocation = true
mapView.userTrackingMode = .follow
mapView.maximumZoomLevel = Constants.mapZoomLevel
} else {
mapView.showsUserLocation = false
mapView.userTrackingMode = .none
@@ -110,7 +108,6 @@ struct LocationSharingMapView: UIViewRepresentable {
}
// MARK: - Coordinator
@available(iOS 14, *)
extension LocationSharingMapView {
class Coordinator: NSObject, MGLMapViewDelegate, UIGestureRecognizerDelegate {
@@ -16,7 +16,6 @@
import SwiftUI
@available(iOS 14.0, *)
struct LocationSharingMarkerView<Content: View>: View {
// MARK: - Properties
@@ -45,7 +44,6 @@ struct LocationSharingMarkerView<Content: View>: View {
// MARK: - Previews
@available(iOS 14.0, *)
struct LocationSharingUserMarkerView_Previews: PreviewProvider {
static var previews: some View {
let avatarData = AvatarInput(mxContentUri: "",
@@ -16,7 +16,6 @@
import SwiftUI
@available(iOS 14.0, *)
struct LocationSharingOptionButton<Content: View>: View {
// MARK: - Properties
@@ -42,7 +41,6 @@ struct LocationSharingOptionButton<Content: View>: View {
}
}
@available(iOS 14.0, *)
struct LocationSharingOptionButton_Previews: PreviewProvider {
static var previews: some View {
VStack(alignment: .leading) {
@@ -17,7 +17,6 @@
import SwiftUI
import CoreLocation
@available(iOS 14.0, *)
struct LocationSharingView: View {
// MARK: - Properties
@@ -26,6 +25,8 @@ struct LocationSharingView: View {
@Environment(\.theme) private var theme: ThemeSwiftUI
@Environment(\.openURL) var openURL
// MARK: Public
@ObservedObject var context: LocationSharingViewModel.Context
@@ -35,12 +36,21 @@ struct LocationSharingView: View {
ZStack(alignment: .bottom) {
mapView
VStack(spacing: 0) {
MapCreditsView()
MapCreditsView(action: {
context.send(viewAction: .mapCreditsDidTap)
})
.padding(.bottom, 10.0)
.actionSheet(isPresented: $context.showMapCreditsSheet) {
return MapCreditsActionSheet(openURL: { url in
openURL(url)
}).sheet
}
buttonsView
.background(theme.colors.background)
.clipShape(RoundedCornerShape(radius: 8, corners: [.topLeft, .topRight]))
}
}
.background(theme.colors.background.ignoresSafeArea())
.toolbar {
ToolbarItem(placement: .navigationBarLeading) {
Button(VectorL10n.cancel, action: {
@@ -164,7 +174,6 @@ struct LocationSharingView: View {
// MARK: - Previews
@available(iOS 14.0, *)
struct LocationSharingView_Previews: PreviewProvider {
static let stateRenderer = MockLocationSharingScreenState.stateRenderer
static var previews: some View {
@@ -16,7 +16,6 @@
import SwiftUI
@available(iOS 14.0, *)
struct MapCreditsView: View {
// MARK: - Properties
@@ -27,16 +26,23 @@ struct MapCreditsView: View {
// MARK: Public
var action: (() -> Void)?
var body: some View {
HStack {
Link("© MapTiler", destination: URL(string: "https://www.maptiler.com/copyright/")!)
Link("© OpenStreetMap contributors", destination: URL(string: "https://www.openstreetmap.org/copyright")!)
Spacer()
Button {
action?()
} label: {
Text(VectorL10n.locationSharingMapCreditsTitle)
.font(theme.fonts.footnote)
.foregroundColor(theme.colors.accent)
}
.padding(.horizontal)
}
.font(theme.fonts.caption1)
}
}
@available(iOS 14.0, *)
struct MapCreditsView_Previews: PreviewProvider {
static var previews: some View {
MapCreditsView()
@@ -18,7 +18,6 @@ import Foundation
import SwiftUI
import Mapbox
@available(iOS 14, *)
class LocationAnnotationView: MGLUserLocationAnnotationView {
// MARK: - Constants
@@ -37,45 +37,21 @@ final class RoomNotificationSettingsCoordinator: RoomNotificationSettingsCoordin
init(room: MXRoom, presentedModally: Bool = true) {
let roomNotificationService = MXRoomNotificationSettingsService(room: room)
let avatarData: AvatarProtocol?
let showAvatar = presentedModally
if #available(iOS 14.0.0, *) {
avatarData = showAvatar ? AvatarInput(
mxContentUri: room.summary.avatar,
matrixItemId: room.roomId,
displayName: room.summary.displayname
) : nil
} else {
avatarData = showAvatar ? RoomAvatarViewData(
roomId: room.roomId,
displayName: room.summary.displayname,
avatarUrl: room.summary.avatar,
mediaManager: room.mxSession.mediaManager
) : nil
}
let viewModel: RoomNotificationSettingsViewModel
let viewController: UIViewController
if #available(iOS 14.0.0, *) {
let swiftUIViewModel = RoomNotificationSettingsSwiftUIViewModel(
roomNotificationService: roomNotificationService,
avatarData: avatarData,
displayName: room.summary.displayname,
roomEncrypted: room.summary.isEncrypted)
let avatarService: AvatarServiceProtocol = AvatarService(mediaManager: room.mxSession.mediaManager)
let view = RoomNotificationSettings(viewModel: swiftUIViewModel, presentedModally: presentedModally)
.addDependency(avatarService)
let host = VectorHostingController(rootView: view)
viewModel = swiftUIViewModel
viewController = host
} else {
viewModel = RoomNotificationSettingsViewModel(
roomNotificationService: roomNotificationService,
avatarData: avatarData,
displayName: room.summary.displayname,
roomEncrypted: room.summary.isEncrypted)
viewController = RoomNotificationSettingsViewController.instantiate(with: viewModel)
}
let avatarData = showAvatar ? AvatarInput(
mxContentUri: room.summary.avatar,
matrixItemId: room.roomId,
displayName: room.summary.displayname
) : nil
let viewModel = RoomNotificationSettingsSwiftUIViewModel(
roomNotificationService: roomNotificationService,
avatarData: avatarData,
displayName: room.summary.displayname,
roomEncrypted: room.summary.isEncrypted)
let avatarService: AvatarServiceProtocol = AvatarService(mediaManager: room.mxSession.mediaManager)
let view = RoomNotificationSettings(viewModel: viewModel, presentedModally: presentedModally)
.addDependency(avatarService)
let viewController = VectorHostingController(rootView: view)
self.roomNotificationSettingsViewModel = viewModel
self.roomNotificationSettingsViewController = viewController
}
@@ -17,7 +17,6 @@
import Foundation
import SwiftUI
@available(iOS 14.0, *)
struct FormItemButtonStyle: ButtonStyle {
@Environment(\.theme) var theme: ThemeSwiftUI
func makeBody(configuration: Self.Configuration) -> some View {
@@ -16,7 +16,6 @@
import SwiftUI
@available(iOS 14.0, *)
struct FormPickerItem: View {
typealias TapCallback = () -> Void
@@ -53,7 +52,6 @@ struct FormPickerItem: View {
}
}
@available(iOS 14.0, *)
struct FormPickerItem_Previews: PreviewProvider {
static let items = ["Item 1", "Item 2", "Item 3"]
@@ -16,7 +16,6 @@
import SwiftUI
@available(iOS 14.0, *)
struct FormSectionFooter: View {
@Environment(\.theme) var theme: ThemeSwiftUI
@@ -32,7 +31,6 @@ struct FormSectionFooter: View {
}
}
@available(iOS 14.0, *)
struct FormSectionFooter_Previews: PreviewProvider {
static var previews: some View {
VectorForm {
@@ -16,7 +16,6 @@
import SwiftUI
@available(iOS 14.0, *)
struct FormSectionHeader: View {
@Environment(\.theme) var theme: ThemeSwiftUI
@@ -34,7 +33,6 @@ struct FormSectionHeader: View {
}
}
@available(iOS 14.0, *)
struct FormSectionHeader_Previews: PreviewProvider {
static var previews: some View {
VectorForm {
@@ -16,7 +16,6 @@
import SwiftUI
@available(iOS 14.0.0, *)
struct RoomNotificationSettings: View {
@Environment(\.theme) var theme: ThemeSwiftUI
@@ -74,7 +73,6 @@ struct RoomNotificationSettings: View {
}
}
@available(iOS 14.0, *)
struct RoomNotificationSettings_Previews: PreviewProvider {
static let mockViewModel = RoomNotificationSettingsSwiftUIViewModel(
@@ -16,7 +16,6 @@
import SwiftUI
@available(iOS 14.0, *)
struct RoomNotificationSettingsHeader: View {
@Environment(\.theme) var theme: ThemeSwiftUI
@@ -41,7 +40,6 @@ struct RoomNotificationSettingsHeader: View {
}
}
@available(iOS 14.0, *)
struct RoomNotificationSettingsHeader_Previews: PreviewProvider {
static let name = "Element"
static var previews: some View {
@@ -16,7 +16,6 @@
import SwiftUI
@available(iOS 14.0, *)
struct VectorForm<Content: View>: View {
@Environment(\.theme) var theme: ThemeSwiftUI
@@ -43,7 +42,6 @@ struct VectorForm<Content: View>: View {
}
}
@available(iOS 14.0, *)
struct VectorForm_Previews: PreviewProvider {
static var previews: some View {
@@ -17,7 +17,6 @@
import Foundation
import Combine
@available(iOS 14.0, *)
class RoomNotificationSettingsSwiftUIViewModel: RoomNotificationSettingsViewModel, ObservableObject {
@Published var viewState: RoomNotificationSettingsViewState
@@ -41,7 +41,6 @@ final class PollEditFormCoordinator: Coordinator, Presentable {
// MARK: - Setup
@available(iOS 14.0, *)
init(parameters: PollEditFormCoordinatorParameters) {
self.parameters = parameters
@@ -65,11 +64,6 @@ final class PollEditFormCoordinator: Coordinator, Presentable {
// MARK: - Public
func start() {
guard #available(iOS 14.0, *) else {
MXLog.error("[PollEditFormCoordinator] start: Invalid iOS version, returning.")
return
}
pollEditFormViewModel.completion = { [weak self] result in
guard let self = self else { return }
switch result {
@@ -17,7 +17,6 @@
import Foundation
import SwiftUI
@available(iOS 14.0, *)
enum MockPollEditFormScreenState: MockScreenState, CaseIterable {
case standard
@@ -22,11 +22,9 @@ struct PollEditFormViewModelParameters {
let pollDetails: EditFormPollDetails
}
@available(iOS 14, *)
typealias PollEditFormViewModelType = StateStoreViewModel <PollEditFormViewState,
Never,
PollEditFormViewAction>
@available(iOS 14, *)
class PollEditFormViewModel: PollEditFormViewModelType, PollEditFormViewModelProtocol {
private struct Constants {
@@ -17,20 +17,9 @@
import XCTest
import RiotSwiftUI
@available(iOS 14.0, *)
class PollEditFormUITests: XCTestCase {
private var app: XCUIApplication!
override func setUp() {
continueAfterFailure = false
app = XCUIApplication()
app.launch()
app.goToScreenWithIdentifier(MockPollEditFormScreenState.standard.title)
}
class PollEditFormUITests: MockScreenTestCase {
func testInitialStateComponents() {
app.goToScreenWithIdentifier(MockPollEditFormScreenState.standard.title)
XCTAssert(app.scrollViews.firstMatch.exists)
@@ -59,6 +48,7 @@ class PollEditFormUITests: XCTestCase {
}
func testRemoveAddAnswerOptions() {
app.goToScreenWithIdentifier(MockPollEditFormScreenState.standard.title)
let deleteAnswerOptionButton = app.buttons["Delete answer option"].firstMatch
@@ -19,7 +19,6 @@ import Combine
@testable import RiotSwiftUI
@available(iOS 14.0, *)
class PollEditFormViewModelTests: XCTestCase {
var viewModel: PollEditFormViewModel!
var context: PollEditFormViewModelType.Context!
@@ -16,7 +16,6 @@
import SwiftUI
@available(iOS 14.0, *)
struct PollEditForm: View {
// MARK: - Properties
@@ -128,7 +127,6 @@ struct PollEditForm: View {
// MARK: - Previews
@available(iOS 14.0, *)
struct PollEditForm_Previews: PreviewProvider {
static let stateRenderer = MockPollEditFormScreenState.stateRenderer
static var previews: some View {
@@ -16,7 +16,6 @@
import SwiftUI
@available(iOS 14.0, *)
struct PollEditFormAnswerOptionView: View {
@Environment(\.theme) private var theme: ThemeSwiftUI
@@ -48,7 +47,6 @@ struct PollEditFormAnswerOptionView: View {
}
}
@available(iOS 14.0, *)
struct PollEditFormAnswerOptionView_Previews: PreviewProvider {
static var previews: some View {
VStack(spacing: 32.0) {
@@ -16,7 +16,6 @@
import SwiftUI
@available(iOS 14.0, *)
struct PollEditFormTypePicker: View {
@Environment(\.theme) private var theme: ThemeSwiftUI
@@ -35,7 +34,6 @@ struct PollEditFormTypePicker: View {
}
}
@available(iOS 14.0, *)
private struct PollEditFormTypeButton: View {
@Environment(\.theme) private var theme: ThemeSwiftUI
@@ -89,7 +87,6 @@ private struct PollEditFormTypeButton: View {
}
}
@available(iOS 14.0, *)
struct PollEditFormTypePicker_Previews: PreviewProvider {
static var previews: some View {
VStack {
@@ -25,7 +25,6 @@ enum RoomAccessCoordinatorCoordinatorAction {
}
@objcMembers
@available(iOS 14.0, *)
final class RoomAccessCoordinator: Coordinator {
// MARK: - Properties
@@ -16,7 +16,6 @@
import UIKit
import MatrixSDK
@available(iOS 14.0, *)
@objc protocol RoomAccessCoordinatorBridgePresenterDelegate {
func roomAccessCoordinatorBridgePresenterDelegate(_ coordinatorBridgePresenter: RoomAccessCoordinatorBridgePresenter, didCancelRoomWithId roomId: String)
func roomAccessCoordinatorBridgePresenterDelegate(_ coordinatorBridgePresenter: RoomAccessCoordinatorBridgePresenter, didCompleteRoomWithId roomId: String)
@@ -27,7 +26,6 @@ import MatrixSDK
/// It breaks the Coordinator abstraction and it has been introduced for Objective-C compatibility (mainly for integration in legacy view controllers).
/// Each bridge should be removed once the underlying Coordinator has been integrated by another Coordinator.
@objcMembers
@available(iOS 14.0, *)
final class RoomAccessCoordinatorBridgePresenter: NSObject {
// MARK: - Properties
@@ -99,7 +97,6 @@ final class RoomAccessCoordinatorBridgePresenter: NSObject {
// MARK: - UIAdaptivePresentationControllerDelegate
@available(iOS 14.0, *)
extension RoomAccessCoordinatorBridgePresenter: UIAdaptivePresentationControllerDelegate {
func roomNotificationSettingsCoordinatorDidComplete(_ presentationController: UIPresentationController) {
@@ -40,7 +40,6 @@ final class RoomAccessTypeChooserCoordinator: Coordinator, Presentable {
// MARK: - Setup
@available(iOS 14.0, *)
init(parameters: RoomAccessTypeChooserCoordinatorParameters) {
self.parameters = parameters
let viewModel = RoomAccessTypeChooserViewModel(roomAccessTypeChooserService: RoomAccessTypeChooserService(roomId: parameters.roomId, allowsRoomUpgrade: parameters.allowsRoomUpgrade, session: parameters.session))
@@ -20,7 +20,6 @@ import SwiftUI
/// Using an enum for the screen allows you define the different state cases with
/// the relevant associated data for each case.
@available(iOS 14.0, *)
enum MockRoomAccessTypeChooserScreenState: MockScreenState, CaseIterable {
// A case for each state you want to represent
// with specific, minimal associated data that will allow you
@@ -17,11 +17,9 @@
import SwiftUI
import Combine
@available(iOS 14, *)
typealias RoomAccessTypeChooserViewModelType = StateStoreViewModel<RoomAccessTypeChooserViewState,
RoomAccessTypeChooserStateAction,
RoomAccessTypeChooserViewAction>
@available(iOS 14.0, *)
class RoomAccessTypeChooserViewModel: RoomAccessTypeChooserViewModelType, RoomAccessTypeChooserViewModelProtocol {
// MARK: - Properties
@@ -18,7 +18,6 @@ import Foundation
protocol RoomAccessTypeChooserViewModelProtocol {
var callback: ((RoomAccessTypeChooserViewModelAction) -> Void)? { get set }
@available(iOS 14, *)
var context: RoomAccessTypeChooserViewModelType.Context { get }
func handleRoomUpgradeResult(_ result: RoomUpgradeCoordinatorResult)
@@ -18,7 +18,6 @@ import Foundation
import Combine
import MatrixSDK
@available(iOS 14.0, *)
class RoomAccessTypeChooserService: RoomAccessTypeChooserServiceProtocol {
// MARK: - Properties
@@ -17,7 +17,6 @@
import Foundation
import Combine
@available(iOS 14.0, *)
class MockRoomAccessTypeChooserService: RoomAccessTypeChooserServiceProtocol {
static let mockAccessItems: [RoomAccessTypeChooserAccessItem] = [
@@ -17,7 +17,6 @@
import Foundation
import Combine
@available(iOS 14.0, *)
protocol RoomAccessTypeChooserServiceProtocol {
var accessItemsSubject: CurrentValueSubject<[RoomAccessTypeChooserAccessItem], Never> { get }
var roomUpgradeRequiredSubject: CurrentValueSubject<Bool, Never> { get }
@@ -17,7 +17,6 @@
import XCTest
import RiotSwiftUI
@available(iOS 14.0, *)
class RoomAccessTypeChooserUITests: MockScreenTest {
class RoomAccessTypeChooserUITests: MockScreenTestCase {
// Tests to be implemented.
}
@@ -19,7 +19,6 @@ import Combine
@testable import RiotSwiftUI
@available(iOS 14.0, *)
class RoomAccessTypeChooserViewModelTests: XCTestCase {
}
@@ -16,7 +16,6 @@
import SwiftUI
@available(iOS 14.0, *)
struct RoomAccessTypeChooser: View {
// MARK: - Properties
@@ -84,7 +83,6 @@ struct RoomAccessTypeChooser: View {
// MARK: - Previews
@available(iOS 14.0, *)
struct RoomAccessTypeChooser_Previews: PreviewProvider {
static let stateRenderer = MockRoomAccessTypeChooserScreenState.stateRenderer
@@ -16,7 +16,6 @@
import SwiftUI
@available(iOS 14.0, *)
struct RoomAccessTypeChooserRow: View {
// MARK: - Properties
@@ -46,7 +45,7 @@ struct RoomAccessTypeChooserRow: View {
Spacer()
Image(systemName: isSelected ? "checkmark.circle.fill" : "circle")
.renderingMode(.template)
.foregroundColor(isSelected ? theme.colors.accent : theme.colors.quarterlyContent)
.foregroundColor(isSelected ? theme.colors.accent : theme.colors.quaternaryContent)
}
if let badgeText = badgeText {
Text(badgeText)
@@ -70,7 +69,6 @@ struct RoomAccessTypeChooserRow: View {
// MARK: - Previews
@available(iOS 14.0, *)
struct RoomAccessTypeChooserRow_Previews: PreviewProvider {
static var previews: some View {
VStack {
@@ -24,7 +24,6 @@ class RoomRestrictedAccessSpaceChooserViewProvider: MatrixItemChooserCoordinator
self.navTitle = navTitle
}
@available(iOS 14, *)
func view(with viewModel: MatrixItemChooserViewModelType.Context) -> AnyView {
return AnyView(RoomRestrictedAccessSpaceChooserSelector(viewModel: viewModel, navTitle: navTitle))
}
@@ -16,7 +16,6 @@
import SwiftUI
@available(iOS 14.0, *)
struct RoomRestrictedAccessSpaceChooserSelector: View {
// MARK: Properties
@@ -38,7 +37,7 @@ struct RoomRestrictedAccessSpaceChooserSelector: View {
Button(VectorL10n.cancel) {
viewModel.send(viewAction: .cancel)
}
.foregroundColor(viewModel.viewState.loading ? theme.colors.quarterlyContent : theme.colors.accent)
.foregroundColor(viewModel.viewState.loading ? theme.colors.quaternaryContent : theme.colors.accent)
.opacity(viewModel.viewState.loading ? 0.7 : 1)
.disabled(viewModel.viewState.loading)
}
@@ -46,7 +45,7 @@ struct RoomRestrictedAccessSpaceChooserSelector: View {
Button(VectorL10n.done) {
viewModel.send(viewAction: .done)
}
.foregroundColor(viewModel.viewState.selectedItemIds.isEmpty || viewModel.viewState.loading ? theme.colors.quarterlyContent : theme.colors.accent)
.foregroundColor(viewModel.viewState.selectedItemIds.isEmpty || viewModel.viewState.loading ? theme.colors.quaternaryContent : theme.colors.accent)
.opacity(viewModel.viewState.selectedItemIds.isEmpty || viewModel.viewState.loading ? 0.7 : 1)
.disabled(viewModel.viewState.selectedItemIds.isEmpty || viewModel.viewState.loading)
}
@@ -23,7 +23,6 @@ enum RoomSuggestionCoordinatorCoordinatorAction {
}
@objcMembers
@available(iOS 14.0, *)
final class RoomSuggestionCoordinator: Coordinator {
// MARK: - Properties
@@ -15,7 +15,6 @@
//
import UIKit
@available(iOS 14.0, *)
@objc protocol RoomSuggestionCoordinatorBridgePresenterDelegate {
func roomSuggestionCoordinatorBridgePresenterDelegateDidCancel(_ coordinatorBridgePresenter: RoomSuggestionCoordinatorBridgePresenter)
func roomSuggestionCoordinatorBridgePresenterDelegateDidComplete(_ coordinatorBridgePresenter: RoomSuggestionCoordinatorBridgePresenter)
@@ -26,7 +25,6 @@ import UIKit
/// It breaks the Coordinator abstraction and it has been introduced for Objective-C compatibility (mainly for integration in legacy view controllers).
/// Each bridge should be removed once the underlying Coordinator has been integrated by another Coordinator.
@objcMembers
@available(iOS 14.0, *)
final class RoomSuggestionCoordinatorBridgePresenter: NSObject {
// MARK: - Properties
@@ -87,7 +85,6 @@ final class RoomSuggestionCoordinatorBridgePresenter: NSObject {
// MARK: - UIAdaptivePresentationControllerDelegate
@available(iOS 14.0, *)
extension RoomSuggestionCoordinatorBridgePresenter: UIAdaptivePresentationControllerDelegate {
func roomNotificationSettingsCoordinatorDidComplete(_ presentationController: UIPresentationController) {
@@ -24,7 +24,6 @@ class RoomSuggestionSpaceChooserViewProvider: MatrixItemChooserCoordinatorViewPr
self.navTitle = navTitle
}
@available(iOS 14, *)
func view(with viewModel: MatrixItemChooserViewModelType.Context) -> AnyView {
return AnyView(RoomSuggestionSpaceChooserSelector(viewModel: viewModel, navTitle: navTitle))
}
@@ -16,7 +16,6 @@
import SwiftUI
@available(iOS 14.0, *)
struct RoomSuggestionSpaceChooserSelector: View {
// MARK: Properties
@@ -42,7 +42,6 @@ final class RoomUpgradeCoordinator: Coordinator, Presentable {
// MARK: - Setup
@available(iOS 14.0, *)
init(parameters: RoomUpgradeCoordinatorParameters) {
self.parameters = parameters
let viewModel = RoomUpgradeViewModel.makeRoomUpgradeViewModel(roomUpgradeService: RoomUpgradeService(session: parameters.session, roomId: parameters.roomId, parentSpaceId: parameters.parentSpaceId, versionOverride: parameters.versionOverride))
@@ -19,7 +19,6 @@ import SwiftUI
/// Using an enum for the screen allows you define the different state cases with
/// the relevant associated data for each case.
@available(iOS 14.0, *)
enum MockRoomUpgradeScreenState: MockScreenState, CaseIterable {
// A case for each state you want to represent
// with specific, minimal associated data that will allow you
@@ -17,11 +17,9 @@
import SwiftUI
import Combine
@available(iOS 14, *)
typealias RoomUpgradeViewModelType = StateStoreViewModel<RoomUpgradeViewState,
Never,
RoomUpgradeViewAction>
@available(iOS 14, *)
class RoomUpgradeViewModel: RoomUpgradeViewModelType, RoomUpgradeViewModelProtocol {
// MARK: - Properties
@@ -19,8 +19,6 @@ import Foundation
protocol RoomUpgradeViewModelProtocol {
var completion: ((RoomUpgradeViewModelResult) -> Void)? { get set }
@available(iOS 14, *)
static func makeRoomUpgradeViewModel(roomUpgradeService: RoomUpgradeServiceProtocol) -> RoomUpgradeViewModelProtocol
@available(iOS 14, *)
var context: RoomUpgradeViewModelType.Context { get }
}
@@ -18,7 +18,6 @@ import Foundation
import Combine
import MatrixSDK
@available(iOS 14.0, *)
class RoomUpgradeService: RoomUpgradeServiceProtocol {
// MARK: - Properties
@@ -17,7 +17,6 @@
import Foundation
import Combine
@available(iOS 14.0, *)
class MockRoomUpgradeService: RoomUpgradeServiceProtocol {
var currentRoomId: String = "!sfdlksjdflkfjds:matrix.org"
@@ -17,7 +17,6 @@
import Foundation
import Combine
@available(iOS 14.0, *)
protocol RoomUpgradeServiceProtocol {
var currentRoomId: String { get }
var parentSpaceName: String? { get }
@@ -17,7 +17,6 @@
import XCTest
import RiotSwiftUI
@available(iOS 14.0, *)
class RoomUpgradeUITests: MockScreenTest {
class RoomUpgradeUITests: MockScreenTestCase {
// Tests to be implemented.
}
@@ -19,7 +19,6 @@ import Combine
@testable import RiotSwiftUI
@available(iOS 14.0, *)
class RoomUpgradeViewModelTests: XCTestCase {
var service: MockRoomUpgradeService!
var viewModel: RoomUpgradeViewModelProtocol!
@@ -16,7 +16,6 @@
import SwiftUI
@available(iOS 14.0, *)
struct RoomUpgrade: View {
// MARK: - Properties
@@ -102,7 +101,6 @@ struct RoomUpgrade: View {
// MARK: - Previews
@available(iOS 14.0, *)
struct RoomUpgrade_Previews: PreviewProvider {
static let stateRenderer = MockRoomUpgradeScreenState.stateRenderer
static var previews: some View {
@@ -20,11 +20,11 @@ import SwiftUI
import MatrixSDK
struct StaticLocationViewingCoordinatorParameters {
let session: MXSession
let mediaManager: MXMediaManager
let avatarData: AvatarInputProtocol
let location: CLLocationCoordinate2D
let coordinateType: LocationSharingCoordinateType
let mxSession: MXSession?
}
final class StaticLocationViewingCoordinator: Coordinator, Presentable {
@@ -47,24 +47,14 @@ final class StaticLocationViewingCoordinator: Coordinator, Presentable {
// MARK: - Setup
@available(iOS 14.0, *)
init(parameters: StaticLocationViewingCoordinatorParameters) {
self.parameters = parameters
var viewModel: StaticLocationViewingViewModel
if let mapStyleUrl = parameters.mxSession?.vc_homeserverConfiguration()?.tileServer.mapStyleURL {
viewModel = StaticLocationViewingViewModel(mapStyleURL: mapStyleUrl,
avatarData: parameters.avatarData,
location: parameters.location,
coordinateType: parameters.coordinateType)
} else {
viewModel = StaticLocationViewingViewModel(mapStyleURL: BuildSettings.tileServerMapStyleURL,
avatarData: parameters.avatarData,
location: parameters.location,
coordinateType: parameters.coordinateType)
}
let viewModel = StaticLocationViewingViewModel(
mapStyleURL: parameters.session.vc_homeserverConfiguration().tileServer.mapStyleURL,
avatarData: parameters.avatarData,
location: parameters.location,
coordinateType: parameters.coordinateType)
let view = StaticLocationView(viewModel: viewModel.context)
.addDependency(AvatarService.instantiate(mediaManager: parameters.mediaManager))
staticLocationViewingViewModel = viewModel
@@ -20,7 +20,6 @@ import CoreLocation
/// Using an enum for the screen allows you define the different state cases with
/// the relevant associated data for each case.
@available(iOS 14.0, *)
enum MockStaticLocationViewingScreenState: MockScreenState, CaseIterable {
// A case for each state you want to represent
// with specific, minimal associated data that will allow you
@@ -32,7 +32,6 @@ enum StaticLocationViewingViewModelResult {
// MARK: View
@available(iOS 14, *)
struct StaticLocationViewingViewState: BindableState {
/// Map style URL
@@ -17,11 +17,9 @@
import SwiftUI
import CoreLocation
@available(iOS 14, *)
typealias StaticLocationViewingViewModelType = StateStoreViewModel<StaticLocationViewingViewState,
Never,
StaticLocationViewingViewAction>
@available(iOS 14, *)
class StaticLocationViewingViewModel: StaticLocationViewingViewModelType, StaticLocationViewingViewModelProtocol {
// MARK: - Properties
@@ -19,6 +19,5 @@ import Foundation
protocol StaticLocationViewingViewModelProtocol {
var completion: ((StaticLocationViewingViewModelResult) -> Void)? { get set }
@available(iOS 14, *)
var context: StaticLocationViewingViewModelType.Context { get }
}
@@ -17,29 +17,6 @@
import XCTest
import RiotSwiftUI
@available(iOS 14.0, *)
class StaticLocationViewingUITests: MockScreenTest {
override class var screenType: MockScreenState.Type {
return MockStaticLocationViewingScreenState.self
}
override class func createTest() -> MockScreenTest {
return StaticLocationViewingUITests(selector: #selector(verifyStaticLocationViewingScreen))
}
func verifyStaticLocationViewingScreen() {
guard let screenState = screenState as? MockStaticLocationViewingScreenState else { fatalError("no screen") }
switch screenState {
case .showUserLocation:
verifyInitialExistingLocation()
case .showPinLocation:
verifyInitialExistingLocation()
}
}
func verifyInitialExistingLocation() {
// This test has issues running consistently on CI. Removed for now until the issue has been fixed.
}
class StaticLocationViewingUITests: MockScreenTestCase {
// This test has issues running consistently on CI. Removed for now until the issue has been fixed.
}
@@ -20,7 +20,6 @@ import CoreLocation
@testable import RiotSwiftUI
@available(iOS 14.0, *)
class StaticLocationViewingViewModelTests: XCTestCase {
var cancellables = Set<AnyCancellable>()
@@ -16,7 +16,6 @@
import SwiftUI
@available(iOS 14.0, *)
struct StaticLocationView: View {
// MARK: - Properties
@@ -62,7 +61,7 @@ struct StaticLocationView: View {
} label: {
Image(uiImage: Asset.Images.locationShareIcon.image)
}
//.disabled(!viewModel.viewState.shareButtonEnabled)
.disabled(!viewModel.viewState.shareButtonEnabled)
.accessibilityIdentifier("shareButton")
.opacity(BwiBuildSettings.bwiLocationShareButtonVisible ? 1.0 : 0.0)
}
@@ -90,7 +89,6 @@ struct StaticLocationView: View {
// MARK: - Previews
@available(iOS 14.0, *)
struct StaticLocationSharingViewer_Previews: PreviewProvider {
static let stateRenderer = MockStaticLocationViewingScreenState.stateRenderer
static var previews: some View {
@@ -24,7 +24,6 @@ struct TimelinePollCoordinatorParameters {
let pollStartEvent: MXEvent
}
@available(iOS 14.0, *)
final class TimelinePollCoordinator: Coordinator, Presentable, PollAggregatorDelegate {
// MARK: - Properties
@@ -45,7 +44,6 @@ final class TimelinePollCoordinator: Coordinator, Presentable, PollAggregatorDel
// MARK: - Setup
@available(iOS 14.0, *)
init(parameters: TimelinePollCoordinatorParameters) throws {
self.parameters = parameters
@@ -88,7 +86,8 @@ final class TimelinePollCoordinator: Coordinator, Presentable, PollAggregatorDel
}
func toPresentable() -> UIViewController {
return VectorHostingController(rootView: TimelinePollView(viewModel: viewModel.context))
return VectorHostingController(rootView: TimelinePollView(viewModel: viewModel.context),
forceZeroSafeAreaInsets: true)
}
func canEndPoll() -> Bool {
@@ -16,7 +16,6 @@
import Foundation
@available(iOS 14, *)
class TimelinePollProvider {
static let shared = TimelinePollProvider()
@@ -17,18 +17,7 @@
import XCTest
import RiotSwiftUI
@available(iOS 14.0, *)
class TimelinePollUITests: XCTestCase {
private var app: XCUIApplication!
override func setUp() {
continueAfterFailure = false
app = XCUIApplication()
app.launch()
}
class TimelinePollUITests: MockScreenTestCase {
func testOpenDisclosedPoll() {
app.goToScreenWithIdentifier(MockTimelinePollScreenState.openDisclosed.title)
@@ -19,7 +19,6 @@ import Combine
@testable import RiotSwiftUI
@available(iOS 14.0, *)
class TimelinePollViewModelTests: XCTestCase {
var viewModel: TimelinePollViewModel!
var context: TimelinePollViewModelType.Context!
@@ -17,7 +17,6 @@
import Foundation
import SwiftUI
@available(iOS 14.0, *)
enum MockTimelinePollScreenState: MockScreenState, CaseIterable {
case openDisclosed
case closedDisclosed
@@ -1,6 +1,5 @@
//
// Copyright 2021 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.
@@ -18,11 +17,9 @@
import SwiftUI
import Combine
@available(iOS 14, *)
typealias TimelinePollViewModelType = StateStoreViewModel<TimelinePollViewState,
Never,
TimelinePollViewAction>
@available(iOS 14, *)
class TimelinePollViewModel: TimelinePollViewModelType, TimelinePollViewModelProtocol {
// MARK: - Properties
@@ -17,7 +17,6 @@
import Foundation
protocol TimelinePollViewModelProtocol {
@available(iOS 14, *)
var context: TimelinePollViewModelType.Context { get }
var completion: ((TimelinePollViewModelResult) -> Void)? { get set }
@@ -16,7 +16,6 @@
import SwiftUI
@available(iOS 14.0, *)
struct TimelinePollAnswerOptionButton: View {
// MARK: - Properties
@@ -90,14 +89,13 @@ struct TimelinePollAnswerOptionButton: View {
var progressViewAccentColor: Color {
guard !poll.closed else {
return (answerOption.winner ? theme.colors.accent : theme.colors.quarterlyContent)
return (answerOption.winner ? theme.colors.accent : theme.colors.quaternaryContent)
}
return answerOption.selected ? theme.colors.accent : theme.colors.quarterlyContent
return answerOption.selected ? theme.colors.accent : theme.colors.quaternaryContent
}
}
@available(iOS 14.0, *)
struct TimelinePollAnswerOptionButton_Previews: PreviewProvider {
static let stateRenderer = MockTimelinePollScreenState.stateRenderer
@@ -16,7 +16,6 @@
import SwiftUI
@available(iOS 14.0, *)
struct TimelinePollView: View {
// MARK: - Properties
@@ -94,7 +93,6 @@ struct TimelinePollView: View {
// MARK: - Previews
@available(iOS 14.0, *)
struct TimelinePollView_Previews: PreviewProvider {
static let stateRenderer = MockTimelinePollScreenState.stateRenderer
static var previews: some View {
@@ -18,7 +18,6 @@ import Foundation
import UIKit
import SwiftUI
@available(iOS 14.0, *)
protocol UserSuggestionCoordinatorDelegate: AnyObject {
func userSuggestionCoordinator(_ coordinator: UserSuggestionCoordinator, didRequestMentionForMember member: MXRoomMember, textTrigger: String?)
}
@@ -28,7 +27,6 @@ struct UserSuggestionCoordinatorParameters {
let room: MXRoom
}
@available(iOS 14.0, *)
final class UserSuggestionCoordinator: Coordinator, Presentable {
// MARK: - Properties
@@ -52,7 +50,6 @@ final class UserSuggestionCoordinator: Coordinator, Presentable {
// MARK: - Setup
@available(iOS 14.0, *)
init(parameters: UserSuggestionCoordinatorParameters) {
self.parameters = parameters
@@ -25,7 +25,6 @@ protocol UserSuggestionCoordinatorBridgeDelegate: AnyObject {
final class UserSuggestionCoordinatorBridge: NSObject {
private var _userSuggestionCoordinator: Any? = nil
@available(iOS 14.0, *)
fileprivate var userSuggestionCoordinator: UserSuggestionCoordinator {
return _userSuggestionCoordinator as! UserSuggestionCoordinator
}
@@ -34,34 +33,23 @@ final class UserSuggestionCoordinatorBridge: NSObject {
init(mediaManager: MXMediaManager, room: MXRoom) {
let parameters = UserSuggestionCoordinatorParameters(mediaManager: mediaManager, room: room)
if #available(iOS 14.0, *) {
let userSuggestionCoordinator = UserSuggestionCoordinator(parameters: parameters)
self._userSuggestionCoordinator = userSuggestionCoordinator
}
let userSuggestionCoordinator = UserSuggestionCoordinator(parameters: parameters)
self._userSuggestionCoordinator = userSuggestionCoordinator
super.init()
if #available(iOS 14.0, *) {
userSuggestionCoordinator.delegate = self
}
userSuggestionCoordinator.delegate = self
}
func processTextMessage(_ textMessage: String) {
if #available(iOS 14.0, *) {
return self.userSuggestionCoordinator.processTextMessage(textMessage)
}
return self.userSuggestionCoordinator.processTextMessage(textMessage)
}
func toPresentable() -> UIViewController? {
if #available(iOS 14.0, *) {
return self.userSuggestionCoordinator.toPresentable()
}
return nil
return self.userSuggestionCoordinator.toPresentable()
}
}
@available(iOS 14.0, *)
extension UserSuggestionCoordinatorBridge: UserSuggestionCoordinatorDelegate {
func userSuggestionCoordinator(_ coordinator: UserSuggestionCoordinator, didRequestMentionForMember member: MXRoomMember, textTrigger: String?) {
delegate?.userSuggestionCoordinatorBridge(self, didRequestMentionForMember: member, textTrigger: textTrigger)
@@ -33,7 +33,6 @@ struct UserSuggestionServiceItem: UserSuggestionItemProtocol {
let avatarUrl: String?
}
@available(iOS 14.0, *)
class UserSuggestionService: UserSuggestionServiceProtocol {
// MARK: - Properties
@@ -23,7 +23,6 @@ protocol UserSuggestionItemProtocol: Avatarable {
var avatarUrl: String? { get }
}
@available(iOS 14.0, *)
protocol UserSuggestionServiceProtocol {
var items: CurrentValueSubject<[UserSuggestionItemProtocol], Never> { get }
@@ -17,19 +17,11 @@
import XCTest
import RiotSwiftUI
@available(iOS 14.0, *)
class UserSuggestionUITests: MockScreenTest {
override class var screenType: MockScreenState.Type {
return MockUserSuggestionScreenState.self
}
override class func createTest() -> MockScreenTest {
return UserSuggestionUITests(selector: #selector(verifyUserSuggestionScreen))
}
func verifyUserSuggestionScreen() throws {
XCTAssert(app.tables.firstMatch.exists)
class UserSuggestionUITests: MockScreenTestCase {
func testUserSuggestionScreen() throws {
app.goToScreenWithIdentifier(MockUserSuggestionScreenState.multipleResults.title)
XCTAssert(app.tables.firstMatch.waitForExistence(timeout: 1))
let firstButton = app.tables.firstMatch.buttons.firstMatch
_ = firstButton.waitForExistence(timeout: 10)
@@ -19,7 +19,6 @@ import Combine
@testable import RiotSwiftUI
@available(iOS 14.0, *)
class UserSuggestionServiceTests: XCTestCase {
var service: UserSuggestionService?
@@ -106,7 +105,6 @@ class UserSuggestionServiceTests: XCTestCase {
}
}
@available(iOS 14.0, *)
extension UserSuggestionServiceTests: RoomMembersProviderProtocol {
func fetchMembers(_ members: @escaping ([RoomMembersProviderMember]) -> Void) {
@@ -17,7 +17,6 @@
import Foundation
import SwiftUI
@available(iOS 14.0, *)
enum MockUserSuggestionScreenState: MockScreenState, CaseIterable {
case multipleResults
@@ -43,7 +42,6 @@ enum MockUserSuggestionScreenState: MockScreenState, CaseIterable {
}
}
@available(iOS 14.0, *)
extension MockUserSuggestionScreenState: RoomMembersProviderProtocol {
func fetchMembers(_ members: ([RoomMembersProviderMember]) -> Void) {
if Self.members == nil {
@@ -17,12 +17,10 @@
import SwiftUI
import Combine
@available(iOS 14.0, *)
typealias UserSuggestionViewModelType = StateStoreViewModel <UserSuggestionViewState,
Never,
UserSuggestionViewAction>
@available(iOS 14.0, *)
class UserSuggestionViewModel: UserSuggestionViewModelType, UserSuggestionViewModelProtocol {
// MARK: - Properties
@@ -16,7 +16,6 @@
import SwiftUI
@available(iOS 14.0, *)
struct UserSuggestionList: View {
private struct Constants {
static let topPadding: CGFloat = 8.0
@@ -76,7 +75,6 @@ struct UserSuggestionList: View {
}
}
@available(iOS 14.0, *)
private struct BackgroundView<Content: View>: View {
var content: () -> Content
@@ -100,7 +98,6 @@ private struct BackgroundView<Content: View>: View {
// MARK: - Previews
@available(iOS 14.0, *)
struct UserSuggestion_Previews: PreviewProvider {
static let stateRenderer = MockUserSuggestionScreenState.stateRenderer
static var previews: some View {
@@ -16,7 +16,6 @@
import SwiftUI
@available(iOS 14.0, *)
struct UserSuggestionListItem: View {
// MARK: - Properties
@@ -52,7 +51,6 @@ struct UserSuggestionListItem: View {
// MARK: - Previews
@available(iOS 14.0, *)
struct UserSuggestionHeader_Previews: PreviewProvider {
static var previews: some View {
UserSuggestionListItem(avatar: MockAvatarInput.example, displayName: "Alice", userId: "@alice:matrix.org")

Some files were not shown because too many files have changed in this diff Show More