From 51886b0c78876f8b03cab620964e14c1fa3fa178 Mon Sep 17 00:00:00 2001
From: Doug <6060466+pixlwave@users.noreply.github.com>
Date: Wed, 26 Mar 2025 14:39:09 +0000
Subject: [PATCH] Refactor the MapTiler configuration into a single place.
 (#3944)

* Refactor the MapTiler configuration into a single place.

* Merge the MapAssets catalog into the normal one.
---
 ElementX.xcodeproj/project.pbxproj            |  48 ++++----------
 .../mapBlurred.imageset/Contents.json         |   0
 .../mapBlurred.imageset/DarkMapBlurred.pdf    | Bin
 .../mapBlurred.imageset/lightMapBlurred.pdf   | Bin
 .../Sources/Application/AppSettings.swift     |  12 ++--
 .../PinnedEventsTimelineFlowCoordinator.swift |   7 +-
 .../RoomFlowCoordinator.swift                 |   5 +-
 ElementX/Sources/Generated/Assets.swift       |   1 +
 .../Sources/Other/Extensions/MapTiler.swift   |  14 ----
 .../MapLibre/MapAssets.xcassets/Contents.json |   6 --
 .../Other/MapLibre/MapLibreMapView.swift      |   6 +-
 .../Other/MapLibre/MapLibreModels.swift       |   8 +++
 .../MapLibre/MapLibreStaticMapView.swift      |  31 +++++----
 .../MapLibre/MapTilerAuthorization.swift      |  20 ------
 .../MapLibre/MapTilerConfiguration.swift      |  62 ++++++++++++++++++
 .../Other/MapLibre/MapTilerStaticMap.swift    |  27 --------
 .../Other/MapLibre/MapTilerStyle.swift        |  14 ----
 .../Other/MapLibre/MapTilerStyleBuilder.swift |  26 --------
 .../MapTilerStyleBuilderProtocol.swift        |  12 ----
 ...swift => MapTilerURLBuilderProtocol.swift} |   4 +-
 .../LocationSharingScreenModels.swift         |  18 ++---
 .../StaticLocationScreenCoordinator.swift     |   3 +-
 .../StaticLocationScreenViewModel.swift       |   4 +-
 .../View/StaticLocationScreen.swift           |  20 ++++--
 .../Screens/Timeline/TimelineModels.swift     |   6 +-
 .../Screens/Timeline/TimelineViewModel.swift  |   5 +-
 .../LocationRoomTimelineView.swift            |  14 ++--
 Enterprise                                    |   2 +-
 ...ts.swift => MapTilerURLBuilderTests.swift} |  22 ++++---
 .../StaticLocationScreenViewModelTests.swift  |   3 +-
 docs/FORKING.md                               |  10 +--
 31 files changed, 190 insertions(+), 220 deletions(-)
 rename ElementX/{Sources/Other/MapLibre/MapAssets.xcassets => Resources/Assets.xcassets/images/location}/mapBlurred.imageset/Contents.json (100%)
 rename ElementX/{Sources/Other/MapLibre/MapAssets.xcassets => Resources/Assets.xcassets/images/location}/mapBlurred.imageset/DarkMapBlurred.pdf (100%)
 rename ElementX/{Sources/Other/MapLibre/MapAssets.xcassets => Resources/Assets.xcassets/images/location}/mapBlurred.imageset/lightMapBlurred.pdf (100%)
 delete mode 100644 ElementX/Sources/Other/Extensions/MapTiler.swift
 delete mode 100644 ElementX/Sources/Other/MapLibre/MapAssets.xcassets/Contents.json
 delete mode 100644 ElementX/Sources/Other/MapLibre/MapTilerAuthorization.swift
 create mode 100644 ElementX/Sources/Other/MapLibre/MapTilerConfiguration.swift
 delete mode 100644 ElementX/Sources/Other/MapLibre/MapTilerStaticMap.swift
 delete mode 100644 ElementX/Sources/Other/MapLibre/MapTilerStyle.swift
 delete mode 100644 ElementX/Sources/Other/MapLibre/MapTilerStyleBuilder.swift
 delete mode 100644 ElementX/Sources/Other/MapLibre/MapTilerStyleBuilderProtocol.swift
 rename ElementX/Sources/Other/MapLibre/{MapTilerStaticMapProtocol.swift => MapTilerURLBuilderProtocol.swift} (82%)
 rename UnitTests/Sources/{MapTilerURLBuildersTests.swift => MapTilerURLBuilderTests.swift} (72%)

diff --git a/ElementX.xcodeproj/project.pbxproj b/ElementX.xcodeproj/project.pbxproj
index c448b1945..702f33c4e 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 801b1a139..3ddb5ed2e 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 ab63e8e74..92e182c90 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 7abb8f100..15eabc62c 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 ce9f069ee..7272f6b08 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 7e4666c8c..000000000
--- 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 73c00596a..000000000
--- 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 5d8388ca2..5db9f9395 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 b0ab2f730..daaf04b37 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 73608e758..efd58ca3e 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 c18a53421..000000000
--- 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 000000000..a2b73c82f
--- /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 d2c2d4157..000000000
--- 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 2f580c815..000000000
--- 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 b8567e3cb..000000000
--- 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 466461eb2..000000000
--- 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 2409530de..de880452c 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 73bd5340e..05858c0f5 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 92e63bd33..a82943869 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 c823ebeee..dc9b96d96 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 0e46fc0a3..3fb4373e5 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 8dc0732ec..dd6467259 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 ccb5b8261..3c1cbfa7a 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 df548a0b3..f0ffe47c2 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 ba6a5f7c9..d7e62932e 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 608f83e24..fa6453059 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 af1e0e436..eb2dbae6b 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 b9d173582..7459b8f5e 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
-- 
GitLab