mirror of
https://github.com/element-hq/element-x-ios.git
synced 2025-03-10 21:39:12 +00:00
Add a UserProfileScreen for profiles of non-members. (#2687)
This commit is contained in:
parent
47912d999b
commit
5c9d0975ce
@ -115,6 +115,7 @@
|
|||||||
1950A80CD198BED283DFC2CE /* ClientProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2958E6D247AE2516BEEE8 /* ClientProxy.swift */; };
|
1950A80CD198BED283DFC2CE /* ClientProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2958E6D247AE2516BEEE8 /* ClientProxy.swift */; };
|
||||||
19DED23340D0855B59693ED2 /* VoiceMessageRecorderProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D45C9EAA86423D7D3126DE4F /* VoiceMessageRecorderProtocol.swift */; };
|
19DED23340D0855B59693ED2 /* VoiceMessageRecorderProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D45C9EAA86423D7D3126DE4F /* VoiceMessageRecorderProtocol.swift */; };
|
||||||
19FE025AE9BA2959B6589B0D /* RoomMemberDetailsScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CC575D1895FA62591451A93 /* RoomMemberDetailsScreen.swift */; };
|
19FE025AE9BA2959B6589B0D /* RoomMemberDetailsScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CC575D1895FA62591451A93 /* RoomMemberDetailsScreen.swift */; };
|
||||||
|
1A3B073568D1DC8F76F1F3A0 /* UserProfileScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 23EE69982BBA18C6D51AD08E /* UserProfileScreen.swift */; };
|
||||||
1A70A2199394B5EC660934A5 /* MatrixRustSDK in Frameworks */ = {isa = PBXBuildFile; productRef = A678E40E917620059695F067 /* MatrixRustSDK */; };
|
1A70A2199394B5EC660934A5 /* MatrixRustSDK in Frameworks */ = {isa = PBXBuildFile; productRef = A678E40E917620059695F067 /* MatrixRustSDK */; };
|
||||||
1A83DD22F3E6F76B13B6E2F9 /* VideoRoomTimelineItemContent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8C8616254EE40CA8BA5E9BC2 /* VideoRoomTimelineItemContent.swift */; };
|
1A83DD22F3E6F76B13B6E2F9 /* VideoRoomTimelineItemContent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8C8616254EE40CA8BA5E9BC2 /* VideoRoomTimelineItemContent.swift */; };
|
||||||
1AB3D8563AB12635250A6A6E /* StaticLocationScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = C15E0017717EAE3A1D02D005 /* StaticLocationScreenCoordinator.swift */; };
|
1AB3D8563AB12635250A6A6E /* StaticLocationScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = C15E0017717EAE3A1D02D005 /* StaticLocationScreenCoordinator.swift */; };
|
||||||
@ -293,6 +294,7 @@
|
|||||||
4557192F5B15A8D9BB920232 /* AdvancedSettingsScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E492690C8B27A892C194CC4 /* AdvancedSettingsScreenCoordinator.swift */; };
|
4557192F5B15A8D9BB920232 /* AdvancedSettingsScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E492690C8B27A892C194CC4 /* AdvancedSettingsScreenCoordinator.swift */; };
|
||||||
46562110EE202E580A5FFD9C /* RoomScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93CF7B19FFCF8EFBE0A8696A /* RoomScreenViewModelTests.swift */; };
|
46562110EE202E580A5FFD9C /* RoomScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93CF7B19FFCF8EFBE0A8696A /* RoomScreenViewModelTests.swift */; };
|
||||||
4681820102DAC8BA586357D4 /* VoiceMessageCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB8D7926A5684E18196B538 /* VoiceMessageCache.swift */; };
|
4681820102DAC8BA586357D4 /* VoiceMessageCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB8D7926A5684E18196B538 /* VoiceMessageCache.swift */; };
|
||||||
|
46A183C6125A669AEB005699 /* UserProfileScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = F134D2D91DFF732FB75B2CB7 /* UserProfileScreenViewModelProtocol.swift */; };
|
||||||
46A261AA898344A1F3C406B1 /* ReportContentScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CCE3636E3D01477C8B2E9D0 /* ReportContentScreenModels.swift */; };
|
46A261AA898344A1F3C406B1 /* ReportContentScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CCE3636E3D01477C8B2E9D0 /* ReportContentScreenModels.swift */; };
|
||||||
46A6DB0F78FB399BD59E2D41 /* EncryptionKeyProviderProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = E78FC546F28E045A560F2963 /* EncryptionKeyProviderProtocol.swift */; };
|
46A6DB0F78FB399BD59E2D41 /* EncryptionKeyProviderProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = E78FC546F28E045A560F2963 /* EncryptionKeyProviderProtocol.swift */; };
|
||||||
46BA7F4B4D3A7164DED44B88 /* FullscreenDialog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 565F1B2B300597C616B37888 /* FullscreenDialog.swift */; };
|
46BA7F4B4D3A7164DED44B88 /* FullscreenDialog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 565F1B2B300597C616B37888 /* FullscreenDialog.swift */; };
|
||||||
@ -445,6 +447,7 @@
|
|||||||
69DE29C3E3180BB17D840690 /* ProgressCursorModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97C8E13A1FBA717B0C277ECC /* ProgressCursorModifier.swift */; };
|
69DE29C3E3180BB17D840690 /* ProgressCursorModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97C8E13A1FBA717B0C277ECC /* ProgressCursorModifier.swift */; };
|
||||||
6A0E7551E0D1793245F34CDD /* ClientError.swift in Sources */ = {isa = PBXBuildFile; fileRef = D09A267106B9585D3D0CFC0D /* ClientError.swift */; };
|
6A0E7551E0D1793245F34CDD /* ClientError.swift in Sources */ = {isa = PBXBuildFile; fileRef = D09A267106B9585D3D0CFC0D /* ClientError.swift */; };
|
||||||
6AD722DD92E465E56D2885AB /* BugReportScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA919F521E9F0EE3638AFC85 /* BugReportScreen.swift */; };
|
6AD722DD92E465E56D2885AB /* BugReportScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA919F521E9F0EE3638AFC85 /* BugReportScreen.swift */; };
|
||||||
|
6AEB650311F694A5702255C9 /* UserProfileScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5B4932E4EFBC8FAC10972CD /* UserProfileScreenCoordinator.swift */; };
|
||||||
6AECC84BE14A13440120FED8 /* NSESettingsProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FB4F169D653296023ED65E6 /* NSESettingsProtocol.swift */; };
|
6AECC84BE14A13440120FED8 /* NSESettingsProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FB4F169D653296023ED65E6 /* NSESettingsProtocol.swift */; };
|
||||||
6B05AA5D9BBCD6D8D63B80EB /* TimelineItemAccessibilityModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74C6F3DAD167F972702C8893 /* TimelineItemAccessibilityModifier.swift */; };
|
6B05AA5D9BBCD6D8D63B80EB /* TimelineItemAccessibilityModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74C6F3DAD167F972702C8893 /* TimelineItemAccessibilityModifier.swift */; };
|
||||||
6B31508C6334C617360C2EAB /* RoomMemberDetailsViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC589E641AE46EFB2962534D /* RoomMemberDetailsViewModelTests.swift */; };
|
6B31508C6334C617360C2EAB /* RoomMemberDetailsViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC589E641AE46EFB2962534D /* RoomMemberDetailsViewModelTests.swift */; };
|
||||||
@ -722,6 +725,7 @@
|
|||||||
AADE7C2497A7B55D8BED7BD6 /* IdentityConfirmedScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8319173DD66C07F45DC48848 /* IdentityConfirmedScreenViewModelProtocol.swift */; };
|
AADE7C2497A7B55D8BED7BD6 /* IdentityConfirmedScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8319173DD66C07F45DC48848 /* IdentityConfirmedScreenViewModelProtocol.swift */; };
|
||||||
AAF0BBED840DF4A53EE85E77 /* MatrixRustSDK in Frameworks */ = {isa = PBXBuildFile; productRef = C2C69B8BA5A9702E7A8BC08F /* MatrixRustSDK */; };
|
AAF0BBED840DF4A53EE85E77 /* MatrixRustSDK in Frameworks */ = {isa = PBXBuildFile; productRef = C2C69B8BA5A9702E7A8BC08F /* MatrixRustSDK */; };
|
||||||
ABF3FAB234AD3565B214309B /* TimelineSenderAvatarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0BC588051E6572A1AF51D738 /* TimelineSenderAvatarView.swift */; };
|
ABF3FAB234AD3565B214309B /* TimelineSenderAvatarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0BC588051E6572A1AF51D738 /* TimelineSenderAvatarView.swift */; };
|
||||||
|
AC1DB27A4134470846BE49F6 /* UserProfileScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0BD116096CAA9139B95EEA9C /* UserProfileScreenViewModel.swift */; };
|
||||||
AC69B6DF15FC451AB2945036 /* UserSessionStoreProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = BEBA759D1347CFFB3D84ED1F /* UserSessionStoreProtocol.swift */; };
|
AC69B6DF15FC451AB2945036 /* UserSessionStoreProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = BEBA759D1347CFFB3D84ED1F /* UserSessionStoreProtocol.swift */; };
|
||||||
AC7AA215D60FBC307F984028 /* Consumable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 127A57D053CE8C87B5EFB089 /* Consumable.swift */; };
|
AC7AA215D60FBC307F984028 /* Consumable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 127A57D053CE8C87B5EFB089 /* Consumable.swift */; };
|
||||||
AC90434798E7894370E80E66 /* SecureBackupScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D79BB714D28C9F588DD69353 /* SecureBackupScreenViewModelProtocol.swift */; };
|
AC90434798E7894370E80E66 /* SecureBackupScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D79BB714D28C9F588DD69353 /* SecureBackupScreenViewModelProtocol.swift */; };
|
||||||
@ -890,6 +894,7 @@
|
|||||||
D415764645491F10344FC6AC /* Publisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 60F18AECC9D38C2B6D85F99C /* Publisher.swift */; };
|
D415764645491F10344FC6AC /* Publisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 60F18AECC9D38C2B6D85F99C /* Publisher.swift */; };
|
||||||
D43F0503EF2CBC55272538FE /* SDKGeneratedMocks.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2F079B5DBD0D85FEA687AAE /* SDKGeneratedMocks.swift */; };
|
D43F0503EF2CBC55272538FE /* SDKGeneratedMocks.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2F079B5DBD0D85FEA687AAE /* SDKGeneratedMocks.swift */; };
|
||||||
D46C33F8B61B55F0C8C2D15F /* LocationRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B2AC540DE619B36832A5DB5 /* LocationRoomTimelineItem.swift */; };
|
D46C33F8B61B55F0C8C2D15F /* LocationRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B2AC540DE619B36832A5DB5 /* LocationRoomTimelineItem.swift */; };
|
||||||
|
D4CB979EB4FE26AAD9F9A72B /* UserProfileScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 604A69C081B935D6A38DE6D8 /* UserProfileScreenModels.swift */; };
|
||||||
D4D5595C4A2A702CFF4E94FF /* HeroImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7EC2F1622C5BBABED6012E12 /* HeroImage.swift */; };
|
D4D5595C4A2A702CFF4E94FF /* HeroImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7EC2F1622C5BBABED6012E12 /* HeroImage.swift */; };
|
||||||
D4D7CCECC6C0AAFC42E165BB /* NotificationPermissionsScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE9BBB18FB27F09032AD8769 /* NotificationPermissionsScreenViewModel.swift */; };
|
D4D7CCECC6C0AAFC42E165BB /* NotificationPermissionsScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE9BBB18FB27F09032AD8769 /* NotificationPermissionsScreenViewModel.swift */; };
|
||||||
D53B80EF02C1062E68659EDD /* ReportContentViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 086C19086DD16E9B38E25954 /* ReportContentViewModelTests.swift */; };
|
D53B80EF02C1062E68659EDD /* ReportContentViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 086C19086DD16E9B38E25954 /* ReportContentViewModelTests.swift */; };
|
||||||
@ -1169,6 +1174,7 @@
|
|||||||
0BB05221D7D941CC82DC8480 /* LogViewerScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogViewerScreenViewModel.swift; sourceTree = "<group>"; };
|
0BB05221D7D941CC82DC8480 /* LogViewerScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogViewerScreenViewModel.swift; sourceTree = "<group>"; };
|
||||||
0BC588051E6572A1AF51D738 /* TimelineSenderAvatarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineSenderAvatarView.swift; sourceTree = "<group>"; };
|
0BC588051E6572A1AF51D738 /* TimelineSenderAvatarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineSenderAvatarView.swift; sourceTree = "<group>"; };
|
||||||
0BCE3FAF40932AC7C7639AC4 /* AnalyticsSettingsScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnalyticsSettingsScreenViewModel.swift; sourceTree = "<group>"; };
|
0BCE3FAF40932AC7C7639AC4 /* AnalyticsSettingsScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnalyticsSettingsScreenViewModel.swift; sourceTree = "<group>"; };
|
||||||
|
0BD116096CAA9139B95EEA9C /* UserProfileScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserProfileScreenViewModel.swift; sourceTree = "<group>"; };
|
||||||
0C34667458773B02AB5FB0B2 /* LegalInformationScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LegalInformationScreenViewModel.swift; sourceTree = "<group>"; };
|
0C34667458773B02AB5FB0B2 /* LegalInformationScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LegalInformationScreenViewModel.swift; sourceTree = "<group>"; };
|
||||||
0C62E07C1164F5120727A2A8 /* AppLockSetupBiometricsScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppLockSetupBiometricsScreenCoordinator.swift; sourceTree = "<group>"; };
|
0C62E07C1164F5120727A2A8 /* AppLockSetupBiometricsScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppLockSetupBiometricsScreenCoordinator.swift; sourceTree = "<group>"; };
|
||||||
0CCC6C31102E1D8B9106DEDE /* AppLockSetupBiometricsScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppLockSetupBiometricsScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
0CCC6C31102E1D8B9106DEDE /* AppLockSetupBiometricsScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppLockSetupBiometricsScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
||||||
@ -1268,6 +1274,7 @@
|
|||||||
2389732B0E115A999A069083 /* NotificationSettingsScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationSettingsScreenCoordinator.swift; sourceTree = "<group>"; };
|
2389732B0E115A999A069083 /* NotificationSettingsScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationSettingsScreenCoordinator.swift; sourceTree = "<group>"; };
|
||||||
23AA3F4B285570805CB0CCDD /* MapTiler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapTiler.swift; sourceTree = "<group>"; };
|
23AA3F4B285570805CB0CCDD /* MapTiler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapTiler.swift; sourceTree = "<group>"; };
|
||||||
23E6EB7960BC9D0F7396B3BD /* RoomChangeRolesScreenRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomChangeRolesScreenRow.swift; sourceTree = "<group>"; };
|
23E6EB7960BC9D0F7396B3BD /* RoomChangeRolesScreenRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomChangeRolesScreenRow.swift; sourceTree = "<group>"; };
|
||||||
|
23EE69982BBA18C6D51AD08E /* UserProfileScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserProfileScreen.swift; sourceTree = "<group>"; };
|
||||||
240610DF32F3213BEC5611D7 /* BlockedUsersScreenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlockedUsersScreenViewModelTests.swift; sourceTree = "<group>"; };
|
240610DF32F3213BEC5611D7 /* BlockedUsersScreenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlockedUsersScreenViewModelTests.swift; sourceTree = "<group>"; };
|
||||||
24227FF9A2797F6EA7F69CDD /* HomeScreenInvitesButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeScreenInvitesButton.swift; sourceTree = "<group>"; };
|
24227FF9A2797F6EA7F69CDD /* HomeScreenInvitesButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeScreenInvitesButton.swift; sourceTree = "<group>"; };
|
||||||
2429224EB0EEA34D35CE9249 /* UserIndicatorControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserIndicatorControllerTests.swift; sourceTree = "<group>"; };
|
2429224EB0EEA34D35CE9249 /* UserIndicatorControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserIndicatorControllerTests.swift; sourceTree = "<group>"; };
|
||||||
@ -1499,6 +1506,7 @@
|
|||||||
5F4134FEFE4EB55759017408 /* UserSessionProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserSessionProtocol.swift; sourceTree = "<group>"; };
|
5F4134FEFE4EB55759017408 /* UserSessionProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserSessionProtocol.swift; sourceTree = "<group>"; };
|
||||||
5FACD034DB52525A3CEF2BDF /* SessionVerificationScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionVerificationScreen.swift; sourceTree = "<group>"; };
|
5FACD034DB52525A3CEF2BDF /* SessionVerificationScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionVerificationScreen.swift; sourceTree = "<group>"; };
|
||||||
6033779EB37259F27F938937 /* ClientProxyProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClientProxyProtocol.swift; sourceTree = "<group>"; };
|
6033779EB37259F27F938937 /* ClientProxyProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClientProxyProtocol.swift; sourceTree = "<group>"; };
|
||||||
|
604A69C081B935D6A38DE6D8 /* UserProfileScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserProfileScreenModels.swift; sourceTree = "<group>"; };
|
||||||
60F18AECC9D38C2B6D85F99C /* Publisher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Publisher.swift; sourceTree = "<group>"; };
|
60F18AECC9D38C2B6D85F99C /* Publisher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Publisher.swift; sourceTree = "<group>"; };
|
||||||
612EF972F2A1800682D32C5E /* StickerRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StickerRoomTimelineView.swift; sourceTree = "<group>"; };
|
612EF972F2A1800682D32C5E /* StickerRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StickerRoomTimelineView.swift; sourceTree = "<group>"; };
|
||||||
61B33F23681660E940BA57F4 /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/SAS.strings; sourceTree = "<group>"; };
|
61B33F23681660E940BA57F4 /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/SAS.strings; sourceTree = "<group>"; };
|
||||||
@ -1965,6 +1973,7 @@
|
|||||||
D529B976F8B2AA654D923422 /* VoiceMessageRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VoiceMessageRoomTimelineItem.swift; sourceTree = "<group>"; };
|
D529B976F8B2AA654D923422 /* VoiceMessageRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VoiceMessageRoomTimelineItem.swift; sourceTree = "<group>"; };
|
||||||
D54E12B98252F6C527E31FEE /* MediaUploadPreviewScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaUploadPreviewScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
D54E12B98252F6C527E31FEE /* MediaUploadPreviewScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaUploadPreviewScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
||||||
D5AC06FC11B6638F7BF1670E /* TimelineDeliveryStatusView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineDeliveryStatusView.swift; sourceTree = "<group>"; };
|
D5AC06FC11B6638F7BF1670E /* TimelineDeliveryStatusView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineDeliveryStatusView.swift; sourceTree = "<group>"; };
|
||||||
|
D5B4932E4EFBC8FAC10972CD /* UserProfileScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserProfileScreenCoordinator.swift; sourceTree = "<group>"; };
|
||||||
D5E26C54362206BBDD096D83 /* test_audio.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; path = test_audio.mp3; sourceTree = "<group>"; };
|
D5E26C54362206BBDD096D83 /* test_audio.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; path = test_audio.mp3; sourceTree = "<group>"; };
|
||||||
D5EA0312A6262484AA393AC9 /* CompletionSuggestionServiceTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CompletionSuggestionServiceTests.swift; sourceTree = "<group>"; };
|
D5EA0312A6262484AA393AC9 /* CompletionSuggestionServiceTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CompletionSuggestionServiceTests.swift; sourceTree = "<group>"; };
|
||||||
D622EC7898469BB1D0881CDD /* PollFormScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PollFormScreen.swift; sourceTree = "<group>"; };
|
D622EC7898469BB1D0881CDD /* PollFormScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PollFormScreen.swift; sourceTree = "<group>"; };
|
||||||
@ -2075,6 +2084,7 @@
|
|||||||
F08776C48FFB47CACF64ED10 /* ServerConfirmationScreenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerConfirmationScreenViewModelTests.swift; sourceTree = "<group>"; };
|
F08776C48FFB47CACF64ED10 /* ServerConfirmationScreenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerConfirmationScreenViewModelTests.swift; sourceTree = "<group>"; };
|
||||||
F0B9F5BC4C80543DE7228B9D /* MapTilerStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapTilerStyle.swift; sourceTree = "<group>"; };
|
F0B9F5BC4C80543DE7228B9D /* MapTilerStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapTilerStyle.swift; sourceTree = "<group>"; };
|
||||||
F0E14FF533D25A0692F7CEB0 /* RoomPollsHistoryScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomPollsHistoryScreenViewModel.swift; sourceTree = "<group>"; };
|
F0E14FF533D25A0692F7CEB0 /* RoomPollsHistoryScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomPollsHistoryScreenViewModel.swift; sourceTree = "<group>"; };
|
||||||
|
F134D2D91DFF732FB75B2CB7 /* UserProfileScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserProfileScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
||||||
F174A5627CDB3CAF280D1880 /* EmojiPickerScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmojiPickerScreenModels.swift; sourceTree = "<group>"; };
|
F174A5627CDB3CAF280D1880 /* EmojiPickerScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmojiPickerScreenModels.swift; sourceTree = "<group>"; };
|
||||||
F17EFA1D3D09FC2F9C5E1CB2 /* MediaProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaProvider.swift; sourceTree = "<group>"; };
|
F17EFA1D3D09FC2F9C5E1CB2 /* MediaProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaProvider.swift; sourceTree = "<group>"; };
|
||||||
F1B8500C152BC59445647DA8 /* UnsupportedRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnsupportedRoomTimelineItem.swift; sourceTree = "<group>"; };
|
F1B8500C152BC59445647DA8 /* UnsupportedRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnsupportedRoomTimelineItem.swift; sourceTree = "<group>"; };
|
||||||
@ -3863,6 +3873,14 @@
|
|||||||
path = Session;
|
path = Session;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
832EB453B3A5D04C18D86117 /* View */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
23EE69982BBA18C6D51AD08E /* UserProfileScreen.swift */,
|
||||||
|
);
|
||||||
|
path = View;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
832FC81F760220239E285294 /* Proxy */ = {
|
832FC81F760220239E285294 /* Proxy */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@ -4015,6 +4033,18 @@
|
|||||||
path = ElementCall;
|
path = ElementCall;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
93C7520ED23C9598BB144DBB /* UserProfileScreen */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
D5B4932E4EFBC8FAC10972CD /* UserProfileScreenCoordinator.swift */,
|
||||||
|
604A69C081B935D6A38DE6D8 /* UserProfileScreenModels.swift */,
|
||||||
|
0BD116096CAA9139B95EEA9C /* UserProfileScreenViewModel.swift */,
|
||||||
|
F134D2D91DFF732FB75B2CB7 /* UserProfileScreenViewModelProtocol.swift */,
|
||||||
|
832EB453B3A5D04C18D86117 /* View */,
|
||||||
|
);
|
||||||
|
path = UserProfileScreen;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
948DD12A5533BE1BC260E437 /* LocationSharing */ = {
|
948DD12A5533BE1BC260E437 /* LocationSharing */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@ -4873,6 +4903,7 @@
|
|||||||
2565414373E6F68005966B8E /* SecureBackup */,
|
2565414373E6F68005966B8E /* SecureBackup */,
|
||||||
70B74A432C241E56A7ACE610 /* Settings */,
|
70B74A432C241E56A7ACE610 /* Settings */,
|
||||||
EC4545C7E37E8294D3FE6800 /* StartChatScreen */,
|
EC4545C7E37E8294D3FE6800 /* StartChatScreen */,
|
||||||
|
93C7520ED23C9598BB144DBB /* UserProfileScreen */,
|
||||||
);
|
);
|
||||||
path = Screens;
|
path = Screens;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -6504,6 +6535,11 @@
|
|||||||
80DEA2A4B20F9E279EAE6B2B /* UserProfile+Mock.swift in Sources */,
|
80DEA2A4B20F9E279EAE6B2B /* UserProfile+Mock.swift in Sources */,
|
||||||
ED90A59F068FD0CA27E602ED /* UserProfileListRow.swift in Sources */,
|
ED90A59F068FD0CA27E602ED /* UserProfileListRow.swift in Sources */,
|
||||||
E21FE4C5B614F311C0955859 /* UserProfileProxy.swift in Sources */,
|
E21FE4C5B614F311C0955859 /* UserProfileProxy.swift in Sources */,
|
||||||
|
1A3B073568D1DC8F76F1F3A0 /* UserProfileScreen.swift in Sources */,
|
||||||
|
6AEB650311F694A5702255C9 /* UserProfileScreenCoordinator.swift in Sources */,
|
||||||
|
D4CB979EB4FE26AAD9F9A72B /* UserProfileScreenModels.swift in Sources */,
|
||||||
|
AC1DB27A4134470846BE49F6 /* UserProfileScreenViewModel.swift in Sources */,
|
||||||
|
46A183C6125A669AEB005699 /* UserProfileScreenViewModelProtocol.swift in Sources */,
|
||||||
8AB8ED1051216546CB35FA0E /* UserSession.swift in Sources */,
|
8AB8ED1051216546CB35FA0E /* UserSession.swift in Sources */,
|
||||||
4A618590DEB72C4F186BFED4 /* UserSessionFlowCoordinator.swift in Sources */,
|
4A618590DEB72C4F186BFED4 /* UserSessionFlowCoordinator.swift in Sources */,
|
||||||
3113065AABBC14CEAE6843FA /* UserSessionFlowCoordinatorStateMachine.swift in Sources */,
|
3113065AABBC14CEAE6843FA /* UserSessionFlowCoordinatorStateMachine.swift in Sources */,
|
||||||
|
@ -186,6 +186,11 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
|
|||||||
case (.roomMemberDetails(_, let fromRoomMembersList), .dismissRoomMemberDetails):
|
case (.roomMemberDetails(_, let fromRoomMembersList), .dismissRoomMemberDetails):
|
||||||
return fromRoomMembersList ? .roomMembersList : .room
|
return fromRoomMembersList ? .roomMembersList : .room
|
||||||
|
|
||||||
|
case (.roomMemberDetails(_, fromRoomMembersList: false), .presentUserProfile(let userID)):
|
||||||
|
return .userProfile(userID: userID)
|
||||||
|
case (.userProfile, .dismissUserProfile):
|
||||||
|
return .room
|
||||||
|
|
||||||
case (.roomDetails, .presentInviteUsersScreen):
|
case (.roomDetails, .presentInviteUsersScreen):
|
||||||
return .inviteUsersScreen(fromRoomMembersList: false)
|
return .inviteUsersScreen(fromRoomMembersList: false)
|
||||||
case (.roomMembersList, .presentInviteUsersScreen):
|
case (.roomMembersList, .presentInviteUsersScreen):
|
||||||
@ -305,6 +310,11 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
|
|||||||
case (.roomMemberDetails, .dismissRoomMemberDetails, .roomMembersList):
|
case (.roomMemberDetails, .dismissRoomMemberDetails, .roomMembersList):
|
||||||
break
|
break
|
||||||
|
|
||||||
|
case (.roomMemberDetails, .presentUserProfile(let userID), .userProfile):
|
||||||
|
replaceRoomMemberDetailsWithUserProfile(userID: userID)
|
||||||
|
case (.userProfile, .dismissUserProfile, .room):
|
||||||
|
break
|
||||||
|
|
||||||
case (.roomDetails, .presentInviteUsersScreen, .inviteUsersScreen):
|
case (.roomDetails, .presentInviteUsersScreen, .inviteUsersScreen):
|
||||||
presentInviteUsersScreen()
|
presentInviteUsersScreen()
|
||||||
case (.inviteUsersScreen, .dismissInviteUsersScreen, .roomDetails):
|
case (.inviteUsersScreen, .dismissInviteUsersScreen, .roomDetails):
|
||||||
@ -874,35 +884,10 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
|
|||||||
coordinator.actions.sink { [weak self] action in
|
coordinator.actions.sink { [weak self] action in
|
||||||
guard let self else { return }
|
guard let self else { return }
|
||||||
switch action {
|
switch action {
|
||||||
|
case .openUserProfile:
|
||||||
|
stateMachine.tryEvent(.presentUserProfile(userID: userID))
|
||||||
case .openDirectChat(let displayName):
|
case .openDirectChat(let displayName):
|
||||||
let loadingIndicatorIdentifier = "OpenDirectChatLoadingIndicator"
|
openDirectChat(with: userID, displayName: displayName)
|
||||||
|
|
||||||
userIndicatorController.submitIndicator(UserIndicator(id: loadingIndicatorIdentifier,
|
|
||||||
type: .modal(progress: .indeterminate, interactiveDismissDisabled: true, allowsInteraction: false),
|
|
||||||
title: L10n.commonLoading,
|
|
||||||
persistent: true))
|
|
||||||
|
|
||||||
Task { [weak self] in
|
|
||||||
guard let self else { return }
|
|
||||||
|
|
||||||
let currentDirectRoom = await userSession.clientProxy.directRoomForUserID(userID)
|
|
||||||
switch currentDirectRoom {
|
|
||||||
case .success(.some(let roomID)):
|
|
||||||
stateMachine.tryEvent(.presentChildRoom(roomID: roomID))
|
|
||||||
case .success(nil):
|
|
||||||
switch await userSession.clientProxy.createDirectRoom(with: userID, expectedRoomName: displayName) {
|
|
||||||
case .success(let roomID):
|
|
||||||
analytics.trackCreatedRoom(isDM: true)
|
|
||||||
stateMachine.tryEvent(.presentChildRoom(roomID: roomID))
|
|
||||||
case .failure:
|
|
||||||
userIndicatorController.alertInfo = .init(id: UUID())
|
|
||||||
}
|
|
||||||
case .failure:
|
|
||||||
userIndicatorController.alertInfo = .init(id: UUID())
|
|
||||||
}
|
|
||||||
|
|
||||||
userIndicatorController.retractIndicatorWithId(loadingIndicatorIdentifier)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.store(in: &cancellables)
|
.store(in: &cancellables)
|
||||||
@ -912,6 +897,60 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func replaceRoomMemberDetailsWithUserProfile(userID: String) {
|
||||||
|
let parameters = UserProfileScreenCoordinatorParameters(userID: userID,
|
||||||
|
clientProxy: userSession.clientProxy,
|
||||||
|
mediaProvider: userSession.mediaProvider,
|
||||||
|
userIndicatorController: userIndicatorController)
|
||||||
|
let coordinator = UserProfileScreenCoordinator(parameters: parameters)
|
||||||
|
coordinator.actionsPublisher.sink { [weak self] action in
|
||||||
|
guard let self else { return }
|
||||||
|
|
||||||
|
switch action {
|
||||||
|
case .openDirectChat(let displayName):
|
||||||
|
openDirectChat(with: userID, displayName: displayName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.store(in: &cancellables)
|
||||||
|
|
||||||
|
// Replace the RoomMemberDetailsScreen without any animation.
|
||||||
|
navigationStackCoordinator.pop(animated: false)
|
||||||
|
navigationStackCoordinator.push(coordinator, animated: false) { [weak self] in
|
||||||
|
self?.stateMachine.tryEvent(.dismissUserProfile)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func openDirectChat(with userID: String, displayName: String?) {
|
||||||
|
let loadingIndicatorIdentifier = "OpenDirectChatLoadingIndicator"
|
||||||
|
|
||||||
|
userIndicatorController.submitIndicator(UserIndicator(id: loadingIndicatorIdentifier,
|
||||||
|
type: .modal(progress: .indeterminate, interactiveDismissDisabled: true, allowsInteraction: false),
|
||||||
|
title: L10n.commonLoading,
|
||||||
|
persistent: true))
|
||||||
|
|
||||||
|
Task { [weak self] in
|
||||||
|
guard let self else { return }
|
||||||
|
|
||||||
|
let currentDirectRoom = await userSession.clientProxy.directRoomForUserID(userID)
|
||||||
|
switch currentDirectRoom {
|
||||||
|
case .success(.some(let roomID)):
|
||||||
|
stateMachine.tryEvent(.presentChildRoom(roomID: roomID))
|
||||||
|
case .success(nil):
|
||||||
|
switch await userSession.clientProxy.createDirectRoom(with: userID, expectedRoomName: displayName) {
|
||||||
|
case .success(let roomID):
|
||||||
|
analytics.trackCreatedRoom(isDM: true)
|
||||||
|
stateMachine.tryEvent(.presentChildRoom(roomID: roomID))
|
||||||
|
case .failure:
|
||||||
|
userIndicatorController.alertInfo = .init(id: UUID())
|
||||||
|
}
|
||||||
|
case .failure:
|
||||||
|
userIndicatorController.alertInfo = .init(id: UUID())
|
||||||
|
}
|
||||||
|
|
||||||
|
userIndicatorController.retractIndicatorWithId(loadingIndicatorIdentifier)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private func presentMessageForwarding(for itemID: TimelineItemIdentifier) {
|
private func presentMessageForwarding(for itemID: TimelineItemIdentifier) {
|
||||||
guard let roomSummaryProvider = userSession.clientProxy.alternateRoomSummaryProvider, let eventID = itemID.eventID else {
|
guard let roomSummaryProvider = userSession.clientProxy.alternateRoomSummaryProvider, let eventID = itemID.eventID else {
|
||||||
fatalError()
|
fatalError()
|
||||||
@ -1160,6 +1199,7 @@ private extension RoomFlowCoordinator {
|
|||||||
case globalNotificationSettings
|
case globalNotificationSettings
|
||||||
case roomMembersList
|
case roomMembersList
|
||||||
case roomMemberDetails(userID: String, fromRoomMembersList: Bool)
|
case roomMemberDetails(userID: String, fromRoomMembersList: Bool)
|
||||||
|
case userProfile(userID: String)
|
||||||
case inviteUsersScreen(fromRoomMembersList: Bool)
|
case inviteUsersScreen(fromRoomMembersList: Bool)
|
||||||
case mediaUploadPicker(source: MediaPickerScreenSource)
|
case mediaUploadPicker(source: MediaPickerScreenSource)
|
||||||
case mediaUploadPreview(fileURL: URL)
|
case mediaUploadPreview(fileURL: URL)
|
||||||
@ -1207,6 +1247,9 @@ private extension RoomFlowCoordinator {
|
|||||||
case presentRoomMemberDetails(userID: String)
|
case presentRoomMemberDetails(userID: String)
|
||||||
case dismissRoomMemberDetails
|
case dismissRoomMemberDetails
|
||||||
|
|
||||||
|
case presentUserProfile(userID: String)
|
||||||
|
case dismissUserProfile
|
||||||
|
|
||||||
case presentInviteUsersScreen
|
case presentInviteUsersScreen
|
||||||
case dismissInviteUsersScreen
|
case dismissInviteUsersScreen
|
||||||
|
|
||||||
|
@ -59,6 +59,22 @@ struct AvatarHeaderView<Footer: View>: View {
|
|||||||
self.footer = footer
|
self.footer = footer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
init(user: UserProfileProxy,
|
||||||
|
avatarSize: AvatarSize,
|
||||||
|
imageProvider: ImageProviderProtocol? = nil,
|
||||||
|
onAvatarTap: (() -> Void)? = nil,
|
||||||
|
@ViewBuilder footer: @escaping () -> Footer) {
|
||||||
|
id = user.userID
|
||||||
|
name = user.displayName
|
||||||
|
subtitle = user.displayName == nil ? nil : user.userID
|
||||||
|
avatarURL = user.avatarURL
|
||||||
|
|
||||||
|
self.avatarSize = avatarSize
|
||||||
|
self.imageProvider = imageProvider
|
||||||
|
self.onAvatarTap = onAvatarTap
|
||||||
|
self.footer = footer
|
||||||
|
}
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
VStack(spacing: 8.0) {
|
VStack(spacing: 8.0) {
|
||||||
Button {
|
Button {
|
||||||
|
@ -26,6 +26,7 @@ struct RoomMemberDetailsScreenCoordinatorParameters {
|
|||||||
}
|
}
|
||||||
|
|
||||||
enum RoomMemberDetailsScreenCoordinatorAction {
|
enum RoomMemberDetailsScreenCoordinatorAction {
|
||||||
|
case openUserProfile
|
||||||
case openDirectChat(displayName: String?)
|
case openDirectChat(displayName: String?)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,6 +53,8 @@ final class RoomMemberDetailsScreenCoordinator: CoordinatorProtocol {
|
|||||||
guard let self else { return }
|
guard let self else { return }
|
||||||
|
|
||||||
switch action {
|
switch action {
|
||||||
|
case .openUserProfile:
|
||||||
|
actionsSubject.send(.openUserProfile)
|
||||||
case .openDirectChat(let displayName):
|
case .openDirectChat(let displayName):
|
||||||
actionsSubject.send(.openDirectChat(displayName: displayName))
|
actionsSubject.send(.openDirectChat(displayName: displayName))
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
enum RoomMemberDetailsScreenViewModelAction {
|
enum RoomMemberDetailsScreenViewModelAction {
|
||||||
|
case openUserProfile
|
||||||
case openDirectChat(displayName: String?)
|
case openDirectChat(displayName: String?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,8 +59,8 @@ class RoomMemberDetailsScreenViewModel: RoomMemberDetailsScreenViewModelType, Ro
|
|||||||
state.memberDetails = RoomMemberDetails(withProxy: member)
|
state.memberDetails = RoomMemberDetails(withProxy: member)
|
||||||
state.isOwnMemberDetails = member.userID == roomProxy.ownUserID
|
state.isOwnMemberDetails = member.userID == roomProxy.ownUserID
|
||||||
case .failure(let error):
|
case .failure(let error):
|
||||||
state.bindings.alertInfo = .init(id: .unknown)
|
MXLog.warning("Failed to find member: \(error)")
|
||||||
MXLog.error("[RoomFlowCoordinator] Failed to get member: \(error)")
|
actionsSubject.send(.openUserProfile)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,19 +21,6 @@ struct RoomMemberDetailsScreen: View {
|
|||||||
@ObservedObject var context: RoomMemberDetailsScreenViewModel.Context
|
@ObservedObject var context: RoomMemberDetailsScreenViewModel.Context
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
content
|
|
||||||
.compoundList()
|
|
||||||
.navigationTitle(L10n.screenRoomMemberDetailsTitle)
|
|
||||||
.alert(item: $context.ignoreUserAlert, actions: blockUserAlertActions, message: blockUserAlertMessage)
|
|
||||||
.alert(item: $context.alertInfo)
|
|
||||||
.track(screen: .User)
|
|
||||||
.interactiveQuickLook(item: $context.mediaPreviewItem, shouldHideControls: true)
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - Private
|
|
||||||
|
|
||||||
@ViewBuilder
|
|
||||||
private var content: some View {
|
|
||||||
Form {
|
Form {
|
||||||
headerSection
|
headerSection
|
||||||
|
|
||||||
@ -42,8 +29,16 @@ struct RoomMemberDetailsScreen: View {
|
|||||||
blockUserSection
|
blockUserSection
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.compoundList()
|
||||||
|
.navigationTitle(L10n.screenRoomMemberDetailsTitle)
|
||||||
|
.alert(item: $context.ignoreUserAlert, actions: blockUserAlertActions, message: blockUserAlertMessage)
|
||||||
|
.alert(item: $context.alertInfo)
|
||||||
|
.track(screen: .User)
|
||||||
|
.interactiveQuickLook(item: $context.mediaPreviewItem, shouldHideControls: true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: - Private
|
||||||
|
|
||||||
@ViewBuilder
|
@ViewBuilder
|
||||||
private var headerSection: some View {
|
private var headerSection: some View {
|
||||||
if let memberDetails = context.viewState.memberDetails {
|
if let memberDetails = context.viewState.memberDetails {
|
||||||
@ -63,7 +58,7 @@ struct RoomMemberDetailsScreen: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
AvatarHeaderView(member: .init(loading: context.viewState.userID),
|
AvatarHeaderView(user: UserProfileProxy(userID: context.viewState.userID),
|
||||||
avatarSize: .user(on: .memberDetails),
|
avatarSize: .user(on: .memberDetails),
|
||||||
imageProvider: context.imageProvider,
|
imageProvider: context.imageProvider,
|
||||||
footer: { })
|
footer: { })
|
||||||
|
@ -0,0 +1,67 @@
|
|||||||
|
//
|
||||||
|
// 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 Combine
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct UserProfileScreenCoordinatorParameters {
|
||||||
|
let userID: String
|
||||||
|
let clientProxy: ClientProxyProtocol
|
||||||
|
let mediaProvider: MediaProviderProtocol
|
||||||
|
let userIndicatorController: UserIndicatorControllerProtocol
|
||||||
|
}
|
||||||
|
|
||||||
|
enum UserProfileScreenCoordinatorAction {
|
||||||
|
case openDirectChat(displayName: String?)
|
||||||
|
}
|
||||||
|
|
||||||
|
final class UserProfileScreenCoordinator: CoordinatorProtocol {
|
||||||
|
private var viewModel: UserProfileScreenViewModelProtocol
|
||||||
|
|
||||||
|
private var cancellables = Set<AnyCancellable>()
|
||||||
|
|
||||||
|
private let actionsSubject: PassthroughSubject<UserProfileScreenCoordinatorAction, Never> = .init()
|
||||||
|
var actionsPublisher: AnyPublisher<UserProfileScreenCoordinatorAction, Never> {
|
||||||
|
actionsSubject.eraseToAnyPublisher()
|
||||||
|
}
|
||||||
|
|
||||||
|
init(parameters: UserProfileScreenCoordinatorParameters) {
|
||||||
|
viewModel = UserProfileScreenViewModel(userID: parameters.userID,
|
||||||
|
clientProxy: parameters.clientProxy,
|
||||||
|
mediaProvider: parameters.mediaProvider,
|
||||||
|
userIndicatorController: parameters.userIndicatorController)
|
||||||
|
}
|
||||||
|
|
||||||
|
func start() {
|
||||||
|
viewModel.actionsPublisher.sink { [weak self] action in
|
||||||
|
guard let self else { return }
|
||||||
|
|
||||||
|
switch action {
|
||||||
|
case .openDirectChat(let displayName):
|
||||||
|
actionsSubject.send(.openDirectChat(displayName: displayName))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.store(in: &cancellables)
|
||||||
|
}
|
||||||
|
|
||||||
|
func stop() {
|
||||||
|
viewModel.stop()
|
||||||
|
}
|
||||||
|
|
||||||
|
func toPresentable() -> AnyView {
|
||||||
|
AnyView(UserProfileScreen(context: viewModel.context))
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,47 @@
|
|||||||
|
//
|
||||||
|
// 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 Foundation
|
||||||
|
|
||||||
|
enum UserProfileScreenViewModelAction {
|
||||||
|
case openDirectChat(displayName: String?)
|
||||||
|
}
|
||||||
|
|
||||||
|
struct UserProfileScreenViewState: BindableState {
|
||||||
|
let userID: String
|
||||||
|
let isOwnUser: Bool
|
||||||
|
|
||||||
|
var userProfile: UserProfileProxy?
|
||||||
|
var permalink: URL?
|
||||||
|
|
||||||
|
var bindings: UserProfileScreenViewStateBindings
|
||||||
|
}
|
||||||
|
|
||||||
|
struct UserProfileScreenViewStateBindings {
|
||||||
|
var alertInfo: AlertInfo<UserProfileScreenError>?
|
||||||
|
|
||||||
|
/// A media item that will be previewed with QuickLook.
|
||||||
|
var mediaPreviewItem: MediaPreviewItem?
|
||||||
|
}
|
||||||
|
|
||||||
|
enum UserProfileScreenViewAction {
|
||||||
|
case displayAvatar
|
||||||
|
case openDirectChat
|
||||||
|
}
|
||||||
|
|
||||||
|
enum UserProfileScreenError: Hashable {
|
||||||
|
case unknown
|
||||||
|
}
|
@ -0,0 +1,119 @@
|
|||||||
|
//
|
||||||
|
// 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 Combine
|
||||||
|
import MatrixRustSDK
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
typealias UserProfileScreenViewModelType = StateStoreViewModel<UserProfileScreenViewState, UserProfileScreenViewAction>
|
||||||
|
|
||||||
|
class UserProfileScreenViewModel: UserProfileScreenViewModelType, UserProfileScreenViewModelProtocol {
|
||||||
|
private let clientProxy: ClientProxyProtocol
|
||||||
|
private let mediaProvider: MediaProviderProtocol
|
||||||
|
private let userIndicatorController: UserIndicatorControllerProtocol
|
||||||
|
|
||||||
|
private var actionsSubject: PassthroughSubject<UserProfileScreenViewModelAction, Never> = .init()
|
||||||
|
var actionsPublisher: AnyPublisher<UserProfileScreenViewModelAction, Never> {
|
||||||
|
actionsSubject.eraseToAnyPublisher()
|
||||||
|
}
|
||||||
|
|
||||||
|
init(userID: String,
|
||||||
|
clientProxy: ClientProxyProtocol,
|
||||||
|
mediaProvider: MediaProviderProtocol,
|
||||||
|
userIndicatorController: UserIndicatorControllerProtocol) {
|
||||||
|
self.clientProxy = clientProxy
|
||||||
|
self.mediaProvider = mediaProvider
|
||||||
|
self.userIndicatorController = userIndicatorController
|
||||||
|
|
||||||
|
let initialViewState = UserProfileScreenViewState(userID: userID,
|
||||||
|
isOwnUser: userID == clientProxy.userID,
|
||||||
|
bindings: .init())
|
||||||
|
|
||||||
|
super.init(initialViewState: initialViewState, imageProvider: mediaProvider)
|
||||||
|
|
||||||
|
showMemberLoadingIndicator()
|
||||||
|
Task {
|
||||||
|
defer {
|
||||||
|
hideMemberLoadingIndicator()
|
||||||
|
}
|
||||||
|
|
||||||
|
switch await clientProxy.profile(for: userID) {
|
||||||
|
case .success(let userProfile):
|
||||||
|
state.userProfile = userProfile
|
||||||
|
state.permalink = (try? matrixToUserPermalink(userId: userID)).flatMap(URL.init(string:))
|
||||||
|
case .failure(let error):
|
||||||
|
state.bindings.alertInfo = .init(id: .unknown)
|
||||||
|
MXLog.error("Failed to find user profile: \(error)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Public
|
||||||
|
|
||||||
|
func stop() {
|
||||||
|
// Work around QLPreviewController dismissal issues, see the InteractiveQuickLookModifier.
|
||||||
|
state.bindings.mediaPreviewItem = nil
|
||||||
|
|
||||||
|
hideMemberLoadingIndicator()
|
||||||
|
}
|
||||||
|
|
||||||
|
override func process(viewAction: UserProfileScreenViewAction) {
|
||||||
|
switch viewAction {
|
||||||
|
case .displayAvatar:
|
||||||
|
displayFullScreenAvatar()
|
||||||
|
case .openDirectChat:
|
||||||
|
guard let userProfile = state.userProfile else { fatalError() }
|
||||||
|
actionsSubject.send(.openDirectChat(displayName: userProfile.displayName))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Private
|
||||||
|
|
||||||
|
private func displayFullScreenAvatar() {
|
||||||
|
guard let userProfile = state.userProfile else { fatalError() }
|
||||||
|
guard let avatarURL = userProfile.avatarURL else { return }
|
||||||
|
|
||||||
|
let loadingIndicatorIdentifier = "roomMemberAvatarLoadingIndicator"
|
||||||
|
userIndicatorController.submitIndicator(UserIndicator(id: loadingIndicatorIdentifier, type: .modal, title: L10n.commonLoading, persistent: true))
|
||||||
|
|
||||||
|
Task {
|
||||||
|
defer {
|
||||||
|
userIndicatorController.retractIndicatorWithId(loadingIndicatorIdentifier)
|
||||||
|
}
|
||||||
|
|
||||||
|
// We don't actually know the mime type here, assume it's an image.
|
||||||
|
if case let .success(file) = await mediaProvider.loadFileFromSource(.init(url: avatarURL, mimeType: "image/jpeg")) {
|
||||||
|
state.bindings.mediaPreviewItem = MediaPreviewItem(file: file, title: userProfile.displayName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: Loading indicator
|
||||||
|
|
||||||
|
private static let loadingIndicatorIdentifier = "\(UserProfileScreenViewModel.self)-Loading"
|
||||||
|
|
||||||
|
private func showMemberLoadingIndicator() {
|
||||||
|
userIndicatorController.submitIndicator(UserIndicator(id: Self.loadingIndicatorIdentifier,
|
||||||
|
type: .modal(progress: .indeterminate, interactiveDismissDisabled: false, allowsInteraction: true),
|
||||||
|
title: L10n.commonLoading,
|
||||||
|
persistent: true),
|
||||||
|
delay: .milliseconds(100))
|
||||||
|
}
|
||||||
|
|
||||||
|
private func hideMemberLoadingIndicator() {
|
||||||
|
userIndicatorController.retractIndicatorWithId(Self.loadingIndicatorIdentifier)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
//
|
||||||
|
// 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 Combine
|
||||||
|
|
||||||
|
@MainActor
|
||||||
|
protocol UserProfileScreenViewModelProtocol {
|
||||||
|
var actionsPublisher: AnyPublisher<UserProfileScreenViewModelAction, Never> { get }
|
||||||
|
var context: UserProfileScreenViewModelType.Context { get }
|
||||||
|
|
||||||
|
func stop()
|
||||||
|
}
|
@ -0,0 +1,99 @@
|
|||||||
|
//
|
||||||
|
// 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 Compound
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct UserProfileScreen: View {
|
||||||
|
@ObservedObject var context: UserProfileScreenViewModel.Context
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
Form {
|
||||||
|
headerSection
|
||||||
|
|
||||||
|
if context.viewState.userProfile != nil, !context.viewState.isOwnUser {
|
||||||
|
directChatSection
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.compoundList()
|
||||||
|
.navigationTitle(L10n.screenRoomMemberDetailsTitle)
|
||||||
|
.alert(item: $context.alertInfo)
|
||||||
|
.track(screen: .User)
|
||||||
|
.interactiveQuickLook(item: $context.mediaPreviewItem, shouldHideControls: true)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Private
|
||||||
|
|
||||||
|
@ViewBuilder
|
||||||
|
private var headerSection: some View {
|
||||||
|
if let userProfile = context.viewState.userProfile {
|
||||||
|
AvatarHeaderView(user: userProfile,
|
||||||
|
avatarSize: .user(on: .memberDetails),
|
||||||
|
imageProvider: context.imageProvider) {
|
||||||
|
context.send(viewAction: .displayAvatar)
|
||||||
|
} footer: {
|
||||||
|
if let permalink = context.viewState.permalink {
|
||||||
|
HStack(spacing: 32) {
|
||||||
|
ShareLink(item: permalink) {
|
||||||
|
CompoundIcon(\.shareIos)
|
||||||
|
}
|
||||||
|
.buttonStyle(FormActionButtonStyle(title: L10n.actionShare))
|
||||||
|
}
|
||||||
|
.padding(.top, 32)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
AvatarHeaderView(user: UserProfileProxy(userID: context.viewState.userID),
|
||||||
|
avatarSize: .user(on: .memberDetails),
|
||||||
|
imageProvider: context.imageProvider,
|
||||||
|
footer: { })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private var directChatSection: some View {
|
||||||
|
Section {
|
||||||
|
ListRow(label: .default(title: L10n.commonDirectChat,
|
||||||
|
icon: \.chat),
|
||||||
|
kind: .button {
|
||||||
|
context.send(viewAction: .openDirectChat)
|
||||||
|
})
|
||||||
|
.accessibilityIdentifier(A11yIdentifiers.roomMemberDetailsScreen.directChat)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Previews
|
||||||
|
|
||||||
|
struct UserProfileScreen_Previews: PreviewProvider, TestablePreview {
|
||||||
|
static let otherUserViewModel = makeViewModel(userID: RoomMemberProxyMock.mockDan.userID)
|
||||||
|
static let accountOwnerViewModel = makeViewModel(userID: RoomMemberProxyMock.mockMe.userID)
|
||||||
|
|
||||||
|
static var previews: some View {
|
||||||
|
UserProfileScreen(context: otherUserViewModel.context)
|
||||||
|
.previewDisplayName("Other User")
|
||||||
|
.snapshot(delay: 0.25)
|
||||||
|
UserProfileScreen(context: accountOwnerViewModel.context)
|
||||||
|
.previewDisplayName("Account Owner")
|
||||||
|
.snapshot(delay: 0.25)
|
||||||
|
}
|
||||||
|
|
||||||
|
static func makeViewModel(userID: String) -> UserProfileScreenViewModel {
|
||||||
|
UserProfileScreenViewModel(userID: userID,
|
||||||
|
clientProxy: ClientProxyMock(.init()),
|
||||||
|
mediaProvider: MockMediaProvider(),
|
||||||
|
userIndicatorController: ServiceLocator.shared.userIndicatorController)
|
||||||
|
}
|
||||||
|
}
|
@ -48,18 +48,6 @@ extension RoomMemberDetails {
|
|||||||
isBanned = proxy.membership == .ban
|
isBanned = proxy.membership == .ban
|
||||||
role = .init(proxy.role)
|
role = .init(proxy.role)
|
||||||
}
|
}
|
||||||
|
|
||||||
init(loading id: String) {
|
|
||||||
self.id = id
|
|
||||||
name = nil
|
|
||||||
avatarURL = nil
|
|
||||||
permalink = nil
|
|
||||||
|
|
||||||
isInvited = false
|
|
||||||
isIgnored = false
|
|
||||||
isBanned = false
|
|
||||||
role = .user
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extension RoomMemberDetails.Role {
|
extension RoomMemberDetails.Role {
|
||||||
|
BIN
PreviewTests/__Snapshots__/PreviewTests/test_userProfileScreen-iPad-en-GB.Account-Owner.png
(Stored with Git LFS)
Normal file
BIN
PreviewTests/__Snapshots__/PreviewTests/test_userProfileScreen-iPad-en-GB.Account-Owner.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
PreviewTests/__Snapshots__/PreviewTests/test_userProfileScreen-iPad-en-GB.Other-User.png
(Stored with Git LFS)
Normal file
BIN
PreviewTests/__Snapshots__/PreviewTests/test_userProfileScreen-iPad-en-GB.Other-User.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
PreviewTests/__Snapshots__/PreviewTests/test_userProfileScreen-iPad-pseudo.Account-Owner.png
(Stored with Git LFS)
Normal file
BIN
PreviewTests/__Snapshots__/PreviewTests/test_userProfileScreen-iPad-pseudo.Account-Owner.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
PreviewTests/__Snapshots__/PreviewTests/test_userProfileScreen-iPad-pseudo.Other-User.png
(Stored with Git LFS)
Normal file
BIN
PreviewTests/__Snapshots__/PreviewTests/test_userProfileScreen-iPad-pseudo.Other-User.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
PreviewTests/__Snapshots__/PreviewTests/test_userProfileScreen-iPhone-15-en-GB.Account-Owner.png
(Stored with Git LFS)
Normal file
BIN
PreviewTests/__Snapshots__/PreviewTests/test_userProfileScreen-iPhone-15-en-GB.Account-Owner.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
PreviewTests/__Snapshots__/PreviewTests/test_userProfileScreen-iPhone-15-en-GB.Other-User.png
(Stored with Git LFS)
Normal file
BIN
PreviewTests/__Snapshots__/PreviewTests/test_userProfileScreen-iPhone-15-en-GB.Other-User.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
PreviewTests/__Snapshots__/PreviewTests/test_userProfileScreen-iPhone-15-pseudo.Account-Owner.png
(Stored with Git LFS)
Normal file
BIN
PreviewTests/__Snapshots__/PreviewTests/test_userProfileScreen-iPhone-15-pseudo.Account-Owner.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
PreviewTests/__Snapshots__/PreviewTests/test_userProfileScreen-iPhone-15-pseudo.Other-User.png
(Stored with Git LFS)
Normal file
BIN
PreviewTests/__Snapshots__/PreviewTests/test_userProfileScreen-iPhone-15-pseudo.Other-User.png
(Stored with Git LFS)
Normal file
Binary file not shown.
1
changelog.d/2634.change
Normal file
1
changelog.d/2634.change
Normal file
@ -0,0 +1 @@
|
|||||||
|
Add a UserProfileScreen to handle permalinks for users that aren't in the current room.
|
Loading…
x
Reference in New Issue
Block a user