diff --git a/ElementX.xcodeproj/project.pbxproj b/ElementX.xcodeproj/project.pbxproj index ba2f03758..74a4d71d8 100644 --- a/ElementX.xcodeproj/project.pbxproj +++ b/ElementX.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 54; + objectVersion = 63; objects = { /* Begin PBXAggregateTarget section */ @@ -876,6 +876,7 @@ A6FFC4C5154C446BAD6B40D8 /* TimelineItemProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8520AFD6680CBAD388F6D927 /* TimelineItemProvider.swift */; }; A722F426FD81FC67706BB1E0 /* CustomLayoutLabelStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42236480CF0431535EBE8387 /* CustomLayoutLabelStyle.swift */; }; A74438ED16F8683A4B793E6A /* AnalyticsSettingsScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0BCE3FAF40932AC7C7639AC4 /* AnalyticsSettingsScreenViewModel.swift */; }; + A7CA45942DEF306400300A02 /* Highlight.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7CA45932DEF306200300A02 /* Highlight.swift */; }; A7D48E44D485B143AADDB77D /* Strings+Untranslated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A18F6CE4D694D21E4EA9B25 /* Strings+Untranslated.swift */; }; A808DC3F72D15C6C5A52317E /* TimelineItemDebugView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BCDA016D05107DED3B9495CB /* TimelineItemDebugView.swift */; }; A816F7087C495D85048AC50E /* RoomMemberDetailsScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B6E30BB748F3F480F077969 /* RoomMemberDetailsScreenModels.swift */; }; @@ -1396,7 +1397,7 @@ 044E501B8331B339874D1B96 /* CompoundIcon.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CompoundIcon.swift; sourceTree = ""; }; 045253F9967A535EE5B16691 /* Label.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Label.swift; sourceTree = ""; }; 046C0D3F53B0B5EF0A1F5BEA /* RoomSummaryTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomSummaryTests.swift; sourceTree = ""; }; - 048A21188AB19349D026BECD /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; path = PrivacyInfo.xcprivacy; sourceTree = ""; }; + 048A21188AB19349D026BECD /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = PrivacyInfo.xcprivacy; sourceTree = ""; }; 04BB8DDE245ED86C489BA983 /* AccessibilityIdentifiers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccessibilityIdentifiers.swift; sourceTree = ""; }; 04DF593C3F7AF4B2FBAEB05D /* FileManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileManager.swift; sourceTree = ""; }; 0516C69708D5CBDE1A8E77EC /* RoomDirectorySearchProxyProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomDirectorySearchProxyProtocol.swift; sourceTree = ""; }; @@ -1470,7 +1471,7 @@ 128501375217576AF0FE3E92 /* RoomAttachmentPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomAttachmentPicker.swift; sourceTree = ""; }; 12B09A94C519227264A41208 /* RoomMembershipDetailsProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMembershipDetailsProxy.swift; sourceTree = ""; }; 12FD5280AF55AB7F50F8E47D /* preview_avatar_room.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = preview_avatar_room.jpg; sourceTree = ""; }; - 1304D9191300873EADA52D6E /* IntegrationTests.xctestplan */ = {isa = PBXFileReference; path = IntegrationTests.xctestplan; sourceTree = ""; }; + 1304D9191300873EADA52D6E /* IntegrationTests.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = IntegrationTests.xctestplan; sourceTree = ""; }; 130ED565A078F7E0B59D9D25 /* UNTextInputNotificationResponse+Creator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UNTextInputNotificationResponse+Creator.swift"; sourceTree = ""; }; 136F80A613B55BDD071DCEA5 /* JoinRoomScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JoinRoomScreenModels.swift; sourceTree = ""; }; 13802897C7AFA360EA74C0B0 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = en; path = en.lproj/Localizable.stringsdict; sourceTree = ""; }; @@ -1572,7 +1573,7 @@ 25F7FE40EF7490A7E09D7BE6 /* NotificationItemProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationItemProxy.swift; sourceTree = ""; }; 25F8664F1FB95AF3C4202478 /* PollFormScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PollFormScreenCoordinator.swift; sourceTree = ""; }; 260004737C573A56FA01E86E /* Encodable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Encodable.swift; sourceTree = ""; }; - 267BB1D5B08A9511F894CB57 /* PreviewTests.xctestplan */ = {isa = PBXFileReference; path = PreviewTests.xctestplan; sourceTree = ""; }; + 267BB1D5B08A9511F894CB57 /* PreviewTests.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = PreviewTests.xctestplan; sourceTree = ""; }; 26B0A96B8FE4849227945067 /* VoiceMessageRecorder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VoiceMessageRecorder.swift; sourceTree = ""; }; 26EAAB54C6CE91D64B69A9F8 /* AppLockServiceProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppLockServiceProtocol.swift; sourceTree = ""; }; 2711E5996016ABD6EAAEB58A /* LogLevel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogLevel.swift; sourceTree = ""; }; @@ -1648,7 +1649,7 @@ 3558A15CFB934F9229301527 /* RestorationToken.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RestorationToken.swift; sourceTree = ""; }; 35AFCF4C05DEED04E3DB1A16 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Localizable.strings; sourceTree = ""; }; 35FA991289149D31F4286747 /* UserPreference.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserPreference.swift; sourceTree = ""; }; - 36DA824791172B9821EACBED /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; path = PrivacyInfo.xcprivacy; sourceTree = ""; }; + 36DA824791172B9821EACBED /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = PrivacyInfo.xcprivacy; sourceTree = ""; }; 36FD673E24FBFCFDF398716A /* RoomMemberProxyMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMemberProxyMock.swift; sourceTree = ""; }; 37A63A59BFDDC494B1C20119 /* CallScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CallScreenViewModel.swift; sourceTree = ""; }; 37CA26F55123E36B50DB0B3A /* AttributedStringTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttributedStringTests.swift; sourceTree = ""; }; @@ -2063,7 +2064,7 @@ 8D55702474F279D910D2D162 /* RoomStateEventStringBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomStateEventStringBuilder.swift; sourceTree = ""; }; 8D8169443E5AC5FF71BFB3DB /* cs */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = cs; path = cs.lproj/Localizable.strings; sourceTree = ""; }; 8DA1E8F287680C8ED25EDBAC /* NetworkMonitorMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkMonitorMock.swift; sourceTree = ""; }; - 8E088F2A1B9EC529D3221931 /* UITests.xctestplan */ = {isa = PBXFileReference; path = UITests.xctestplan; sourceTree = ""; }; + 8E088F2A1B9EC529D3221931 /* UITests.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = UITests.xctestplan; sourceTree = ""; }; 8E1584F8BCF407BB94F48F04 /* EncryptionResetPasswordScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EncryptionResetPasswordScreen.swift; sourceTree = ""; }; 8EAF4A49F3ACD8BB8B0D2371 /* ClientSDKMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClientSDKMock.swift; sourceTree = ""; }; 8F062DD2CCD95DC33528A16F /* KnockRequestProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KnockRequestProxy.swift; sourceTree = ""; }; @@ -2184,6 +2185,7 @@ A7978C9EFBDD7DE39BD86726 /* RestorationTokenTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RestorationTokenTests.swift; sourceTree = ""; }; A7A1B80FE6E3BA72F9C748AD /* AdvancedSettingsScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdvancedSettingsScreenViewModel.swift; sourceTree = ""; }; A7C4EA55DA62F9D0F984A2AE /* CollapsibleTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollapsibleTimelineItem.swift; sourceTree = ""; }; + A7CA45932DEF306200300A02 /* Highlight.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Highlight.swift; sourceTree = ""; }; A7D452AF7B5F7E3A0A7DB54C /* SessionVerificationScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionVerificationScreenViewModelProtocol.swift; sourceTree = ""; }; A7E37072597F67C4DD8CC2DB /* ComposerDraftServiceProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposerDraftServiceProtocol.swift; sourceTree = ""; }; A84D413BF49F0E980F010A6B /* LogViewerScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogViewerScreenCoordinator.swift; sourceTree = ""; }; @@ -2269,7 +2271,7 @@ B53AC78E49A297AC1D72A7CF /* AppMediator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppMediator.swift; sourceTree = ""; }; B590BD4507D4F0A377FDE01A /* LoadableAvatarImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoadableAvatarImage.swift; sourceTree = ""; }; B5D829FD8958376614504B18 /* TargetConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TargetConfiguration.swift; sourceTree = ""; }; - B61C339A2FDDBD067FF6635C /* ConfettiScene.scn */ = {isa = PBXFileReference; path = ConfettiScene.scn; sourceTree = ""; }; + B61C339A2FDDBD067FF6635C /* ConfettiScene.scn */ = {isa = PBXFileReference; lastKnownFileType = file.bplist; path = ConfettiScene.scn; sourceTree = ""; }; B6404166CBF5CC88673FF9E2 /* RoomDetails.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomDetails.swift; sourceTree = ""; }; B655A536341D2695158C6664 /* AuthenticationClientBuilderFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthenticationClientBuilderFactory.swift; sourceTree = ""; }; B65DDCF8E41759890355ACBC /* AuthenticationStartScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthenticationStartScreenViewModelProtocol.swift; sourceTree = ""; }; @@ -2297,7 +2299,7 @@ BA40B98B098B6F0371B750B3 /* TemplateScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemplateScreenModels.swift; sourceTree = ""; }; BA919F521E9F0EE3638AFC85 /* BugReportScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BugReportScreen.swift; sourceTree = ""; }; BB284643AF7AB131E307DCE0 /* AudioSessionProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioSessionProtocol.swift; sourceTree = ""; }; - BB576F4118C35E6B5124FA22 /* test_apple_image.heic */ = {isa = PBXFileReference; path = test_apple_image.heic; sourceTree = ""; }; + BB576F4118C35E6B5124FA22 /* test_apple_image.heic */ = {isa = PBXFileReference; lastKnownFileType = file; path = test_apple_image.heic; sourceTree = ""; }; BB5B00A014307CE37B2812CD /* TimelineViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineViewModelProtocol.swift; sourceTree = ""; }; BB6ED50FE104992419310EEB /* NotificationHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationHandler.swift; sourceTree = ""; }; BB8BC4C791D0E88CFCF4E5DF /* ServerSelectionScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerSelectionScreenCoordinator.swift; sourceTree = ""; }; @@ -2396,7 +2398,7 @@ CDB3227C7A74B734924942E9 /* RoomSummaryProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomSummaryProvider.swift; sourceTree = ""; }; CDE3F3911FF7CC639BDE5844 /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/Localizable.strings; sourceTree = ""; }; CEE20623EB4A9B88FB29F2BA /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/SAS.strings; sourceTree = ""; }; - CEE41494C837AA403A06A5D9 /* UnitTests.xctestplan */ = {isa = PBXFileReference; path = UnitTests.xctestplan; sourceTree = ""; }; + CEE41494C837AA403A06A5D9 /* UnitTests.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = UnitTests.xctestplan; sourceTree = ""; }; D01FD1171FF40E34D707FD00 /* BigIcon.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BigIcon.swift; sourceTree = ""; }; D03D7ECAC68C2FFB8CF01BCB /* DeactivateAccountScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeactivateAccountScreen.swift; sourceTree = ""; }; D046ABB22E680F7C5054441B /* SecurityAndPrivacyScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecurityAndPrivacyScreenViewModelProtocol.swift; sourceTree = ""; }; @@ -2459,7 +2461,7 @@ DC0AEA686E425F86F6BA0404 /* UNNotification+Creator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UNNotification+Creator.swift"; sourceTree = ""; }; DC10CCC8D68B863E20660DBC /* MessageForwardingScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageForwardingScreenViewModelProtocol.swift; sourceTree = ""; }; DC528B3764E3CF7FCFEF40E7 /* PollInteractionHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PollInteractionHandler.swift; sourceTree = ""; }; - DCA2D836BD10303F37FAAEED /* test_voice_message.m4a */ = {isa = PBXFileReference; path = test_voice_message.m4a; sourceTree = ""; }; + DCA2D836BD10303F37FAAEED /* test_voice_message.m4a */ = {isa = PBXFileReference; lastKnownFileType = file; path = test_voice_message.m4a; sourceTree = ""; }; DCAC01A97A43BE07B9E94E43 /* ShareExtensionModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareExtensionModels.swift; sourceTree = ""; }; DCDAB580109C09A6AA97AF7E /* PollFormScreenTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PollFormScreenTests.swift; sourceTree = ""; }; DCF239C619971FDE48132550 /* SecureBackupLogoutConfirmationScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecureBackupLogoutConfirmationScreenModels.swift; sourceTree = ""; }; @@ -2500,7 +2502,7 @@ E5272BC4A60B6AD7553BACA1 /* BlurHashDecode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlurHashDecode.swift; sourceTree = ""; }; E53BFB7E4F329621C844E8C3 /* AnalyticsPromptScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnalyticsPromptScreen.swift; sourceTree = ""; }; E55B5EA766E89FF1F87C3ACB /* RoomNotificationSettingsProxyProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomNotificationSettingsProxyProtocol.swift; sourceTree = ""; }; - E5E7D4EE7CA295E5039FDA21 /* portrait_test_video.mp4 */ = {isa = PBXFileReference; path = portrait_test_video.mp4; sourceTree = ""; }; + E5E7D4EE7CA295E5039FDA21 /* portrait_test_video.mp4 */ = {isa = PBXFileReference; lastKnownFileType = file; path = portrait_test_video.mp4; sourceTree = ""; }; E5E94DCFEE803E5ABAE8ACCE /* KeychainControllerProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeychainControllerProtocol.swift; sourceTree = ""; }; E5F2B6443D1ED8602F328539 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = ru; path = ru.lproj/Localizable.stringsdict; sourceTree = ""; }; E5FDFAA04174CC99FB66391C /* EditRoomAddressScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditRoomAddressScreenViewModel.swift; sourceTree = ""; }; @@ -2542,7 +2544,7 @@ ED0CBEAB5F796BEFBAF7BB6A /* VideoRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoRoomTimelineView.swift; sourceTree = ""; }; ED1D792EB82506A19A72C8DE /* RoomTimelineItemProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomTimelineItemProtocol.swift; sourceTree = ""; }; ED33988DA4FD4FC666800106 /* SessionVerificationScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionVerificationScreenViewModel.swift; sourceTree = ""; }; - ED482057AE39D5C6D9C5F3D8 /* message.caf */ = {isa = PBXFileReference; path = message.caf; sourceTree = ""; }; + ED482057AE39D5C6D9C5F3D8 /* message.caf */ = {isa = PBXFileReference; lastKnownFileType = file; path = message.caf; sourceTree = ""; }; ED49073BB1C1FC649DAC2CCD /* LocationRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationRoomTimelineView.swift; sourceTree = ""; }; ED60E4D2CD678E1EBF16F77A /* BlockedUsersScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlockedUsersScreen.swift; sourceTree = ""; }; EE378083653EF0C9B5E9D580 /* EmoteRoomTimelineItemContent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmoteRoomTimelineItemContent.swift; sourceTree = ""; }; @@ -3327,6 +3329,7 @@ 328DD5DA1281F758B72006C7 /* Views */ = { isa = PBXGroup; children = ( + A7CA45932DEF306200300A02 /* Highlight.swift */, 8F21ED7205048668BEB44A38 /* AppActivityView.swift */, CC743C7A85E3171BCBF0A653 /* AvatarHeaderView.swift */, 9A028783CFFF861C5E44FFB1 /* BadgeLabel.swift */, @@ -6471,7 +6474,6 @@ EC6D0C817B1C21D9D096505A /* XCRemoteSwiftPackageReference "Version" */, EE40B0E16A55BD23ECBFFD22 /* XCRemoteSwiftPackageReference "matrix-rich-text-editor-swift" */, ); - preferredProjectObjectVersion = 54; projectDirPath = ""; projectRoot = ""; targets = ( @@ -7635,6 +7637,7 @@ FA71CD334F2D2289BEF0D749 /* SecureBackupRecoveryKeyScreen.swift in Sources */, B1387648C6F71F1B98244803 /* SecureBackupRecoveryKeyScreenCoordinator.swift in Sources */, 8AA84EF202F2EFC8453A97BD /* SecureBackupRecoveryKeyScreenModels.swift in Sources */, + A7CA45942DEF306400300A02 /* Highlight.swift in Sources */, 27F015B0D5436633B5B3C8C3 /* SecureBackupRecoveryKeyScreenViewModel.swift in Sources */, F0570F1ECD70C4C851FB2052 /* SecureBackupRecoveryKeyScreenViewModelProtocol.swift in Sources */, E84ADFE9696936C18C2424B5 /* SecureBackupScreen.swift in Sources */, @@ -8128,9 +8131,7 @@ "@executable_path/../../Frameworks", ); MARKETING_VERSION = "$(MARKETING_VERSION)"; - OTHER_SWIFT_FLAGS = ( - "-DIS_NSE", - ); + OTHER_SWIFT_FLAGS = "-DIS_NSE"; PRODUCT_BUNDLE_IDENTIFIER = "${BASE_BUNDLE_IDENTIFIER}.nse"; PRODUCT_DISPLAY_NAME = "$(APP_DISPLAY_NAME)"; PRODUCT_NAME = NSE; @@ -8179,9 +8180,7 @@ "@executable_path/Frameworks", ); MARKETING_VERSION = "$(MARKETING_VERSION)"; - OTHER_SWIFT_FLAGS = ( - "-DIS_MAIN_APP", - ); + OTHER_SWIFT_FLAGS = "-DIS_MAIN_APP"; PILLS_UT_TYPE_IDENTIFIER = "$(BASE_BUNDLE_IDENTIFIER).pills"; PRODUCT_BUNDLE_IDENTIFIER = "$(BASE_BUNDLE_IDENTIFIER)"; PRODUCT_NAME = "$(APP_NAME)"; @@ -8207,9 +8206,7 @@ "@executable_path/Frameworks", ); MARKETING_VERSION = "$(MARKETING_VERSION)"; - OTHER_SWIFT_FLAGS = ( - "-DIS_MAIN_APP", - ); + OTHER_SWIFT_FLAGS = "-DIS_MAIN_APP"; PILLS_UT_TYPE_IDENTIFIER = "$(BASE_BUNDLE_IDENTIFIER).pills"; PRODUCT_BUNDLE_IDENTIFIER = "$(BASE_BUNDLE_IDENTIFIER)"; PRODUCT_NAME = "$(APP_NAME)"; @@ -8434,9 +8431,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - OTHER_SWIFT_FLAGS = ( - "-DDEBUG", - ); + OTHER_SWIFT_FLAGS = "-DDEBUG"; PRODUCT_BUNDLE_IDENTIFIER = "${BASE_BUNDLE_IDENTIFIER}.ui.tests"; PRODUCT_NAME = UITests; SDKROOT = iphoneos; @@ -8455,9 +8450,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - OTHER_SWIFT_FLAGS = ( - "-DRELEASE", - ); + OTHER_SWIFT_FLAGS = "-DRELEASE"; PRODUCT_BUNDLE_IDENTIFIER = "${BASE_BUNDLE_IDENTIFIER}.ui.tests"; PRODUCT_NAME = UITests; SDKROOT = iphoneos; @@ -8479,9 +8472,7 @@ "@executable_path/../../Frameworks", ); MARKETING_VERSION = "$(MARKETING_VERSION)"; - OTHER_SWIFT_FLAGS = ( - "-DIS_NSE", - ); + OTHER_SWIFT_FLAGS = "-DIS_NSE"; PRODUCT_BUNDLE_IDENTIFIER = "${BASE_BUNDLE_IDENTIFIER}.nse"; PRODUCT_DISPLAY_NAME = "$(APP_DISPLAY_NAME)"; PRODUCT_NAME = NSE; diff --git a/ElementX/Resources/Localizations/en.lproj/Localizable.strings b/ElementX/Resources/Localizations/en.lproj/Localizable.strings index a4768a07f..0e8c40dd8 100644 --- a/ElementX/Resources/Localizations/en.lproj/Localizable.strings +++ b/ElementX/Resources/Localizations/en.lproj/Localizable.strings @@ -515,6 +515,11 @@ "screen_room_details_pinned_events_row_title" = "Pinned messages"; "screen_room_details_profile_row_title" = "Profile"; "screen_room_details_requests_to_join_title" = "Requests to join"; +"screen_room_timeline_tombstoned_room_action" = "Jump to new room"; +"screen_room_timeline_tombstoned_room_message" = "This room has been replaced and is no longer active"; +"screen_room_timeline_upgraded_room_action" = "See old messages"; +"screen_room_timeline_upgraded_room_message" = "This room is a continuation of another room"; +"screen_roomlist_tombstoned_room_description" = "This room has been upgraded"; "screen_security_and_privacy_add_room_address_action" = "Add room address"; "screen_security_and_privacy_ask_to_join_option_description" = "Anyone can ask to join the room but an administrator or moderator will have to accept the request."; "screen_security_and_privacy_enable_encryption_alert_confirm_button_title" = "Yes, enable encryption"; diff --git a/ElementX/Sources/FlowCoordinators/RoomFlowCoordinator.swift b/ElementX/Sources/FlowCoordinators/RoomFlowCoordinator.swift index 00b79f1bf..b27997911 100644 --- a/ElementX/Sources/FlowCoordinators/RoomFlowCoordinator.swift +++ b/ElementX/Sources/FlowCoordinators/RoomFlowCoordinator.swift @@ -549,6 +549,8 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol { stateMachine.tryEvent(.presentKnockRequestsListScreen) case .presentThread(let itemID): stateMachine.tryEvent(.presentThread(itemID: itemID)) + case .presentRoom(roomID: let roomID): + stateMachine.tryEvent(.startChildFlow(roomID: roomID, via: [], entryPoint: .room)) } } .store(in: &cancellables) diff --git a/ElementX/Sources/Generated/Strings.swift b/ElementX/Sources/Generated/Strings.swift index 25a380d13..2ad557839 100644 --- a/ElementX/Sources/Generated/Strings.swift +++ b/ElementX/Sources/Generated/Strings.swift @@ -2312,6 +2312,14 @@ internal enum L10n { internal static func screenRoomTimelineStateChanges(_ p1: Int) -> String { return L10n.tr("Localizable", "screen_room_timeline_state_changes", p1) } + /// Jump to new room + internal static var screenRoomTimelineTombstonedRoomAction: String { return L10n.tr("Localizable", "screen_room_timeline_tombstoned_room_action") } + /// This room has been replaced and is no longer active + internal static var screenRoomTimelineTombstonedRoomMessage: String { return L10n.tr("Localizable", "screen_room_timeline_tombstoned_room_message") } + /// See old messages + internal static var screenRoomTimelineUpgradedRoomAction: String { return L10n.tr("Localizable", "screen_room_timeline_upgraded_room_action") } + /// This room is a continuation of another room + internal static var screenRoomTimelineUpgradedRoomMessage: String { return L10n.tr("Localizable", "screen_room_timeline_upgraded_room_message") } /// Chat internal static var screenRoomTitle: String { return L10n.tr("Localizable", "screen_room_title") } /// Plural format key: "%#@COUNT@" @@ -2380,6 +2388,8 @@ internal enum L10n { internal static var screenRoomlistMarkAsRead: String { return L10n.tr("Localizable", "screen_roomlist_mark_as_read") } /// Mark as unread internal static var screenRoomlistMarkAsUnread: String { return L10n.tr("Localizable", "screen_roomlist_mark_as_unread") } + /// This room has been upgraded + internal static var screenRoomlistTombstonedRoomDescription: String { return L10n.tr("Localizable", "screen_roomlist_tombstoned_room_description") } /// Add room address internal static var screenSecurityAndPrivacyAddRoomAddressAction: String { return L10n.tr("Localizable", "screen_security_and_privacy_add_room_address_action") } /// Anyone can ask to join the room but an administrator or moderator will have to accept the request. diff --git a/ElementX/Sources/Mocks/Generated/GeneratedMocks.swift b/ElementX/Sources/Mocks/Generated/GeneratedMocks.swift index a7b0738fc..1c04daed1 100644 --- a/ElementX/Sources/Mocks/Generated/GeneratedMocks.swift +++ b/ElementX/Sources/Mocks/Generated/GeneratedMocks.swift @@ -6484,6 +6484,7 @@ class JoinedRoomProxyMock: JoinedRoomProxyProtocol, @unchecked Sendable { set(value) { underlyingTimeline = value } } var underlyingTimeline: TimelineProxyProtocol! + var predecessorRoom: PredecessorRoom? var id: String { get { return underlyingId } set(value) { underlyingId = value } diff --git a/ElementX/Sources/Mocks/JoinedRoomProxyMock.swift b/ElementX/Sources/Mocks/JoinedRoomProxyMock.swift index 40423cd2e..49ee14d75 100644 --- a/ElementX/Sources/Mocks/JoinedRoomProxyMock.swift +++ b/ElementX/Sources/Mocks/JoinedRoomProxyMock.swift @@ -48,6 +48,8 @@ struct JoinedRoomProxyMockConfiguration { var membership: Membership = .joined var isVisibleInPublicDirectory = false + var predecessor: PredecessorRoom? + var successor: SuccessorRoom? } extension JoinedRoomProxyMock { @@ -137,6 +139,8 @@ extension JoinedRoomProxyMock { clearDraftReturnValue = .success(()) sendTypingNotificationIsTypingReturnValue = .success(()) isVisibleInRoomDirectoryReturnValue = .success(configuration.isVisibleInPublicDirectory) + + predecessorRoom = configuration.predecessor } } @@ -152,7 +156,7 @@ extension RoomInfo { isDirect: configuration.isDirect, isPublic: configuration.isPublic, isSpace: configuration.isSpace, - successorRoom: nil, + successorRoom: configuration.successor, isFavourite: false, canonicalAlias: configuration.canonicalAlias, alternativeAliases: configuration.alternativeAliases, diff --git a/ElementX/Sources/Mocks/RoomSummaryProviderMock.swift b/ElementX/Sources/Mocks/RoomSummaryProviderMock.swift index a41b5d316..b5b79f14f 100644 --- a/ElementX/Sources/Mocks/RoomSummaryProviderMock.swift +++ b/ElementX/Sources/Mocks/RoomSummaryProviderMock.swift @@ -89,7 +89,8 @@ extension RoomSummary { alternativeAliases: [], hasOngoingCall: false, isMarkedUnread: false, - isFavourite: false) + isFavourite: false, + isTombstoned: false) } } @@ -113,7 +114,8 @@ extension Array where Element == RoomSummary { alternativeAliases: [], hasOngoingCall: false, isMarkedUnread: false, - isFavourite: false), + isFavourite: false, + isTombstoned: false), RoomSummary(room: RoomSDKMock(), id: "2", joinRequestType: nil, @@ -132,7 +134,8 @@ extension Array where Element == RoomSummary { alternativeAliases: [], hasOngoingCall: false, isMarkedUnread: false, - isFavourite: false), + isFavourite: false, + isTombstoned: false), RoomSummary(room: RoomSDKMock(), id: "3", joinRequestType: nil, @@ -151,7 +154,8 @@ extension Array where Element == RoomSummary { alternativeAliases: [], hasOngoingCall: false, isMarkedUnread: false, - isFavourite: false), + isFavourite: false, + isTombstoned: false), RoomSummary(room: RoomSDKMock(), id: "4", joinRequestType: nil, @@ -170,7 +174,8 @@ extension Array where Element == RoomSummary { alternativeAliases: [], hasOngoingCall: false, isMarkedUnread: false, - isFavourite: false), + isFavourite: false, + isTombstoned: false), RoomSummary(room: RoomSDKMock(), id: "5", joinRequestType: nil, @@ -189,7 +194,8 @@ extension Array where Element == RoomSummary { alternativeAliases: [], hasOngoingCall: true, isMarkedUnread: false, - isFavourite: false), + isFavourite: false, + isTombstoned: false), RoomSummary(room: RoomSDKMock(), id: "6", joinRequestType: nil, @@ -208,7 +214,28 @@ extension Array where Element == RoomSummary { alternativeAliases: [], hasOngoingCall: true, isMarkedUnread: false, - isFavourite: false), + isFavourite: false, + isTombstoned: false), + RoomSummary(room: RoomSDKMock(), + id: "7", + joinRequestType: nil, + name: "Tombstoned", + isDirect: false, + avatarURL: nil, + heroes: [], + activeMembersCount: 0, + lastMessage: nil, + lastMessageDate: .mock, + unreadMessagesCount: 1, + unreadMentionsCount: 0, + unreadNotificationsCount: 1, + notificationMode: .allMessages, + canonicalAlias: nil, + alternativeAliases: [], + hasOngoingCall: false, + isMarkedUnread: false, + isFavourite: false, + isTombstoned: true), RoomSummary(room: RoomSDKMock(), id: "0", joinRequestType: nil, @@ -227,7 +254,8 @@ extension Array where Element == RoomSummary { alternativeAliases: [], hasOngoingCall: false, isMarkedUnread: false, - isFavourite: false) + isFavourite: false, + isTombstoned: false) ] static let mockRoomsWithNotificationsState: [Element] = { @@ -279,7 +307,8 @@ extension Array where Element == RoomSummary { alternativeAliases: [], hasOngoingCall: false, isMarkedUnread: false, - isFavourite: false), + isFavourite: false, + isTombstoned: false), RoomSummary(room: RoomSDKMock(), id: "someAwesomeRoomId2", joinRequestType: .invite(inviter: RoomMemberProxyMock.mockCharlie), @@ -298,6 +327,7 @@ extension Array where Element == RoomSummary { alternativeAliases: [], hasOngoingCall: false, isMarkedUnread: false, - isFavourite: false) + isFavourite: false, + isTombstoned: false) ] } diff --git a/ElementX/Sources/Other/SwiftUI/Views/Highlight.swift b/ElementX/Sources/Other/SwiftUI/Views/Highlight.swift new file mode 100644 index 000000000..9c1fcbebd --- /dev/null +++ b/ElementX/Sources/Other/SwiftUI/Views/Highlight.swift @@ -0,0 +1,35 @@ +// +// Copyright 2025 New Vector Ltd. +// +// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial +// Please see LICENSE files in the repository root for full details. +// + +import Compound +import SwiftUI + +struct Highlight: ViewModifier { + let borderColor: Color + let primaryColor: Color + let secondaryColor: Color + + func body(content: Content) -> some View { + ZStack(alignment: .top) { + VStack(spacing: 0) { + borderColor + .frame(height: 1) + LinearGradient(colors: [primaryColor, secondaryColor], + startPoint: .top, + endPoint: .bottom) + } + content + .layoutPriority(1) + } + } +} + +extension View { + func highlight(borderColor: Color, primaryColor: Color, secondaryColor: Color) -> some View { + modifier(Highlight(borderColor: borderColor, primaryColor: primaryColor, secondaryColor: secondaryColor)) + } +} diff --git a/ElementX/Sources/Other/SwiftUI/Views/PlaceholderAvatarImage.swift b/ElementX/Sources/Other/SwiftUI/Views/PlaceholderAvatarImage.swift index 9b6a9be13..8816d05b2 100644 --- a/ElementX/Sources/Other/SwiftUI/Views/PlaceholderAvatarImage.swift +++ b/ElementX/Sources/Other/SwiftUI/Views/PlaceholderAvatarImage.swift @@ -12,6 +12,7 @@ struct PlaceholderAvatarImage: View { @Environment(\.redactionReasons) private var redactionReasons private let textForImage: String + /// When `nil` the tombstoned colors will be used private let contentID: String? var body: some View { @@ -22,7 +23,9 @@ struct PlaceholderAvatarImage: View { // This text's frame doesn't look right when redacted if redactionReasons != .placeholder { Text(textForImage) - .foregroundColor(avatarColor?.text ?? .white) + .foregroundColor(avatarColor?.text ?? + // tombstoned room foreground + .compound.iconTertiary) .font(.system(size: geometry.size.width * 0.5625, weight: .semibold)) .minimumScaleFactor(0.001) .frame(alignment: .center) @@ -43,7 +46,9 @@ struct PlaceholderAvatarImage: View { return Color(.systemGray4) // matches the default text redaction } - return avatarColor?.background ?? .compound.iconPrimary + return avatarColor?.background ?? + // tombstoned room background + .compound.bgSubtlePrimary } private var avatarColor: DecorativeColor? { @@ -70,6 +75,10 @@ struct PlaceholderAvatarImage_Previews: PreviewProvider, TestablePreview { .clipShape(Circle()) .frame(width: 150, height: 100) + PlaceholderAvatarImage(name: "!", contentID: nil) + .clipShape(Circle()) + .frame(width: 100, height: 100) + PlaceholderAvatarImage(name: nil, contentID: "@fooserid:matrix.org") .clipShape(Circle()) .frame(width: 30, height: 30) diff --git a/ElementX/Sources/Other/SwiftUI/Views/RoomAvatarImage.swift b/ElementX/Sources/Other/SwiftUI/Views/RoomAvatarImage.swift index 6be9d20df..d60308083 100644 --- a/ElementX/Sources/Other/SwiftUI/Views/RoomAvatarImage.swift +++ b/ElementX/Sources/Other/SwiftUI/Views/RoomAvatarImage.swift @@ -13,13 +13,17 @@ enum RoomAvatar: Equatable { case room(id: String, name: String?, avatarURL: URL?) /// An avatar generated from the room's heroes. case heroes([UserProfileProxy]) + /// A static avatar for a tombstoned room. + case tombstoned var removingAvatar: RoomAvatar { switch self { case let .room(id, name, _): - return .room(id: id, name: name, avatarURL: nil) + .room(id: id, name: name, avatarURL: nil) case let .heroes(users): - return .heroes(users.map { .init(userID: $0.userID, displayName: $0.displayName, avatarURL: nil) }) + .heroes(users.map { .init(userID: $0.userID, displayName: $0.displayName, avatarURL: nil) }) + case .tombstoned: + .tombstoned } } } @@ -91,6 +95,12 @@ struct RoomAvatarImage: View { mediaProvider: mediaProvider, onTap: onAvatarTap) } + case .tombstoned: + LoadableAvatarImage(url: nil, + name: "!", + contentID: nil, avatarSize: avatarSize, + mediaProvider: mediaProvider, + onTap: onAvatarTap) } } } @@ -126,6 +136,8 @@ struct RoomAvatarImage_Previews: PreviewProvider, TestablePreview { .init(userID: "@bob:server.net", displayName: "Bob", avatarURL: nil)]), avatarSize: .room(on: .home), mediaProvider: MediaProviderMock(configuration: .init())) + + RoomAvatarImage(avatar: .tombstoned, avatarSize: .room(on: .home), mediaProvider: MediaProviderMock(configuration: .init())) } } } diff --git a/ElementX/Sources/Screens/HomeScreen/HomeScreenModels.swift b/ElementX/Sources/Screens/HomeScreen/HomeScreenModels.swift index 8af3a70c8..4ad8b6351 100644 --- a/ElementX/Sources/Screens/HomeScreen/HomeScreenModels.swift +++ b/ElementX/Sources/Screens/HomeScreen/HomeScreenModels.swift @@ -197,6 +197,8 @@ struct HomeScreenRoom: Identifiable, Equatable { let canonicalAlias: String? + let isTombstoned: Bool + static func placeholder() -> HomeScreenRoom { HomeScreenRoom(id: UUID().uuidString, roomID: nil, @@ -209,7 +211,8 @@ struct HomeScreenRoom: Identifiable, Equatable { timestamp: "Now", lastMessage: placeholderLastMessage, avatar: .room(id: "", name: "", avatarURL: nil), - canonicalAlias: nil) + canonicalAlias: nil, + isTombstoned: false) } } @@ -246,6 +249,7 @@ extension HomeScreenRoom { timestamp: summary.lastMessageDate?.formattedMinimal(), lastMessage: summary.lastMessage, avatar: summary.avatar, - canonicalAlias: summary.canonicalAlias) + canonicalAlias: summary.canonicalAlias, + isTombstoned: summary.isTombstoned) } } diff --git a/ElementX/Sources/Screens/HomeScreen/View/HomeScreenInviteCell.swift b/ElementX/Sources/Screens/HomeScreen/View/HomeScreenInviteCell.swift index de16ddd1a..2067e1940 100644 --- a/ElementX/Sources/Screens/HomeScreen/View/HomeScreenInviteCell.swift +++ b/ElementX/Sources/Screens/HomeScreen/View/HomeScreenInviteCell.swift @@ -217,7 +217,8 @@ private extension HomeScreenRoom { alternativeAliases: [], hasOngoingCall: false, isMarkedUnread: false, - isFavourite: false) + isFavourite: false, + isTombstoned: false) return .init(summary: summary, hideUnreadMessagesBadge: false) } @@ -246,7 +247,8 @@ private extension HomeScreenRoom { alternativeAliases: [], hasOngoingCall: false, isMarkedUnread: false, - isFavourite: false) + isFavourite: false, + isTombstoned: false) return .init(summary: summary, hideUnreadMessagesBadge: false) } diff --git a/ElementX/Sources/Screens/HomeScreen/View/HomeScreenKnockedCell.swift b/ElementX/Sources/Screens/HomeScreen/View/HomeScreenKnockedCell.swift index 43d67b0f5..b4a10692e 100644 --- a/ElementX/Sources/Screens/HomeScreen/View/HomeScreenKnockedCell.swift +++ b/ElementX/Sources/Screens/HomeScreen/View/HomeScreenKnockedCell.swift @@ -162,7 +162,8 @@ private extension HomeScreenRoom { alternativeAliases: [], hasOngoingCall: false, isMarkedUnread: false, - isFavourite: false) + isFavourite: false, + isTombstoned: false) return .init(summary: summary, hideUnreadMessagesBadge: false) } @@ -191,7 +192,8 @@ private extension HomeScreenRoom { alternativeAliases: [], hasOngoingCall: false, isMarkedUnread: false, - isFavourite: false) + isFavourite: false, + isTombstoned: false) return .init(summary: summary, hideUnreadMessagesBadge: false) } diff --git a/ElementX/Sources/Screens/HomeScreen/View/HomeScreenRoomCell.swift b/ElementX/Sources/Screens/HomeScreen/View/HomeScreenRoomCell.swift index 581ae75ed..0de1093c9 100644 --- a/ElementX/Sources/Screens/HomeScreen/View/HomeScreenRoomCell.swift +++ b/ElementX/Sources/Screens/HomeScreen/View/HomeScreenRoomCell.swift @@ -135,7 +135,11 @@ struct HomeScreenRoomCell: View { @ViewBuilder private var lastMessage: some View { - if let lastMessage = room.lastMessage { + // If the room is tombstoned, show a specific message, regardless of any last message. + if room.isTombstoned { + Text(L10n.screenRoomlistTombstonedRoomDescription) + .lastMessageFormatting() + } else if let lastMessage = room.lastMessage { Text(lastMessage) .lastMessageFormatting() } diff --git a/ElementX/Sources/Screens/MediaEventsTimelineScreen/MediaEventsTimelineScreenViewModel.swift b/ElementX/Sources/Screens/MediaEventsTimelineScreen/MediaEventsTimelineScreenViewModel.swift index 798adbd09..1d22f2cc1 100644 --- a/ElementX/Sources/Screens/MediaEventsTimelineScreen/MediaEventsTimelineScreenViewModel.swift +++ b/ElementX/Sources/Screens/MediaEventsTimelineScreen/MediaEventsTimelineScreenViewModel.swift @@ -81,7 +81,7 @@ class MediaEventsTimelineScreenViewModel: MediaEventsTimelineScreenViewModelType case .displayEmojiPicker, .displayReportContent, .displayCameraPicker, .displayMediaPicker, .displayDocumentPicker, .displayLocationPicker, .displayPollForm, .displayMediaUploadPreviewScreen, .displaySenderDetails, .displayMessageForwarding, .displayLocation, .displayResolveSendFailure, - .displayThread, .composer, .hasScrolled, .viewInRoomTimeline: + .displayThread, .composer, .hasScrolled, .viewInRoomTimeline, .displayRoom: break } } @@ -103,7 +103,7 @@ class MediaEventsTimelineScreenViewModel: MediaEventsTimelineScreenViewModelType case .displayEmojiPicker, .displayReportContent, .displayCameraPicker, .displayMediaPicker, .displayDocumentPicker, .displayLocationPicker, .displayPollForm, .displayMediaUploadPreviewScreen, .displaySenderDetails, .displayMessageForwarding, .displayLocation, .displayResolveSendFailure, - .displayThread, .composer, .hasScrolled, .viewInRoomTimeline: + .displayThread, .composer, .hasScrolled, .viewInRoomTimeline, .displayRoom: break } } diff --git a/ElementX/Sources/Screens/PinnedEventsTimelineScreen/PinnedEventsTimelineScreenCoordinator.swift b/ElementX/Sources/Screens/PinnedEventsTimelineScreen/PinnedEventsTimelineScreenCoordinator.swift index 4a09b7782..ecb606ca4 100644 --- a/ElementX/Sources/Screens/PinnedEventsTimelineScreen/PinnedEventsTimelineScreenCoordinator.swift +++ b/ElementX/Sources/Screens/PinnedEventsTimelineScreen/PinnedEventsTimelineScreenCoordinator.swift @@ -91,7 +91,7 @@ final class PinnedEventsTimelineScreenCoordinator: CoordinatorProtocol { // These other actions will not be handled in this view case .displayEmojiPicker, .displayReportContent, .displayCameraPicker, .displayMediaPicker, .displayDocumentPicker, .displayLocationPicker, .displayPollForm, .displayMediaUploadPreviewScreen, - .displayResolveSendFailure, .displayThread, .composer, .hasScrolled: + .displayResolveSendFailure, .displayThread, .composer, .hasScrolled, .displayRoom: // These actions are not handled in this coordinator break } diff --git a/ElementX/Sources/Screens/RoomScreen/RoomScreenCoordinator.swift b/ElementX/Sources/Screens/RoomScreen/RoomScreenCoordinator.swift index e069fb392..863bfb1e8 100644 --- a/ElementX/Sources/Screens/RoomScreen/RoomScreenCoordinator.swift +++ b/ElementX/Sources/Screens/RoomScreen/RoomScreenCoordinator.swift @@ -45,6 +45,7 @@ enum RoomScreenCoordinatorAction { case presentResolveSendFailure(failure: TimelineItemSendFailure.VerifiedUser, sendHandle: SendHandleProxy) case presentKnockRequestsList case presentThread(itemID: TimelineItemIdentifier) + case presentRoom(roomID: String) } final class RoomScreenCoordinator: CoordinatorProtocol { @@ -151,6 +152,8 @@ final class RoomScreenCoordinator: CoordinatorProtocol { composerViewModel.process(timelineAction: action) case .hasScrolled(direction: let direction): roomViewModel.timelineHasScrolled(direction: direction) + case .displayRoom(let roomID): + actionsSubject.send(.presentRoom(roomID: roomID)) case .viewInRoomTimeline: fatalError("The action: \(action) should not be sent to this coordinator") } @@ -182,6 +185,8 @@ final class RoomScreenCoordinator: CoordinatorProtocol { composerViewModel.process(timelineAction: .removeFocus) case .displayKnockRequests: actionsSubject.send(.presentKnockRequestsList) + case .displayRoom(let roomID): + actionsSubject.send(.presentRoom(roomID: roomID)) } } .store(in: &cancellables) diff --git a/ElementX/Sources/Screens/RoomScreen/RoomScreenModels.swift b/ElementX/Sources/Screens/RoomScreen/RoomScreenModels.swift index 0c9559ad7..86cdfa77b 100644 --- a/ElementX/Sources/Screens/RoomScreen/RoomScreenModels.swift +++ b/ElementX/Sources/Screens/RoomScreen/RoomScreenModels.swift @@ -15,6 +15,7 @@ enum RoomScreenViewModelAction: Equatable { case displayCall case removeComposerFocus case displayKnockRequests + case displayRoom(roomID: String) } enum RoomScreenViewAction { @@ -26,6 +27,7 @@ enum RoomScreenViewAction { case acceptKnock(eventID: String) case dismissKnockRequests case viewKnockRequests + case displaySuccessorRoom } struct RoomScreenViewState: BindableState { @@ -53,6 +55,8 @@ struct RoomScreenViewState: BindableState { var unseenKnockRequests: [KnockRequestInfo] = [] var handledEventIDs: Set = [] + var hasSuccessor: Bool + var displayedKnockRequests: [KnockRequestInfo] { unseenKnockRequests.filter { !handledEventIDs.contains($0.eventID) } } diff --git a/ElementX/Sources/Screens/RoomScreen/RoomScreenViewModel.swift b/ElementX/Sources/Screens/RoomScreen/RoomScreenViewModel.swift index 53f2c8131..1c564d281 100644 --- a/ElementX/Sources/Screens/RoomScreen/RoomScreenViewModel.swift +++ b/ElementX/Sources/Screens/RoomScreen/RoomScreenViewModel.swift @@ -72,6 +72,7 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol super.init(initialViewState: .init(roomTitle: roomProxy.infoPublisher.value.displayName ?? roomProxy.id, roomAvatar: roomProxy.infoPublisher.value.avatar, hasOngoingCall: roomProxy.infoPublisher.value.hasRoomCall, + hasSuccessor: roomProxy.infoPublisher.value.successor != nil, bindings: .init()), mediaProvider: mediaProvider) @@ -114,6 +115,9 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol Task { await markAllKnocksAsSeen() } case .viewKnockRequests: actionsSubject.send(.displayKnockRequests) + case .displaySuccessorRoom: + guard let successorID = roomProxy.infoPublisher.value.successor?.roomId else { return } + actionsSubject.send(.displayRoom(roomID: successorID)) } } @@ -326,6 +330,7 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol } private func handleRoomInfoUpdate(_ roomInfo: RoomInfoProxy) async { + state.hasSuccessor = roomInfo.successor != nil let pinnedEventIDs = roomInfo.pinnedEventIDs // Only update the loading state of the banner if state.pinnedEventsBannerState.isLoading { diff --git a/ElementX/Sources/Screens/RoomScreen/View/RoomScreen.swift b/ElementX/Sources/Screens/RoomScreen/View/RoomScreen.swift index e7f3a526a..a5b7b1d39 100644 --- a/ElementX/Sources/Screens/RoomScreen/View/RoomScreen.swift +++ b/ElementX/Sources/Screens/RoomScreen/View/RoomScreen.swift @@ -151,7 +151,9 @@ struct RoomScreen: View { @ViewBuilder private var composer: some View { - if roomContext.viewState.canSendMessage { + if roomContext.viewState.hasSuccessor { + tombstonedDialogue + } else if roomContext.viewState.canSendMessage { composerToolbar } else { Text(L10n.screenRoomTimelineNoPermissionToPost) @@ -162,6 +164,28 @@ struct RoomScreen: View { } } + private var tombstonedDialogue: some View { + VStack(spacing: 16) { + Text(L10n.screenRoomTimelineTombstonedRoomMessage) + .font(.compound.bodyMD) + .foregroundStyle(.compound.textPrimary) + + Button { + roomContext.send(viewAction: .displaySuccessorRoom) + } label: { + Text(L10n.screenRoomTimelineTombstonedRoomAction) + .frame(maxWidth: .infinity) + } + .buttonStyle(.compound(.primary, size: .medium)) + } + .padding(.top, 16) + .padding(.horizontal, 16) + .padding(.bottom, 8) + .highlight(borderColor: .compound.borderInfoSubtle, + primaryColor: .compound.bgInfoSubtle, + secondaryColor: .compound.bgCanvasDefault) + } + @ViewBuilder private var loadingIndicator: some View { if timelineContext.viewState.showLoading { @@ -233,6 +257,7 @@ struct RoomScreen: View { struct RoomScreen_Previews: PreviewProvider, TestablePreview { static let viewModels = makeViewModels() static let readOnlyViewModels = makeViewModels(canSendMessage: false) + static let tombstonedViewModels = makeViewModels(hasSuccessor: true) static var previews: some View { NavigationStack { @@ -249,13 +274,22 @@ struct RoomScreen_Previews: PreviewProvider, TestablePreview { } .previewDisplayName("Read-only") .snapshotPreferences(expect: readOnlyViewModels.room.context.$viewState.map { !$0.canSendMessage }) + + NavigationStack { + RoomScreen(roomViewModel: tombstonedViewModels.room, + timelineViewModel: tombstonedViewModels.timeline, + composerToolbar: ComposerToolbar.mock()) + } + .previewDisplayName("Tombstoned") + .snapshotPreferences(expect: tombstonedViewModels.room.context.$viewState.map(\.hasSuccessor)) } - static func makeViewModels(canSendMessage: Bool = true) -> ViewModels { + static func makeViewModels(canSendMessage: Bool = true, hasSuccessor: Bool = false) -> ViewModels { let roomProxyMock = JoinedRoomProxyMock(.init(id: "stable_id", name: "Preview room", hasOngoingCall: true, - canUserSendMessage: canSendMessage)) + canUserSendMessage: canSendMessage, + successor: hasSuccessor ? .init(roomId: UUID().uuidString, reason: nil) : nil)) let roomViewModel = RoomScreenViewModel.mock(roomProxyMock: roomProxyMock) let timelineViewModel = TimelineViewModel(roomProxy: roomProxyMock, timelineController: MockTimelineController(), diff --git a/ElementX/Sources/Screens/RoomScreen/View/RoomScreenFooterView.swift b/ElementX/Sources/Screens/RoomScreen/View/RoomScreenFooterView.swift index eaddcb04b..28381ee2c 100644 --- a/ElementX/Sources/Screens/RoomScreen/View/RoomScreenFooterView.swift +++ b/ElementX/Sources/Screens/RoomScreen/View/RoomScreenFooterView.swift @@ -12,32 +12,44 @@ struct RoomScreenFooterView: View { let mediaProvider: MediaProviderProtocol? let callback: (RoomScreenFooterViewAction) -> Void + private var borderColor: Color { + switch details { + case .pinViolation: + .compound.borderInfoSubtle + case .verificationViolation: + .compound.borderCriticalSubtle + case .none: + Color.compound.bgCanvasDefault + } + } + + private var gradientColor: Color { + switch details { + case .pinViolation: + .compound.bgInfoSubtle + case .verificationViolation: + .compound.bgCriticalSubtle + case .none: + Color.compound.bgCanvasDefault + } + } + var body: some View { if let details { - ZStack(alignment: .top) { - switch details { - case .pinViolation(let member, let learnMoreURL): - VStack(spacing: 0) { - Color.compound.borderInfoSubtle - .frame(height: 1) - LinearGradient(colors: [.compound.bgInfoSubtle, .compound.bgCanvasDefault], - startPoint: .top, - endPoint: .bottom) - } - pinViolation(member: member, learnMoreURL: learnMoreURL) - case .verificationViolation(member: let member, learnMoreURL: let learnMoreURL): - VStack(spacing: 0) { - Color.compound.borderCriticalSubtle - .frame(height: 1) - LinearGradient(colors: [.compound.bgCriticalSubtle, .compound.bgCanvasDefault], - startPoint: .top, - endPoint: .bottom) - } - verificationViolation(member: member, learnMoreURL: learnMoreURL) - } - } - .padding(.top, 8) - .fixedSize(horizontal: false, vertical: true) + detailsView(details) + .highlight(borderColor: borderColor, primaryColor: gradientColor, secondaryColor: .compound.bgCanvasDefault) + .padding(.top, 8) + .fixedSize(horizontal: false, vertical: true) + } + } + + @ViewBuilder + private func detailsView(_ details: RoomScreenFooterViewDetails) -> some View { + switch details { + case .pinViolation(let member, let learnMoreURL): + pinViolation(member: member, learnMoreURL: learnMoreURL) + case .verificationViolation(member: let member, learnMoreURL: let learnMoreURL): + verificationViolation(member: member, learnMoreURL: learnMoreURL) } } diff --git a/ElementX/Sources/Screens/ThreadTimelineScreen/ThreadTimelineScreenCoordinator.swift b/ElementX/Sources/Screens/ThreadTimelineScreen/ThreadTimelineScreenCoordinator.swift index 7327fdc25..5275c3216 100644 --- a/ElementX/Sources/Screens/ThreadTimelineScreen/ThreadTimelineScreenCoordinator.swift +++ b/ElementX/Sources/Screens/ThreadTimelineScreen/ThreadTimelineScreenCoordinator.swift @@ -96,7 +96,7 @@ final class ThreadTimelineScreenCoordinator: CoordinatorProtocol { actionsSubject.send(.presentLocationViewer(body: body, geoURI: geoURI, description: description)) case .displayResolveSendFailure(let failure, let sendHandle): actionsSubject.send(.presentResolveSendFailure(failure: failure, sendHandle: sendHandle)) - case .displayThread, .composer, .hasScrolled: + case .displayThread, .composer, .hasScrolled, .displayRoom: break case .viewInRoomTimeline: fatalError("The action: \(action) should not be sent to this coordinator") diff --git a/ElementX/Sources/Screens/Timeline/TimelineModels.swift b/ElementX/Sources/Screens/Timeline/TimelineModels.swift index 151909e2f..2395ce3e9 100644 --- a/ElementX/Sources/Screens/Timeline/TimelineModels.swift +++ b/ElementX/Sources/Screens/Timeline/TimelineModels.swift @@ -28,6 +28,7 @@ enum TimelineViewModelAction { case composer(action: TimelineComposerAction) case hasScrolled(direction: ScrollDirection) case viewInRoomTimeline(eventID: String) + case displayRoom(roomID: String) } enum TimelineViewPollAction { @@ -77,6 +78,8 @@ enum TimelineViewAction { case hasScrolled(direction: ScrollDirection) case setOpenURLAction(OpenURLAction) + + case seePredecessorTapped } enum TimelineComposerAction { @@ -106,6 +109,8 @@ struct TimelineViewState: BindableState { var isViewSourceEnabled: Bool var areThreadsEnabled: Bool var hideTimelineMedia: Bool + + let hasPredecessor: Bool // The `pinnedEventIDs` are used only to determine if an item is already pinned or not. // It's updated from the room info, so it's faster than using the timeline diff --git a/ElementX/Sources/Screens/Timeline/TimelineViewModel.swift b/ElementX/Sources/Screens/Timeline/TimelineViewModel.swift index ac99c4751..3de408818 100644 --- a/ElementX/Sources/Screens/Timeline/TimelineViewModel.swift +++ b/ElementX/Sources/Screens/Timeline/TimelineViewModel.swift @@ -104,6 +104,7 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol { isViewSourceEnabled: appSettings.viewSourceEnabled, areThreadsEnabled: appSettings.threadsEnabled, hideTimelineMedia: hideTimelineMedia, + hasPredecessor: roomProxy.predecessorRoom != nil, pinnedEventIDs: roomProxy.infoPublisher.value.pinnedEventIDs, emojiProvider: emojiProvider, mapTilerConfiguration: appSettings.mapTilerConfiguration, @@ -211,6 +212,9 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol { actionsSubject.send(.hasScrolled(direction: direction)) case .setOpenURLAction(let action): state.openURL = action + case .seePredecessorTapped: + guard let predecessorID = roomProxy.predecessorRoom?.roomId else { return } + actionsSubject.send(.displayRoom(roomID: predecessorID)) } } @@ -1018,11 +1022,12 @@ private extension RoomInfoProxy { extension TimelineViewModel { static let mock = mock(timelineKind: .live) - static func mock(timelineKind: TimelineKind = .live, timelineController: MockTimelineController? = nil) -> TimelineViewModel { + static func mock(timelineKind: TimelineKind = .live, timelineController: MockTimelineController? = nil, hasPredecessor: Bool = false) -> TimelineViewModel { let clientProxyMock = ClientProxyMock(.init()) clientProxyMock.roomSummaryForAliasReturnValue = .mock(id: "!room:matrix.org", name: "Room") clientProxyMock.roomSummaryForIdentifierReturnValue = .mock(id: "!room:matrix.org", name: "Room", canonicalAlias: "#room:matrix.org") - return TimelineViewModel(roomProxy: JoinedRoomProxyMock(.init(name: "Preview room")), + let roomProxy = JoinedRoomProxyMock(.init(name: "Preview room", predecessor: hasPredecessor ? .init(roomId: UUID().uuidString, lastEventId: UUID().uuidString) : nil)) + return TimelineViewModel(roomProxy: roomProxy, focussedEventID: nil, timelineController: timelineController ?? MockTimelineController(timelineKind: timelineKind), mediaProvider: MediaProviderMock(configuration: .init()), diff --git a/ElementX/Sources/Screens/Timeline/View/TimelineItemViews/TimelineStartRoomTimelineView.swift b/ElementX/Sources/Screens/Timeline/View/TimelineItemViews/TimelineStartRoomTimelineView.swift index 46c42f451..f986aeae9 100644 --- a/ElementX/Sources/Screens/Timeline/View/TimelineItemViews/TimelineStartRoomTimelineView.swift +++ b/ElementX/Sources/Screens/Timeline/View/TimelineItemViews/TimelineStartRoomTimelineView.swift @@ -5,20 +5,50 @@ // Please see LICENSE files in the repository root for full details. // +import Compound import SwiftUI struct TimelineStartRoomTimelineView: View { let timelineItem: TimelineStartRoomTimelineItem + @Environment(\.timelineContext) private var context var body: some View { - Text(title) - .font(.compound.bodySM) - .foregroundColor(.compound.textSecondary) - .padding(.vertical, 24) - .frame(maxWidth: .infinity) + VStack(spacing: 14) { + if context?.viewState.hasPredecessor == true { + upgrade + } + if context?.viewState.isDirectOneToOneRoom != true { + Text(title) + .font(.compound.bodySM) + .foregroundColor(.compound.textSecondary) + .padding(.bottom, 24) + .padding(.top, context?.viewState.hasPredecessor == true ? 0 : 24) + .frame(maxWidth: .infinity) + } + } } - var title: String { + private var upgrade: some View { + VStack(spacing: 16) { + Text(L10n.screenRoomTimelineUpgradedRoomMessage) + .font(.compound.bodyMD) + .foregroundColor(.compound.textPrimary) + Button { + context?.send(viewAction: .seePredecessorTapped) + } label: { + Text(L10n.screenRoomTimelineUpgradedRoomAction) + .frame(maxWidth: .infinity) + } + .buttonStyle(.compound(.primary, size: .medium)) + .frame(maxWidth: .infinity) + } + .padding(.top, 16) + .padding(.bottom, 8) + .padding(.horizontal, 16) + .highlight(borderColor: .compound.borderInfoSubtle, primaryColor: .compound.bgInfoSubtle, secondaryColor: Color.clear) + } + + private var title: String { var text = L10n.screenRoomTimelineBeginningOfRoomNoName if let name = timelineItem.name { text = L10n.screenRoomTimelineBeginningOfRoom(name) @@ -28,8 +58,15 @@ struct TimelineStartRoomTimelineView: View { } struct TimelineStartRoomTimelineView_Previews: PreviewProvider, TestablePreview { + static let viewModel = TimelineViewModel.mock(hasPredecessor: true) + static var previews: some View { let item = TimelineStartRoomTimelineItem(name: "Alice and Bob") TimelineStartRoomTimelineView(timelineItem: item) + .previewLayout(.sizeThatFits) + TimelineStartRoomTimelineView(timelineItem: item) + .environment(\.timelineContext, viewModel.context) + .previewLayout(.sizeThatFits) + .previewDisplayName("with predecessor") } } diff --git a/ElementX/Sources/Services/Room/JoinedRoomProxy.swift b/ElementX/Sources/Services/Room/JoinedRoomProxy.swift index 091d3902c..e74963012 100644 --- a/ElementX/Sources/Services/Room/JoinedRoomProxy.swift +++ b/ElementX/Sources/Services/Room/JoinedRoomProxy.swift @@ -34,6 +34,8 @@ class JoinedRoomProxy: JoinedRoomProxyProtocol { var ownUserID: String { room.ownUserId() } + lazy var predecessorRoom: PredecessorRoom? = room.predecessorRoom() + let timeline: TimelineProxyProtocol private let infoSubject: CurrentValueSubject diff --git a/ElementX/Sources/Services/Room/RoomInfoProxy.swift b/ElementX/Sources/Services/Room/RoomInfoProxy.swift index e44932ff4..d5e6bacb4 100644 --- a/ElementX/Sources/Services/Room/RoomInfoProxy.swift +++ b/ElementX/Sources/Services/Room/RoomInfoProxy.swift @@ -33,6 +33,10 @@ struct RoomInfoProxy: BaseRoomInfoProxyProtocol { var avatarURL: URL? { roomInfo.avatarUrl.flatMap(URL.init) } /// The room's avatar info for use in a ``RoomAvatarImage``. var avatar: RoomAvatar { + guard successor == nil else { + return .tombstoned + } + if isDirect, avatarURL == nil, heroes.count == 1 { return .heroes(heroes.map(UserProfileProxy.init)) } @@ -61,7 +65,7 @@ struct RoomInfoProxy: BaseRoomInfoProxyProtocol { } var isSpace: Bool { roomInfo.isSpace } - var tombstoneInfo: SuccessorRoom? { roomInfo.successorRoom } + var successor: SuccessorRoom? { roomInfo.successorRoom } var isFavourite: Bool { roomInfo.isFavourite } var canonicalAlias: String? { roomInfo.canonicalAlias } var alternativeAliases: [String] { roomInfo.alternativeAliases } diff --git a/ElementX/Sources/Services/Room/RoomProxyProtocol.swift b/ElementX/Sources/Services/Room/RoomProxyProtocol.swift index 1ddc13690..fb47183cc 100644 --- a/ElementX/Sources/Services/Room/RoomProxyProtocol.swift +++ b/ElementX/Sources/Services/Room/RoomProxyProtocol.swift @@ -76,6 +76,8 @@ protocol JoinedRoomProxyProtocol: RoomProxyProtocol { var timeline: TimelineProxyProtocol { get } + var predecessorRoom: PredecessorRoom? { get } + func subscribeForUpdates() async func subscribeToRoomInfoUpdates() diff --git a/ElementX/Sources/Services/Room/RoomSummary/RoomSummary.swift b/ElementX/Sources/Services/Room/RoomSummary/RoomSummary.swift index b7eb022d5..8a662cf02 100644 --- a/ElementX/Sources/Services/Room/RoomSummary/RoomSummary.swift +++ b/ElementX/Sources/Services/Room/RoomSummary/RoomSummary.swift @@ -56,6 +56,8 @@ struct RoomSummary { let isMarkedUnread: Bool let isFavourite: Bool + let isTombstoned: Bool + var hasUnreadMessages: Bool { unreadMessagesCount > 0 } var hasUnreadMentions: Bool { unreadMentionsCount > 0 } var hasUnreadNotifications: Bool { unreadNotificationsCount > 0 } @@ -124,14 +126,19 @@ extension RoomSummary { joinRequestType = nil isMarkedUnread = false isFavourite = false + isTombstoned = false } // This doesn't have to work properly for DM invites, the heroes are always empty var avatar: RoomAvatar { + guard !isTombstoned else { + return .tombstoned + } + if isDirect, avatarURL == nil, heroes.count == 1 { - .heroes(heroes) + return .heroes(heroes) } else { - .room(id: id, name: name, avatarURL: avatarURL) + return .room(id: id, name: name, avatarURL: avatarURL) } } } diff --git a/ElementX/Sources/Services/Room/RoomSummary/RoomSummaryProvider.swift b/ElementX/Sources/Services/Room/RoomSummary/RoomSummaryProvider.swift index 76038a2cd..fbdbcb33f 100644 --- a/ElementX/Sources/Services/Room/RoomSummary/RoomSummaryProvider.swift +++ b/ElementX/Sources/Services/Room/RoomSummary/RoomSummaryProvider.swift @@ -281,7 +281,8 @@ class RoomSummaryProvider: RoomSummaryProviderProtocol { alternativeAliases: .init(roomInfo.alternativeAliases), hasOngoingCall: roomInfo.hasRoomCall, isMarkedUnread: roomInfo.isMarkedUnread, - isFavourite: roomInfo.isFavourite) + isFavourite: roomInfo.isFavourite, + isTombstoned: roomInfo.successorRoom != nil) } private func buildDiff(from diff: RoomListEntriesUpdate, on rooms: [RoomSummary]) -> CollectionDifference? { diff --git a/ElementX/Sources/Services/Timeline/TimelineController/TimelineController.swift b/ElementX/Sources/Services/Timeline/TimelineController/TimelineController.swift index e7d8ccf05..744ef67e5 100644 --- a/ElementX/Sources/Services/Timeline/TimelineController/TimelineController.swift +++ b/ElementX/Sources/Services/Timeline/TimelineController/TimelineController.swift @@ -185,11 +185,13 @@ class TimelineController: TimelineControllerProtocol { sender: nil, attachments: nil) - let avatarURL = switch roomProxy.details.avatar { + let avatarURL: URL? = switch roomProxy.details.avatar { case .room(_, _, let avatarURL): avatarURL case .heroes(let userProfiles): userProfiles.first?.avatarURL + case .tombstoned: + nil } func addPlacehoder() { @@ -389,6 +391,7 @@ class TimelineController: TimelineControllerProtocol { let isDM = roomProxy.isDirectOneToOneRoom let displayName = roomProxy.infoPublisher.value.displayName + let hasPredecessor = roomProxy.predecessorRoom != nil var newTimelineItems = await Task.detached { [timelineItemFactory, activeTimeline] in var newTimelineItems = [RoomTimelineItemProtocol]() @@ -401,6 +404,7 @@ class TimelineController: TimelineControllerProtocol { let items = collapsibleChunk.compactMap { itemProxy in let timelineItem = self.buildTimelineItem(for: itemProxy, isDM: isDM, + hasPredecessor: hasPredecessor, roomDisplayName: displayName, timelineItemFactory: timelineItemFactory, activeTimeline: activeTimeline) @@ -451,6 +455,7 @@ class TimelineController: TimelineControllerProtocol { private nonisolated func buildTimelineItem(for itemProxy: TimelineItemProxy, isDM: Bool, + hasPredecessor: Bool, roomDisplayName: String?, timelineItemFactory: RoomTimelineItemFactoryProtocol, activeTimeline: TimelineProxyProtocol) -> RoomTimelineItemProtocol? { @@ -475,7 +480,11 @@ class TimelineController: TimelineControllerProtocol { case .readMarker: return ReadMarkerRoomTimelineItem(id: .virtual(uniqueID: uniqueID)) case .timelineStart: - return isDM ? nil : TimelineStartRoomTimelineItem(name: roomDisplayName) + if hasPredecessor { + return TimelineStartRoomTimelineItem(name: roomDisplayName) + } else { + return isDM ? nil : TimelineStartRoomTimelineItem(name: roomDisplayName) + } } case .unknown: return nil diff --git a/ElementX/Sources/Services/Timeline/TimelineItems/Items/Virtual/TimelineStartRoomTimelineItem.swift b/ElementX/Sources/Services/Timeline/TimelineItems/Items/Virtual/TimelineStartRoomTimelineItem.swift index 785c6daf0..7da47d39c 100644 --- a/ElementX/Sources/Services/Timeline/TimelineItems/Items/Virtual/TimelineStartRoomTimelineItem.swift +++ b/ElementX/Sources/Services/Timeline/TimelineItems/Items/Virtual/TimelineStartRoomTimelineItem.swift @@ -8,6 +8,6 @@ import Foundation struct TimelineStartRoomTimelineItem: DecorationTimelineItemProtocol, Equatable { - let id: TimelineItemIdentifier = .virtual(uniqueID: .init(UUID().uuidString)) + let id: TimelineItemIdentifier = .virtual(uniqueID: .init("TimelineStart")) let name: String? } diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/globalSearchScreen.iPad-en-GB-0.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/globalSearchScreen.iPad-en-GB-0.png index eae437f6e..3aac7fe5b 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/globalSearchScreen.iPad-en-GB-0.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/globalSearchScreen.iPad-en-GB-0.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:35951ab2ca021aacb1d40c8ae270efe23f47b38d0715b0475b93e0878300253d -size 163854 +oid sha256:8330191544e3657e0e3533d668e9b0a87d026a657d85df753b59d7ac7dcc0a88 +size 169757 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/globalSearchScreen.iPad-pseudo-0.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/globalSearchScreen.iPad-pseudo-0.png index bd78981f5..7b3d59fb6 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/globalSearchScreen.iPad-pseudo-0.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/globalSearchScreen.iPad-pseudo-0.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:31ddb9be88bf2a6469fc8d3c8178170ca246b7c5429f9db98bb6f737cb282703 -size 164238 +oid sha256:634dace53b6cf3fd5333581f6af4b7a4fc61aea536f9c3521d4066eff5bf4bf9 +size 170141 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/globalSearchScreen.iPhone-16-en-GB-0.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/globalSearchScreen.iPhone-16-en-GB-0.png index c96a20ce4..50573149e 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/globalSearchScreen.iPhone-16-en-GB-0.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/globalSearchScreen.iPhone-16-en-GB-0.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8687afad034254066ea656378022ae61aed58cc2b2214edaf323ab13aded7c73 -size 99720 +oid sha256:76d43f9eeaed0fc25fef35f560cfef46968f58406a2856616b27eea74853b93d +size 103810 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/globalSearchScreen.iPhone-16-pseudo-0.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/globalSearchScreen.iPhone-16-pseudo-0.png index 380e0548b..ef34610d4 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/globalSearchScreen.iPhone-16-pseudo-0.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/globalSearchScreen.iPhone-16-pseudo-0.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:03d9f85d77b1e75bbc8ab40ce84756067a30d35d09a7ce6e821302ba35dbdece -size 100052 +oid sha256:4437a44dfc2fda3db1823458d07043f82610f70065bece40e5178301bd536536 +size 104142 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/homeScreen.Loaded-iPad-en-GB.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/homeScreen.Loaded-iPad-en-GB.png index 3588131bc..5448fd037 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/homeScreen.Loaded-iPad-en-GB.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/homeScreen.Loaded-iPad-en-GB.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4e891998fd95aa30f8c191deab533a059a9c1feb815ae5bf0852540c9b1e9ab4 -size 251107 +oid sha256:d8857f34fc49bd98435b4e5595c10b1a463987f83084edc7682591993f69137e +size 260979 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/homeScreen.Loaded-iPad-pseudo.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/homeScreen.Loaded-iPad-pseudo.png index dacf16417..752bd922b 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/homeScreen.Loaded-iPad-pseudo.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/homeScreen.Loaded-iPad-pseudo.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ecf700e5999db8abed896b329e74903335c481cce0e06dc7d6568561168c45ad -size 255196 +oid sha256:93bec421deab287621f9491cb3c8f1f6c5a2032f035b33c0e694eab5e73e40ae +size 269355 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/homeScreen.Loaded-iPhone-16-en-GB.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/homeScreen.Loaded-iPhone-16-en-GB.png index 242549ac5..78be0c8f2 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/homeScreen.Loaded-iPhone-16-en-GB.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/homeScreen.Loaded-iPhone-16-en-GB.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:28f525c2f84acf155af7b5eaa7d3c9726a7d0861fad83c7e5249925d57fefd81 -size 188085 +oid sha256:5c17c1409da49b67f48bbc12856a7411368741c1e987933d1304fef98aa1a81f +size 195209 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/homeScreen.Loaded-iPhone-16-pseudo.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/homeScreen.Loaded-iPhone-16-pseudo.png index 94894d420..452fbfa96 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/homeScreen.Loaded-iPhone-16-pseudo.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/homeScreen.Loaded-iPhone-16-pseudo.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2582a1c209166a3488335a70697fb0be7c7c81228db2ca2198e4a959b9cff3f7 -size 190520 +oid sha256:bdc4b92d1659096dc1bc61acfeab73799d520a990b34621ff398fa1563cbbf83 +size 202572 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/homeScreenRoomCell.Generic-iPad-en-GB.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/homeScreenRoomCell.Generic-iPad-en-GB.png index 18d347f9b..6cbcb3f62 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/homeScreenRoomCell.Generic-iPad-en-GB.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/homeScreenRoomCell.Generic-iPad-en-GB.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:511bbebdefd00ca3169790a06c4286fda86e90a0c814b6327dbcd3b54aa9fa95 -size 228009 +oid sha256:5049db4e463707a92bf4d6a82001f6bf06f63221f182870bf0efb88a9390fbf4 +size 242678 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/homeScreenRoomCell.Generic-iPad-pseudo.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/homeScreenRoomCell.Generic-iPad-pseudo.png index dd4a27a51..ba784a794 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/homeScreenRoomCell.Generic-iPad-pseudo.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/homeScreenRoomCell.Generic-iPad-pseudo.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:79a8204c246186be948bfd1d1ac0ccf87edf3a047304705b077436540fad299a -size 229275 +oid sha256:32da7e0537cbd586dba8bdb79d155a81c7f5fae7a9749555a0ee26b90bd5b715 +size 248416 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/homeScreenRoomCell.Generic-iPhone-16-en-GB.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/homeScreenRoomCell.Generic-iPhone-16-en-GB.png index 763310758..8e855c2b0 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/homeScreenRoomCell.Generic-iPhone-16-en-GB.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/homeScreenRoomCell.Generic-iPhone-16-en-GB.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fba85304ab17f100b391904278da5b82fbaa458e3b53de446ba98d088c0908a1 -size 169063 +oid sha256:a1cd038069eeba5235567fb9ca53768b3675e4e3a6ccea351c7ef846b005f310 +size 180368 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/homeScreenRoomCell.Generic-iPhone-16-pseudo.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/homeScreenRoomCell.Generic-iPhone-16-pseudo.png index 3f5fa95ab..25dc65d4c 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/homeScreenRoomCell.Generic-iPhone-16-pseudo.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/homeScreenRoomCell.Generic-iPhone-16-pseudo.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0586a60dc2d7cbc8d0679015b11e88e163c4ab2749233db1948685f52c69b8c0 -size 168689 +oid sha256:0998f864dfeca1c729cdd5aad48edc0509c611ec0974538ed1cfb0f443893d00 +size 184752 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/messageForwardingScreen.iPad-en-GB-0.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/messageForwardingScreen.iPad-en-GB-0.png index 8e96b2dca..b695a7d7c 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/messageForwardingScreen.iPad-en-GB-0.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/messageForwardingScreen.iPad-en-GB-0.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:18a5a2705faf3823e0db694088206dc582621b4c52f31b7e5bdf5682889d5b94 -size 165467 +oid sha256:e8070b141426f12f70536ec19130566f1d33b4a8e163f60696bab457c806076d +size 169986 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/messageForwardingScreen.iPad-pseudo-0.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/messageForwardingScreen.iPad-pseudo-0.png index 7b6a4d842..0585b4af8 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/messageForwardingScreen.iPad-pseudo-0.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/messageForwardingScreen.iPad-pseudo-0.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cae43b115dc17061874c1338042c62d71b0e41eebfee30e8c6e8c094490be64a -size 167363 +oid sha256:515b38dd917617cd93d3db645bb4e5a187da6d2057a1e8ffac98b58df9e67500 +size 171882 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/messageForwardingScreen.iPhone-16-en-GB-0.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/messageForwardingScreen.iPhone-16-en-GB-0.png index 27a303fbc..c468cfa61 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/messageForwardingScreen.iPhone-16-en-GB-0.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/messageForwardingScreen.iPhone-16-en-GB-0.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:70ad8dc0e88cd46109fea561c0b7e220ca6bad6c7eb124d5b9f14b233f537820 -size 112987 +oid sha256:b9b027ff00710c620f8fe31d278d5ba6b65820d3463686327f6fe9c63c9e8623 +size 116692 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/messageForwardingScreen.iPhone-16-pseudo-0.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/messageForwardingScreen.iPhone-16-pseudo-0.png index 1ca291f7f..f9e625abe 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/messageForwardingScreen.iPhone-16-pseudo-0.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/messageForwardingScreen.iPhone-16-pseudo-0.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b2c4306135e1efa0552deddcaa09e22cae4f23687b0dcf840c9e39bad61635c0 -size 112846 +oid sha256:37a1f360bc89ee6025f7f91cdb88ada5d5dcace0ae4001001b64ff47ccb91d4f +size 116551 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/notificationSettingsEditScreenRoomCell.iPad-en-GB-0.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/notificationSettingsEditScreenRoomCell.iPad-en-GB-0.png index bbbdb6550..9e330d2f9 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/notificationSettingsEditScreenRoomCell.iPad-en-GB-0.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/notificationSettingsEditScreenRoomCell.iPad-en-GB-0.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cf1b83a17875ff7f68adf737693f70b4b5b8d48260488d01165f5f3f0433660f -size 125352 +oid sha256:e902bdfcd9a475267b1eefda4833c3d94fcc250cdfa7460b7c1c53ba1cacf4ff +size 130244 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/notificationSettingsEditScreenRoomCell.iPad-pseudo-0.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/notificationSettingsEditScreenRoomCell.iPad-pseudo-0.png index bbbdb6550..9e330d2f9 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/notificationSettingsEditScreenRoomCell.iPad-pseudo-0.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/notificationSettingsEditScreenRoomCell.iPad-pseudo-0.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cf1b83a17875ff7f68adf737693f70b4b5b8d48260488d01165f5f3f0433660f -size 125352 +oid sha256:e902bdfcd9a475267b1eefda4833c3d94fcc250cdfa7460b7c1c53ba1cacf4ff +size 130244 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/notificationSettingsEditScreenRoomCell.iPhone-16-en-GB-0.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/notificationSettingsEditScreenRoomCell.iPhone-16-en-GB-0.png index d36341ea5..acf87035c 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/notificationSettingsEditScreenRoomCell.iPhone-16-en-GB-0.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/notificationSettingsEditScreenRoomCell.iPhone-16-en-GB-0.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d2e6632fe1a83c6bd4f1601025027dd1e2515b56b98d0a4fde35eb56c3e56b40 -size 82324 +oid sha256:efd42154d6ed807c7de34d79bafcfc25767796aa6d9ce31a346d0bd39cf87db2 +size 86366 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/notificationSettingsEditScreenRoomCell.iPhone-16-pseudo-0.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/notificationSettingsEditScreenRoomCell.iPhone-16-pseudo-0.png index d36341ea5..acf87035c 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/notificationSettingsEditScreenRoomCell.iPhone-16-pseudo-0.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/notificationSettingsEditScreenRoomCell.iPhone-16-pseudo-0.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d2e6632fe1a83c6bd4f1601025027dd1e2515b56b98d0a4fde35eb56c3e56b40 -size 82324 +oid sha256:efd42154d6ed807c7de34d79bafcfc25767796aa6d9ce31a346d0bd39cf87db2 +size 86366 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/placeholderAvatarImage.iPad-en-GB-0.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/placeholderAvatarImage.iPad-en-GB-0.png index 6f56315b8..09dc28d86 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/placeholderAvatarImage.iPad-en-GB-0.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/placeholderAvatarImage.iPad-en-GB-0.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:eaa4236ec02b96b3883fccefc5e45b0b296448ab52ecc87201a837e5b1b23a83 -size 96810 +oid sha256:acc53e8fc7d224fc2ec0ce663efde39aaa625dcf11de3ca43f52704c814d0825 +size 101058 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/placeholderAvatarImage.iPad-pseudo-0.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/placeholderAvatarImage.iPad-pseudo-0.png index 6f56315b8..09dc28d86 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/placeholderAvatarImage.iPad-pseudo-0.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/placeholderAvatarImage.iPad-pseudo-0.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:eaa4236ec02b96b3883fccefc5e45b0b296448ab52ecc87201a837e5b1b23a83 -size 96810 +oid sha256:acc53e8fc7d224fc2ec0ce663efde39aaa625dcf11de3ca43f52704c814d0825 +size 101058 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/placeholderAvatarImage.iPhone-16-en-GB-0.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/placeholderAvatarImage.iPhone-16-en-GB-0.png index 401d8ce2d..fafe12fef 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/placeholderAvatarImage.iPhone-16-en-GB-0.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/placeholderAvatarImage.iPhone-16-en-GB-0.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:21089ce2daaa37f7e86031e11eab89d2dd9e80bb319c004fb86a9fc0e83d84f1 -size 55228 +oid sha256:ec055acc51709c62fe9d76a93db885da6de917eb014bde88c51307b9582e352e +size 59276 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/placeholderAvatarImage.iPhone-16-pseudo-0.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/placeholderAvatarImage.iPhone-16-pseudo-0.png index 401d8ce2d..fafe12fef 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/placeholderAvatarImage.iPhone-16-pseudo-0.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/placeholderAvatarImage.iPhone-16-pseudo-0.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:21089ce2daaa37f7e86031e11eab89d2dd9e80bb319c004fb86a9fc0e83d84f1 -size 55228 +oid sha256:ec055acc51709c62fe9d76a93db885da6de917eb014bde88c51307b9582e352e +size 59276 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/roomAvatarImage.iPad-en-GB-0.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/roomAvatarImage.iPad-en-GB-0.png index 85d5c54d0..d6633c6bf 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/roomAvatarImage.iPad-en-GB-0.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/roomAvatarImage.iPad-en-GB-0.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1ce3b3010ca5fbfdd4c4e44e1b5042bfd4b42edbba6e5546d8f95e3597ce8ffd -size 101458 +oid sha256:1896e5328d738494310900bf5d0f4a7441bb70f91103a20bce20ca064b6e6d5e +size 103499 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/roomAvatarImage.iPad-pseudo-0.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/roomAvatarImage.iPad-pseudo-0.png index 85d5c54d0..d6633c6bf 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/roomAvatarImage.iPad-pseudo-0.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/roomAvatarImage.iPad-pseudo-0.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1ce3b3010ca5fbfdd4c4e44e1b5042bfd4b42edbba6e5546d8f95e3597ce8ffd -size 101458 +oid sha256:1896e5328d738494310900bf5d0f4a7441bb70f91103a20bce20ca064b6e6d5e +size 103499 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/roomAvatarImage.iPhone-16-en-GB-0.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/roomAvatarImage.iPhone-16-en-GB-0.png index e886c9bd9..9278d4cc8 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/roomAvatarImage.iPhone-16-en-GB-0.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/roomAvatarImage.iPhone-16-en-GB-0.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:887d9c813a0a286e9b635713218e50042b8c1a5e49c753f4745abf7b6dc98d8d -size 57309 +oid sha256:d84daf5a9f2f6caed69fca648e8f677b3a1055f238d482bbfd7ede5769605bb6 +size 58978 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/roomAvatarImage.iPhone-16-pseudo-0.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/roomAvatarImage.iPhone-16-pseudo-0.png index e886c9bd9..9278d4cc8 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/roomAvatarImage.iPhone-16-pseudo-0.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/roomAvatarImage.iPhone-16-pseudo-0.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:887d9c813a0a286e9b635713218e50042b8c1a5e49c753f4745abf7b6dc98d8d -size 57309 +oid sha256:d84daf5a9f2f6caed69fca648e8f677b3a1055f238d482bbfd7ede5769605bb6 +size 58978 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/roomScreen.Tombstoned-iPad-en-GB.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/roomScreen.Tombstoned-iPad-en-GB.png new file mode 100644 index 000000000..fd612f0ad --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/roomScreen.Tombstoned-iPad-en-GB.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:42ce084b1cd46ffd146b54c669bae1fa6f842e02e9f840ae92972af4f035ba3e +size 352872 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/roomScreen.Tombstoned-iPad-pseudo.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/roomScreen.Tombstoned-iPad-pseudo.png new file mode 100644 index 000000000..82ffc4e12 --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/roomScreen.Tombstoned-iPad-pseudo.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7d73de09a9fbe543821b29fa1261d5175e3a0d994b90e21b71157bd05d463a48 +size 365960 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/roomScreen.Tombstoned-iPhone-16-en-GB.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/roomScreen.Tombstoned-iPhone-16-en-GB.png new file mode 100644 index 000000000..d9db1a2c9 --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/roomScreen.Tombstoned-iPhone-16-en-GB.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:816d2ea7bd4c6653e9c27a7735575ba05890a5f16d39d3d38db344a10e8c0ce9 +size 205525 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/roomScreen.Tombstoned-iPhone-16-pseudo.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/roomScreen.Tombstoned-iPhone-16-pseudo.png new file mode 100644 index 000000000..873cc7f2a --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/roomScreen.Tombstoned-iPhone-16-pseudo.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2a46c473e05f8b8fa538e78dc0bf33ba3867fe5b7a33fc2be325bfb75e7cd688 +size 213588 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/roomSelectionScreen.iPad-en-GB-0.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/roomSelectionScreen.iPad-en-GB-0.png index 8684c4847..606007272 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/roomSelectionScreen.iPad-en-GB-0.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/roomSelectionScreen.iPad-en-GB-0.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:69544d0b3042e3997689f0131e87af191929ef1b62647b22b13bfe362307db1d -size 162531 +oid sha256:348e37e04af9dc3297e28c01a33176594b63d01a701f16a1e3278666d4ffd41d +size 167050 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/roomSelectionScreen.iPad-pseudo-0.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/roomSelectionScreen.iPad-pseudo-0.png index 153a14eb7..30748b21d 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/roomSelectionScreen.iPad-pseudo-0.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/roomSelectionScreen.iPad-pseudo-0.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d224a0f3ea5243508744166a1ce4b635eeb4f08363e6c2558bf1ec2574ce8a1d -size 164014 +oid sha256:29acfd6916630e8a47dd3fc51eda53a0f3fbb0af609a72ceee08a7db5dec2396 +size 168533 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/roomSelectionScreen.iPhone-16-en-GB-0.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/roomSelectionScreen.iPhone-16-en-GB-0.png index fcb69de22..e09e15a6f 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/roomSelectionScreen.iPhone-16-en-GB-0.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/roomSelectionScreen.iPhone-16-en-GB-0.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a995e503150a60c80666fba9135b70b3d21a59134ec400f8caf9bac3df16c54c -size 110886 +oid sha256:993b6d680dd7fea259ab9debaeb45e5ee4fd58c0f029f87446692f5010eeacf8 +size 114591 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/roomSelectionScreen.iPhone-16-pseudo-0.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/roomSelectionScreen.iPhone-16-pseudo-0.png index 6b91338d4..7f0c6f910 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/roomSelectionScreen.iPhone-16-pseudo-0.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/roomSelectionScreen.iPhone-16-pseudo-0.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f5921b93c625428f436a43fec74d940a277d11fabbcf0e1412efbe574222101d -size 112186 +oid sha256:8eb5e58c5cdf0000578dbb5cf2185e80ba1bbf95e418b29bc850e9ba5eb05864 +size 115891 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineStartRoomTimelineView.iPad-en-GB-0.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineStartRoomTimelineView.iPad-en-GB-0.png index 2c0dd8e1a..583a21632 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineStartRoomTimelineView.iPad-en-GB-0.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineStartRoomTimelineView.iPad-en-GB-0.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:405dfc63227335d693dd6411d80516090c3ba34b029bd8e6d437734838e3019b -size 72781 +oid sha256:f6a23002b129e657affa39005cfd798b7cba69410cfc2217e8ca68473c9c1904 +size 12023 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineStartRoomTimelineView.iPad-pseudo-0.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineStartRoomTimelineView.iPad-pseudo-0.png index 2911b310e..2656c4f52 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineStartRoomTimelineView.iPad-pseudo-0.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineStartRoomTimelineView.iPad-pseudo-0.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:09f0344ac2df6a6480c4023c4172df5afebb9ef3520f6cde9ee16233f903df8a -size 76139 +oid sha256:af63be3b23ffe433d52a494b13182630cedbec07ef1787ef39904b8a085f206f +size 15444 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineStartRoomTimelineView.iPhone-16-en-GB-0.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineStartRoomTimelineView.iPhone-16-en-GB-0.png index bc246e453..80f774c3e 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineStartRoomTimelineView.iPhone-16-en-GB-0.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineStartRoomTimelineView.iPhone-16-en-GB-0.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8a79e77f39d2ff11558b0cd813b81e6bedcb25349872d151dfa02639e72835e9 -size 32196 +oid sha256:ca6209bc798f344af1923871ae59ce1c8bd91913dd50d7740d6352b5428e5d07 +size 8416 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineStartRoomTimelineView.iPhone-16-pseudo-0.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineStartRoomTimelineView.iPhone-16-pseudo-0.png index 99684315a..05f2af0ea 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineStartRoomTimelineView.iPhone-16-pseudo-0.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineStartRoomTimelineView.iPhone-16-pseudo-0.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:89c98670abb61eeb3e8af31bb4d0401f73f02645d9d2e777db85b401c540e501 -size 35560 +oid sha256:90137e56f48b5c2c84907876e21cebcfd4fd4c62b030669144e830fcb1a9bea1 +size 12081 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineStartRoomTimelineView.with-predecessor-iPad-en-GB.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineStartRoomTimelineView.with-predecessor-iPad-en-GB.png new file mode 100644 index 000000000..e3bc228ac --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineStartRoomTimelineView.with-predecessor-iPad-en-GB.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f4bc3686bbbd334bd0e159e5baed9580462fe18c10d22742604dae738d377f9a +size 86439 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineStartRoomTimelineView.with-predecessor-iPad-pseudo.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineStartRoomTimelineView.with-predecessor-iPad-pseudo.png new file mode 100644 index 000000000..4f010f13c --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineStartRoomTimelineView.with-predecessor-iPad-pseudo.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:205fe4317844539ef5f9fcfb2ea1e36d6a877272c3ee1804654cd25d9da08b28 +size 95010 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineStartRoomTimelineView.with-predecessor-iPhone-16-en-GB.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineStartRoomTimelineView.with-predecessor-iPhone-16-en-GB.png new file mode 100644 index 000000000..40ad87353 --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineStartRoomTimelineView.with-predecessor-iPhone-16-en-GB.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b4a9f8adea22b87db13d8f99f95908fdcf17010117857f98731921b15d214095 +size 44895 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineStartRoomTimelineView.with-predecessor-iPhone-16-pseudo.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineStartRoomTimelineView.with-predecessor-iPhone-16-pseudo.png new file mode 100644 index 000000000..ad39742d3 --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/timelineStartRoomTimelineView.with-predecessor-iPhone-16-pseudo.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cb0db63457ff2bfc24377e28ddd6d32833199ea5edceb23317dedee88547c381 +size 67013