diff --git a/ElementX.xcodeproj/project.pbxproj b/ElementX.xcodeproj/project.pbxproj index c448b1945cc06e9c203f293600e0c6ca145d2751..702f33c4e258613970e4e7d38b76e31b40319ac2 100644 --- a/ElementX.xcodeproj/project.pbxproj +++ b/ElementX.xcodeproj/project.pbxproj @@ -116,11 +116,11 @@ 1318721F4E5F307586D98112 /* VoiceMessageButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8516302ACCA94A0E680AB3B /* VoiceMessageButton.swift */; }; 13C77FDF17C4C6627CFFC205 /* RoomTimelineItemFactoryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D25A35764C7B3DB78954AB5 /* RoomTimelineItemFactoryProtocol.swift */; }; 13CBC470FB619A6393A21908 /* RoomNotificationSettingsScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8296D6FB451E25CEC0767BBA /* RoomNotificationSettingsScreenCoordinator.swift */; }; - 14343C2F9AD2BFEA92CA28FF /* MapTilerStyleBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7AE92E7BFF71797BDE1D261 /* MapTilerStyleBuilder.swift */; }; 1443CEEE42491CF7CD8A146A /* XCTestCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85A1941B874A3BE9CDDF43EF /* XCTestCase.swift */; }; 1471A080552631358D152C18 /* AudioPlayerState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2BDB3E65A79779EDA5D33D8A /* AudioPlayerState.swift */; }; 147597951DB07123A87AA1D1 /* landscape_test_image.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 96CE9D6642DD487D8CC90C9C /* landscape_test_image.jpg */; }; 149D1942DC005D0485FB8D93 /* LoggingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DC1943ADE6A62ED5129D7C8 /* LoggingTests.swift */; }; + 14D423FCBE4C1D7E64806CC3 /* MapTilerConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32A1FAE3EEAB27D8D38E3273 /* MapTilerConfiguration.swift */; }; 14E99D27628B1A6F0CB46FEA /* SeparatorRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6A9F49B3EE59147AF2F70BB /* SeparatorRoomTimelineItem.swift */; }; 151D2477F75782C8702F2873 /* PollInteractionHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC528B3764E3CF7FCFEF40E7 /* PollInteractionHandler.swift */; }; 155063E980E763D4910EA3CF /* Analytics+SwiftUI.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4CFE236419E830E8946639C /* Analytics+SwiftUI.swift */; }; @@ -302,6 +302,7 @@ 3B277D9538090766DA6C4566 /* StateRoomTimelineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B2AF1828A5B76B7C371240FE /* StateRoomTimelineView.swift */; }; 3B28408450BCAED911283AA2 /* UserPreference.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35FA991289149D31F4286747 /* UserPreference.swift */; }; 3B98049F56025726FB646ABD /* SwipeToReplyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B0E0B55E2EE75AF67029924 /* SwipeToReplyView.swift */; }; + 3BEBDCB42BABFA3B456FECA7 /* MapTilerURLBuilderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D262A26713C18BB70C82CA5 /* MapTilerURLBuilderTests.swift */; }; 3C312A3AEDE58BB1C9BBB07C /* preview_avatar_room.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 12FD5280AF55AB7F50F8E47D /* preview_avatar_room.jpg */; }; 3C31E1A65EEB61E72E1113B4 /* AudioRecorderProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBEC57C204D77908E355EF42 /* AudioRecorderProtocol.swift */; }; 3C549A0BF39F8A854D45D9FD /* KeychainAccess in Frameworks */ = {isa = PBXBuildFile; productRef = 020597E28A4BC8E1BE8EDF6E /* KeychainAccess */; }; @@ -496,6 +497,7 @@ 63780F9DA06573E38A471ECA /* GenericCallLinkWidgetDriver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28C202C1C7E330F124981A31 /* GenericCallLinkWidgetDriver.swift */; }; 6386EA3C898AD1A4BC1DC8A5 /* TimelineMediaPreviewModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FD40B92FCF20165658296AD /* TimelineMediaPreviewModifier.swift */; }; 63CDC201A5980F304F6D0A1C /* WaveformInteractionModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFEE91FB8ABB5F5884B6D940 /* WaveformInteractionModifier.swift */; }; + 63DCEBC1DD555E0D645B9E98 /* MapTilerURLBuilderProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1033290D99D5BBA1AF3560A /* MapTilerURLBuilderProtocol.swift */; }; 63E46D18B91D08E15FC04125 /* ExpiringTaskRunner.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B25F959A434BB9923A3223F /* ExpiringTaskRunner.swift */; }; 63FD7DBE7BBA149B4B8B99D7 /* TimelineControllerFactoryMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = B0F5CC38803B8382D2C63222 /* TimelineControllerFactoryMock.swift */; }; 642DF13C49ED4121C148230E /* TestablePreview.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1E227F34BE43B08E098796E /* TestablePreview.swift */; }; @@ -530,7 +532,6 @@ 68184EF36396424FE19A727D /* MediaLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8AFCE895ECFFA53FEE64D62B /* MediaLoader.swift */; }; 6832733838C57A7D3FE8FEB5 /* KeychainAccess in Frameworks */ = {isa = PBXBuildFile; productRef = 78A5A8DE1E2B09C978C7F3B0 /* KeychainAccess */; }; 6851B077B4C913CC12DB6E77 /* AppLockFlowCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCE93F0CBF0D96B77111C413 /* AppLockFlowCoordinator.swift */; }; - 6860721DB3091BE08164C132 /* MapAssets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B48B7AD4908C5C374517B892 /* MapAssets.xcassets */; }; 695825D20A761C678809345D /* MessageForwardingScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52135BD9E0E7A091688F627A /* MessageForwardingScreenModels.swift */; }; 69A9B430397C15075D86193F /* UserPropertiesExt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66AFD800AF033D8B0D11191A /* UserPropertiesExt.swift */; }; 69B3C6010B42010F591FC3CB /* RoomRolesAndPermissionsScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C1AF829F12FDC99717082D9 /* RoomRolesAndPermissionsScreenViewModel.swift */; }; @@ -601,7 +602,6 @@ 77693820498ABF3508814D49 /* AppLockServiceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD97F9661ABF08CE002054A2 /* AppLockServiceTests.swift */; }; 77920AFA8091AC6B9F190C90 /* Signposter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 752A0EB49BF5BCEA37EDF7A3 /* Signposter.swift */; }; 77BB228AEA861E50FFD6A228 /* HomeScreenEmptyStateView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0FEA560929DD73FFEF8C3DF /* HomeScreenEmptyStateView.swift */; }; - 77C1A2F49CD90D3EFDF376E5 /* MapTilerURLBuildersTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 376D941BF8BB294389C0DE24 /* MapTilerURLBuildersTests.swift */; }; 77E33FF0E4A50B555BF3A8AA /* AudioFileEventsTimelineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC9044BE0E4A66F5B963E834 /* AudioFileEventsTimelineView.swift */; }; 77FB08C303F4C74C0E8577E2 /* TimelineMediaPreviewModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A2BB38DF61F5100B8723112 /* TimelineMediaPreviewModels.swift */; }; 7807B1DEE32617896886A8E5 /* FormattingToolbar.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE1E6FAA3719E9B7A2D5510B /* FormattingToolbar.swift */; }; @@ -624,7 +624,6 @@ 7A8B264506D3DDABC01B4EEB /* AppMediator.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53AC78E49A297AC1D72A7CF /* AppMediator.swift */; }; 7B1605C6FFD4D195F264A684 /* RoomPollsHistoryScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B40233F2989AD49906BB310D /* RoomPollsHistoryScreenViewModelTests.swift */; }; 7B3A59786DB2F741A1743ED0 /* PinnedEventsTimelineScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 510E89B989477E5EE8E503C0 /* PinnedEventsTimelineScreenViewModelProtocol.swift */; }; - 7B5DAB915357BE596529BF25 /* MapTilerStaticMapProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 20872C3887F835958CE2F1D0 /* MapTilerStaticMapProtocol.swift */; }; 7B66DA4E7E5FE4D1A0FCEAA4 /* JoinRoomScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEAB5662310AE73D93815134 /* JoinRoomScreenViewModelProtocol.swift */; }; 7BB31E67648CF32D2AB5E502 /* RoomScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9CE3C90E487B255B735D73C8 /* RoomScreenViewModel.swift */; }; 7BD2123144A32F082CECC108 /* AudioRoomTimelineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B2EAFFD44F81F86012D6EC27 /* AudioRoomTimelineView.swift */; }; @@ -661,7 +660,6 @@ 828EA5009557C2B9DCD4CA0F /* UserDiscoverySection.swift in Sources */ = {isa = PBXBuildFile; fileRef = D071F86CD47582B9196C9D16 /* UserDiscoverySection.swift */; }; 832A4EA1094B8FE423A08700 /* RoomChangeRolesScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B2A421198FD20AAAED20004 /* RoomChangeRolesScreen.swift */; }; 8358D145F9BF94F412BEDCA8 /* RoomRolesAndPermissionsScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DE7969EBCAF078813E18EA1 /* RoomRolesAndPermissionsScreenModels.swift */; }; - 83A4DAB181C56987C3E804FF /* MapTilerStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0B9F5BC4C80543DE7228B9D /* MapTilerStyle.swift */; }; 83B17A44D3E7E6DF22D9A2A4 /* RoomModerationRole.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B32BBA8887BD7A5C4ECF16F /* RoomModerationRole.swift */; }; 83D519C509F0F76EDBB60455 /* KnockRequestProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F062DD2CCD95DC33528A16F /* KnockRequestProxy.swift */; }; 84226AD2E1F1FBC965F3B09E /* UnitTestsAppCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6A8E19C4645D3F5F9FB02355 /* UnitTestsAppCoordinator.swift */; }; @@ -960,7 +958,6 @@ BDC4EB54CC3036730475CB8B /* QRCodeLoginScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 25E7E9B7FEAB6169D960C206 /* QRCodeLoginScreenViewModelTests.swift */; }; BDED6DA7AD1E76018C424143 /* LegalInformationScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C34667458773B02AB5FB0B2 /* LegalInformationScreenViewModel.swift */; }; BE8E5985771DF9137C6CE89A /* ProcessInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 077B01C13BBA2996272C5FB5 /* ProcessInfo.swift */; }; - BEA646DF302711A753F0D420 /* MapTilerStyleBuilderProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 225EFCA26877E75CDFE7F48D /* MapTilerStyleBuilderProtocol.swift */; }; BEC6DFEA506085D3027E353C /* MediaEventsTimelineScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 002399C6CB875C4EBB01CBC0 /* MediaEventsTimelineScreen.swift */; }; BFEB24336DFD5F196E6F3456 /* IntentionalMentions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0DF5CBAF69BDF5DF31C661E1 /* IntentionalMentions.swift */; }; C0090506A52A1991BAF4BA68 /* NotificationSettingsChatType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07579F9C29001E40715F3014 /* NotificationSettingsChatType.swift */; }; @@ -1050,7 +1047,6 @@ D0A965852D6C04138FA55181 /* SecureBackupLogoutConfirmationScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCF239C619971FDE48132550 /* SecureBackupLogoutConfirmationScreenModels.swift */; }; D10BA4F041DC58580A440A32 /* RoomRolesAndPermissionsScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = B2B1DC3B3FB40A7F4AE9B7BF /* RoomRolesAndPermissionsScreen.swift */; }; D12F440F7973F1489F61389D /* NotificationSettingsScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0F64447FF544298A6A3BEF85 /* NotificationSettingsScreenModels.swift */; }; - D181AC8FF236B7F91C0A8C28 /* MapTiler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 23AA3F4B285570805CB0CCDD /* MapTiler.swift */; }; D18B70975644C24F60656C0D /* KnockRequestProxyProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = C07851F4EA81AA3339806A7B /* KnockRequestProxyProtocol.swift */; }; D19A748E95E2FAB2940570F0 /* CallScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4103AB4340F2974D690A12A /* CallScreen.swift */; }; D2048FD56760BDABA3DB5FC2 /* AppLockServiceProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26EAAB54C6CE91D64B69A9F8 /* AppLockServiceProtocol.swift */; }; @@ -1077,7 +1073,6 @@ D5FE90A6AF5FD5AE91BD37C7 /* NotificationSettingsEditScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 780258F1B9D15E30549FF4BE /* NotificationSettingsEditScreenViewModel.swift */; }; D6152E21036B88C44ECB22E7 /* EncryptionResetPasswordScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 303D9438EFB481F57A366E82 /* EncryptionResetPasswordScreenViewModel.swift */; }; D63974A88CF2BC721F109C77 /* Compound in Frameworks */ = {isa = PBXBuildFile; productRef = DCA3C4A997AD28E6918D4CE5 /* Compound */; }; - D6661A94DBD97658B2ADBD6A /* MapTilerStaticMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A4D29F2683F5772AC72406F /* MapTilerStaticMap.swift */; }; D6DE764B17FB4A9A12C33BF4 /* MessageComposer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F1DF3FFFE5ED2B8133F43A7 /* MessageComposer.swift */; }; D7CDBAE82782BD0529DECB5F /* AttributedString.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52BD6ED18E2EB61E28C340AD /* AttributedString.swift */; }; D8459AAD6969B1431ECBE990 /* UnsupportedRoomTimelineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9E535B3388755B65C34CD10 /* UnsupportedRoomTimelineView.swift */; }; @@ -1261,7 +1256,6 @@ FC10228E73323BDC09526F97 /* Mapbox in Frameworks */ = {isa = PBXBuildFile; productRef = C1BF15833233CD3BDB7E2B1D /* Mapbox */; }; FC8B95EC506E6BB5793D81CE /* ClientProtocolTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E34685D186453E429ADEE58E /* ClientProtocolTests.swift */; }; FCD3F2B82CAB29A07887A127 /* KeychainAccess in Frameworks */ = {isa = PBXBuildFile; productRef = 2B43F2AF7456567FE37270A7 /* KeychainAccess */; }; - FCDA202B246F75BA28E10C5F /* MapTilerAuthorization.swift in Sources */ = {isa = PBXBuildFile; fileRef = E062C1750EFC8627DE4CAB8E /* MapTilerAuthorization.swift */; }; FD29471C72872F8B7580E3E1 /* KeychainControllerMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39C0D861FC397AC34BCF089E /* KeychainControllerMock.swift */; }; FD4C21F8DA1E273DE94FCD1A /* NotificationItemProxyProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B927CF5EF7FCCDA5EDC474B /* NotificationItemProxyProtocol.swift */; }; FD762761C5D0C30E6255C3D8 /* ServerConfirmationScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABA4CF2F5B4F68D02E412004 /* ServerConfirmationScreenViewModelProtocol.swift */; }; @@ -1473,7 +1467,6 @@ 1A1265FAF2C0AF1C30605BE7 /* SessionVerificationRequestDetailsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionVerificationRequestDetailsView.swift; sourceTree = "<group>"; }; 1A13364350970987B93F6018 /* JoinRoomByAddressView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JoinRoomByAddressView.swift; sourceTree = "<group>"; }; 1A18F6CE4D694D21E4EA9B25 /* Strings+Untranslated.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Strings+Untranslated.swift"; sourceTree = "<group>"; }; - 1A4D29F2683F5772AC72406F /* MapTilerStaticMap.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapTilerStaticMap.swift; sourceTree = "<group>"; }; 1A7ED2EF5BDBAD2A7DBC4636 /* GeoURITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeoURITests.swift; sourceTree = "<group>"; }; 1B065EC39C99C1303A101C1C /* WebRegistrationScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebRegistrationScreen.swift; sourceTree = "<group>"; }; 1B10423B9102086A2D9BFCBA /* EventTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventTimelineItem.swift; sourceTree = "<group>"; }; @@ -1491,6 +1484,7 @@ 1C7F63EB1525E697CAEB002B /* BlankFormCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlankFormCoordinator.swift; sourceTree = "<group>"; }; 1CC575D1895FA62591451A93 /* RoomMemberDetailsScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMemberDetailsScreen.swift; sourceTree = "<group>"; }; 1CD7C0A2750998C2D77AD00F /* JoinRoomScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JoinRoomScreenViewModel.swift; sourceTree = "<group>"; }; + 1D262A26713C18BB70C82CA5 /* MapTilerURLBuilderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapTilerURLBuilderTests.swift; sourceTree = "<group>"; }; 1D56469A9EE0CFA2B7BA9760 /* SessionVerificationControllerProxyProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionVerificationControllerProxyProtocol.swift; sourceTree = "<group>"; }; 1D652E78832289CD9EB64488 /* hu */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hu; path = hu.lproj/InfoPlist.strings; sourceTree = "<group>"; }; 1D67E616BCA82D8A1258D488 /* NetworkMonitor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkMonitor.swift; sourceTree = "<group>"; }; @@ -1514,7 +1508,6 @@ 200626E8353AB2729444F991 /* preview_image.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = preview_image.jpg; sourceTree = "<group>"; }; 201305507D7DFD16E544563A /* EmojiLoaderProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmojiLoaderProtocol.swift; sourceTree = "<group>"; }; 203D1ACC20287F8986C959D3 /* target.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = target.yml; sourceTree = "<group>"; }; - 20872C3887F835958CE2F1D0 /* MapTilerStaticMapProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapTilerStaticMapProtocol.swift; sourceTree = "<group>"; }; 20E69F67D2A70ABD08CA6D54 /* NotificationPermissionsScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationPermissionsScreenViewModelProtocol.swift; sourceTree = "<group>"; }; 2141693488CE5446BB391964 /* Date.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Date.swift; sourceTree = "<group>"; }; 216F0DDC98F2A2C162D09C28 /* FileRoomTimelineItemContent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileRoomTimelineItemContent.swift; sourceTree = "<group>"; }; @@ -1523,13 +1516,11 @@ 21BA866267F84BF4350B0CB7 /* pt-BR */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = "pt-BR"; path = "pt-BR.lproj/Localizable.stringsdict"; sourceTree = "<group>"; }; 21DD8599815136EFF5B73F38 /* UserFlowTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserFlowTests.swift; sourceTree = "<group>"; }; 2214C32EA81FA9168D923D4C /* CreateRoomScreenTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreateRoomScreenTests.swift; sourceTree = "<group>"; }; - 225EFCA26877E75CDFE7F48D /* MapTilerStyleBuilderProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapTilerStyleBuilderProtocol.swift; sourceTree = "<group>"; }; 22730A30C50AC2E3D5BA8642 /* InviteUsersScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InviteUsersScreenViewModelProtocol.swift; sourceTree = "<group>"; }; 227AC5D71A4CE43512062243 /* URL.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URL.swift; sourceTree = "<group>"; }; 22DB19219E6CC4D002E15D48 /* GlobalSearchScreenCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GlobalSearchScreenCell.swift; sourceTree = "<group>"; }; 2355398E4A55DA5A89128AD1 /* EncryptionKeyProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EncryptionKeyProvider.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>"; }; 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>"; }; @@ -1606,6 +1597,7 @@ 31A6314FDC51DA25712D9A81 /* PillContextTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PillContextTests.swift; sourceTree = "<group>"; }; 31D6764D6976D235926FE5FC /* HomeScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeScreenViewModel.swift; sourceTree = "<group>"; }; 3203C6566DC17B7AECC1B7FD /* RoomNotificationSettingsUserDefinedScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomNotificationSettingsUserDefinedScreen.swift; sourceTree = "<group>"; }; + 32A1FAE3EEAB27D8D38E3273 /* MapTilerConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapTilerConfiguration.swift; sourceTree = "<group>"; }; 32B5E17028C02DFA7DDA3931 /* RoomMemberProxyProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMemberProxyProtocol.swift; sourceTree = "<group>"; }; 32C5DAA1773F57653BF1C4F9 /* SoftLogoutViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SoftLogoutViewModelTests.swift; sourceTree = "<group>"; }; 33035418BB35754232985871 /* TimelineReadReceiptsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineReadReceiptsView.swift; sourceTree = "<group>"; }; @@ -1625,7 +1617,6 @@ 36DA824791172B9821EACBED /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; path = PrivacyInfo.xcprivacy; sourceTree = "<group>"; }; 36FD673E24FBFCFDF398716A /* RoomMemberProxyMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMemberProxyMock.swift; sourceTree = "<group>"; }; 371B248460BD1A3F20318137 /* TimelineProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineProvider.swift; sourceTree = "<group>"; }; - 376D941BF8BB294389C0DE24 /* MapTilerURLBuildersTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapTilerURLBuildersTests.swift; sourceTree = "<group>"; }; 37A63A59BFDDC494B1C20119 /* CallScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CallScreenViewModel.swift; sourceTree = "<group>"; }; 37CA26F55123E36B50DB0B3A /* AttributedStringTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttributedStringTests.swift; sourceTree = "<group>"; }; 37F46CC4FD89ECF4CF26391A /* AuthenticationFlowCoordinatorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthenticationFlowCoordinatorTests.swift; sourceTree = "<group>"; }; @@ -2220,7 +2211,6 @@ B410B32B72C90BF94E481F33 /* AppLockSetupPINScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppLockSetupPINScreenModels.swift; sourceTree = "<group>"; }; B43456E73F8A2D52B69B9FB9 /* TemplateScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemplateScreenViewModel.swift; sourceTree = "<group>"; }; B4427AF4B7FB7EF3E3D424C7 /* QRCodeLoginService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QRCodeLoginService.swift; sourceTree = "<group>"; }; - B48B7AD4908C5C374517B892 /* MapAssets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = MapAssets.xcassets; sourceTree = "<group>"; }; B4AE42C19EDE64B7CB7BE4D0 /* SecurityAndPrivacyScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecurityAndPrivacyScreen.swift; sourceTree = "<group>"; }; B4CFE236419E830E8946639C /* Analytics+SwiftUI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Analytics+SwiftUI.swift"; sourceTree = "<group>"; }; B50F03079F6B5EF9CA005F14 /* TimelineProxyProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineProxyProtocol.swift; sourceTree = "<group>"; }; @@ -2239,7 +2229,6 @@ B746EFA112532A7B701FB914 /* RoomNotificationSettingsCustomSectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomNotificationSettingsCustomSectionView.swift; sourceTree = "<group>"; }; B7884BD256C091EB511B2EDF /* AppLockSetupPINScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppLockSetupPINScreenViewModelProtocol.swift; sourceTree = "<group>"; }; B788615712FED326F73D3F83 /* GlobalSearchScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GlobalSearchScreenViewModelProtocol.swift; sourceTree = "<group>"; }; - B7AE92E7BFF71797BDE1D261 /* MapTilerStyleBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapTilerStyleBuilder.swift; sourceTree = "<group>"; }; B7F0192CE2F891141A25B49F /* UITestsSignalling.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITestsSignalling.swift; sourceTree = "<group>"; }; B8108C8F0ACF6A7EB72D0117 /* RoomScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomScreenCoordinator.swift; sourceTree = "<group>"; }; B81B6170DB690013CEB646F4 /* MapLibreModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapLibreModels.swift; sourceTree = "<group>"; }; @@ -2423,7 +2412,6 @@ DF17EA323AD0205A6AB621AA /* Snapshotting.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Snapshotting.swift; sourceTree = "<group>"; }; DF3D25B3EDB283B5807EADCF /* ReadMarkerRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReadMarkerRoomTimelineItem.swift; sourceTree = "<group>"; }; DFFB0E7C6D8E190AFA0176DC /* uz */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = uz; path = uz.lproj/Localizable.stringsdict; sourceTree = "<group>"; }; - E062C1750EFC8627DE4CAB8E /* MapTilerAuthorization.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapTilerAuthorization.swift; sourceTree = "<group>"; }; E06AAD6D9D3F5833E7A5A2F9 /* RoomListFilterModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomListFilterModels.swift; sourceTree = "<group>"; }; E0F7CCC4A9D1927223F559D5 /* AuthenticationStartScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthenticationStartScreenViewModelProtocol.swift; sourceTree = "<group>"; }; E0FCA0957FAA0E15A9F5579D /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = en; path = en.lproj/Untranslated.stringsdict; sourceTree = "<group>"; }; @@ -2511,8 +2499,8 @@ F012CB5EE3F2B67359F6CC52 /* target.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = target.yml; sourceTree = "<group>"; }; F0205C03F98BE861EDABCB0D /* be */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = be; path = be.lproj/Localizable.strings; 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>"; }; F0E14FF533D25A0692F7CEB0 /* RoomPollsHistoryScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomPollsHistoryScreenViewModel.swift; sourceTree = "<group>"; }; + F1033290D99D5BBA1AF3560A /* MapTilerURLBuilderProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapTilerURLBuilderProtocol.swift; sourceTree = "<group>"; }; F104596B0620CEFE5DFD31B1 /* RoomSelectionScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomSelectionScreenCoordinator.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>"; }; @@ -3615,7 +3603,6 @@ 4E2245243369B99216C7D84E /* ImageCache.swift */, 045253F9967A535EE5B16691 /* Label.swift */, C14D83B2B7CD5501A0089EFC /* LayoutDirection.swift */, - 23AA3F4B285570805CB0CCDD /* MapTiler.swift */, F72EFC8C634469F9262659C7 /* NSItemProvider.swift */, 95BAC0F6C9644336E9567EE6 /* NSRegularExpresion.swift */, 62B07B296D7A9D2F09120853 /* OrderedSet.swift */, @@ -4237,7 +4224,7 @@ C070FD43DC6BF4E50217965A /* LocalizationTests.swift */, 3DC1943ADE6A62ED5129D7C8 /* LoggingTests.swift */, 5A43964330459965AF048A8C /* LoginScreenViewModelTests.swift */, - 376D941BF8BB294389C0DE24 /* MapTilerURLBuildersTests.swift */, + 1D262A26713C18BB70C82CA5 /* MapTilerURLBuilderTests.swift */, F31F59030205A6F65B057E1A /* MatrixEntityRegexTests.swift */, 2D7A2C4A3A74F0D2FFE9356A /* MediaPlayerProviderTests.swift */, AE203026B9AD3DB412439866 /* MediaUploadingPreprocessorTests.swift */, @@ -5345,16 +5332,11 @@ isa = PBXGroup; children = ( AAD8234D0E9C9B12BF9F240B /* LocationAnnotation.swift */, - B48B7AD4908C5C374517B892 /* MapAssets.xcassets */, 622D09D4ECE759189009AEAF /* MapLibreMapView.swift */, B81B6170DB690013CEB646F4 /* MapLibreModels.swift */, 592A35163B0749C66BFD6186 /* MapLibreStaticMapView.swift */, - E062C1750EFC8627DE4CAB8E /* MapTilerAuthorization.swift */, - 1A4D29F2683F5772AC72406F /* MapTilerStaticMap.swift */, - 20872C3887F835958CE2F1D0 /* MapTilerStaticMapProtocol.swift */, - F0B9F5BC4C80543DE7228B9D /* MapTilerStyle.swift */, - B7AE92E7BFF71797BDE1D261 /* MapTilerStyleBuilder.swift */, - 225EFCA26877E75CDFE7F48D /* MapTilerStyleBuilderProtocol.swift */, + 32A1FAE3EEAB27D8D38E3273 /* MapTilerConfiguration.swift */, + F1033290D99D5BBA1AF3560A /* MapTilerURLBuilderProtocol.swift */, ); path = MapLibre; sourceTree = "<group>"; @@ -6395,7 +6377,6 @@ B6DA66EFC13A90846B625836 /* InfoPlist.strings in Resources */, 5F5488FBC9CFEB6F433D74A4 /* Localizable.strings in Resources */, 0EA6537A07E2DC882AEA5962 /* Localizable.stringsdict in Resources */, - 6860721DB3091BE08164C132 /* MapAssets.xcassets in Resources */, 8B408C574E35E1C9B43A50CE /* PrivacyInfo.xcprivacy in Resources */, C3317EF833AB4060988DF098 /* SAS.strings in Resources */, 5FCD8AFA364206EE32B909A3 /* Settings.bundle in Resources */, @@ -6720,7 +6701,7 @@ 0033481EE363E4914295F188 /* LocalizationTests.swift in Sources */, 149D1942DC005D0485FB8D93 /* LoggingTests.swift in Sources */, 7434A7F02D587A920B376A9A /* LoginScreenViewModelTests.swift in Sources */, - 77C1A2F49CD90D3EFDF376E5 /* MapTilerURLBuildersTests.swift in Sources */, + 3BEBDCB42BABFA3B456FECA7 /* MapTilerURLBuilderTests.swift in Sources */, 2E43A3D221BE9587BC19C3F1 /* MatrixEntityRegexTests.swift in Sources */, 4B978C09567387EF4366BD7A /* MediaLoaderTests.swift in Sources */, 3582056513A384F110EC8274 /* MediaPlayerProviderTests.swift in Sources */, @@ -7208,13 +7189,8 @@ C1D0AB8222D7BAFC9AF9C8C0 /* MapLibreMapView.swift in Sources */, C9BE065FA7D4E77E4C61CB69 /* MapLibreModels.swift in Sources */, E2DDA49BD62F03F180A42E30 /* MapLibreStaticMapView.swift in Sources */, - D181AC8FF236B7F91C0A8C28 /* MapTiler.swift in Sources */, - FCDA202B246F75BA28E10C5F /* MapTilerAuthorization.swift in Sources */, - D6661A94DBD97658B2ADBD6A /* MapTilerStaticMap.swift in Sources */, - 7B5DAB915357BE596529BF25 /* MapTilerStaticMapProtocol.swift in Sources */, - 83A4DAB181C56987C3E804FF /* MapTilerStyle.swift in Sources */, - 14343C2F9AD2BFEA92CA28FF /* MapTilerStyleBuilder.swift in Sources */, - BEA646DF302711A753F0D420 /* MapTilerStyleBuilderProtocol.swift in Sources */, + 14D423FCBE4C1D7E64806CC3 /* MapTilerConfiguration.swift in Sources */, + 63DCEBC1DD555E0D645B9E98 /* MapTilerURLBuilderProtocol.swift in Sources */, 67C05C50AD734283374605E3 /* MatrixEntityRegex.swift in Sources */, 8658F5034EAD7357CE7F9AC7 /* MatrixUserShareLink.swift in Sources */, 84E514915DF0C168B08A3A0A /* MediaEventsTimelineFlowCoordinator.swift in Sources */, diff --git a/ElementX/Sources/Other/MapLibre/MapAssets.xcassets/mapBlurred.imageset/Contents.json b/ElementX/Resources/Assets.xcassets/images/location/mapBlurred.imageset/Contents.json similarity index 100% rename from ElementX/Sources/Other/MapLibre/MapAssets.xcassets/mapBlurred.imageset/Contents.json rename to ElementX/Resources/Assets.xcassets/images/location/mapBlurred.imageset/Contents.json diff --git a/ElementX/Sources/Other/MapLibre/MapAssets.xcassets/mapBlurred.imageset/DarkMapBlurred.pdf b/ElementX/Resources/Assets.xcassets/images/location/mapBlurred.imageset/DarkMapBlurred.pdf similarity index 100% rename from ElementX/Sources/Other/MapLibre/MapAssets.xcassets/mapBlurred.imageset/DarkMapBlurred.pdf rename to ElementX/Resources/Assets.xcassets/images/location/mapBlurred.imageset/DarkMapBlurred.pdf diff --git a/ElementX/Sources/Other/MapLibre/MapAssets.xcassets/mapBlurred.imageset/lightMapBlurred.pdf b/ElementX/Resources/Assets.xcassets/images/location/mapBlurred.imageset/lightMapBlurred.pdf similarity index 100% rename from ElementX/Sources/Other/MapLibre/MapAssets.xcassets/mapBlurred.imageset/lightMapBlurred.pdf rename to ElementX/Resources/Assets.xcassets/images/location/mapBlurred.imageset/lightMapBlurred.pdf diff --git a/ElementX/Sources/Application/AppSettings.swift b/ElementX/Sources/Application/AppSettings.swift index 801b1a139f33d7a25f8643d2e01ee1a4b65ca6d6..3ddb5ed2e0c396d26ee89ec52105c9da210aea4c 100644 --- a/ElementX/Sources/Application/AppSettings.swift +++ b/ElementX/Sources/Application/AppSettings.swift @@ -97,7 +97,8 @@ final class AppSettings { copyrightURL: URL, acceptableUseURL: URL, privacyURL: URL, - supportEmailAddress: String) { + supportEmailAddress: String, + mapTilerConfiguration: MapTilerConfiguration) { self.defaultHomeserverAddress = defaultHomeserverAddress self.oidcRedirectURL = oidcRedirectURL self.websiteURL = websiteURL @@ -106,6 +107,7 @@ final class AppSettings { self.acceptableUseURL = acceptableUseURL self.privacyURL = privacyURL self.supportEmailAddress = supportEmailAddress + self.mapTilerConfiguration = mapTilerConfiguration } // MARK: - Application @@ -290,10 +292,10 @@ final class AppSettings { // MARK: - Maps // maptiler base url - let mapTilerBaseURL: URL = "https://api.maptiler.com/maps" - - // maptiler api key - let mapTilerApiKey = Secrets.mapLibreAPIKey + private(set) var mapTilerConfiguration = MapTilerConfiguration(baseURL: "https://api.maptiler.com/maps", + apiKey: Secrets.mapLibreAPIKey, + lightStyleID: "9bc819c8-e627-474a-a348-ec144fe3d810", + darkStyleID: "dea61faf-292b-4774-9660-58fcef89a7f3") // MARK: - Presence diff --git a/ElementX/Sources/FlowCoordinators/PinnedEventsTimelineFlowCoordinator.swift b/ElementX/Sources/FlowCoordinators/PinnedEventsTimelineFlowCoordinator.swift index ab63e8e743085e6f40282fa9d7fc7c4b8ad0e70b..92e182c9036fe5d45398a6f6c49225b36ca32264 100644 --- a/ElementX/Sources/FlowCoordinators/PinnedEventsTimelineFlowCoordinator.swift +++ b/ElementX/Sources/FlowCoordinators/PinnedEventsTimelineFlowCoordinator.swift @@ -21,6 +21,7 @@ class PinnedEventsTimelineFlowCoordinator: FlowCoordinatorProtocol { private let timelineControllerFactory: TimelineControllerFactoryProtocol private let roomProxy: JoinedRoomProxyProtocol private let userIndicatorController: UserIndicatorControllerProtocol + private let appSettings: AppSettings private let appMediator: AppMediatorProtocol private let emojiProvider: EmojiProviderProtocol @@ -36,6 +37,7 @@ class PinnedEventsTimelineFlowCoordinator: FlowCoordinatorProtocol { timelineControllerFactory: TimelineControllerFactoryProtocol, roomProxy: JoinedRoomProxyProtocol, userIndicatorController: UserIndicatorControllerProtocol, + appSettings: AppSettings, appMediator: AppMediatorProtocol, emojiProvider: EmojiProviderProtocol) { self.navigationStackCoordinator = navigationStackCoordinator @@ -43,6 +45,7 @@ class PinnedEventsTimelineFlowCoordinator: FlowCoordinatorProtocol { self.timelineControllerFactory = timelineControllerFactory self.roomProxy = roomProxy self.userIndicatorController = userIndicatorController + self.appSettings = appSettings self.appMediator = appMediator self.emojiProvider = emojiProvider } @@ -106,7 +109,9 @@ class PinnedEventsTimelineFlowCoordinator: FlowCoordinatorProtocol { private func presentMapNavigator(geoURI: GeoURI, description: String?) { let stackCoordinator = NavigationStackCoordinator() - let params = StaticLocationScreenCoordinatorParameters(interactionMode: .viewOnly(geoURI: geoURI, description: description), appMediator: appMediator) + let params = StaticLocationScreenCoordinatorParameters(interactionMode: .viewOnly(geoURI: geoURI, description: description), + mapURLBuilder: appSettings.mapTilerConfiguration, + appMediator: appMediator) let coordinator = StaticLocationScreenCoordinator(parameters: params) coordinator.actions.sink { [weak self] action in diff --git a/ElementX/Sources/FlowCoordinators/RoomFlowCoordinator.swift b/ElementX/Sources/FlowCoordinators/RoomFlowCoordinator.swift index 7abb8f1000e3281400a4393b96e6335aeefb6c6e..15eabc62c53a73b311f6f2e79473ddd64b7675b9 100644 --- a/ElementX/Sources/FlowCoordinators/RoomFlowCoordinator.swift +++ b/ElementX/Sources/FlowCoordinators/RoomFlowCoordinator.swift @@ -1076,7 +1076,9 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol { private func presentMapNavigator(interactionMode: StaticLocationInteractionMode) { let stackCoordinator = NavigationStackCoordinator() - let params = StaticLocationScreenCoordinatorParameters(interactionMode: interactionMode, appMediator: appMediator) + let params = StaticLocationScreenCoordinatorParameters(interactionMode: interactionMode, + mapURLBuilder: appSettings.mapTilerConfiguration, + appMediator: appMediator) let coordinator = StaticLocationScreenCoordinator(parameters: params) coordinator.actions.sink { [weak self] action in @@ -1563,6 +1565,7 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol { timelineControllerFactory: timelineControllerFactory, roomProxy: roomProxy, userIndicatorController: userIndicatorController, + appSettings: appSettings, appMediator: appMediator, emojiProvider: emojiProvider) diff --git a/ElementX/Sources/Generated/Assets.swift b/ElementX/Sources/Generated/Assets.swift index ce9f069eeeaad3b4a6130f69b504ed40fd043e4f..7272f6b08a1bd3873a3b23558bca35621a76e5ec 100644 --- a/ElementX/Sources/Generated/Assets.swift +++ b/ElementX/Sources/Generated/Assets.swift @@ -37,6 +37,7 @@ internal enum Asset { internal static let stopRecording = ImageAsset(name: "images/stop-recording") internal static let launchBackground = ImageAsset(name: "images/launch-background") internal static let locationMarkerShape = ImageAsset(name: "images/location-marker-shape") + internal static let mapBlurred = ImageAsset(name: "images/mapBlurred") internal static let mediaPause = ImageAsset(name: "images/media-pause") internal static let mediaPlay = ImageAsset(name: "images/media-play") internal static let notificationsPromptGraphic = ImageAsset(name: "images/notifications-prompt-graphic") diff --git a/ElementX/Sources/Other/Extensions/MapTiler.swift b/ElementX/Sources/Other/Extensions/MapTiler.swift deleted file mode 100644 index 7e4666c8cea93d9fbae94147737bcac6a3978a86..0000000000000000000000000000000000000000 --- a/ElementX/Sources/Other/Extensions/MapTiler.swift +++ /dev/null @@ -1,14 +0,0 @@ -// -// Copyright 2023, 2024 New Vector Ltd. -// -// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial -// Please see LICENSE files in the repository root for full details. -// - -import Foundation - -extension MapTilerStyleBuilder { - init(appSettings: AppSettings) { - self.init(baseURL: appSettings.mapTilerBaseURL, key: appSettings.mapTilerApiKey) - } -} diff --git a/ElementX/Sources/Other/MapLibre/MapAssets.xcassets/Contents.json b/ElementX/Sources/Other/MapLibre/MapAssets.xcassets/Contents.json deleted file mode 100644 index 73c00596a7fca3f3d4bdd64053b69d86745f9e10..0000000000000000000000000000000000000000 --- a/ElementX/Sources/Other/MapLibre/MapAssets.xcassets/Contents.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/ElementX/Sources/Other/MapLibre/MapLibreMapView.swift b/ElementX/Sources/Other/MapLibre/MapLibreMapView.swift index 5d8388ca2dff4db769386210782b1894de44b07d..5db9f93959d7eda7b6c3727ddd801566414ce145 100644 --- a/ElementX/Sources/Other/MapLibre/MapLibreMapView.swift +++ b/ElementX/Sources/Other/MapLibre/MapLibreMapView.swift @@ -34,7 +34,7 @@ struct MapLibreMapView: UIViewRepresentable { @Environment(\.colorScheme) private var colorScheme - let builder: MapTilerStyleBuilderProtocol + let mapURLBuilder: MapTilerURLBuilderProtocol let options: Options @@ -64,7 +64,7 @@ struct MapLibreMapView: UIViewRepresentable { // Don't set the same value twice. Otherwise, if there is an error loading the map, a loop // is caused as the `error` binding being set, which triggers this update, which sets a // new URL, which causes another error, and so it goes on round and round in a circle. - let dynamicMapURL = builder.dynamicMapURL(for: .init(colorScheme)) + let dynamicMapURL = mapURLBuilder.dynamicMapURL(for: .init(colorScheme)) if mapView.styleURL != dynamicMapURL { mapView.styleURL = dynamicMapURL } @@ -85,7 +85,7 @@ struct MapLibreMapView: UIViewRepresentable { } private func makeMapView() -> MGLMapView { - let mapView = MGLMapView(frame: .zero, styleURL: colorScheme == .dark ? builder.dynamicMapURL(for: .dark) : builder.dynamicMapURL(for: .light)) + let mapView = MGLMapView(frame: .zero, styleURL: mapURLBuilder.dynamicMapURL(for: colorScheme == .dark ? .dark : .light)) mapView.logoViewPosition = .topLeft mapView.attributionButtonPosition = .topLeft mapView.attributionButtonMargins = .init(x: mapView.logoView.frame.maxX + 8, y: mapView.logoView.center.y / 2) diff --git a/ElementX/Sources/Other/MapLibre/MapLibreModels.swift b/ElementX/Sources/Other/MapLibre/MapLibreModels.swift index b0ab2f73006d4de88822d3a7ab9dceb449311b28..daaf04b3788f5f10e2ae5a1c1dd74d78736cfd06 100644 --- a/ElementX/Sources/Other/MapLibre/MapLibreModels.swift +++ b/ElementX/Sources/Other/MapLibre/MapLibreModels.swift @@ -24,6 +24,14 @@ enum MapLibreError: Error { case failedLocatingUser } +/// The style to show a map in. +/// +/// There can be any number of styles, we have defined one for light and another for dark. +enum MapTilerStyle { + case light + case dark +} + enum MapTilerAttributionPlacement: String { case bottomRight = "bottomright" case bottomLeft = "bottomleft" diff --git a/ElementX/Sources/Other/MapLibre/MapLibreStaticMapView.swift b/ElementX/Sources/Other/MapLibre/MapLibreStaticMapView.swift index 73608e7586c36879b42745835edc0e0693ee4206..efd58ca3e3577e3dde1f657ebdf9a1a9a2bbe38f 100644 --- a/ElementX/Sources/Other/MapLibre/MapLibreStaticMapView.swift +++ b/ElementX/Sources/Other/MapLibre/MapLibreStaticMapView.swift @@ -11,7 +11,7 @@ import SwiftUI struct MapLibreStaticMapView<PinAnnotation: View>: View { private let coordinates: CLLocationCoordinate2D private let zoomLevel: Double - private let mapTilerStatic: MapTilerStaticMapProtocol + private let mapURLBuilder: MapTilerURLBuilderProtocol private let mapTilerAttributionPlacement: MapTilerAttributionPlacement private let mapSize: CGSize private let pinAnnotationView: PinAnnotation @@ -22,12 +22,12 @@ struct MapLibreStaticMapView<PinAnnotation: View>: View { init(coordinates: CLLocationCoordinate2D, zoomLevel: Double, attributionPlacement: MapTilerAttributionPlacement, - mapTilerStatic: MapTilerStaticMapProtocol, + mapURLBuilder: MapTilerURLBuilderProtocol, mapSize: CGSize, @ViewBuilder pinAnnotationView: () -> PinAnnotation) { self.coordinates = coordinates self.zoomLevel = zoomLevel - self.mapTilerStatic = mapTilerStatic + self.mapURLBuilder = mapURLBuilder mapTilerAttributionPlacement = attributionPlacement self.mapSize = mapSize self.pinAnnotationView = pinAnnotationView() @@ -35,11 +35,11 @@ struct MapLibreStaticMapView<PinAnnotation: View>: View { var body: some View { GeometryReader { geometry in - if let url = mapTilerStatic.staticMapURL(for: colorScheme.mapStyle, - coordinates: coordinates, - zoomLevel: zoomLevel, - size: mapSize, // temporary using a fixed size since the refresh doesn't work properly on the UITableView based timeline - attribution: mapTilerAttributionPlacement) { + if let url = mapURLBuilder.staticMapURL(for: colorScheme.mapStyle, + coordinates: coordinates, + zoomLevel: zoomLevel, + size: mapSize, // temporary using a fixed size since the refresh doesn't work properly on the UITableView based timeline + attribution: mapTilerAttributionPlacement) { AsyncImage(url: url) { phase in switch phase { case .empty: @@ -66,7 +66,7 @@ struct MapLibreStaticMapView<PinAnnotation: View>: View { } private var placeholderImage: some View { - Image("mapBlurred") + Image(asset: Asset.Images.mapBlurred) .resizable() .scaledToFill() } @@ -104,15 +104,22 @@ struct MapLibreStaticMapView_Previews: PreviewProvider, TestablePreview { MapLibreStaticMapView(coordinates: CLLocationCoordinate2D(), zoomLevel: 15, attributionPlacement: .bottomLeft, - mapTilerStatic: MapTilerStaticMapMock(), mapSize: .init(width: 300, height: 200)) { + mapURLBuilder: MapTilerURLBuilderMock(), + mapSize: .init(width: 300, height: 200)) { Image(systemName: "mappin.circle.fill") .padding(.bottom, 35) } } } -private struct MapTilerStaticMapMock: MapTilerStaticMapProtocol { - func staticMapURL(for style: MapTilerStyle, coordinates: CLLocationCoordinate2D, zoomLevel: Double, size: CGSize, attribution: MapTilerAttributionPlacement) -> URL? { +private struct MapTilerURLBuilderMock: MapTilerURLBuilderProtocol { + func dynamicMapURL(for style: MapTilerStyle) -> URL? { nil } + + func staticMapURL(for style: MapTilerStyle, + coordinates: CLLocationCoordinate2D, + zoomLevel: Double, + size: CGSize, + attribution: MapTilerAttributionPlacement) -> URL? { switch style { case .light: return URL(string: "https://www.maptiler.com/img/cloud/home/map5.webp") diff --git a/ElementX/Sources/Other/MapLibre/MapTilerAuthorization.swift b/ElementX/Sources/Other/MapLibre/MapTilerAuthorization.swift deleted file mode 100644 index c18a5342171483e5600b1c8fb52e60a86b511c2e..0000000000000000000000000000000000000000 --- a/ElementX/Sources/Other/MapLibre/MapTilerAuthorization.swift +++ /dev/null @@ -1,20 +0,0 @@ -// -// Copyright 2023, 2024 New Vector Ltd. -// -// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial -// Please see LICENSE files in the repository root for full details. -// - -import Foundation - -struct MapTilerAuthorization { - private let key: String - - init(key: String) { - self.key = key - } - - func authorizeURL(_ url: URL) -> URL { - url.appending(queryItems: [URLQueryItem(name: "key", value: key)]) - } -} diff --git a/ElementX/Sources/Other/MapLibre/MapTilerConfiguration.swift b/ElementX/Sources/Other/MapLibre/MapTilerConfiguration.swift new file mode 100644 index 0000000000000000000000000000000000000000..a2b73c82f7ddc84eb076a6de59b3697078e043fc --- /dev/null +++ b/ElementX/Sources/Other/MapLibre/MapTilerConfiguration.swift @@ -0,0 +1,62 @@ +// +// Copyright 2023, 2024 New Vector Ltd. +// +// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial +// Please see LICENSE files in the repository root for full details. +// + +import CoreLocation + +/// All of the configuration necessary to use MapTiler maps. +/// +/// The style IDs need to be generated with the account that the API key belongs to. For more information read +/// [FORKING.md](https://github.com/element-hq/element-x-ios/blob/develop/docs/FORKING.md#setup-the-location-sharing) +struct MapTilerConfiguration { + let baseURL: URL + let apiKey: String + /// A MapLibre style ID for a light-mode map. + let lightStyleID: String + /// A MapLibre style ID for a dark-mode map. + let darkStyleID: String +} + +extension MapTilerConfiguration: MapTilerURLBuilderProtocol { + func dynamicMapURL(for style: MapTilerStyle) -> URL? { + var url = makeNewURL(for: style) + url.appendPathComponent("style.json", conformingTo: .json) + return url + } + + func staticMapURL(for style: MapTilerStyle, + coordinates: CLLocationCoordinate2D, + zoomLevel: Double, + size: CGSize, + attribution: MapTilerAttributionPlacement) -> URL? { + var url = makeNewURL(for: style) + url.appendPathComponent(String(format: "static/%f,%f,%f/%dx%d@2x.png", + coordinates.longitude, + coordinates.latitude, + zoomLevel, + Int(size.width), + Int(size.height)), + conformingTo: .png) + url.append(queryItems: [.init(name: "attribution", value: attribution.rawValue)]) + return url + } + + // MARK: Private + + private func makeNewURL(for style: MapTilerStyle) -> URL { + var url: URL = baseURL + url.appendPathComponent(styleID(for: style), conformingTo: .item) + url.append(queryItems: [URLQueryItem(name: "key", value: apiKey)]) + return url + } + + private func styleID(for style: MapTilerStyle) -> String { + switch style { + case .light: lightStyleID + case .dark: darkStyleID + } + } +} diff --git a/ElementX/Sources/Other/MapLibre/MapTilerStaticMap.swift b/ElementX/Sources/Other/MapLibre/MapTilerStaticMap.swift deleted file mode 100644 index d2c2d4157185d9787cc1c52d54286f4596b4c718..0000000000000000000000000000000000000000 --- a/ElementX/Sources/Other/MapLibre/MapTilerStaticMap.swift +++ /dev/null @@ -1,27 +0,0 @@ -// -// Copyright 2023, 2024 New Vector Ltd. -// -// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial -// Please see LICENSE files in the repository root for full details. -// - -import CoreLocation - -struct MapTilerStaticMap: MapTilerStaticMapProtocol { - private let baseURL: URL - private let key: String - - init(baseURL: URL, key: String) { - self.baseURL = baseURL - self.key = key - } - - func staticMapURL(for style: MapTilerStyle, coordinates: CLLocationCoordinate2D, zoomLevel: Double, size: CGSize, attribution: MapTilerAttributionPlacement) -> URL? { - var url: URL = baseURL - url.appendPathComponent(style.rawValue, conformingTo: .item) - url.appendPathComponent(String(format: "static/%f,%f,%f/%dx%d@2x.png", coordinates.longitude, coordinates.latitude, zoomLevel, Int(size.width), Int(size.height)), conformingTo: .png) - url.append(queryItems: [.init(name: "attribution", value: attribution.rawValue)]) - let authorization = MapTilerAuthorization(key: key) - return authorization.authorizeURL(url) - } -} diff --git a/ElementX/Sources/Other/MapLibre/MapTilerStyle.swift b/ElementX/Sources/Other/MapLibre/MapTilerStyle.swift deleted file mode 100644 index 2f580c81535455f5e42ba3345e4c08fcfd5aed0a..0000000000000000000000000000000000000000 --- a/ElementX/Sources/Other/MapLibre/MapTilerStyle.swift +++ /dev/null @@ -1,14 +0,0 @@ -// -// Copyright 2023, 2024 New Vector Ltd. -// -// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial -// Please see LICENSE files in the repository root for full details. -// - -/// The style for a map. -/// Values should be Map Libre style IDs generated with an account where the API key belongs to. -/// For more information read [FORKING.md](https://github.com/element-hq/element-x-ios/blob/develop/docs/FORKING.md#setup-the-location-sharing). -enum MapTilerStyle: String { - case light = "9bc819c8-e627-474a-a348-ec144fe3d810" - case dark = "dea61faf-292b-4774-9660-58fcef89a7f3" -} diff --git a/ElementX/Sources/Other/MapLibre/MapTilerStyleBuilder.swift b/ElementX/Sources/Other/MapLibre/MapTilerStyleBuilder.swift deleted file mode 100644 index b8567e3cbca62508b0ef0784d429e3bf2b39b101..0000000000000000000000000000000000000000 --- a/ElementX/Sources/Other/MapLibre/MapTilerStyleBuilder.swift +++ /dev/null @@ -1,26 +0,0 @@ -// -// Copyright 2023, 2024 New Vector Ltd. -// -// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial -// Please see LICENSE files in the repository root for full details. -// - -import Foundation - -struct MapTilerStyleBuilder: MapTilerStyleBuilderProtocol { - private let baseURL: URL - private let key: String - - init(baseURL: URL, key: String) { - self.baseURL = baseURL - self.key = key - } - - func dynamicMapURL(for style: MapTilerStyle) -> URL? { - var url: URL = baseURL - url.appendPathComponent(style.rawValue, conformingTo: .item) - url.appendPathComponent("style.json", conformingTo: .json) - let authorization = MapTilerAuthorization(key: key) - return authorization.authorizeURL(url) - } -} diff --git a/ElementX/Sources/Other/MapLibre/MapTilerStyleBuilderProtocol.swift b/ElementX/Sources/Other/MapLibre/MapTilerStyleBuilderProtocol.swift deleted file mode 100644 index 466461eb284474a2407c5dc4c40e994fb4ebc85c..0000000000000000000000000000000000000000 --- a/ElementX/Sources/Other/MapLibre/MapTilerStyleBuilderProtocol.swift +++ /dev/null @@ -1,12 +0,0 @@ -// -// Copyright 2023, 2024 New Vector Ltd. -// -// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial -// Please see LICENSE files in the repository root for full details. -// - -import Foundation - -protocol MapTilerStyleBuilderProtocol { - func dynamicMapURL(for style: MapTilerStyle) -> URL? -} diff --git a/ElementX/Sources/Other/MapLibre/MapTilerStaticMapProtocol.swift b/ElementX/Sources/Other/MapLibre/MapTilerURLBuilderProtocol.swift similarity index 82% rename from ElementX/Sources/Other/MapLibre/MapTilerStaticMapProtocol.swift rename to ElementX/Sources/Other/MapLibre/MapTilerURLBuilderProtocol.swift index 2409530dee9d25121dc01ef336989315d9f95b74..de880452cdf3eda1a15dd9077b0d09094a4c5abb 100644 --- a/ElementX/Sources/Other/MapLibre/MapTilerStaticMapProtocol.swift +++ b/ElementX/Sources/Other/MapLibre/MapTilerURLBuilderProtocol.swift @@ -7,7 +7,9 @@ import CoreLocation -protocol MapTilerStaticMapProtocol { +protocol MapTilerURLBuilderProtocol { + func dynamicMapURL(for style: MapTilerStyle) -> URL? + func staticMapURL(for style: MapTilerStyle, coordinates: CLLocationCoordinate2D, zoomLevel: Double, diff --git a/ElementX/Sources/Screens/LocationSharing/LocationSharingScreenModels.swift b/ElementX/Sources/Screens/LocationSharing/LocationSharingScreenModels.swift index 73bd5340ed05a651f612df02b384682acb53cd65..05858c0f5a7dd896ed0514e4ff470d1926cbf220 100644 --- a/ElementX/Sources/Screens/LocationSharing/LocationSharingScreenModels.swift +++ b/ElementX/Sources/Screens/LocationSharing/LocationSharingScreenModels.swift @@ -25,24 +25,26 @@ enum StaticLocationInteractionMode: Hashable { } struct StaticLocationScreenViewState: BindableState { - init(interactionMode: StaticLocationInteractionMode) { + init(interactionMode: StaticLocationInteractionMode, mapURLBuilder: MapTilerURLBuilderProtocol) { self.interactionMode = interactionMode - switch interactionMode { - case .picker: - bindings.showsUserLocationMode = .showAndFollow - case .viewOnly: - bindings.showsUserLocationMode = .show + self.mapURLBuilder = mapURLBuilder + + bindings.showsUserLocationMode = switch interactionMode { + case .picker: .showAndFollow + case .viewOnly: .show } } let interactionMode: StaticLocationInteractionMode + let mapURLBuilder: MapTilerURLBuilderProtocol + + var bindings = StaticLocationScreenBindings(showsUserLocationMode: .hide) + /// Indicates whether the user is sharing his current location var isSharingUserLocation: Bool { bindings.isLocationAuthorized == true && bindings.showsUserLocationMode == .showAndFollow } - var bindings = StaticLocationScreenBindings(showsUserLocationMode: .hide) - var initialMapCenter: CLLocationCoordinate2D { switch interactionMode { case .picker: diff --git a/ElementX/Sources/Screens/LocationSharing/StaticLocationScreenCoordinator.swift b/ElementX/Sources/Screens/LocationSharing/StaticLocationScreenCoordinator.swift index 92e63bd33f749dfafff4cd7ff059a75f900ddc8e..a8294386972d601b76bb4bb4e9126e74c4d3e1e1 100644 --- a/ElementX/Sources/Screens/LocationSharing/StaticLocationScreenCoordinator.swift +++ b/ElementX/Sources/Screens/LocationSharing/StaticLocationScreenCoordinator.swift @@ -10,6 +10,7 @@ import SwiftUI struct StaticLocationScreenCoordinatorParameters { let interactionMode: StaticLocationInteractionMode + let mapURLBuilder: MapTilerURLBuilderProtocol let appMediator: AppMediatorProtocol } @@ -32,7 +33,7 @@ final class StaticLocationScreenCoordinator: CoordinatorProtocol { init(parameters: StaticLocationScreenCoordinatorParameters) { self.parameters = parameters - viewModel = StaticLocationScreenViewModel(interactionMode: parameters.interactionMode) + viewModel = StaticLocationScreenViewModel(interactionMode: parameters.interactionMode, mapURLBuilder: parameters.mapURLBuilder) } // MARK: - Public diff --git a/ElementX/Sources/Screens/LocationSharing/StaticLocationScreenViewModel.swift b/ElementX/Sources/Screens/LocationSharing/StaticLocationScreenViewModel.swift index c823ebeee793ec68db106d57084ba76126eee912..dc9b96d9678a09975338e5cd010562613ad83f0f 100644 --- a/ElementX/Sources/Screens/LocationSharing/StaticLocationScreenViewModel.swift +++ b/ElementX/Sources/Screens/LocationSharing/StaticLocationScreenViewModel.swift @@ -17,8 +17,8 @@ class StaticLocationScreenViewModel: StaticLocationScreenViewModelType, StaticLo actionsSubject.eraseToAnyPublisher() } - init(interactionMode: StaticLocationInteractionMode) { - super.init(initialViewState: .init(interactionMode: interactionMode)) + init(interactionMode: StaticLocationInteractionMode, mapURLBuilder: MapTilerURLBuilderProtocol) { + super.init(initialViewState: .init(interactionMode: interactionMode, mapURLBuilder: mapURLBuilder)) } override func process(viewAction: StaticLocationScreenViewAction) { diff --git a/ElementX/Sources/Screens/LocationSharing/View/StaticLocationScreen.swift b/ElementX/Sources/Screens/LocationSharing/View/StaticLocationScreen.swift index 0e46fc0a3b840cf54104d756f36d070e71c526f3..3fb4373e5c4cf6048103145b9a13e9aab3b0f77b 100644 --- a/ElementX/Sources/Screens/LocationSharing/View/StaticLocationScreen.swift +++ b/ElementX/Sources/Screens/LocationSharing/View/StaticLocationScreen.swift @@ -11,8 +11,6 @@ import SwiftUI struct StaticLocationScreen: View { @ObservedObject var context: StaticLocationScreenViewModel.Context - private let builder = MapTilerStyleBuilder(appSettings: ServiceLocator.shared.settings) - var body: some View { VStack(spacing: 0) { if let locationDescription = context.viewState.locationDescription { @@ -34,7 +32,7 @@ struct StaticLocationScreen: View { private var mapView: some View { ZStack(alignment: .center) { - MapLibreMapView(builder: builder, + MapLibreMapView(mapURLBuilder: context.viewState.mapURLBuilder, options: mapOptions, showsUserLocationMode: $context.showsUserLocationMode, error: $context.mapError, @@ -148,19 +146,29 @@ struct StaticLocationScreen: View { // MARK: - Previews struct StaticLocationScreenViewer_Previews: PreviewProvider, TestablePreview { + static let viewModel = StaticLocationScreenViewModel(interactionMode: .viewOnly(geoURI: .init(latitude: 41.9027835, + longitude: 12.4963655)), + mapURLBuilder: ServiceLocator.shared.settings.mapTilerConfiguration) + static let pickerViewModel = StaticLocationScreenViewModel(interactionMode: .picker, + mapURLBuilder: ServiceLocator.shared.settings.mapTilerConfiguration) + static let descriptionViewModel = StaticLocationScreenViewModel(interactionMode: .viewOnly(geoURI: .init(latitude: 41.9027835, + longitude: 12.4963655), + description: "Cool position"), + mapURLBuilder: ServiceLocator.shared.settings.mapTilerConfiguration) + static var previews: some View { NavigationStack { - StaticLocationScreen(context: StaticLocationScreenViewModel(interactionMode: .picker).context) + StaticLocationScreen(context: pickerViewModel.context) } .previewDisplayName("Picker") NavigationStack { - StaticLocationScreen(context: StaticLocationScreenViewModel(interactionMode: .viewOnly(geoURI: .init(latitude: 41.9027835, longitude: 12.4963655))).context) + StaticLocationScreen(context: viewModel.context) } .previewDisplayName("View Only") NavigationStack { - StaticLocationScreen(context: StaticLocationScreenViewModel(interactionMode: .viewOnly(geoURI: .init(latitude: 41.9027835, longitude: 12.4963655), description: "Cool position")).context) + StaticLocationScreen(context: descriptionViewModel.context) } .previewDisplayName("View Only (with description)") } diff --git a/ElementX/Sources/Screens/Timeline/TimelineModels.swift b/ElementX/Sources/Screens/Timeline/TimelineModels.swift index 8dc0732ec6480d5eebb320a5a9f5279537822947..dd6467259178062066ae75b0bcf8c154dc5d5e08 100644 --- a/ElementX/Sources/Screens/Timeline/TimelineModels.swift +++ b/ElementX/Sources/Screens/Timeline/TimelineModels.swift @@ -109,8 +109,6 @@ struct TimelineViewState: BindableState { /// an openURL closure which opens URLs first using the App's environment rather than skipping out to external apps var openURL: OpenURLAction? - var bindings: TimelineViewStateBindings - /// A closure providing the associated audio player state for an item in the timeline. var audioPlayerStateProvider: (@MainActor (_ itemId: TimelineItemIdentifier) -> AudioPlayerState?)? @@ -124,6 +122,10 @@ struct TimelineViewState: BindableState { var roomNameForAliasResolver: (@MainActor (String) -> String?)? var emojiProvider: EmojiProviderProtocol + + var mapURLBuilder: MapTilerURLBuilderProtocol + + var bindings: TimelineViewStateBindings } struct TimelineViewStateBindings { diff --git a/ElementX/Sources/Screens/Timeline/TimelineViewModel.swift b/ElementX/Sources/Screens/Timeline/TimelineViewModel.swift index ccb5b8261a6c3032df32b8ccc7dfb5023e675cbb..3c1cbfa7aed9d4c7c006160793f69402ad8ed7da 100644 --- a/ElementX/Sources/Screens/Timeline/TimelineViewModel.swift +++ b/ElementX/Sources/Screens/Timeline/TimelineViewModel.swift @@ -94,8 +94,9 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol { isViewSourceEnabled: appSettings.viewSourceEnabled, hideTimelineMedia: appSettings.hideTimelineMedia, pinnedEventIDs: roomProxy.infoPublisher.value.pinnedEventIDs, - bindings: .init(reactionsCollapsed: [:]), - emojiProvider: emojiProvider), + emojiProvider: emojiProvider, + mapURLBuilder: appSettings.mapTilerConfiguration, + bindings: .init(reactionsCollapsed: [:])), mediaProvider: mediaProvider) if focussedEventID != nil { diff --git a/ElementX/Sources/Screens/Timeline/View/TimelineItemViews/LocationRoomTimelineView.swift b/ElementX/Sources/Screens/Timeline/View/TimelineItemViews/LocationRoomTimelineView.swift index df548a0b3bf11497f2854ef4ea6ab1c5a8d30599..f0ffe47c242d550ca10a2e724abdd05599f81162 100644 --- a/ElementX/Sources/Screens/Timeline/View/TimelineItemViews/LocationRoomTimelineView.swift +++ b/ElementX/Sources/Screens/Timeline/View/TimelineItemViews/LocationRoomTimelineView.swift @@ -8,7 +8,7 @@ import SwiftUI struct LocationRoomTimelineView: View { - @Environment(\.timelineContext) private var context + @Environment(\.timelineContext) private var context: TimelineViewModel.Context! let timelineItem: LocationRoomTimelineItem var body: some View { @@ -17,7 +17,7 @@ struct LocationRoomTimelineView: View { .accessibilityElement(children: .ignore) .accessibilityLabel(accessibilityLabel) .onTapGesture { - context?.send(viewAction: .mediaTapped(itemID: timelineItem.id)) + context.send(viewAction: .mediaTapped(itemID: timelineItem.id)) } } } @@ -29,7 +29,9 @@ struct LocationRoomTimelineView: View { descriptionView .frame(maxWidth: mapAspectRatio * mapMaxHeight, alignment: .leading) - MapLibreStaticMapView(geoURI: geoURI, mapSize: .init(width: mapAspectRatio * mapMaxHeight, height: mapMaxHeight)) { + MapLibreStaticMapView(geoURI: geoURI, + mapURLBuilder: context.viewState.mapURLBuilder, + mapSize: .init(width: mapAspectRatio * mapMaxHeight, height: mapMaxHeight)) { LocationMarkerView() } .frame(maxHeight: mapMaxHeight) @@ -64,12 +66,11 @@ struct LocationRoomTimelineView: View { } private extension MapLibreStaticMapView { - init(geoURI: GeoURI, mapSize: CGSize, @ViewBuilder pinAnnotationView: () -> PinAnnotation) { + init(geoURI: GeoURI, mapURLBuilder: MapTilerURLBuilderProtocol, mapSize: CGSize, @ViewBuilder pinAnnotationView: () -> PinAnnotation) { self.init(coordinates: .init(latitude: geoURI.latitude, longitude: geoURI.longitude), zoomLevel: 15, attributionPlacement: .bottomLeft, - mapTilerStatic: MapTilerStaticMap(baseURL: ServiceLocator.shared.settings.mapTilerBaseURL, - key: ServiceLocator.shared.settings.mapTilerApiKey), + mapURLBuilder: mapURLBuilder, mapSize: mapSize, pinAnnotationView: pinAnnotationView) } @@ -85,6 +86,7 @@ struct LocationRoomTimelineView_Previews: PreviewProvider, TestablePreview { } } .environmentObject(viewModel.context) + .environment(\.timelineContext, viewModel.context) .previewDisplayName("Bubbles") } diff --git a/Enterprise b/Enterprise index ba6a5f7c9cdf992bcc370b6d86b1fc067d6d5bca..d7e62932e75cf9309948f868fd75e0f24697241c 160000 --- a/Enterprise +++ b/Enterprise @@ -1 +1 @@ -Subproject commit ba6a5f7c9cdf992bcc370b6d86b1fc067d6d5bca +Subproject commit d7e62932e75cf9309948f868fd75e0f24697241c diff --git a/UnitTests/Sources/MapTilerURLBuildersTests.swift b/UnitTests/Sources/MapTilerURLBuilderTests.swift similarity index 72% rename from UnitTests/Sources/MapTilerURLBuildersTests.swift rename to UnitTests/Sources/MapTilerURLBuilderTests.swift index 608f83e24273a77c6558411e3501bc9c926b9bc3..fa6453059f0aa40f2361f785662deefbddb4fd1d 100644 --- a/UnitTests/Sources/MapTilerURLBuildersTests.swift +++ b/UnitTests/Sources/MapTilerURLBuilderTests.swift @@ -9,38 +9,44 @@ import CoreLocation @testable import ElementX import XCTest -final class MapTilerURLBuildersTests: XCTestCase { +final class MapTilerURLBuilderTests: XCTestCase { private static let baseURL: URL = "http://www.foo.com" private static let apiKey = "some_key" + private static let lightStyleID = "9bc819c8-e627-474a-a348-ec144fe3d810" + private static let darkStyleID = "dea61faf-292b-4774-9660-58fcef89a7f3" + + var builder: MapTilerURLBuilderProtocol! + + override func setUp() { + builder = MapTilerConfiguration(baseURL: Self.baseURL, + apiKey: Self.apiKey, + lightStyleID: Self.lightStyleID, + darkStyleID: Self.darkStyleID) + } func testStaticMapBuilder() { - let builder = MapTilerStaticMap(baseURL: Self.baseURL, key: Self.apiKey) - let url = builder.staticMapURL(for: .light, coordinates: .init(latitude: 1, longitude: 2), zoomLevel: 5, size: .init(width: 300, height: 200), attribution: .hidden) - let expectedURL: URL = "http://www.foo.com/9bc819c8-e627-474a-a348-ec144fe3d810/static/2.000000,1.000000,5.000000/300x200@2x.png?attribution=false&key=some_key" + let expectedURL: URL = "http://www.foo.com/9bc819c8-e627-474a-a348-ec144fe3d810/static/2.000000,1.000000,5.000000/300x200@2x.png?key=some_key&attribution=false" XCTAssertEqual(url, expectedURL) } func testStaticMapBuilderWithAttribution() { - let builder = MapTilerStaticMap(baseURL: Self.baseURL, key: Self.apiKey) - let url = builder.staticMapURL(for: .dark, coordinates: .init(latitude: 1, longitude: 2), zoomLevel: 5, size: .init(width: 300, height: 200), attribution: .topLeft) - let expectedURL: URL = "http://www.foo.com/dea61faf-292b-4774-9660-58fcef89a7f3/static/2.000000,1.000000,5.000000/300x200@2x.png?attribution=topleft&key=some_key" + let expectedURL: URL = "http://www.foo.com/dea61faf-292b-4774-9660-58fcef89a7f3/static/2.000000,1.000000,5.000000/300x200@2x.png?key=some_key&attribution=topleft" XCTAssertEqual(url, expectedURL) } func testDynamicMapBuilder() { - let builder = MapTilerStyleBuilder(baseURL: Self.baseURL, key: Self.apiKey) let url = builder.dynamicMapURL(for: .dark) let expectedURL: URL = "http://www.foo.com/dea61faf-292b-4774-9660-58fcef89a7f3/style.json?key=some_key" XCTAssertEqual(url, expectedURL) diff --git a/UnitTests/Sources/StaticLocationScreenViewModelTests.swift b/UnitTests/Sources/StaticLocationScreenViewModelTests.swift index af1e0e436f7600385a7115d17234ff46733e0944..eb2dbae6b3e91fd900bec8ace5d8313029ed2dae 100644 --- a/UnitTests/Sources/StaticLocationScreenViewModelTests.swift +++ b/UnitTests/Sources/StaticLocationScreenViewModelTests.swift @@ -22,7 +22,8 @@ class StaticLocationScreenViewModelTests: XCTestCase { override func setUpWithError() throws { cancellables.removeAll() - let viewModel = StaticLocationScreenViewModel(interactionMode: .picker) + let viewModel = StaticLocationScreenViewModel(interactionMode: .picker, + mapURLBuilder: ServiceLocator.shared.settings.mapTilerConfiguration) viewModel.state.bindings.isLocationAuthorized = true self.viewModel = viewModel } diff --git a/docs/FORKING.md b/docs/FORKING.md index b9d17358207b3bd6ef4685ecdb7505f9b2bc0fdd..7459b8f5ea4bfe26ff0c6e5a42a0210a0cfcfe72 100644 --- a/docs/FORKING.md +++ b/docs/FORKING.md @@ -32,13 +32,13 @@ git update-index assume-unchanged Secrets/Secrets.swift ``` this will prevent pushing any update of the file `Secrets.swift`. -Finally you need to setup your map styles overriding the values you find in the code: +Finally you need to setup your map styles overriding the values you find in AppSettings.swift: ```swift -enum MapTilerStyle: String { - case light = “your_style_id_light” - case dark = “your_style_id_dark” -} +MapTilerConfiguration(baseURL: "https://api.maptiler.com/maps", + apiKey: Secrets.mapLibreAPIKey, + lightStyleID: "your_style_id_light", + darkStyleID: "your_style_id_dark") ``` You aren’t required to use custom styles here. You can use already available styles like `basic-v2` and `basic-v2-dark` \ No newline at end of file