diff --git a/AccessibilityTests/Sources/GeneratedAccessibilityTests.swift b/AccessibilityTests/Sources/GeneratedAccessibilityTests.swift index 07695d744..20447fc3d 100644 --- a/AccessibilityTests/Sources/GeneratedAccessibilityTests.swift +++ b/AccessibilityTests/Sources/GeneratedAccessibilityTests.swift @@ -299,6 +299,10 @@ extension AccessibilityTests { try await performAccessibilityAudit(named: "LocationMarkerView_Previews") } + func testLocationPickerSheet() async throws { + try await performAccessibilityAudit(named: "LocationPickerSheet_Previews") + } + func testLocationRoomTimelineView() async throws { try await performAccessibilityAudit(named: "LocationRoomTimelineView_Previews") } @@ -699,6 +703,10 @@ extension AccessibilityTests { try await performAccessibilityAudit(named: "StateRoomTimelineView_Previews") } + func testStaticLocationSheet() async throws { + try await performAccessibilityAudit(named: "StaticLocationSheet_Previews") + } + func testStickerRoomTimelineView() async throws { try await performAccessibilityAudit(named: "StickerRoomTimelineView_Previews") } diff --git a/ElementX.xcodeproj/project.pbxproj b/ElementX.xcodeproj/project.pbxproj index e4e153a28..de38ff1a8 100644 --- a/ElementX.xcodeproj/project.pbxproj +++ b/ElementX.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 77; + objectVersion = 63; objects = { /* Begin PBXAggregateTarget section */ @@ -149,6 +149,7 @@ 16E4F1B8B9BFE1367F96DDA7 /* CompletionSuggestionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 989FC684408B31A677F5538B /* CompletionSuggestionView.swift */; }; 1702981A8085BE4FB0EC001B /* Application.swift in Sources */ = {isa = PBXBuildFile; fileRef = D33116993D54FADC0C721C1F /* Application.swift */; }; 172E6E9A612ADCF10A62CF13 /* BugReportServiceProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A68BCE6438873D2661D93D0 /* BugReportServiceProtocol.swift */; }; + 1743EAB45DA264AAFABDD3EF /* StaticLocationSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECE03E834CC8C2721899E6AC /* StaticLocationSheet.swift */; }; 1795EA6A6C4942CAE0459DF0 /* SecureBackupKeyBackupScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82B612853BFB68373249777B /* SecureBackupKeyBackupScreenViewModel.swift */; }; 17BC15DA08A52587466698C5 /* RoomMessageEventStringBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 80E815FF3CC5E5A355E3A25E /* RoomMessageEventStringBuilder.swift */; }; 1801F1467ABCEA080419E150 /* preview_avatar_user.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 87FC42213E86E8182CFD3A49 /* preview_avatar_user.jpg */; }; @@ -976,6 +977,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 */; }; + A7455F6B2F5AF7DD00E8D8BB /* LocationPickerSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7455F6A2F5AF7D400E8D8BB /* LocationPickerSheet.swift */; }; A7D48E44D485B143AADDB77D /* Strings+Untranslated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A18F6CE4D694D21E4EA9B25 /* Strings+Untranslated.swift */; }; A7DB75E090542331F6668A23 /* CreateRoomScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = CF19027E7FFA5E63D148873A /* CreateRoomScreenViewModel.swift */; }; A808DC3F72D15C6C5A52317E /* TimelineItemDebugView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BCDA016D05107DED3B9495CB /* TimelineItemDebugView.swift */; }; @@ -1580,7 +1582,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 = ""; }; @@ -1665,7 +1667,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 = ""; }; @@ -1686,7 +1688,7 @@ 16D09C79746BDCD9173EB3A7 /* RoomDetailsEditScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomDetailsEditScreenModels.swift; sourceTree = ""; }; 16D353E10A64172D863769BF /* TombstonedAvatarImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TombstonedAvatarImage.swift; sourceTree = ""; }; 1715E3D7F53C0748AA50C91C /* PostHogAnalyticsClient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PostHogAnalyticsClient.swift; sourceTree = ""; }; - 174E4AEF3DED300AA81046EC /* compound-ios */ = {isa = PBXFileReference; lastKnownFileType = folder; name = "compound-ios"; path = "compound-ios"; sourceTree = SOURCE_ROOT; }; + 174E4AEF3DED300AA81046EC /* compound-ios */ = {isa = PBXFileReference; lastKnownFileType = folder; path = "compound-ios"; sourceTree = SOURCE_ROOT; }; 17A8AA0DFA06012A9DAB951E /* TimelineProxyMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineProxyMock.swift; sourceTree = ""; }; 17BAE25A0E9E9F2F1BBA8930 /* DeactivateAccountScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeactivateAccountScreenViewModel.swift; sourceTree = ""; }; 181CF280BC8E3F335AFCB4B8 /* RemotePreferenceTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RemotePreferenceTests.swift; sourceTree = ""; }; @@ -1777,7 +1779,7 @@ 25E7E9B7FEAB6169D960C206 /* QRCodeLoginScreenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QRCodeLoginScreenViewModelTests.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 = ""; }; @@ -1859,7 +1861,7 @@ 358528B29FA72ACFD0D9644B /* SpacesScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpacesScreenCoordinator.swift; sourceTree = ""; }; 35A057BA9BE0F079784CD061 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; 35AFCF4C05DEED04E3DB1A16 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Localizable.strings; 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 = ""; }; 3747C96188856006F784BF49 /* ko */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = ko; path = ko.lproj/Localizable.stringsdict; sourceTree = ""; }; 37A63A59BFDDC494B1C20119 /* CallScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CallScreenViewModel.swift; sourceTree = ""; }; @@ -1977,7 +1979,7 @@ 4A2B5274C1D3D2999D643786 /* EncryptionResetPasswordScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EncryptionResetPasswordScreenViewModelProtocol.swift; sourceTree = ""; }; 4A5B4CD611DE7E94F5BA87B2 /* AppLockTimerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppLockTimerTests.swift; sourceTree = ""; }; 4AB29A2D95D3469B5F016655 /* SecureBackupControllerMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecureBackupControllerMock.swift; sourceTree = ""; }; - 4B1F71AC585827E6C416C15A /* AppIcon.icon */ = {isa = PBXFileReference; path = AppIcon.icon; sourceTree = ""; }; + 4B1F71AC585827E6C416C15A /* AppIcon.icon */ = {isa = PBXFileReference; lastKnownFileType = folder.iconcomposer.icon; path = AppIcon.icon; sourceTree = ""; }; 4B2B564CA6570E1487A7C7CC /* SpaceRoomListProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpaceRoomListProxy.swift; sourceTree = ""; }; 4B2D4EEBE8C098BBADD10939 /* SecureBackupKeyBackupScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecureBackupKeyBackupScreenCoordinator.swift; sourceTree = ""; }; 4B41FABA2B0AEF4389986495 /* LoginMode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginMode.swift; sourceTree = ""; }; @@ -2326,7 +2328,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 = ""; }; @@ -2455,6 +2457,7 @@ A6C11AD9813045E44F950410 /* ElementCallWidgetDriverProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ElementCallWidgetDriverProtocol.swift; sourceTree = ""; }; A6EA0D8B0BBD8805F7D5A133 /* TextBasedRoomTimelineViewProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextBasedRoomTimelineViewProtocol.swift; sourceTree = ""; }; A73A07BAEDD74C48795A996A /* AsyncSequence.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AsyncSequence.swift; sourceTree = ""; }; + A7455F6A2F5AF7D400E8D8BB /* LocationPickerSheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationPickerSheet.swift; sourceTree = ""; }; A768CA51A59B8A5D8C8FD599 /* AuthenticationStartScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthenticationStartScreen.swift; sourceTree = ""; }; A7978C9EFBDD7DE39BD86726 /* RestorationTokenTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RestorationTokenTests.swift; sourceTree = ""; }; A7A1B80FE6E3BA72F9C748AD /* AdvancedSettingsScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdvancedSettingsScreenViewModel.swift; sourceTree = ""; }; @@ -2478,7 +2481,7 @@ AAD8234D0E9C9B12BF9F240B /* LocationAnnotation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationAnnotation.swift; sourceTree = ""; }; AB07F03461023BC39C730922 /* PhishingDetector.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhishingDetector.swift; sourceTree = ""; }; AB26D5444A4A7E095222DE8B /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = "zh-Hans"; path = "zh-Hans.lproj/Localizable.stringsdict"; sourceTree = ""; }; - AB389C38BD41EB3E47092CFB /* AccessibilityTests.xctestplan */ = {isa = PBXFileReference; path = AccessibilityTests.xctestplan; sourceTree = ""; }; + AB389C38BD41EB3E47092CFB /* AccessibilityTests.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = AccessibilityTests.xctestplan; sourceTree = ""; }; ABA4CF2F5B4F68D02E412004 /* ServerConfirmationScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerConfirmationScreenViewModelProtocol.swift; sourceTree = ""; }; AC0275CEE9CA078B34028BDF /* AppLockScreenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppLockScreenViewModelTests.swift; sourceTree = ""; }; AC1DA29A5A041CC0BACA7CB0 /* MockImageCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockImageCache.swift; sourceTree = ""; }; @@ -2546,7 +2549,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 = ""; }; B65DDCF8E41759890355ACBC /* AuthenticationStartScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthenticationStartScreenViewModelProtocol.swift; sourceTree = ""; }; B682FE2C44C5E163E7023B05 /* CopyTextButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CopyTextButton.swift; sourceTree = ""; }; @@ -2579,7 +2582,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 = ""; }; @@ -2681,7 +2684,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 = ""; }; CF19027E7FFA5E63D148873A /* CreateRoomScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreateRoomScreenViewModel.swift; sourceTree = ""; }; CF847A34FC4C8C937CD39E08 /* LabsScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabsScreenViewModelProtocol.swift; sourceTree = ""; }; CFFA5E881D281810AB428EA3 /* RoomPowerLevelsProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomPowerLevelsProxy.swift; sourceTree = ""; }; @@ -2751,7 +2754,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 = ""; }; @@ -2797,7 +2800,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 = ""; }; @@ -2838,6 +2841,7 @@ EC589E641AE46EFB2962534D /* RoomMemberDetailsViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMemberDetailsViewModelTests.swift; sourceTree = ""; }; ECB836DD8BE31931F51B8AC9 /* EncryptionSettingsFlowCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EncryptionSettingsFlowCoordinator.swift; sourceTree = ""; }; ECD5FCBA169B6A82F501CA1B /* AnalyticsSettingsScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnalyticsSettingsScreenViewModelProtocol.swift; sourceTree = ""; }; + ECE03E834CC8C2721899E6AC /* StaticLocationSheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StaticLocationSheet.swift; sourceTree = ""; }; ECF79FB25E2D4BD6F50CE7C9 /* RoomMembersListScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMembersListScreenViewModel.swift; sourceTree = ""; }; ED044D00F2176681CC02CD54 /* HomeScreenRoomCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeScreenRoomCell.swift; sourceTree = ""; }; ED096460D7F26F10168FA33B /* LinkNewDeviceScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LinkNewDeviceScreenViewModelProtocol.swift; sourceTree = ""; }; @@ -2845,7 +2849,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 = ""; }; EDDE826EAB1BAB80C1104980 /* SpaceFlowCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpaceFlowCoordinator.swift; sourceTree = ""; }; @@ -5558,7 +5562,9 @@ 9FD8D798D879069243A7E7F7 /* View */ = { isa = PBXGroup; children = ( + A7455F6A2F5AF7D400E8D8BB /* LocationPickerSheet.swift */, 6F56E6E41C6DFE8054787D57 /* LocationSharingScreen.swift */, + ECE03E834CC8C2721899E6AC /* StaticLocationSheet.swift */, ); path = View; sourceTree = ""; @@ -7236,7 +7242,6 @@ EE40B0E16A55BD23ECBFFD22 /* XCRemoteSwiftPackageReference "matrix-rich-text-editor-swift" */, C89CF7729E028671C5DC461E /* XCLocalSwiftPackageReference "compound-ios" */, ); - preferredProjectObjectVersion = 77; projectDirPath = ""; projectRoot = ""; targets = ( @@ -8063,6 +8068,7 @@ 1D69E31913DF66426985909B /* EmojiPickerScreenViewModelProtocol.swift in Sources */, FBF09B6C900415800DDF2A21 /* EmojiProvider.swift in Sources */, A5B455D1A6DADF7476F7B417 /* EmojiProviderProtocol.swift in Sources */, + A7455F6B2F5AF7DD00E8D8BB /* LocationPickerSheet.swift in Sources */, 5D27B6537591471A42C89027 /* EmoteRoomTimelineItem.swift in Sources */, 8B41D0357B91CD3B6F6A3BCA /* EmoteRoomTimelineItemContent.swift in Sources */, 661EF50C1F7D4B0BC8A7AAE3 /* EmoteRoomTimelineView.swift in Sources */, @@ -8678,6 +8684,7 @@ 3B277D9538090766DA6C4566 /* StateRoomTimelineView.swift in Sources */, B4AAB3257A83B73F53FB2689 /* StateStoreViewModel.swift in Sources */, CF638B8C6FDCE920AE061FAE /* StateStoreViewModelV2.swift in Sources */, + 1743EAB45DA264AAFABDD3EF /* StaticLocationSheet.swift in Sources */, C58E305C380D3ADDF7912180 /* StickerRoomTimelineItem.swift in Sources */, 197441F1EF23A5DABACCA79F /* StickerRoomTimelineView.swift in Sources */, 2F94054F50E312AF30BE07F3 /* String.swift in Sources */, @@ -9149,9 +9156,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - OTHER_SWIFT_FLAGS = ( - "-DRELEASE", - ); + OTHER_SWIFT_FLAGS = "-DRELEASE"; PRODUCT_BUNDLE_IDENTIFIER = "${BASE_BUNDLE_IDENTIFIER}.accessibility.tests"; PRODUCT_NAME = AccessibilityTests; SDKROOT = iphoneos; @@ -9170,9 +9175,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - OTHER_SWIFT_FLAGS = ( - "-DDEBUG", - ); + OTHER_SWIFT_FLAGS = "-DDEBUG"; PRODUCT_BUNDLE_IDENTIFIER = "${BASE_BUNDLE_IDENTIFIER}.accessibility.tests"; PRODUCT_NAME = AccessibilityTests; SDKROOT = iphoneos; @@ -9194,9 +9197,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; @@ -9263,9 +9264,7 @@ "$(inherited)", "-ObjC", ); - 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)"; @@ -9295,9 +9294,7 @@ "$(inherited)", "-ObjC", ); - 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)"; @@ -9522,9 +9519,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; @@ -9543,9 +9538,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; @@ -9567,9 +9560,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.xcodeproj/xcshareddata/xcschemes/PreviewTests.xcscheme b/ElementX.xcodeproj/xcshareddata/xcschemes/PreviewTests.xcscheme index 3d2a81967..86b8247e9 100644 --- a/ElementX.xcodeproj/xcshareddata/xcschemes/PreviewTests.xcscheme +++ b/ElementX.xcodeproj/xcshareddata/xcschemes/PreviewTests.xcscheme @@ -4,8 +4,7 @@ version = "1.7"> + buildImplicitDependencies = "YES"> - - - - - - - - + + + + - - - - String { + return L10n.tr("Localizable", "screen_static_location_sheet_timestamp_description", String(describing: p1)) + } + /// On the map + internal static var screenStaticLocationSheetTitle: String { return L10n.tr("Localizable", "screen_static_location_sheet_title") } /// Message not sent because %1$@’s verified identity was reset. internal static func screenTimelineItemMenuSendFailureChangedIdentity(_ p1: Any) -> String { return L10n.tr("Localizable", "screen_timeline_item_menu_send_failure_changed_identity", String(describing: p1)) diff --git a/ElementX/Sources/Other/SwiftUI/RowDivider.swift b/ElementX/Sources/Other/SwiftUI/RowDivider.swift index c0677fa96..aeda2d9d7 100644 --- a/ElementX/Sources/Other/SwiftUI/RowDivider.swift +++ b/ElementX/Sources/Other/SwiftUI/RowDivider.swift @@ -24,7 +24,7 @@ struct RowDivider: ViewModifier { } extension View { - func rowDivider(alignment: Alignment = .bottom, horizontalInsets: CGFloat) -> some View { + func rowDivider(alignment: Alignment = .bottom, horizontalInsets: CGFloat = .zero) -> some View { modifier(RowDivider(alignment: alignment, horizontalInsets: horizontalInsets)) } } diff --git a/ElementX/Sources/Other/TestablePreview/TestablePreviewsDictionary.swift b/ElementX/Sources/Other/TestablePreview/TestablePreviewsDictionary.swift index 016ef0646..f4c4dbec2 100644 --- a/ElementX/Sources/Other/TestablePreview/TestablePreviewsDictionary.swift +++ b/ElementX/Sources/Other/TestablePreview/TestablePreviewsDictionary.swift @@ -82,6 +82,7 @@ enum TestablePreviewsDictionary { "LinkNewDeviceScreen_Previews" : LinkNewDeviceScreen_Previews.self, "LoadableImage_Previews" : LoadableImage_Previews.self, "LocationMarkerView_Previews" : LocationMarkerView_Previews.self, + "LocationPickerSheet_Previews" : LocationPickerSheet_Previews.self, "LocationRoomTimelineView_Previews" : LocationRoomTimelineView_Previews.self, "LocationSharingScreen_Previews" : LocationSharingScreen_Previews.self, "LoginScreen_Previews" : LoginScreen_Previews.self, @@ -182,6 +183,7 @@ enum TestablePreviewsDictionary { "StackedAvatarsView_Previews" : StackedAvatarsView_Previews.self, "StartChatScreen_Previews" : StartChatScreen_Previews.self, "StateRoomTimelineView_Previews" : StateRoomTimelineView_Previews.self, + "StaticLocationSheet_Previews" : StaticLocationSheet_Previews.self, "StickerRoomTimelineView_Previews" : StickerRoomTimelineView_Previews.self, "SwipeRightAction_Previews" : SwipeRightAction_Previews.self, "SwipeToReplyView_Previews" : SwipeToReplyView_Previews.self, diff --git a/ElementX/Sources/Screens/LocationSharing/LocationSharingScreenModels.swift b/ElementX/Sources/Screens/LocationSharing/LocationSharingScreenModels.swift index d9d6f0ec8..48c878370 100644 --- a/ElementX/Sources/Screens/LocationSharing/LocationSharingScreenModels.swift +++ b/ElementX/Sources/Screens/LocationSharing/LocationSharingScreenModels.swift @@ -8,6 +8,7 @@ import CoreLocation import Foundation +import MatrixRustSDK enum LocationSharingViewError: Error, Hashable { case missingAuthorization @@ -21,25 +22,18 @@ enum LocationSharingScreenViewModelAction { enum LocationSharingInteractionMode: Hashable { case picker - case viewStatic(senderID: String?, geoURI: GeoURI) - - var canShowAvatar: Bool { - switch self { - case .picker, .viewStatic(.some(_), _): - true - default: - false - } - } + case viewStatic(StaticLocationData) } struct LocationSharingScreenViewState: BindableState { init(interactionMode: LocationSharingInteractionMode, mapURLBuilder: MapTilerURLBuilderProtocol, - showLiveLocationSharingButton: Bool) { + showLiveLocationSharingButton: Bool, + ownUserID: String) { self.interactionMode = interactionMode self.mapURLBuilder = mapURLBuilder self.showLiveLocationSharingButton = showLiveLocationSharingButton + self.ownUserID = ownUserID bindings.showsUserLocationMode = switch interactionMode { case .picker: .showAndFollow @@ -50,6 +44,7 @@ struct LocationSharingScreenViewState: BindableState { let interactionMode: LocationSharingInteractionMode let mapURLBuilder: MapTilerURLBuilderProtocol let showLiveLocationSharingButton: Bool + let ownUserID: String var bindings = LocationSharingScreenBindings(showsUserLocationMode: .hide) @@ -62,9 +57,9 @@ struct LocationSharingScreenViewState: BindableState { switch interactionMode { case .picker: // middle point in Europe, to be used if the users location is not yet known - return .init(latitude: 49.843, longitude: 9.902056) - case .viewStatic(_, let geoURI): - return .init(latitude: geoURI.latitude, longitude: geoURI.longitude) + .init(latitude: 49.843, longitude: 9.902056) + case .viewStatic(let location): + .init(latitude: location.geoURI.latitude, longitude: location.geoURI.longitude) } } @@ -76,15 +71,6 @@ struct LocationSharingScreenViewState: BindableState { false } } - - var showShareAction: Bool { - switch interactionMode { - case .picker: - return false - case .viewStatic: - return true - } - } var isLocationLoading: Bool { !bindings.hasLoadedUserLocation && bindings.isLocationAuthorized != false @@ -105,12 +91,12 @@ struct LocationSharingScreenViewState: BindableState { var userProfile: UserProfileProxy? - var shownUserProfile: UserProfileProxy? { + var staticLocationMarkerUserProfile: UserProfileProxy? { switch interactionMode { case .picker: isSharingUserLocation ? userProfile : nil - case .viewStatic: - userProfile + case .viewStatic(let location): + location.kind == .sender ? userProfile : nil } } } @@ -172,3 +158,10 @@ extension AlertInfo where T == LocationSharingViewError { } } } + +struct StaticLocationData: Hashable { + let sender: TimelineItemSender + let geoURI: GeoURI + let kind: StaticLocationKind + let timestamp: Date +} diff --git a/ElementX/Sources/Screens/LocationSharing/LocationSharingScreenViewModel.swift b/ElementX/Sources/Screens/LocationSharing/LocationSharingScreenViewModel.swift index 4add6589d..1101c0635 100644 --- a/ElementX/Sources/Screens/LocationSharing/LocationSharingScreenViewModel.swift +++ b/ElementX/Sources/Screens/LocationSharing/LocationSharingScreenViewModel.swift @@ -37,13 +37,12 @@ class LocationSharingScreenViewModel: LocationSharingScreenViewModelType, Locati super.init(initialViewState: .init(interactionMode: interactionMode, mapURLBuilder: mapURLBuilder, - showLiveLocationSharingButton: liveLocationSharingEnabled), + showLiveLocationSharingButton: liveLocationSharingEnabled, + ownUserID: roomProxy.ownUserID), mediaProvider: mediaProvider) - if interactionMode.canShowAvatar { - updateShownUserProfile(members: roomProxy.membersPublisher.value) - setupSubscriptions() - } + updateShownUserProfile(members: roomProxy.membersPublisher.value) + setupSubscriptions() } override func process(viewAction: LocationSharingScreenViewAction) { @@ -86,14 +85,12 @@ class LocationSharingScreenViewModel: LocationSharingScreenViewModelType, Locati } else { state.userProfile = .init(userID: roomProxy.ownUserID) } - case .viewStatic(.some(let senderID), _): - if let sender = members.first(where: { $0.userID == senderID }).map(UserProfileProxy.init) { + case .viewStatic(let location): + if let sender = members.first(where: { $0.userID == location.sender.id }).map(UserProfileProxy.init) { state.userProfile = sender } else { - state.userProfile = .init(userID: senderID) + state.userProfile = .init(sender: location.sender) } - default: - state.userProfile = nil } } @@ -127,3 +124,39 @@ class LocationSharingScreenViewModel: LocationSharingScreenViewModelType, Locati "\(Self.self)-Status" } } + +extension LocationSharingScreenViewModel { + enum MockType { + case picker + case staticSenderLocation + case staticPinLocation + } + + static func mock(type: MockType, senderID: String = "@dan:matrix.org") -> LocationSharingScreenViewModel { + let interactionMode: LocationSharingInteractionMode = switch type { + case .picker: + .picker + case .staticPinLocation: + .viewStatic(.init(sender: .init(id: senderID), + geoURI: .init(latitude: 41.9027835, + longitude: 12.4963655), + kind: .pin, + timestamp: .mock)) + case .staticSenderLocation: + .viewStatic(.init(sender: .init(id: senderID), + geoURI: .init(latitude: 41.9027835, + longitude: 12.4963655), + kind: .sender, + timestamp: .mock)) + } + + return LocationSharingScreenViewModel(interactionMode: interactionMode, + mapURLBuilder: ServiceLocator.shared.settings.mapTilerConfiguration, + liveLocationSharingEnabled: true, + roomProxy: JoinedRoomProxyMock(.init()), + timelineController: MockTimelineController(), + analytics: ServiceLocator.shared.analytics, + userIndicatorController: UserIndicatorControllerMock(), + mediaProvider: MediaProviderMock(configuration: .init())) + } +} diff --git a/ElementX/Sources/Screens/LocationSharing/View/LocationPickerSheet.swift b/ElementX/Sources/Screens/LocationSharing/View/LocationPickerSheet.swift new file mode 100644 index 000000000..95507631d --- /dev/null +++ b/ElementX/Sources/Screens/LocationSharing/View/LocationPickerSheet.swift @@ -0,0 +1,77 @@ +// +// Copyright 2026 Element Creations 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 LocationPickerSheet: View { + @Bindable var context: LocationSharingScreenViewModel.Context + @State private var height: CGFloat = .zero + + var body: some View { + VStack(alignment: .leading, spacing: 0) { + Button { + context.send(viewAction: .selectLocation) + } label: { + if context.viewState.isSharingUserLocation { + LocationPickerLabel(text: L10n.screenShareMyLocationAction, + icon: \.locationNavigatorCentred, + iconColor: .compound.iconSecondary) + } else { + LocationPickerLabel(text: L10n.screenShareThisLocationAction, + icon: \.locationNavigator, + iconColor: .compound.iconSecondary) + } + } + if context.viewState.showLiveLocationSharingButton { + Button { } label: { + LocationPickerLabel(text: L10n.actionShareLiveLocation, + icon: \.locationPinSolid, + iconColor: .compound.iconAccentPrimary) + } + } + } + .font(.compound.bodyLG) + .foregroundStyle(.compound.textPrimary) + .padding(.top, 38) + .readHeight($height) + .interactiveDismissDisabled() + .presentationBackground(.compound.bgCanvasDefault) + .presentationBackgroundInteraction(.enabled) + .presentationDragIndicator(.hidden) + .presentationDetents([.height(height)]) + } +} + +private struct LocationPickerLabel: View { + let text: String + let icon: KeyPath + let iconColor: Color + + var body: some View { + Label { + Text(text) + .frame(maxWidth: .infinity, alignment: .leading) + .padding(.vertical, 14) + .rowDivider(alignment: .top) + .padding(.trailing, 16) + } icon: { + CompoundIcon(icon) + .foregroundStyle(iconColor) + } + .padding(.leading, 16) + .frame(maxWidth: .infinity, alignment: .leading) + } +} + +struct LocationPickerSheet_Previews: PreviewProvider, TestablePreview { + static let viewModel = LocationSharingScreenViewModel.mock(type: .picker) + + static var previews: some View { + LocationPickerSheet(context: viewModel.context) + } +} diff --git a/ElementX/Sources/Screens/LocationSharing/View/LocationSharingScreen.swift b/ElementX/Sources/Screens/LocationSharing/View/LocationSharingScreen.swift index 1f72d7a7a..ed1ff2a28 100644 --- a/ElementX/Sources/Screens/LocationSharing/View/LocationSharingScreen.swift +++ b/ElementX/Sources/Screens/LocationSharing/View/LocationSharingScreen.swift @@ -13,15 +13,19 @@ struct LocationSharingScreen: View { @Bindable var context: LocationSharingScreenViewModel.Context var body: some View { - if context.viewState.isLocationPickerMode { + switch context.viewState.interactionMode { + case .picker: mainContent .sheet(isPresented: .constant(true)) { - sharingOptionsSheet + LocationPickerSheet(context: context) .alert(item: $context.alertInfo) } - } else { + case .viewStatic: mainContent - .alert(item: $context.alertInfo) + .sheet(isPresented: .constant(true)) { + StaticLocationSheet(context: context) + .alert(item: $context.alertInfo) + } } } @@ -51,7 +55,7 @@ struct LocationSharingScreen: View { .ignoresSafeArea(.all, edges: mapSafeAreaEdges) if context.viewState.isLocationPickerMode { - LocationMarkerView(userProfile: context.viewState.shownUserProfile, mediaProvider: context.mediaProvider) + LocationMarkerView(userProfile: context.viewState.staticLocationMarkerUserProfile, mediaProvider: context.mediaProvider) } } .overlay(alignment: .topTrailing) { @@ -61,32 +65,21 @@ struct LocationSharingScreen: View { @ToolbarContentBuilder private var toolbar: some ToolbarContent { - ToolbarItem(placement: context.viewState.showShareAction ? .topBarLeading : .topBarTrailing) { + ToolbarItem(placement: .primaryAction) { ToolbarButton(role: .close) { context.send(viewAction: .close) } } - - if context.viewState.showShareAction { - ToolbarItem(placement: .topBarTrailing) { - Button { - context.showShareSheet = true - } label: { - Image(systemName: "square.and.arrow.up") - } - .popover(isPresented: $context.showShareSheet) { shareSheet } - } - } } private var mapOptions: MapLibreMapView.Options { var annotations: [String: LocationAnnotation] = [:] if !context.viewState.isLocationPickerMode { - let id = context.viewState.shownUserProfile?.userID ?? UUID().uuidString + let id = context.viewState.staticLocationMarkerUserProfile?.userID ?? UUID().uuidString let annotation = LocationAnnotation(id: id, coordinate: context.viewState.initialMapCenter, anchorPoint: .bottomCenter) { - LocationMarkerView(userProfile: context.viewState.shownUserProfile, mediaProvider: context.mediaProvider) + LocationMarkerView(userProfile: context.viewState.staticLocationMarkerUserProfile, mediaProvider: context.mediaProvider) } annotations[id] = annotation } @@ -135,7 +128,7 @@ struct LocationSharingScreen: View { @ViewBuilder private var shareSheet: some View { let location = context.viewState.initialMapCenter - let senderName = context.viewState.shownUserProfile?.displayName + let senderName = context.viewState.staticLocationMarkerUserProfile?.displayName ?? context.viewState.staticLocationMarkerUserProfile?.userID AppActivityView(activityItems: [ShareToMapsAppActivity.MapsAppType.apple.activityURL(for: location, senderName: senderName)], applicationActivities: ShareToMapsAppActivity.MapsAppType.allCases.map { ShareToMapsAppActivity(type: $0, location: location, senderName: senderName) }) .edgesIgnoringSafeArea(.bottom) @@ -151,95 +144,16 @@ struct LocationSharingScreen: View { .sheet } } - - @State private var sharingOptionsSheetHeight: CGFloat = .zero - - private var sharingOptionsSheet: some View { - VStack(alignment: .leading, spacing: 0) { - Button { - context.send(viewAction: .selectLocation) - } label: { - if context.viewState.isSharingUserLocation { - LocationSharingLabel(text: L10n.screenShareMyLocationAction, - icon: \.locationNavigatorCentred, - iconColor: .compound.iconSecondary) - } else { - LocationSharingLabel(text: L10n.screenShareThisLocationAction, - icon: \.locationNavigator, - iconColor: .compound.iconSecondary) - } - } - if context.viewState.showLiveLocationSharingButton { - Button { } label: { - LocationSharingLabel(text: L10n.actionShareLiveLocation, - icon: \.locationPinSolid, - iconColor: .compound.iconAccentPrimary) - } - } - } - .font(.compound.bodyLG) - .foregroundStyle(.compound.textPrimary) - .padding(.top, 38) - .readHeight($sharingOptionsSheetHeight) - .interactiveDismissDisabled() - .presentationBackground(.compound.bgCanvasDefault) - .presentationBackgroundInteraction(.enabled) - .presentationDragIndicator(.hidden) - .presentationDetents([.height(sharingOptionsSheetHeight)]) - } -} - -private struct LocationSharingLabel: View { - let text: String - let icon: KeyPath - let iconColor: Color - - var body: some View { - Label { - Text(text) - .frame(maxWidth: .infinity, alignment: .leading) - .padding(.vertical, 14) - .rowDivider(alignment: .top, horizontalInsets: 16.0) - } icon: { - CompoundIcon(icon) - .foregroundStyle(iconColor) - } - .padding(.leading, 16) - .frame(maxWidth: .infinity, alignment: .leading) - } } // MARK: - Previews struct LocationSharingScreen_Previews: PreviewProvider, TestablePreview { - static let viewModel = LocationSharingScreenViewModel(interactionMode: .viewStatic(senderID: "@dan:matrix.org", geoURI: .init(latitude: 41.9027835, - longitude: 12.4963655)), - mapURLBuilder: ServiceLocator.shared.settings.mapTilerConfiguration, - liveLocationSharingEnabled: true, - roomProxy: JoinedRoomProxyMock(.init()), - timelineController: MockTimelineController(), - analytics: ServiceLocator.shared.analytics, - userIndicatorController: UserIndicatorControllerMock(), - mediaProvider: MediaProviderMock(configuration: .init())) + static let viewModel = LocationSharingScreenViewModel.mock(type: .staticSenderLocation) - static let pinViewModel = LocationSharingScreenViewModel(interactionMode: .viewStatic(senderID: nil, geoURI: .init(latitude: 41.9027835, - longitude: 12.4963655)), - mapURLBuilder: ServiceLocator.shared.settings.mapTilerConfiguration, - liveLocationSharingEnabled: true, - roomProxy: JoinedRoomProxyMock(.init()), - timelineController: MockTimelineController(), - analytics: ServiceLocator.shared.analytics, - userIndicatorController: UserIndicatorControllerMock(), - mediaProvider: MediaProviderMock(configuration: .init())) + static let pinViewModel = LocationSharingScreenViewModel.mock(type: .staticPinLocation) - static let pickerViewModel = LocationSharingScreenViewModel(interactionMode: .picker, - mapURLBuilder: ServiceLocator.shared.settings.mapTilerConfiguration, - liveLocationSharingEnabled: true, - roomProxy: JoinedRoomProxyMock(.init()), - timelineController: MockTimelineController(), - analytics: ServiceLocator.shared.analytics, - userIndicatorController: UserIndicatorControllerMock(), - mediaProvider: MediaProviderMock(configuration: .init())) + static let pickerViewModel = LocationSharingScreenViewModel.mock(type: .picker) static var previews: some View { ElementNavigationStack { diff --git a/ElementX/Sources/Screens/LocationSharing/View/StaticLocationSheet.swift b/ElementX/Sources/Screens/LocationSharing/View/StaticLocationSheet.swift new file mode 100644 index 000000000..9d8211bf0 --- /dev/null +++ b/ElementX/Sources/Screens/LocationSharing/View/StaticLocationSheet.swift @@ -0,0 +1,112 @@ +// +// Copyright 2026 Element Creations 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 StaticLocationSheet: View { + @Bindable var context: LocationSharingScreenViewModel.Context + @State private var height = CGFloat.zero + + var body: some View { + mainContent + .readHeight($height) + .interactiveDismissDisabled() + .presentationBackground(.compound.bgCanvasDefault) + .presentationBackgroundInteraction(.enabled) + .presentationDragIndicator(.hidden) + .presentationDetents([.height(height)]) + } + + @ViewBuilder + private var mainContent: some View { + if case let .viewStatic(location) = context.viewState.interactionMode, + let userProfile = context.viewState.userProfile { + VStack(spacing: 0) { + Text(L10n.screenStaticLocationSheetTitle) + .foregroundStyle(.compound.textPrimary) + .font(.compound.bodyLGSemibold) + .padding(.top, 29) + .padding(.bottom, 25) + Button { + context.showShareSheet = true + } label: { + UserLocationCell(profile: userProfile, + isOwnUser: userProfile.userID == context.viewState.ownUserID, + isUserLocation: location.kind == .sender, + timestamp: location.timestamp, + mediaProvider: context.mediaProvider) + } + accessibilityHint(L10n.actionShare) + } + } + } +} + +/// This may be reused for live location sharing sheet in the future with some tweaks +private struct UserLocationCell: View { + let profile: UserProfileProxy + let isOwnUser: Bool + let isUserLocation: Bool + let timestamp: Date + var mediaProvider: MediaProviderProtocol? + + private var name: String { + isOwnUser ? L10n.commonYou : profile.displayName ?? profile.userID + } + + var body: some View { + HStack(spacing: 12) { + LoadableAvatarImage(url: profile.avatarURL, + name: profile.displayName, + contentID: profile.id, + avatarSize: .user(on: .map), + mediaProvider: mediaProvider) + .accessibilityHidden(true) + + HStack(spacing: 12) { + VStack(alignment: .leading, spacing: 0) { + Text(name) + .font(.compound.bodyLG) + .foregroundStyle(.compound.textPrimary) + HStack(spacing: 4) { + CompoundIcon(isUserLocation ? \.locationNavigatorCentred : \.locationNavigator, + size: .xSmall, + relativeTo: .compound.bodyMD) + .foregroundStyle(.compound.iconSecondary) + .accessibilityLabel(isUserLocation ? L10n.a11ySenderLocation : L10n.a11yPinnedLocation) + Text(L10n.screenStaticLocationSheetTimestampDescription(timestamp.formatted(.relative(presentation: .named)))) + .font(.compound.bodyMD) + .foregroundStyle(.compound.textSecondary) + } + } + + Spacer() + CompoundIcon(\.shareIos) + .foregroundStyle(.compound.iconSecondary) + .accessibilityHidden(true) + } + .padding(.vertical, 12) + .rowDivider(alignment: .top) + } + .padding(.horizontal, 16) + .accessibilityElement(children: .combine) + } +} + +struct StaticLocationSheet_Previews: PreviewProvider, TestablePreview { + static let viewModel = LocationSharingScreenViewModel.mock(type: .staticSenderLocation, senderID: RoomMemberProxyMock.mockMe.userID) + + static let pinViewModel = LocationSharingScreenViewModel.mock(type: .staticPinLocation) + + static var previews: some View { + StaticLocationSheet(context: viewModel.context) + .previewDisplayName("Static own location") + StaticLocationSheet(context: pinViewModel.context) + .previewDisplayName("Static pin location") + } +} diff --git a/ElementX/Sources/Screens/PinnedEventsTimelineScreen/PinnedEventsTimelineScreenCoordinator.swift b/ElementX/Sources/Screens/PinnedEventsTimelineScreen/PinnedEventsTimelineScreenCoordinator.swift index 04bcf000a..392222d8e 100644 --- a/ElementX/Sources/Screens/PinnedEventsTimelineScreen/PinnedEventsTimelineScreenCoordinator.swift +++ b/ElementX/Sources/Screens/PinnedEventsTimelineScreen/PinnedEventsTimelineScreenCoordinator.swift @@ -26,7 +26,7 @@ struct PinnedEventsTimelineScreenCoordinatorParameters { enum PinnedEventsTimelineScreenCoordinatorAction { case dismiss case displayUser(userID: String) - case presentLocationViewer(senderID: String?, geoURI: GeoURI) + case presentLocationViewer(StaticLocationData) case displayMessageForwarding(forwardingItem: MessageForwardingItem) case displayRoomScreenWithFocussedPin(eventID: String, threadRootEventID: String?) } @@ -87,9 +87,8 @@ final class PinnedEventsTimelineScreenCoordinator: CoordinatorProtocol { actionsSubject.send(.displayMessageForwarding(forwardingItem: forwardingItem)) case .displayMediaPreview(let mediaPreviewViewModel): viewModel.displayMediaPreview(mediaPreviewViewModel) - case .displayLocation(let senderID, let geoURI): - actionsSubject.send(.presentLocationViewer(senderID: senderID, - geoURI: geoURI)) + case .displayLocation(let location): + actionsSubject.send(.presentLocationViewer(location)) case .viewInRoomTimeline(let eventID, let threadRootEventID): actionsSubject.send(.displayRoomScreenWithFocussedPin(eventID: eventID, threadRootEventID: threadRootEventID)) // These other actions will not be handled in this view diff --git a/ElementX/Sources/Screens/RoomScreen/RoomScreenCoordinator.swift b/ElementX/Sources/Screens/RoomScreen/RoomScreenCoordinator.swift index a3cb718dd..c17a9ebca 100644 --- a/ElementX/Sources/Screens/RoomScreen/RoomScreenCoordinator.swift +++ b/ElementX/Sources/Screens/RoomScreen/RoomScreenCoordinator.swift @@ -39,7 +39,7 @@ enum RoomScreenCoordinatorAction { case presentRoomDetails case presentLocationPicker case presentPollForm(mode: PollFormMode) - case presentLocationViewer(senderID: String?, geoURI: GeoURI) + case presentLocationViewer(StaticLocationData) case presentEmojiPicker(itemID: TimelineItemIdentifier, selectedEmojis: Set) case presentRoomMemberDetails(userID: String) case presentMessageForwarding(forwardingItem: MessageForwardingItem) @@ -137,8 +137,8 @@ final class RoomScreenCoordinator: CoordinatorProtocol { actionsSubject.send(.presentRoomMemberDetails(userID: userID)) case .displayMessageForwarding(let forwardingItem): actionsSubject.send(.presentMessageForwarding(forwardingItem: forwardingItem)) - case .displayLocation(let senderID, let geoURI): - actionsSubject.send(.presentLocationViewer(senderID: senderID, geoURI: geoURI)) + case .displayLocation(let location): + actionsSubject.send(.presentLocationViewer(location)) case .displayResolveSendFailure(let failure, let sendHandle): actionsSubject.send(.presentResolveSendFailure(failure: failure, sendHandle: sendHandle)) case .displayThread(let itemID): diff --git a/ElementX/Sources/Screens/ThreadTimelineScreen/ThreadTimelineScreenCoordinator.swift b/ElementX/Sources/Screens/ThreadTimelineScreen/ThreadTimelineScreenCoordinator.swift index b0dbc1cb6..d803cb764 100644 --- a/ElementX/Sources/Screens/ThreadTimelineScreen/ThreadTimelineScreenCoordinator.swift +++ b/ElementX/Sources/Screens/ThreadTimelineScreen/ThreadTimelineScreenCoordinator.swift @@ -33,7 +33,7 @@ enum ThreadTimelineScreenCoordinatorAction { case presentMediaUploadPicker(mode: MediaPickerScreenMode) case presentMediaUploadPreviewScreen(mediaURLs: [URL]) case presentLocationPicker - case presentLocationViewer(senderID: String?, geoURI: GeoURI) + case presentLocationViewer(StaticLocationData) case presentPollForm(mode: PollFormMode) case presentEmojiPicker(itemID: TimelineItemIdentifier, selectedEmojis: Set) case presentRoomMemberDetails(userID: String) @@ -118,9 +118,8 @@ final class ThreadTimelineScreenCoordinator: CoordinatorProtocol { viewModel.displayMediaPreview(mediaPreviewViewModel) case .displayLocationPicker: actionsSubject.send(.presentLocationPicker) - case .displayLocation(let senderID, let geoURI): - actionsSubject.send(.presentLocationViewer(senderID: senderID, - geoURI: geoURI)) + case .displayLocation(let location): + actionsSubject.send(.presentLocationViewer(location)) case .displayPollForm(let mode): actionsSubject.send(.presentPollForm(mode: mode)) case .displayMediaUploadPreviewScreen(let mediaURLs): diff --git a/ElementX/Sources/Screens/Timeline/TimelineInteractionHandler.swift b/ElementX/Sources/Screens/Timeline/TimelineInteractionHandler.swift index 05a59364e..07410e3b4 100644 --- a/ElementX/Sources/Screens/Timeline/TimelineInteractionHandler.swift +++ b/ElementX/Sources/Screens/Timeline/TimelineInteractionHandler.swift @@ -536,8 +536,10 @@ class TimelineInteractionHandler { switch timelineItem { case let item as LocationRoomTimelineItem: guard let geoURI = item.content.geoURI else { return .none } - return .displayLocation(senderID: item.content.kind == .sender ? item.sender.id : nil, - geoURI: geoURI) + return .displayLocation(.init(sender: item.sender, + geoURI: geoURI, + kind: item.content.kind, + timestamp: item.timestamp)) case is ImageRoomTimelineItem, is VideoRoomTimelineItem: return await mediaPreviewAction(for: timelineItem, messageTypes: [.image, .video]) diff --git a/ElementX/Sources/Screens/Timeline/TimelineModels.swift b/ElementX/Sources/Screens/Timeline/TimelineModels.swift index 02d03c52f..a20ca5415 100644 --- a/ElementX/Sources/Screens/Timeline/TimelineModels.swift +++ b/ElementX/Sources/Screens/Timeline/TimelineModels.swift @@ -23,7 +23,7 @@ enum TimelineViewModelAction { case displaySenderDetails(userID: String) case displayMessageForwarding(forwardingItem: MessageForwardingItem) case displayMediaPreview(TimelineMediaPreviewViewModel) - case displayLocation(senderID: String?, geoURI: GeoURI) + case displayLocation(StaticLocationData) case displayResolveSendFailure(failure: TimelineItemSendFailure.VerifiedUser, sendHandle: SendHandleProxy) case displayThread(itemID: TimelineItemIdentifier) case composer(action: TimelineComposerAction) diff --git a/ElementX/Sources/Screens/Timeline/TimelineViewModel.swift b/ElementX/Sources/Screens/Timeline/TimelineViewModel.swift index b625a774d..a1268aa33 100644 --- a/ElementX/Sources/Screens/Timeline/TimelineViewModel.swift +++ b/ElementX/Sources/Screens/Timeline/TimelineViewModel.swift @@ -655,8 +655,8 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol { let mediaPreviewViewModel = makeMediaPreviewViewModel(item: item, timelineViewModelKind: timelineViewModelKind) actionsSubject.send(.displayMediaPreview(mediaPreviewViewModel)) - case .displayLocation(let senderID, let geoURI): - actionsSubject.send(.displayLocation(senderID: senderID, geoURI: geoURI)) + case .displayLocation(let location): + actionsSubject.send(.displayLocation(location)) case .none: break } diff --git a/ElementX/Sources/Screens/Timeline/View/TimelineItemViews/LocationRoomTimelineView.swift b/ElementX/Sources/Screens/Timeline/View/TimelineItemViews/LocationRoomTimelineView.swift index 55c7a4dbd..81b298c02 100644 --- a/ElementX/Sources/Screens/Timeline/View/TimelineItemViews/LocationRoomTimelineView.swift +++ b/ElementX/Sources/Screens/Timeline/View/TimelineItemViews/LocationRoomTimelineView.swift @@ -30,7 +30,8 @@ struct LocationRoomTimelineView: View { MapLibreStaticMapView(geoURI: geoURI, mapURLBuilder: context.viewState.mapTilerConfiguration, mapSize: .init(width: mapAspectRatio * mapMaxHeight, height: mapMaxHeight)) { - LocationMarkerView(userProfile: timelineItem.content.kind == .sender ? .init(sender: timelineItem.sender) : nil, mediaProvider: context.mediaProvider) + LocationMarkerView(userProfile: timelineItem.content.kind == .sender ? .init(sender: timelineItem.sender) : nil, + mediaProvider: context.mediaProvider) } .frame(maxHeight: mapMaxHeight) .aspectRatio(mapAspectRatio, contentMode: .fit) diff --git a/ElementX/Sources/Services/Timeline/TimelineController/TimelineControllerProtocol.swift b/ElementX/Sources/Services/Timeline/TimelineController/TimelineControllerProtocol.swift index 4e096531b..3907ea5c4 100644 --- a/ElementX/Sources/Services/Timeline/TimelineController/TimelineControllerProtocol.swift +++ b/ElementX/Sources/Services/Timeline/TimelineController/TimelineControllerProtocol.swift @@ -25,7 +25,7 @@ enum TimelineControllerAction { } case displayMediaPreview(item: EventBasedMessageTimelineItemProtocol, timelineViewModel: TimelineViewModelKind) - case displayLocation(senderID: String?, geoURI: GeoURI) + case displayLocation(StaticLocationData) case none } diff --git a/ElementX/Sources/Services/Timeline/TimelineItems/Items/Messages/LocationRoomTimelineItemContent.swift b/ElementX/Sources/Services/Timeline/TimelineItems/Items/Messages/LocationRoomTimelineItemContent.swift index 59ee6c491..69127e717 100644 --- a/ElementX/Sources/Services/Timeline/TimelineItems/Items/Messages/LocationRoomTimelineItemContent.swift +++ b/ElementX/Sources/Services/Timeline/TimelineItems/Items/Messages/LocationRoomTimelineItemContent.swift @@ -9,29 +9,29 @@ import MatrixRustSDK struct LocationRoomTimelineItemContent: Hashable { - enum Kind { - case sender - case pin - - init(from asset: AssetType?) { - self = switch asset { - case .pin: - .pin - case .sender, .none: - .sender - } - } - } - let body: String let geoURI: GeoURI? - let kind: Kind + let kind: StaticLocationKind init(body: String, geoURI: GeoURI? = nil, - kind: Kind = .sender) { + kind: StaticLocationKind = .sender) { self.body = body self.geoURI = geoURI self.kind = kind } } + +enum StaticLocationKind { + case sender + case pin + + init(from asset: AssetType?) { + switch asset { + case .pin: + self = .pin + default: + self = .sender + } + } +} diff --git a/PreviewTests/Sources/GeneratedPreviewTests.swift b/PreviewTests/Sources/GeneratedPreviewTests.swift index 3603cc107..e773a6cdf 100644 --- a/PreviewTests/Sources/GeneratedPreviewTests.swift +++ b/PreviewTests/Sources/GeneratedPreviewTests.swift @@ -595,6 +595,14 @@ extension PreviewTests { } } + @Test + func locationPickerSheet() async throws { + AppSettings.resetAllSettings() // Ensure this test's previews start with fresh settings. + for (index, preview) in LocationPickerSheet_Previews._allPreviews.enumerated() { + try await assertSnapshots(matching: preview, step: index) + } + } + @Test func locationRoomTimelineView() async throws { AppSettings.resetAllSettings() // Ensure this test's previews start with fresh settings. @@ -1395,6 +1403,14 @@ extension PreviewTests { } } + @Test + func staticLocationSheet() async throws { + AppSettings.resetAllSettings() // Ensure this test's previews start with fresh settings. + for (index, preview) in StaticLocationSheet_Previews._allPreviews.enumerated() { + try await assertSnapshots(matching: preview, step: index) + } + } + @Test func stickerRoomTimelineView() async throws { AppSettings.resetAllSettings() // Ensure this test's previews start with fresh settings. diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/locationPickerSheet.iPad-en-GB-0.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/locationPickerSheet.iPad-en-GB-0.png new file mode 100644 index 000000000..34a9095e4 --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/locationPickerSheet.iPad-en-GB-0.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e90029735b3e8d91d3e7dffa6b0b9e292198406747cdbe369401fac4bfed3083 +size 78507 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/locationPickerSheet.iPad-pseudo-0.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/locationPickerSheet.iPad-pseudo-0.png new file mode 100644 index 000000000..7201f077f --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/locationPickerSheet.iPad-pseudo-0.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e161124402355f12e73f54f392098e9e51a35418fa067c5e6bab3e3f826c4c47 +size 80563 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/locationPickerSheet.iPhone-en-GB-0.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/locationPickerSheet.iPhone-en-GB-0.png new file mode 100644 index 000000000..477a15eb5 --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/locationPickerSheet.iPhone-en-GB-0.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:508a889587a0f58725312a524011f8c2c23745bf10158d55bf20b4ba98945100 +size 38102 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/locationPickerSheet.iPhone-pseudo-0.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/locationPickerSheet.iPhone-pseudo-0.png new file mode 100644 index 000000000..313833aca --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/locationPickerSheet.iPhone-pseudo-0.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ba81cf51fd3ead374e763a54c1e8f1f8b14d66e4f4708a2d93329537c4838981 +size 44398 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/locationSharingScreen.Pin-Static-Location-iPad-en-GB.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/locationSharingScreen.Pin-Static-Location-iPad-en-GB.png index 5b28befe4..3fa30dbfb 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/locationSharingScreen.Pin-Static-Location-iPad-en-GB.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/locationSharingScreen.Pin-Static-Location-iPad-en-GB.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cbf4a51ed98c176336fc2e5be99311342bdae0d931d5d78dabca0ace3dd3a85b -size 80783 +oid sha256:64737509400fe27cdb017b8f66cffe8c0807f958827cff84a9ce5484db0ca3fc +size 80109 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/locationSharingScreen.Pin-Static-Location-iPad-pseudo.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/locationSharingScreen.Pin-Static-Location-iPad-pseudo.png index 5b28befe4..3fa30dbfb 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/locationSharingScreen.Pin-Static-Location-iPad-pseudo.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/locationSharingScreen.Pin-Static-Location-iPad-pseudo.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cbf4a51ed98c176336fc2e5be99311342bdae0d931d5d78dabca0ace3dd3a85b -size 80783 +oid sha256:64737509400fe27cdb017b8f66cffe8c0807f958827cff84a9ce5484db0ca3fc +size 80109 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/locationSharingScreen.Pin-Static-Location-iPhone-en-GB.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/locationSharingScreen.Pin-Static-Location-iPhone-en-GB.png index 8e2bbfa03..215b1c7ff 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/locationSharingScreen.Pin-Static-Location-iPhone-en-GB.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/locationSharingScreen.Pin-Static-Location-iPhone-en-GB.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:117ab2273ccfba15cee5546e521a85b87c8f7b915b869a299234c7d1a0caecd2 -size 41622 +oid sha256:a068c98796f52c050c1adbffcd58a73f848c2ffccc814545c3e825fe70cff608 +size 38354 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/locationSharingScreen.Pin-Static-Location-iPhone-pseudo.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/locationSharingScreen.Pin-Static-Location-iPhone-pseudo.png index 8e2bbfa03..215b1c7ff 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/locationSharingScreen.Pin-Static-Location-iPhone-pseudo.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/locationSharingScreen.Pin-Static-Location-iPhone-pseudo.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:117ab2273ccfba15cee5546e521a85b87c8f7b915b869a299234c7d1a0caecd2 -size 41622 +oid sha256:a068c98796f52c050c1adbffcd58a73f848c2ffccc814545c3e825fe70cff608 +size 38354 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/locationSharingScreen.User-Static-Location-iPad-en-GB.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/locationSharingScreen.User-Static-Location-iPad-en-GB.png index 7612969bb..47d3affd1 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/locationSharingScreen.User-Static-Location-iPad-en-GB.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/locationSharingScreen.User-Static-Location-iPad-en-GB.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b4635f42e9d912d20f4963c5c3627f543cb00f95183fa0e902c9cc61b1afc921 -size 93073 +oid sha256:40b1b5e02ed04dce7e1c384004f295f2ac535e7a5a21e807122239bd6979688c +size 92341 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/locationSharingScreen.User-Static-Location-iPad-pseudo.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/locationSharingScreen.User-Static-Location-iPad-pseudo.png index 7612969bb..47d3affd1 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/locationSharingScreen.User-Static-Location-iPad-pseudo.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/locationSharingScreen.User-Static-Location-iPad-pseudo.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b4635f42e9d912d20f4963c5c3627f543cb00f95183fa0e902c9cc61b1afc921 -size 93073 +oid sha256:40b1b5e02ed04dce7e1c384004f295f2ac535e7a5a21e807122239bd6979688c +size 92341 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/locationSharingScreen.User-Static-Location-iPhone-en-GB.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/locationSharingScreen.User-Static-Location-iPhone-en-GB.png index b5c8cb0be..7a3a5c6cd 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/locationSharingScreen.User-Static-Location-iPhone-en-GB.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/locationSharingScreen.User-Static-Location-iPhone-en-GB.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c68d58d06123afaa7e02fc798b2360e1818c450fd277b275308d5704203e5547 -size 53102 +oid sha256:8cc0b6d024146792039a958fcc043be64b7e002bf4b796de3e2d7a3497f80995 +size 50211 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/locationSharingScreen.User-Static-Location-iPhone-pseudo.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/locationSharingScreen.User-Static-Location-iPhone-pseudo.png index b5c8cb0be..7a3a5c6cd 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/locationSharingScreen.User-Static-Location-iPhone-pseudo.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/locationSharingScreen.User-Static-Location-iPhone-pseudo.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c68d58d06123afaa7e02fc798b2360e1818c450fd277b275308d5704203e5547 -size 53102 +oid sha256:8cc0b6d024146792039a958fcc043be64b7e002bf4b796de3e2d7a3497f80995 +size 50211 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/staticLocationSheet.Static-own-location-iPad-en-GB.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/staticLocationSheet.Static-own-location-iPad-en-GB.png new file mode 100644 index 000000000..9d5059fa2 --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/staticLocationSheet.Static-own-location-iPad-en-GB.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6ae12e39a82005f3a05628586575eca9731723bc6e84f5cc615120b34a3abcd1 +size 91071 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/staticLocationSheet.Static-own-location-iPad-pseudo.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/staticLocationSheet.Static-own-location-iPad-pseudo.png new file mode 100644 index 000000000..161defe05 --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/staticLocationSheet.Static-own-location-iPad-pseudo.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ca50e6e8aed44c7fae7074946d3991a4ccd37f69df40fc84aa42da4e7c27871d +size 93402 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/staticLocationSheet.Static-own-location-iPhone-en-GB.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/staticLocationSheet.Static-own-location-iPhone-en-GB.png new file mode 100644 index 000000000..5dc7982b0 --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/staticLocationSheet.Static-own-location-iPhone-en-GB.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:65740d7427b80648ee701c7f8ee14fcc2b51408ae2f71bf6e2f21b27cbdec440 +size 47976 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/staticLocationSheet.Static-own-location-iPhone-pseudo.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/staticLocationSheet.Static-own-location-iPhone-pseudo.png new file mode 100644 index 000000000..426eaff05 --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/staticLocationSheet.Static-own-location-iPhone-pseudo.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8b2164e0fb7394363c4dfd82a60e852fc84fc6db53cda01e871208e147b3ecdd +size 51137 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/staticLocationSheet.Static-pin-location-iPad-en-GB.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/staticLocationSheet.Static-pin-location-iPad-en-GB.png new file mode 100644 index 000000000..f28d9794d --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/staticLocationSheet.Static-pin-location-iPad-en-GB.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a3c481f252728c952db62718fddee02526c96a65e98d3baa876015bbacecb21e +size 90853 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/staticLocationSheet.Static-pin-location-iPad-pseudo.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/staticLocationSheet.Static-pin-location-iPad-pseudo.png new file mode 100644 index 000000000..1df26aabc --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/staticLocationSheet.Static-pin-location-iPad-pseudo.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cda862691055a9cf8ed316bbdee74fecf2258b919086aaf92daebf8f93804f3e +size 92210 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/staticLocationSheet.Static-pin-location-iPhone-en-GB.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/staticLocationSheet.Static-pin-location-iPhone-en-GB.png new file mode 100644 index 000000000..87a44d95f --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/staticLocationSheet.Static-pin-location-iPhone-en-GB.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cf1c86651f913230a7ff2d1fbfa9a9e6f8ee5abd69f6ef6988699ad343b8ec1b +size 47986 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/staticLocationSheet.Static-pin-location-iPhone-pseudo.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/staticLocationSheet.Static-pin-location-iPhone-pseudo.png new file mode 100644 index 000000000..85ea94c25 --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/staticLocationSheet.Static-pin-location-iPhone-pseudo.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b099800fa1e8e53e981382786474027d2d34ab6cee4ef85a27a1bd9d678c9681 +size 50674