diff --git a/.gitmodules b/.gitmodules
index a9f9d67495ca6f98f5a611842ae41f2f86353448..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,3 +0,0 @@
-[submodule "Ring/WhirlyGlobeMaply"]
-	path = Ring/WhirlyGlobeMaply
-	url = https://github.com/mousebird/WhirlyGlobe.git
diff --git a/Ring/Ring.xcodeproj/project.pbxproj b/Ring/Ring.xcodeproj/project.pbxproj
index a82ab9143c23f06dc4520d24a0ef285f2383baaa..7660830fcd48ccb57be93d9219aa55558ecaa99f 100644
--- a/Ring/Ring.xcodeproj/project.pbxproj
+++ b/Ring/Ring.xcodeproj/project.pbxproj
@@ -208,8 +208,6 @@
 		26074FD924F7FF9500374570 /* PreviewViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26074FD824F7FF9500374570 /* PreviewViewController.swift */; };
 		26074FDB24F7FFC100374570 /* PreviewContollerModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26074FDA24F7FFC100374570 /* PreviewContollerModel.swift */; };
 		26074FDD24F7FFF500374570 /* PreviewViewController.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 26074FDC24F7FFF500374570 /* PreviewViewController.storyboard */; };
-		2607B1CE293192BF00F0107C /* WhirlyGlobe.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6452143D24B4AB44007203D5 /* WhirlyGlobe.framework */; };
-		2607B1CF293192BF00F0107C /* WhirlyGlobe.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 6452143D24B4AB44007203D5 /* WhirlyGlobe.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
 		260C73F129196B66005C513F /* MessageHistoryVM.swift in Sources */ = {isa = PBXBuildFile; fileRef = 260C73F029196B66005C513F /* MessageHistoryVM.swift */; };
 		260C73F329196C6C005C513F /* MessageStackVM.swift in Sources */ = {isa = PBXBuildFile; fileRef = 260C73F229196C6C005C513F /* MessageStackVM.swift */; };
 		263B7158246D9390007044C4 /* SmartListCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 263B7157246D9390007044C4 /* SmartListCell.swift */; };
@@ -459,17 +457,12 @@
 		62E55B6F1F793ADE00D3FEF4 /* AvatarsColors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62E55B6E1F793ADE00D3FEF4 /* AvatarsColors.swift */; };
 		642AD48424EC64CE00521127 /* CopyableLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 642AD48324EC64CE00521127 /* CopyableLabel.swift */; };
 		6452144424B4ACA7007203D5 /* CoreLocation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6452144324B4ACA7007203D5 /* CoreLocation.framework */; };
-		645BDD7724B7415A009129B1 /* MessageCellLocationSharingSent.xib in Resources */ = {isa = PBXBuildFile; fileRef = 645BDD6C24B7415A009129B1 /* MessageCellLocationSharingSent.xib */; };
-		645BDD7B24B7415A009129B1 /* MessageCellLocationSharingSent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 645BDD7024B7415A009129B1 /* MessageCellLocationSharingSent.swift */; };
 		645BDD8124B74BCB009129B1 /* LocationSharingService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 645BDD8024B74BCB009129B1 /* LocationSharingService.swift */; };
 		648AF76D24ED7CA90004D727 /* UITextView+Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 648AF76C24ED7CA90004D727 /* UITextView+Helpers.swift */; };
 		649AD3C324B4CFC700A0236D /* libsqlite3.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 6452144724B4ACDE007203D5 /* libsqlite3.tbd */; };
 		649AD3C624B4CFD500A0236D /* libxml2.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 6452144524B4ACC8007203D5 /* libxml2.tbd */; };
 		649AD3C724B4D00100A0236D /* libc++.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 6452144124B4AC9F007203D5 /* libc++.tbd */; };
 		64DBCD2224DB3CF600CB5CA2 /* UserSearchResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = 64DBCD2124DB3CF600CB5CA2 /* UserSearchResponse.m */; };
-		64F8127724B8AA5200A7DE6A /* MessageCellLocationSharingReceived.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64F8127324B8AA5200A7DE6A /* MessageCellLocationSharingReceived.swift */; };
-		64F8127824B8AA5200A7DE6A /* MessageCellLocationSharingReceived.xib in Resources */ = {isa = PBXBuildFile; fileRef = 64F8127624B8AA5200A7DE6A /* MessageCellLocationSharingReceived.xib */; };
-		64F8127A24BBC19C00A7DE6A /* MessageCellLocationSharing.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64F8127924BBC19C00A7DE6A /* MessageCellLocationSharing.swift */; };
 		6613A612214AFF4700B497D1 /* ScanViewController.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6613A611214AFF4700B497D1 /* ScanViewController.storyboard */; };
 		66266FC021557D2F002757A6 /* ScanViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66266FBF21557D2F002757A6 /* ScanViewModel.swift */; };
 		66266FC4215C18F8002757A6 /* Emoji+Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66266FC3215C18F8002757A6 /* Emoji+Helpers.swift */; };
@@ -477,16 +470,18 @@
 		66ACB430214AE28C00A94162 /* ScanViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66ACB42F214AE28C00A94162 /* ScanViewController.swift */; };
 		66E6381221764C2C005EA2B0 /* GrowingTextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66E6381121764C2C005EA2B0 /* GrowingTextView.swift */; };
 		66F295DE2166A5930044ED6F /* Devices+Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66F295DD2166A5930044ED6F /* Devices+Helpers.swift */; };
-		BB1E8C7129159DFC005AE1D6 /* SwarmInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB1E8C6C29159DEE005AE1D6 /* SwarmInfoView.swift */; };
 		BB1E8C7329159DFC005AE1D6 /* MembersList.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB1E8C6E29159DF6005AE1D6 /* MembersList.swift */; };
 		BB1E8C7529159DFC005AE1D6 /* SettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB1E8C7029159DFC005AE1D6 /* SettingsView.swift */; };
 		BB1E8C7729159E1F005AE1D6 /* SwarmInfoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB1E8C7629159E1F005AE1D6 /* SwarmInfoViewController.swift */; };
 		BB1E8C7A29159E3E005AE1D6 /* SwarmInfoVM.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB1E8C7929159E3E005AE1D6 /* SwarmInfoVM.swift */; };
 		BB3AB06C29316FA6006906BA /* ViewDidLoadModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB3AB06929316FA0006906BA /* ViewDidLoadModifier.swift */; };
+		BB3B0A412971AEE30083CAD8 /* LocationSharingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB3B0A402971AEE30083CAD8 /* LocationSharingView.swift */; };
 		BB3E5815291C138600E85BEA /* SwarmInfoViewController.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = BB3E5814291C138600E85BEA /* SwarmInfoViewController.storyboard */; };
 		BB4C6E2629229131001C901A /* ColorExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB4C6E2529229131001C901A /* ColorExtension.swift */; };
 		BB90263528F0918700B85859 /* PaddingTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB90263428F0918700B85859 /* PaddingTextField.swift */; };
 		BB91FAAD292EA36200BB41C1 /* EventData.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB91FAA9292EA26900BB41C1 /* EventData.swift */; };
+		BBB76E412966062C00A42DF5 /* MapView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBB76E402966062C00A42DF5 /* MapView.swift */; };
+		BBD3D751297B4CA00098DB02 /* SwarmInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBD3D750297B4CA00098DB02 /* SwarmInfoView.swift */; };
 /* End PBXBuildFile section */
 
 /* Begin PBXContainerItemProxy section */
@@ -511,20 +506,6 @@
 			remoteGlobalIDString = 26A88C03266FFFC800888EED;
 			remoteInfo = jamiNotificationExtension;
 		};
-		6452143C24B4AB44007203D5 /* PBXContainerItemProxy */ = {
-			isa = PBXContainerItemProxy;
-			containerPortal = 6452143724B4AB43007203D5 /* WhirlyGlobeMaplyComponent.xcodeproj */;
-			proxyType = 2;
-			remoteGlobalIDString = 2BE536FF1D2499E500B60FAD;
-			remoteInfo = WhirlyGlobeMaplyComponent;
-		};
-		6452143E24B4AB44007203D5 /* PBXContainerItemProxy */ = {
-			isa = PBXContainerItemProxy;
-			containerPortal = 6452143724B4AB43007203D5 /* WhirlyGlobeMaplyComponent.xcodeproj */;
-			proxyType = 2;
-			remoteGlobalIDString = 2BE537091D2499E500B60FAD;
-			remoteInfo = WhirlyGlobeMaplyComponentTests;
-		};
 /* End PBXContainerItemProxy section */
 
 /* Begin PBXCopyFilesBuildPhase section */
@@ -551,7 +532,6 @@
 				44DFB3B5288704910023878C /* RxRelay.xcframework in Embed Frameworks */,
 				44DFB39D2887048F0023878C /* RxSwift.xcframework in Embed Frameworks */,
 				44DFB3A9288704900023878C /* Differentiator.xcframework in Embed Frameworks */,
-				2607B1CF293192BF00F0107C /* WhirlyGlobe.framework in Embed Frameworks */,
 				44DFB3A12887048F0023878C /* RxRealm.xcframework in Embed Frameworks */,
 				44DFB3B9288704920023878C /* RealmSwift.xcframework in Embed Frameworks */,
 				44DFB39B2887048E0023878C /* PKHUD.xcframework in Embed Frameworks */,
@@ -1102,20 +1082,14 @@
 		62E55B6C1F758E6F00D3FEF4 /* String+Helpers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "String+Helpers.swift"; sourceTree = "<group>"; };
 		62E55B6E1F793ADE00D3FEF4 /* AvatarsColors.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AvatarsColors.swift; sourceTree = "<group>"; };
 		642AD48324EC64CE00521127 /* CopyableLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CopyableLabel.swift; sourceTree = "<group>"; };
-		6452143724B4AB43007203D5 /* WhirlyGlobeMaplyComponent.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = WhirlyGlobeMaplyComponent.xcodeproj; path = "WhirlyGlobeMaply/ios/library/WhirlyGlobe-MaplyComponent/WhirlyGlobeMaplyComponent.xcodeproj"; sourceTree = "<group>"; };
 		6452144124B4AC9F007203D5 /* libc++.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = "libc++.tbd"; path = "usr/lib/libc++.tbd"; sourceTree = SDKROOT; };
 		6452144324B4ACA7007203D5 /* CoreLocation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreLocation.framework; path = System/Library/Frameworks/CoreLocation.framework; sourceTree = SDKROOT; };
 		6452144524B4ACC8007203D5 /* libxml2.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libxml2.tbd; path = usr/lib/libxml2.tbd; sourceTree = SDKROOT; };
 		6452144724B4ACDE007203D5 /* libsqlite3.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libsqlite3.tbd; path = usr/lib/libsqlite3.tbd; sourceTree = SDKROOT; };
-		645BDD6C24B7415A009129B1 /* MessageCellLocationSharingSent.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MessageCellLocationSharingSent.xib; sourceTree = "<group>"; };
-		645BDD7024B7415A009129B1 /* MessageCellLocationSharingSent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessageCellLocationSharingSent.swift; sourceTree = "<group>"; };
 		645BDD8024B74BCB009129B1 /* LocationSharingService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationSharingService.swift; sourceTree = "<group>"; };
 		648AF76C24ED7CA90004D727 /* UITextView+Helpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UITextView+Helpers.swift"; sourceTree = "<group>"; };
 		64DBCD1E24DB3CA900CB5CA2 /* UserSearchResponse.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = UserSearchResponse.h; sourceTree = "<group>"; };
 		64DBCD2124DB3CF600CB5CA2 /* UserSearchResponse.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = UserSearchResponse.m; sourceTree = "<group>"; };
-		64F8127324B8AA5200A7DE6A /* MessageCellLocationSharingReceived.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessageCellLocationSharingReceived.swift; sourceTree = "<group>"; };
-		64F8127624B8AA5200A7DE6A /* MessageCellLocationSharingReceived.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MessageCellLocationSharingReceived.xib; sourceTree = "<group>"; };
-		64F8127924BBC19C00A7DE6A /* MessageCellLocationSharing.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageCellLocationSharing.swift; sourceTree = "<group>"; };
 		6613A611214AFF4700B497D1 /* ScanViewController.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = ScanViewController.storyboard; sourceTree = "<group>"; };
 		66266FBF21557D2F002757A6 /* ScanViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScanViewModel.swift; sourceTree = "<group>"; };
 		66266FC3215C18F8002757A6 /* Emoji+Helpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Emoji+Helpers.swift"; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
@@ -1123,16 +1097,18 @@
 		66ACB42F214AE28C00A94162 /* ScanViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScanViewController.swift; sourceTree = "<group>"; };
 		66E6381121764C2C005EA2B0 /* GrowingTextView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GrowingTextView.swift; sourceTree = "<group>"; };
 		66F295DD2166A5930044ED6F /* Devices+Helpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Devices+Helpers.swift"; sourceTree = "<group>"; };
-		BB1E8C6C29159DEE005AE1D6 /* SwarmInfoView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwarmInfoView.swift; sourceTree = "<group>"; };
 		BB1E8C6E29159DF6005AE1D6 /* MembersList.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MembersList.swift; sourceTree = "<group>"; };
 		BB1E8C7029159DFC005AE1D6 /* SettingsView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingsView.swift; sourceTree = "<group>"; };
 		BB1E8C7629159E1F005AE1D6 /* SwarmInfoViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwarmInfoViewController.swift; sourceTree = "<group>"; };
 		BB1E8C7929159E3E005AE1D6 /* SwarmInfoVM.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwarmInfoVM.swift; sourceTree = "<group>"; };
 		BB3AB06929316FA0006906BA /* ViewDidLoadModifier.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewDidLoadModifier.swift; sourceTree = "<group>"; };
+		BB3B0A402971AEE30083CAD8 /* LocationSharingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationSharingView.swift; sourceTree = "<group>"; };
 		BB3E5814291C138600E85BEA /* SwarmInfoViewController.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = SwarmInfoViewController.storyboard; sourceTree = "<group>"; };
 		BB4C6E2529229131001C901A /* ColorExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorExtension.swift; sourceTree = "<group>"; };
 		BB90263428F0918700B85859 /* PaddingTextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaddingTextField.swift; sourceTree = "<group>"; };
 		BB91FAA9292EA26900BB41C1 /* EventData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventData.swift; sourceTree = "<group>"; };
+		BBB76E402966062C00A42DF5 /* MapView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapView.swift; sourceTree = "<group>"; };
+		BBD3D750297B4CA00098DB02 /* SwarmInfoView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwarmInfoView.swift; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
@@ -1154,7 +1130,6 @@
 				269DA07428D0D366007D51D6 /* libspeexdsp.a in Frameworks */,
 				269DA06C28D0D366007D51D6 /* libpjsip-simple.a in Frameworks */,
 				6452144424B4ACA7007203D5 /* CoreLocation.framework in Frameworks */,
-				2607B1CE293192BF00F0107C /* WhirlyGlobe.framework in Frameworks */,
 				269DA05C28D0D366007D51D6 /* libgmp.a in Frameworks */,
 				269DA05328D0D366007D51D6 /* libargon2.a in Frameworks */,
 				44DFB3AC288704900023878C /* GSKStretchyHeaderView.xcframework in Frameworks */,
@@ -1396,7 +1371,6 @@
 				6452144524B4ACC8007203D5 /* libxml2.tbd */,
 				6452144324B4ACA7007203D5 /* CoreLocation.framework */,
 				6452144124B4AC9F007203D5 /* libc++.tbd */,
-				6452143724B4AB43007203D5 /* WhirlyGlobeMaplyComponent.xcodeproj */,
 				0E4A51CB23282BCC00357AFC /* libhttp_parser.a */,
 				0ECB4E2922B2D4BB0097CD7B /* CallKit.framework */,
 				0E639459224AB32200C0890A /* Contacts.framework */,
@@ -2088,11 +2062,6 @@
 				62AD58472056DA6800AF0701 /* MessageCellDataTransferReceived.xib */,
 				62AD58492056DADF00AF0701 /* MessageCellDataTransferReceived.swift */,
 				62AD584B2056DB2700AF0701 /* MessageCellDataTransferSent.swift */,
-				64F8127924BBC19C00A7DE6A /* MessageCellLocationSharing.swift */,
-				645BDD7024B7415A009129B1 /* MessageCellLocationSharingSent.swift */,
-				645BDD6C24B7415A009129B1 /* MessageCellLocationSharingSent.xib */,
-				64F8127324B8AA5200A7DE6A /* MessageCellLocationSharingReceived.swift */,
-				64F8127624B8AA5200A7DE6A /* MessageCellLocationSharingReceived.xib */,
 			);
 			path = Cells;
 			sourceTree = "<group>";
@@ -2205,6 +2174,8 @@
 			children = (
 				26EF35EE29075A5300D97E14 /* MessageStackView.swift */,
 				269DA09C28E23F57007D51D6 /* MessagesListView.swift */,
+				BB3B0A402971AEE30083CAD8 /* LocationSharingView.swift */,
+				BBB76E402966062C00A42DF5 /* MapView.swift */,
 				26EF35E628E3401800D97E14 /* ReplyHistory.swift */,
 				26EF35E828E3847100D97E14 /* MessageContentView.swift */,
 				269DA09828E23D37007D51D6 /* MessageRowView.swift */,
@@ -2350,15 +2321,6 @@
 			name = Cells;
 			sourceTree = "<group>";
 		};
-		6452143824B4AB43007203D5 /* Products */ = {
-			isa = PBXGroup;
-			children = (
-				6452143D24B4AB44007203D5 /* WhirlyGlobe.framework */,
-				6452143F24B4AB44007203D5 /* WhirlyGlobeMaplyComponentTests.xctest */,
-			);
-			name = Products;
-			sourceTree = "<group>";
-		};
 		6613A610214AF8B100B497D1 /* QRCode */ = {
 			isa = PBXGroup;
 			children = (
@@ -2386,8 +2348,8 @@
 			children = (
 				BB1E8C6E29159DF6005AE1D6 /* MembersList.swift */,
 				BB1E8C7029159DFC005AE1D6 /* SettingsView.swift */,
+				BBD3D750297B4CA00098DB02 /* SwarmInfoView.swift */,
 				BB3AB06929316FA0006906BA /* ViewDidLoadModifier.swift */,
-				BB1E8C6C29159DEE005AE1D6 /* SwarmInfoView.swift */,
 				1DF75AC5296E0C2A0055EA87 /* AddMoreParticipantsInSwarm.swift */,
 			);
 			path = View;
@@ -2585,12 +2547,6 @@
 			mainGroup = 043999EA1D1C2D9D00E99CD9;
 			productRefGroup = 043999F41D1C2D9D00E99CD9 /* Products */;
 			projectDirPath = "";
-			projectReferences = (
-				{
-					ProductGroup = 6452143824B4AB43007203D5 /* Products */;
-					ProjectRef = 6452143724B4AB43007203D5 /* WhirlyGlobeMaplyComponent.xcodeproj */;
-				},
-			);
 			projectRoot = "";
 			targets = (
 				043999F21D1C2D9D00E99CD9 /* Ring */,
@@ -2602,23 +2558,6 @@
 		};
 /* End PBXProject section */
 
-/* Begin PBXReferenceProxy section */
-		6452143D24B4AB44007203D5 /* WhirlyGlobe.framework */ = {
-			isa = PBXReferenceProxy;
-			fileType = wrapper.framework;
-			path = WhirlyGlobe.framework;
-			remoteRef = 6452143C24B4AB44007203D5 /* PBXContainerItemProxy */;
-			sourceTree = BUILT_PRODUCTS_DIR;
-		};
-		6452143F24B4AB44007203D5 /* WhirlyGlobeMaplyComponentTests.xctest */ = {
-			isa = PBXReferenceProxy;
-			fileType = wrapper.cfbundle;
-			path = WhirlyGlobeMaplyComponentTests.xctest;
-			remoteRef = 6452143E24B4AB44007203D5 /* PBXContainerItemProxy */;
-			sourceTree = BUILT_PRODUCTS_DIR;
-		};
-/* End PBXReferenceProxy section */
-
 /* Begin PBXResourcesBuildPhase section */
 		043999F11D1C2D9D00E99CD9 /* Resources */ = {
 			isa = PBXResourcesBuildPhase;
@@ -2663,9 +2602,7 @@
 				446FAF192373424700519C4F /* SendFileViewController.storyboard in Resources */,
 				BB3E5815291C138600E85BEA /* SwarmInfoViewController.storyboard in Resources */,
 				0EF49AA323828CD00064CD98 /* ConferenceParticipantView.xib in Resources */,
-				645BDD7724B7415A009129B1 /* MessageCellLocationSharingSent.xib in Resources */,
 				0E72374A20460320006B0C7D /* ProfileHeaderView.xib in Resources */,
-				64F8127824B8AA5200A7DE6A /* MessageCellLocationSharingReceived.xib in Resources */,
 				4430A66D236CBC5900747177 /* ContactPickerViewController.storyboard in Resources */,
 				0E96ED75225D06250016C07D /* GeneralSettingsViewController.storyboard in Resources */,
 				0EB1A5CF1F8EBE03009923E2 /* DeviceCell.xib in Resources */,
@@ -2801,7 +2738,7 @@
 				0E49096A1FEAB156005CAA50 /* CallsAdapter.mm in Sources */,
 				1A2D18A61F27F7A400B2C785 /* UIViewController+Rx.swift in Sources */,
 				26BC15EE29302B00003FC8D1 /* ContactMessageVM.swift in Sources */,
-				64F8127724B8AA5200A7DE6A /* MessageCellLocationSharingReceived.swift in Sources */,
+				BB3B0A412971AEE30083CAD8 /* LocationSharingView.swift in Sources */,
 				66E6381221764C2C005EA2B0 /* GrowingTextView.swift in Sources */,
 				267AD77E252B979F00047593 /* ConferenceParticipant.swift in Sources */,
 				0E7CF4DB20164B6700CD967D /* ButtonsContainerView.swift in Sources */,
@@ -2860,6 +2797,7 @@
 				1ABE07E21F0D924700D36361 /* Strings.swift in Sources */,
 				0E6F544D223BFE3E00ECC3CE /* DisposableCell.swift in Sources */,
 				1DE93595291B119900E426CF /* SwarmCreationViewController.swift in Sources */,
+				BBD3D751297B4CA00098DB02 /* SwarmInfoView.swift in Sources */,
 				621231FB1F8D6FEE009B86F0 /* MessageCell.swift in Sources */,
 				2662FC7D246B78E800FA7782 /* IncognitoSmartListViewController.swift in Sources */,
 				56AC650E1E85694D00EA1AA9 /* DesignableTextField.swift in Sources */,
@@ -2882,7 +2820,6 @@
 				BB1E8C7729159E1F005AE1D6 /* SwarmInfoViewController.swift in Sources */,
 				0E403F811F7D797300C80BC2 /* MessageCellGenerated.swift in Sources */,
 				2659F65827483656009107F1 /* VideoManager.swift in Sources */,
-				64F8127A24BBC19C00A7DE6A /* MessageCellLocationSharing.swift in Sources */,
 				0E6D959C2407116E00996A28 /* LinkToAccountManagerViewModel.swift in Sources */,
 				62AD584C2056DB2700AF0701 /* MessageCellDataTransferSent.swift in Sources */,
 				0ECA5683243394960055D31E /* MigrateAccountViewController.swift in Sources */,
@@ -2903,6 +2840,7 @@
 				0E36979D20322D75009A68CA /* BlockListViewModel.swift in Sources */,
 				1A2D18C21F29180700B2C785 /* AccountCredentialsModel.swift in Sources */,
 				1A2D18FF1F29352D00B2C785 /* MeViewModel.swift in Sources */,
+				BBB76E412966062C00A42DF5 /* MapView.swift in Sources */,
 				62A88D391F6C323500F8AB18 /* PresenceAdapter.mm in Sources */,
 				1DF75AC6296E0C2A0055EA87 /* AddMoreParticipantsInSwarm.swift in Sources */,
 				1A2D18B71F29164700B2C785 /* SmartlistViewModel.swift in Sources */,
@@ -2936,7 +2874,6 @@
 				0E3697A1203235EA009A68CA /* BannedContactItem.swift in Sources */,
 				265DFAF32929C01400834B97 /* MessageRowVM.swift in Sources */,
 				56BBC9DF1EDDC9D300CDAF8B /* LookupNameResponse.m in Sources */,
-				645BDD7B24B7415A009129B1 /* MessageCellLocationSharingSent.swift in Sources */,
 				BB1E8C7A29159E3E005AE1D6 /* SwarmInfoVM.swift in Sources */,
 				66F295DE2166A5930044ED6F /* Devices+Helpers.swift in Sources */,
 				1A2041911F1FD46300C08435 /* DesignableView.swift in Sources */,
@@ -2945,7 +2882,6 @@
 				1A3D28A91F0EBF0200B524EE /* UIView+Ring.swift in Sources */,
 				1A2041881F1EA1EA00C08435 /* CreateAccountViewModel.swift in Sources */,
 				62E55B6D1F758E6F00D3FEF4 /* String+Helpers.swift in Sources */,
-				BB1E8C7129159DFC005AE1D6 /* SwarmInfoView.swift in Sources */,
 				1ABE07D21F0D8FE800D36361 /* Images.swift in Sources */,
 				0273C3081E0C68BF00CF00BA /* DesignableButton.swift in Sources */,
 				1A5DC0321F3566140075E8EF /* ConversationSection.swift in Sources */,
@@ -3253,10 +3189,7 @@
 				FRAMEWORK_SEARCH_PATHS = "$(inherited)";
 				GCC_PRECOMPILE_PREFIX_HEADER = YES;
 				GCC_PREFIX_HEADER = Ring/RingPrefixHeader.pch;
-				HEADER_SEARCH_PATHS = (
-					"$(SRCROOT)/../fat/include",
-					"$(SRCROOT)/WhirlyGlobeMaply/ios/library/WhirlyGlobe-MaplyComponent/include/**",
-				);
+				HEADER_SEARCH_PATHS = "$(SRCROOT)/../fat/include";
 				INFOPLIST_FILE = Ring/Info.plist;
 				IPHONEOS_DEPLOYMENT_TARGET = 14.5;
 				LD_RUNPATH_SEARCH_PATHS = (
@@ -3294,10 +3227,7 @@
 				FRAMEWORK_SEARCH_PATHS = "$(inherited)";
 				GCC_PRECOMPILE_PREFIX_HEADER = YES;
 				GCC_PREFIX_HEADER = Ring/RingPrefixHeader.pch;
-				HEADER_SEARCH_PATHS = (
-					"$(SRCROOT)/../fat/include",
-					"$(SRCROOT)/WhirlyGlobeMaply/ios/library/WhirlyGlobe-MaplyComponent/include/**",
-				);
+				HEADER_SEARCH_PATHS = "$(SRCROOT)/../fat/include";
 				INFOPLIST_FILE = Ring/Info.plist;
 				IPHONEOS_DEPLOYMENT_TARGET = 14.5;
 				LD_RUNPATH_SEARCH_PATHS = (
@@ -3325,7 +3255,6 @@
 				HEADER_SEARCH_PATHS = (
 					"$(SRCROOT)/../fat/include",
 					"$(SRCROOT)/../../daemon/contrib/native-arm64/ffmpeg",
-					"$(SRCROOT)/WhirlyGlobeMaply/ios/library/WhirlyGlobe-MaplyComponent/include/**",
 				);
 				INFOPLIST_FILE = RingTests/Info.plist;
 				LD_RUNPATH_SEARCH_PATHS = (
@@ -3351,7 +3280,6 @@
 				HEADER_SEARCH_PATHS = (
 					"$(SRCROOT)/../fat/include",
 					"$(SRCROOT)/../../daemon/contrib/native-arm64/ffmpeg",
-					"$(SRCROOT)/WhirlyGlobeMaply/ios/library/WhirlyGlobe-MaplyComponent/include/**",
 				);
 				INFOPLIST_FILE = RingTests/Info.plist;
 				LD_RUNPATH_SEARCH_PATHS = (
@@ -3631,10 +3559,7 @@
 				FRAMEWORK_SEARCH_PATHS = "$(inherited)";
 				GCC_PRECOMPILE_PREFIX_HEADER = YES;
 				GCC_PREFIX_HEADER = Ring/RingPrefixHeader.pch;
-				HEADER_SEARCH_PATHS = (
-					"$(SRCROOT)/../fat/include",
-					"$(SRCROOT)/WhirlyGlobeMaply/ios/library/WhirlyGlobe-MaplyComponent/include/**",
-				);
+				HEADER_SEARCH_PATHS = "$(SRCROOT)/../fat/include";
 				INFOPLIST_FILE = Ring/Info.plist;
 				IPHONEOS_DEPLOYMENT_TARGET = 14.5;
 				LD_RUNPATH_SEARCH_PATHS = (
@@ -3663,7 +3588,6 @@
 				HEADER_SEARCH_PATHS = (
 					"$(SRCROOT)/../fat/include",
 					"$(SRCROOT)/../../daemon/contrib/native-arm64/ffmpeg",
-					"$(SRCROOT)/WhirlyGlobeMaply/ios/library/WhirlyGlobe-MaplyComponent/include/**",
 				);
 				INFOPLIST_FILE = RingTests/Info.plist;
 				LD_RUNPATH_SEARCH_PATHS = (
diff --git a/Ring/Ring/Bridging/Ring-Bridging-Header.h b/Ring/Ring/Bridging/Ring-Bridging-Header.h
index 2fa398e91f3514dfa3458c3f73476f5a97fe89b2..26bece8cad82dde793d1d7e1e7f7d96f92a94cba 100644
--- a/Ring/Ring/Bridging/Ring-Bridging-Header.h
+++ b/Ring/Ring/Bridging/Ring-Bridging-Header.h
@@ -47,6 +47,7 @@
 #import <UserNotifications/UserNotifications.h>
 #import <GSKStretchyHeaderView/GSKStretchyHeaderView.h>
 #import "DataTransferAdapter.h"
-#import "../../WhirlyGlobeMaply/ios/library/WhirlyGlobe-MaplyComponent/include/MaplyBridge.h"
 #import "ObjCHandler.h"
+#import <CoreLocation/CoreLocation.h>
+#import <MapKit/MapKit.h>
 #import "LinkPresentation/LinkPresentation.h"
diff --git a/Ring/Ring/Extensions/UIImage+Helpers.swift b/Ring/Ring/Extensions/UIImage+Helpers.swift
index 8e53bfd6d89b33da5b36a862fdb5c9fdb1782e14..d4ad761644976930dc3eb88bbb950fbc08162b19 100644
--- a/Ring/Ring/Extensions/UIImage+Helpers.swift
+++ b/Ring/Ring/Extensions/UIImage+Helpers.swift
@@ -265,7 +265,8 @@ extension UIImage {
         return image
     }
 
-    class func defaultJamiAvatarFor(profileName: String?, account: AccountModel) -> UIImage {
+    class func defaultJamiAvatarFor(profileName: String?, account: AccountModel?) -> UIImage {
+        guard let account = account else { return UIImage(asset: Asset.icContactPicture)! }
         let image = UIImage(asset: Asset.icContactPicture)!
             .withAlignmentRectInsets(UIEdgeInsets(top: 4, left: 4, bottom: 4, right: 4))
         var name: String? = (profileName != nil) ? profileName :
@@ -298,7 +299,7 @@ extension UIImage {
         let width = spacing + leftImage.size.width + rightImage.size.width
 
         let size = CGSize(width: width, height: height)
-        UIGraphicsBeginImageContextWithOptions(size, false, 0.0)
+        UIGraphicsBeginImageContextWithOptions(size, false, 0)
 
         leftImage.draw(in: CGRect(x: 0, y: 0, width: leftImage.size.width, height: height))
         rightImage.draw(in: CGRect(x: spacing + leftImage.size.width, y: 0, width: rightImage.size.width, height: height))
diff --git a/Ring/Ring/Features/Conversations/Conversation/Cells/MessageCellLocationSharing.swift b/Ring/Ring/Features/Conversations/Conversation/Cells/MessageCellLocationSharing.swift
deleted file mode 100644
index ffbb592de930222677221c917472ad5ae621410b..0000000000000000000000000000000000000000
--- a/Ring/Ring/Features/Conversations/Conversation/Cells/MessageCellLocationSharing.swift
+++ /dev/null
@@ -1,430 +0,0 @@
-/*
- *  Copyright (C) 2020 Savoir-faire Linux Inc.
- *
- *  Author: Raphaël Brulé <raphael.brule@savoirfairelinux.com>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
- */
-
-import UIKit
-import Reusable
-import RxCocoa
-
-class MessageCellLocationSharing: MessageCell {
-
-    typealias MarkerAndComponentObject = (marker: MaplyScreenMarker, componentObject: MaplyComponentObject?)
-
-    private static let osmCopyrightAndLicenseURL = "https://www.openstreetmap.org/copyright"
-    private static let remoteTileSourceBaseUrl = MessageCellLocationSharing.getBaseURL()
-
-    @IBOutlet weak var locationSharingMessageTextView: UITextView!
-    @IBOutlet weak var bubbleHeight: NSLayoutConstraint!
-    var loader: MaplyQuadImageLoader!
-    var fetcher: MaplyRemoteTileFetcher!
-
-    var xButton: UIButton?
-    var myPositionButton: UIButton?
-
-    let locationTapped = BehaviorRelay<(Bool, Bool)>(value: (false, false)) // (shouldAnimate, expanding)
-
-    var maplyViewController: MaplyBaseViewController? // protected in Swift?
-    /// The usage of this variable allows for the view to not be refreshed on reuse (e.g. when scrolling)
-    private var preventUnnecessaryReuseCounter = 0
-
-    override func willRemoveSubview(_ subview: UIView) {
-        super.willRemoveSubview(subview)
-        self.preventUnnecessaryReuseCounter = 0
-    }
-
-    required init?(coder: NSCoder) {
-        super.init(coder: coder)
-        NotificationCenter.default.addObserver(self, selector: #selector(shrink), name: UIResponder.keyboardWillShowNotification, object: nil)
-    }
-
-    override func configureFromItem(_ conversationViewModel: ConversationViewModel, _ items: [MessageViewModel]?, cellForRowAt indexPath: IndexPath) {
-        super.configureFromItem(conversationViewModel, items, cellForRowAt: indexPath)
-
-        self.shrink()
-
-        if self.maplyViewController as? MaplyViewController == nil || preventUnnecessaryReuseCounter < 2 {
-            self.setupMaply()
-            self.displayMapTile()
-
-            self.configureTapGesture()
-            self.setupOSMCopyrightButton()
-            let name = (conversationViewModel.displayName.value != nil && !conversationViewModel.displayName.value!.isEmpty) ?
-                conversationViewModel.displayName.value! : conversationViewModel.userName.value
-            self.setUplocationSharingMessageTextView(username: name)
-            preventUnnecessaryReuseCounter += 1
-        }
-    }
-
-    func setUplocationSharingMessageTextView(username: String) {
-        self.locationSharingMessageTextView.isEditable = false
-        self.locationSharingMessageTextView.textColor = UIColor.jamiTextBlue
-        self.locationSharingMessageTextView.backgroundColor = UIColor.jamiBackgroundColor.withAlphaComponent(0.75)
-        self.bubble.addSubview(self.locationSharingMessageTextView)
-    }
-
-    override func configureTapGesture() {
-        self.bubble.isUserInteractionEnabled = true
-        self.tapGestureRecognizer = UITapGestureRecognizer()
-        self.tapGestureRecognizer!.rx.event.bind(onNext: { [weak self] _ in self?.onTapGesture() }).disposed(by: self.disposeBag)
-        self.bubble.addGestureRecognizer(tapGestureRecognizer!)
-    }
-
-    override func onTapGesture() {
-        if !locationTapped.value.1 {
-            self.expandOrShrink()
-        }
-    }
-
-    private func removeTapDefaultGestureFromMaply() {
-        if let whirlyKitEAGLView = (self.maplyViewController as? MaplyViewController)?.view.subviews[0],
-           let gesture = whirlyKitEAGLView.gestureRecognizers?.first(where: { (gesture) -> Bool in gesture is UITapGestureRecognizer }) {
-            whirlyKitEAGLView.removeGestureRecognizer(gesture)
-        }
-    }
-
-    private func setupMaply() {
-        self.maplyViewController?.view.removeFromSuperview()
-
-        self.maplyViewController = MaplyViewController(mapType: .typeFlat)
-        self.removeTapDefaultGestureFromMaply()
-
-        self.bubble.addSubview(self.maplyViewController!.view)
-        self.maplyViewController!.view.frame = self.bubble.bounds
-    }
-
-    lazy var samplingParams: MaplySamplingParams = {
-        let samplingParams = MaplySamplingParams()
-        samplingParams.coverPoles = true
-        samplingParams.edgeMatching = false
-        samplingParams.singleLevel = false
-        samplingParams.coverPoles = false
-        return samplingParams
-    }()
-
-    private func displayMapTile() {
-        // TODO: implement location map with a new API
-        self.maplyViewController!.clearColor = UIColor.white
-
-        // thirty fps if we can get it
-        self.maplyViewController!.frameInterval = 2
-        let baseCacheDir = NSSearchPathForDirectoriesInDomains(.cachesDirectory, .userDomainMask, true)[0]
-        let tilesCacheDir = "\(baseCacheDir)/openstreetmap/"
-        let maxZoom = Int32(19)
-        let info = MaplyRemoteTileFetchInfo()
-        let request = URLRequest(url: URL(string: MessageCellLocationSharing.remoteTileSourceBaseUrl)!)
-        info.urlReq = request as URLRequest
-        let tileSource = MaplyRemoteTileInfoNew(baseURL: MessageCellLocationSharing.remoteTileSourceBaseUrl,
-                                                minZoom: 0,
-                                                maxZoom: maxZoom)
-        tileSource.cacheDir = tilesCacheDir
-        fetcher = MaplyRemoteTileFetcher(name: "fetcher", connections: 2)
-        loader = MaplyQuadImageLoader(params: samplingParams, tileInfo: tileSource, viewC: maplyViewController!)
-        loader?.setTileFetcher(fetcher)
-
-        if let mapViewC = self.maplyViewController as? MaplyViewController {
-            self.toggleMaplyGesture(false)
-            mapViewC.height = 0.0001
-        }
-    }
-
-    private func toggleMaplyGesture(_ value: Bool) {
-        if let mapViewC = self.maplyViewController as? MaplyViewController {
-            mapViewC.panGesture = value
-            mapViewC.pinchGesture = value
-            mapViewC.rotateGesture = value
-            mapViewC.twoFingerTapGesture = value
-            mapViewC.doubleTapDragGesture = value
-            mapViewC.doubleTapZoomGesture = value
-        }
-    }
-
-    private static func getBaseURL() -> String {
-        // OpenStreetMap Tiles, © OpenStreetMap contributors
-        let urls = ["https://a.tile.openstreetmap.org/",
-                    "https://b.tile.openstreetmap.org/",
-                    "https://c.tile.openstreetmap.org/"]
-        let rngIndex = Int.random(in: 0 ..< 3)
-
-        return urls[rngIndex]
-    }
-}
-
-// For children
-extension MessageCellLocationSharing {
-    func updateLocationAndMarker(location: CLLocationCoordinate2D,
-                                 imageData: Data?,
-                                 username: String?,
-                                 marker: MaplyScreenMarker,
-                                 markerDump: MaplyComponentObject?,
-                                 tryToAnimateToMarker: Bool = true) -> MaplyComponentObject? {
-        // only the first time
-        if markerDump == nil {
-            marker.layoutImportance = MAXFLOAT
-            if let imageData = imageData, let circledImage = UIImage(data: imageData)?.circleMasked {
-                marker.image = circledImage
-            } else {
-                marker.image = AvatarView(profileImageData: nil, username: username ?? "", size: 24).convertToImage()
-            }
-            marker.size = CGSize(width: 24, height: 24)
-        }
-
-        let maplyCoordonate = MaplyCoordinateMakeWithDegrees(Float(location.longitude), Float(location.latitude))
-
-        marker.loc.x = maplyCoordonate.x
-        marker.loc.y = maplyCoordonate.y
-
-        var dumpToReturn: MaplyComponentObject?
-
-        if let mapViewC = self.maplyViewController as? MaplyViewController {
-            if markerDump != nil {
-                self.maplyViewController!.remove(markerDump!)
-            }
-            dumpToReturn = self.maplyViewController!.addScreenMarkers([marker], desc: nil)
-
-            if tryToAnimateToMarker && !locationTapped.value.1 {
-                mapViewC.animate(toPosition: maplyCoordonate, time: 0.1)
-            }
-        }
-        return dumpToReturn
-    }
-}
-
-// For OSM Copyrights
-extension MessageCellLocationSharing {
-    private func setupOSMCopyrightButton() {
-        let infoButton = UIButton(type: .detailDisclosure)
-        infoButton.backgroundColor = UIColor.init(white: 0.75, alpha: 0.25)
-        infoButton.cornerRadius = infoButton.frame.height / 2.0
-        self.bubble.addSubview(infoButton)
-
-        infoButton.translatesAutoresizingMaskIntoConstraints = false
-        let constraintX = NSLayoutConstraint(item: infoButton,
-                                             attribute: NSLayoutConstraint.Attribute.centerX,
-                                             relatedBy: NSLayoutConstraint.Relation.equal,
-                                             toItem: self.bubble,
-                                             attribute: NSLayoutConstraint.Attribute.right,
-                                             multiplier: 1,
-                                             constant: -28)
-        let constraintY = NSLayoutConstraint(item: infoButton,
-                                             attribute: NSLayoutConstraint.Attribute.centerY,
-                                             relatedBy: NSLayoutConstraint.Relation.equal,
-                                             toItem: self.bubble,
-                                             attribute: NSLayoutConstraint.Attribute.bottom,
-                                             multiplier: 1,
-                                             constant: -28)
-        NSLayoutConstraint.activate([constraintX, constraintY])
-        infoButton.addTarget(self, action: #selector(buttonAction), for: .touchUpInside)
-    }
-
-    @objc
-    func buttonAction(sender: UIButton!) {
-        let alert = UIAlertController.init(title: L10n.Alerts.mapInformation,
-                                           message: L10n.Alerts.openStreetMapCopyright,
-                                           preferredStyle: .alert)
-        alert.addAction(.init(title: L10n.Alerts.openStreetMapCopyrightMoreInfo, style: UIAlertAction.Style.default, handler: { (_) in
-            if let url = URL(string: MessageCellLocationSharing.osmCopyrightAndLicenseURL), UIApplication.shared.canOpenURL(url) {
-                UIApplication.shared.open(url, completionHandler: nil)
-            }
-        }))
-        alert.addAction(.init(title: L10n.Global.ok, style: UIAlertAction.Style.cancel))
-
-        self.window?.rootViewController?.present(alert, animated: true, completion: nil)
-    }
-}
-
-// For bigger map
-extension MessageCellLocationSharing {
-    @objc
-    private func shrink() {
-        if self.bubbleHeight.constant > 220 {
-            self.expandOrShrink()
-        }
-    }
-
-    private func expandOrShrink() {
-        let shouldExpand = !self.locationTapped.value.1
-
-        self.updateHeight(shouldExpand)
-        // self.updateWidth(shouldExpand) now in controller, for animation
-        self.toggleMaplyGesture(shouldExpand)
-
-        if shouldExpand {
-            self.setupXButton()
-            self.setupMyPositionButton()
-        } else {
-            self.removeXButton()
-            self.removeMyPositionButton()
-        }
-
-        self.locationTapped.accept((true, shouldExpand))
-    }
-
-    private func updateHeight(_ shouldExpand: Bool, extendedHeight: CGFloat = 350) {
-        let normalHeight: CGFloat = 220
-        if shouldExpand {
-            self.bubbleHeight.constant = extendedHeight
-        } else {
-            self.bubbleHeight.constant = normalHeight
-        }
-    }
-
-    @objc
-    func updateWidth(_ shouldExpand: Bool) {
-        fatalError("Must override this function")
-    }
-
-    func expandHeight(_ shouldExpand: Bool, _ height: CGFloat) {
-        if shouldExpand {
-            let percentage: CGFloat = self.hasTopNotch() ? 0.88 : 0.91
-
-            self.updateHeight(shouldExpand,
-                              extendedHeight: (height * percentage) - self.bubbleTopConstraint.constant)
-        }
-    }
-
-    func hasTopNotch() -> Bool {
-        return UIApplication.shared.windows.filter { $0.isKeyWindow }.first?.safeAreaInsets.top ?? 0 > 20
-    }
-}
-
-extension MessageCellLocationSharing {
-    private func setupXButton() {
-        self.setUpLocationSharingMessageTextViewInset(expanding: true)
-
-        self.xButton = UIButton()
-        let xButton = self.xButton!
-        xButton.setBackgroundImage(UIImage(asset: Asset.closeIcon)!, for: UIControl.State.normal)
-        xButton.tintColor = UIColor.jamiTextBlue
-        self.bubble.addSubview(xButton)
-
-        xButton.translatesAutoresizingMaskIntoConstraints = false
-        let constraintX = NSLayoutConstraint(item: xButton,
-                                             attribute: NSLayoutConstraint.Attribute.centerX,
-                                             relatedBy: NSLayoutConstraint.Relation.equal,
-                                             toItem: self.bubble,
-                                             attribute: NSLayoutConstraint.Attribute.left,
-                                             multiplier: 1,
-                                             constant: 24)
-        let constraintY = NSLayoutConstraint(item: xButton,
-                                             attribute: NSLayoutConstraint.Attribute.centerY,
-                                             relatedBy: NSLayoutConstraint.Relation.equal,
-                                             toItem: self.bubble,
-                                             attribute: NSLayoutConstraint.Attribute.top,
-                                             multiplier: 1,
-                                             constant: 24)
-        let height = NSLayoutConstraint(item: xButton,
-                                        attribute: NSLayoutConstraint.Attribute.height,
-                                        relatedBy: NSLayoutConstraint.Relation.equal,
-                                        toItem: nil,
-                                        attribute: NSLayoutConstraint.Attribute.notAnAttribute,
-                                        multiplier: 1,
-                                        constant: 32)
-        let width = NSLayoutConstraint(item: xButton,
-                                       attribute: NSLayoutConstraint.Attribute.width,
-                                       relatedBy: NSLayoutConstraint.Relation.equal,
-                                       toItem: nil,
-                                       attribute: NSLayoutConstraint.Attribute.notAnAttribute,
-                                       multiplier: 1,
-                                       constant: 32)
-        NSLayoutConstraint.activate([constraintX, constraintY, height, width])
-        xButton.addTarget(self, action: #selector(XButtonAction), for: .touchUpInside)
-    }
-
-    private func removeXButton() {
-        self.setUpLocationSharingMessageTextViewInset(expanding: false)
-
-        self.xButton?.removeFromSuperview()
-        self.xButton = nil
-    }
-
-    @objc
-    func XButtonAction(sender: UIButton!) {
-        self.expandOrShrink()
-    }
-
-    func setUpLocationSharingMessageTextViewInset(expanding: Bool) {
-        if expanding {
-            self.locationSharingMessageTextView.textContainerInset.left = 48
-            self.locationSharingMessageTextView.textAlignment = .left
-        } else {
-            self.locationSharingMessageTextView.textContainerInset.left = self.locationSharingMessageTextView.textContainerInset.right
-            self.locationSharingMessageTextView.textAlignment = .center
-        }
-    }
-
-    func onAnimationCompletion() {
-        self.locationSharingMessageTextView.adjustHeightFromContentSize(minHeight: 48)
-    }
-}
-
-extension MessageCellLocationSharing {
-    private func setupMyPositionButton() {
-        if self as? MessageCellLocationSharingSent != nil {
-            self.myPositionButton = UIButton()
-            let myLocation = self.myPositionButton!
-            myLocation.setImage(UIImage(asset: Asset.myLocation)!, for: .normal)
-            myLocation.tintColor = UIColor.jamiTextBlue
-            myLocation.backgroundColor = UIColor.jamiBackgroundColor.withAlphaComponent(0.75)
-            myLocation.cornerRadius = 16
-            self.bubble.addSubview(myLocation)
-
-            myLocation.translatesAutoresizingMaskIntoConstraints = false
-            let constraintX = NSLayoutConstraint(item: myLocation,
-                                                 attribute: NSLayoutConstraint.Attribute.centerX,
-                                                 relatedBy: NSLayoutConstraint.Relation.equal,
-                                                 toItem: self.bubble,
-                                                 attribute: NSLayoutConstraint.Attribute.right,
-                                                 multiplier: 1,
-                                                 constant: -28)
-            let constraintY = NSLayoutConstraint(item: myLocation,
-                                                 attribute: NSLayoutConstraint.Attribute.centerY,
-                                                 relatedBy: NSLayoutConstraint.Relation.equal,
-                                                 toItem: self.bubble,
-                                                 attribute: NSLayoutConstraint.Attribute.bottom,
-                                                 multiplier: 1,
-                                                 constant: -70)
-            let height = NSLayoutConstraint(item: myLocation,
-                                            attribute: NSLayoutConstraint.Attribute.height,
-                                            relatedBy: NSLayoutConstraint.Relation.equal,
-                                            toItem: nil,
-                                            attribute: NSLayoutConstraint.Attribute.notAnAttribute,
-                                            multiplier: 1,
-                                            constant: 32)
-            let width = NSLayoutConstraint(item: myLocation,
-                                           attribute: NSLayoutConstraint.Attribute.width,
-                                           relatedBy: NSLayoutConstraint.Relation.equal,
-                                           toItem: nil,
-                                           attribute: NSLayoutConstraint.Attribute.notAnAttribute,
-                                           multiplier: 1,
-                                           constant: 32)
-            NSLayoutConstraint.activate([constraintX, constraintY, height, width])
-            myLocation.addTarget(self, action: #selector(myPositionButtonAction), for: .touchUpInside)
-        }
-    }
-
-    private func removeMyPositionButton() {
-        self.myPositionButton?.removeFromSuperview()
-        self.myPositionButton = nil
-    }
-
-    @objc
-    func myPositionButtonAction(sender: UIButton!) {
-        fatalError("Must override this function")
-    }
-}
diff --git a/Ring/Ring/Features/Conversations/Conversation/Cells/MessageCellLocationSharingReceived.swift b/Ring/Ring/Features/Conversations/Conversation/Cells/MessageCellLocationSharingReceived.swift
deleted file mode 100644
index e76f0332cc38f696d9dd36d467394c75a49188f5..0000000000000000000000000000000000000000
--- a/Ring/Ring/Features/Conversations/Conversation/Cells/MessageCellLocationSharingReceived.swift
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- *  Copyright (C) 2020 Savoir-faire Linux Inc.
- *
- *  Author: Raphaël Brulé <raphael.brule@savoirfairelinux.com>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
- */
-
-import UIKit
-import Reusable
-
-class MessageCellLocationSharingReceived: MessageCellLocationSharing {
-
-    /// Primary location
-    private var myContactsLocation: MarkerAndComponentObject = (marker: MaplyScreenMarker(), componentObject: nil)
-    /// Secondary location
-    private var myLocation: MarkerAndComponentObject = (marker: MaplyScreenMarker(), componentObject: nil)
-
-    @IBOutlet weak var receivedBubbleLeading: NSLayoutConstraint!
-    @IBOutlet weak var receivedBubbleTrailling: NSLayoutConstraint!
-
-    override func configureFromItem(_ conversationViewModel: ConversationViewModel, _ items: [MessageViewModel]?, cellForRowAt indexPath: IndexPath) {
-        super.configureFromItem(conversationViewModel, items, cellForRowAt: indexPath)
-
-        // Primary location
-        conversationViewModel.myContactsLocation
-            .subscribe(onNext: { [weak self, weak conversationViewModel] location in
-                guard let self = self, let location = location else { return }
-
-                self.myContactsLocation.componentObject = self.updateLocationAndMarker(location: location,
-                                                                                       imageData: conversationViewModel?.profileImageData.value,
-                                                                                       username: conversationViewModel?.userName.value,
-                                                                                       marker: self.myContactsLocation.marker,
-                                                                                       markerDump: self.myContactsLocation.componentObject)
-            })
-            .disposed(by: self.disposeBag)
-
-        // Secondary location
-        conversationViewModel.myLocation
-            .subscribe(onNext: { [weak self, weak conversationViewModel] location in
-                guard let self = self else { return }
-
-                if let location = location?.coordinate {
-                    self.myLocation.componentObject = self.updateLocationAndMarker(location: location,
-                                                                                   imageData: conversationViewModel?.myOwnProfileImageData,
-                                                                                   username: conversationViewModel?.userName.value,
-                                                                                   marker: self.myLocation.marker,
-                                                                                   markerDump: self.myLocation.componentObject,
-                                                                                   tryToAnimateToMarker: false)
-                } else if let componentObject = self.myLocation.componentObject,
-                          let maplyViewController = self.maplyViewController {
-                    maplyViewController.remove(componentObject)
-                    self.myLocation.componentObject = nil
-                }
-            })
-            .disposed(by: self.disposeBag)
-    }
-
-    override func setUplocationSharingMessageTextView(username: String) {
-        super.setUplocationSharingMessageTextView(username: username)
-        self.locationSharingMessageTextView.text = L10n.Conversation.explanationReceivingLocationFrom + username
-        self.locationSharingMessageTextView.adjustHeightFromContentSize()
-    }
-
-    override func updateWidth(_ shouldExpand: Bool) {
-        let normalValue: CGFloat = 116
-        let extendedValue: CGFloat = 16
-        if shouldExpand {
-            self.receivedBubbleTrailling.constant = extendedValue
-            self.receivedBubbleLeading.constant = extendedValue
-        } else {
-            self.receivedBubbleTrailling.constant = normalValue
-            self.receivedBubbleLeading.constant = 64
-        }
-    }
-}
diff --git a/Ring/Ring/Features/Conversations/Conversation/Cells/MessageCellLocationSharingReceived.xib b/Ring/Ring/Features/Conversations/Conversation/Cells/MessageCellLocationSharingReceived.xib
deleted file mode 100644
index 019f45b2de43a31ae69e3eb02ea623f2bde190be..0000000000000000000000000000000000000000
--- a/Ring/Ring/Features/Conversations/Conversation/Cells/MessageCellLocationSharingReceived.xib
+++ /dev/null
@@ -1,106 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="16097.2" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
-    <device id="retina4_7" orientation="portrait" appearance="light"/>
-    <dependencies>
-        <deployment identifier="iOS"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="16087"/>
-        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
-    </dependencies>
-    <objects>
-        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
-        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
-        <tableViewCell contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" rowHeight="253" id="3QB-g7-MaS" userLabel="Message Cell Location Sharing Received" customClass="MessageCellLocationSharingReceived" customModule="Ring" customModuleProvider="target">
-            <rect key="frame" x="0.0" y="0.0" width="510" height="240"/>
-            <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
-            <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" ambiguous="YES" tableViewCell="3QB-g7-MaS" id="Dkz-SA-3Af">
-                <rect key="frame" x="0.0" y="0.0" width="510" height="240"/>
-                <autoresizingMask key="autoresizingMask"/>
-                <subviews>
-                    <view clipsSubviews="YES" contentMode="scaleToFill" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="xVQ-Jk-Sxy" customClass="MessageBubble" customModule="Ring" customModuleProvider="target">
-                        <rect key="frame" x="64" y="8" width="330" height="220"/>
-                        <subviews>
-                            <textView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleToFill" fixedFrame="YES" scrollEnabled="NO" editable="NO" textAlignment="center" selectable="NO" translatesAutoresizingMaskIntoConstraints="NO" id="bBn-eM-Hsx">
-                                <rect key="frame" x="0.0" y="0.0" width="330" height="56"/>
-                                <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
-                                <color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
-                                <color key="textColor" systemColor="labelColor" cocoaTouchSystemColor="darkTextColor"/>
-                                <fontDescription key="fontDescription" type="system" pointSize="14"/>
-                                <textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
-                            </textView>
-                        </subviews>
-                        <color key="backgroundColor" systemColor="systemGray4Color" red="0.81960784310000001" green="0.81960784310000001" blue="0.83921568629999999" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
-                        <constraints>
-                            <constraint firstAttribute="height" constant="220" id="hS0-Te-OEU"/>
-                        </constraints>
-                        <userDefinedRuntimeAttributes>
-                            <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
-                                <integer key="value" value="15"/>
-                            </userDefinedRuntimeAttribute>
-                        </userDefinedRuntimeAttributes>
-                    </view>
-                    <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="11/14/2016 12:34PM" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="4OM-U1-teG" userLabel="Message Time">
-                        <rect key="frame" x="178" y="9" width="154" height="20.5"/>
-                        <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
-                        <fontDescription key="fontDescription" type="system" pointSize="17"/>
-                        <nil key="textColor"/>
-                        <nil key="highlightedColor"/>
-                    </label>
-                    <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Wm5-ce-Sf6" userLabel="Left Divider">
-                        <rect key="frame" x="31" y="19" width="131" height="1"/>
-                        <color key="backgroundColor" red="0.94117647059999998" green="0.94117647059999998" blue="0.94117647059999998" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
-                        <constraints>
-                            <constraint firstAttribute="height" constant="1" id="dEi-Ni-etd"/>
-                        </constraints>
-                    </view>
-                    <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="WgT-u7-Mgl" userLabel="Right Divider">
-                        <rect key="frame" x="348" y="19" width="131" height="1"/>
-                        <color key="backgroundColor" red="0.94117647059999998" green="0.94117647059999998" blue="0.94117647059999998" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
-                        <constraints>
-                            <constraint firstAttribute="height" constant="1" id="9kZ-1u-mwB"/>
-                        </constraints>
-                    </view>
-                    <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="aRL-o9-tZc" userLabel="Avatar View">
-                        <rect key="frame" x="16" y="194" width="32" height="32"/>
-                        <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
-                        <constraints>
-                            <constraint firstAttribute="height" constant="32" id="JKg-Rh-evV"/>
-                            <constraint firstAttribute="width" constant="32" id="NQC-fC-Mw5"/>
-                        </constraints>
-                    </view>
-                </subviews>
-                <color key="tintColor" name="controlColor" catalog="System" colorSpace="catalog"/>
-                <constraints>
-                    <constraint firstAttribute="trailingMargin" secondItem="WgT-u7-Mgl" secondAttribute="trailing" constant="16" id="6Dc-L8-sJC"/>
-                    <constraint firstItem="WgT-u7-Mgl" firstAttribute="centerY" secondItem="4OM-U1-teG" secondAttribute="centerY" id="ALc-pa-7ZW"/>
-                    <constraint firstItem="4OM-U1-teG" firstAttribute="top" secondItem="Dkz-SA-3Af" secondAttribute="topMargin" constant="-2" id="CbK-m1-TUR"/>
-                    <constraint firstItem="aRL-o9-tZc" firstAttribute="trailing" secondItem="xVQ-Jk-Sxy" secondAttribute="leading" constant="-16" id="DIQ-qi-aUb"/>
-                    <constraint firstItem="Wm5-ce-Sf6" firstAttribute="leading" secondItem="Dkz-SA-3Af" secondAttribute="leadingMargin" constant="16" id="Faa-N7-gPP"/>
-                    <constraint firstItem="WgT-u7-Mgl" firstAttribute="leading" secondItem="4OM-U1-teG" secondAttribute="trailing" constant="16" id="Foe-Zm-1oU"/>
-                    <constraint firstItem="Wm5-ce-Sf6" firstAttribute="centerY" secondItem="4OM-U1-teG" secondAttribute="centerY" id="Q4u-AX-3D6"/>
-                    <constraint firstAttribute="bottom" secondItem="xVQ-Jk-Sxy" secondAttribute="bottom" constant="8" id="Qbn-zO-KWj"/>
-                    <constraint firstItem="xVQ-Jk-Sxy" firstAttribute="top" secondItem="Dkz-SA-3Af" secondAttribute="top" constant="8" id="R6Q-PY-A3m"/>
-                    <constraint firstItem="aRL-o9-tZc" firstAttribute="bottom" secondItem="xVQ-Jk-Sxy" secondAttribute="bottom" constant="-2" id="aM1-qu-Iys"/>
-                    <constraint firstItem="Wm5-ce-Sf6" firstAttribute="trailing" secondItem="4OM-U1-teG" secondAttribute="leading" constant="-16" id="dlX-Gh-ImE"/>
-                    <constraint firstItem="xVQ-Jk-Sxy" firstAttribute="leading" secondItem="Dkz-SA-3Af" secondAttribute="leading" constant="64" id="qxE-d6-psE"/>
-                    <constraint firstAttribute="trailing" secondItem="xVQ-Jk-Sxy" secondAttribute="trailing" constant="116" id="uTe-7R-qUz"/>
-                    <constraint firstItem="4OM-U1-teG" firstAttribute="centerX" secondItem="Dkz-SA-3Af" secondAttribute="centerX" id="zxy-XJ-QAl"/>
-                </constraints>
-            </tableViewCellContentView>
-            <connections>
-                <outlet property="avatarView" destination="aRL-o9-tZc" id="ROC-7p-3of"/>
-                <outlet property="bubble" destination="xVQ-Jk-Sxy" id="dRd-NH-FPh"/>
-                <outlet property="bubbleBottomConstraint" destination="Qbn-zO-KWj" id="hKY-TA-wId"/>
-                <outlet property="bubbleHeight" destination="hS0-Te-OEU" id="G9h-6Z-A7m"/>
-                <outlet property="bubbleTopConstraint" destination="R6Q-PY-A3m" id="IQA-QC-eV0"/>
-                <outlet property="leftDivider" destination="Wm5-ce-Sf6" id="EaQ-1G-8Db"/>
-                <outlet property="locationSharingMessageTextView" destination="bBn-eM-Hsx" id="LPV-Lc-9rj"/>
-                <outlet property="messageLabelMarginConstraint" destination="CbK-m1-TUR" id="8qD-tP-8QW"/>
-                <outlet property="receivedBubbleLeading" destination="qxE-d6-psE" id="aaK-f3-9Nx"/>
-                <outlet property="receivedBubbleTrailling" destination="uTe-7R-qUz" id="RXi-mN-T16"/>
-                <outlet property="rightDivider" destination="WgT-u7-Mgl" id="k10-3V-ZLw"/>
-                <outlet property="timeLabel" destination="4OM-U1-teG" id="ub4-Z8-CsM"/>
-            </connections>
-            <point key="canvasLocation" x="-411.19999999999999" y="-45.877061469265371"/>
-        </tableViewCell>
-    </objects>
-</document>
diff --git a/Ring/Ring/Features/Conversations/Conversation/Cells/MessageCellLocationSharingSent.swift b/Ring/Ring/Features/Conversations/Conversation/Cells/MessageCellLocationSharingSent.swift
deleted file mode 100644
index 8e494f4fb056b9d6dae5139e4d89ee169c49f047..0000000000000000000000000000000000000000
--- a/Ring/Ring/Features/Conversations/Conversation/Cells/MessageCellLocationSharingSent.swift
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- *  Copyright (C) 2020 Savoir-faire Linux Inc.
- *
- *  Author: Raphaël Brulé <raphael.brule@savoirfairelinux.com>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
- */
-
-import UIKit
-import Reusable
-import RxCocoa
-
-class MessageCellLocationSharingSent: MessageCellLocationSharing {
-
-    /// Primary location
-    private var myLocation: MarkerAndComponentObject = (marker: MaplyScreenMarker(), componentObject: nil)
-    /// Secondary location
-    private var myContactsLocation: MarkerAndComponentObject = (marker: MaplyScreenMarker(), componentObject: nil)
-
-    @IBOutlet weak var sentBubbleLeading: NSLayoutConstraint!
-
-    @IBOutlet weak var stopSharingButton: UIButton!
-
-    @IBAction func stopSharingButton(_ sender: Any) {
-        self.delete(sender)
-    }
-
-    override func configureFromItem(_ conversationViewModel: ConversationViewModel, _ items: [MessageViewModel]?, cellForRowAt indexPath: IndexPath) {
-        super.configureFromItem(conversationViewModel, items, cellForRowAt: indexPath)
-
-        // Primary location
-        conversationViewModel.myLocation
-            .subscribe(onNext: { [weak self, weak conversationViewModel] location in
-                guard let self = self, let location = location?.coordinate else { return }
-
-                self.myLocation.componentObject = self.updateLocationAndMarker(location: location,
-                                                                               imageData: conversationViewModel?.myOwnProfileImageData,
-                                                                               username: conversationViewModel?.userName.value,
-                                                                               marker: self.myLocation.marker,
-                                                                               markerDump: self.myLocation.componentObject)
-            })
-            .disposed(by: self.disposeBag)
-
-        // Secondary location
-        conversationViewModel.myContactsLocation
-            .subscribe(onNext: { [weak self, weak conversationViewModel] location in
-                guard let self = self else { return }
-
-                if let location = location {
-                    self.myContactsLocation.componentObject = self.updateLocationAndMarker(location: location,
-                                                                                           imageData: conversationViewModel?.profileImageData.value,
-                                                                                           username: conversationViewModel?.userName.value,
-                                                                                           marker: self.myContactsLocation.marker,
-                                                                                           markerDump: self.myContactsLocation.componentObject,
-                                                                                           tryToAnimateToMarker: false)
-                } else if let componentObject = self.myContactsLocation.componentObject,
-                          let maplyViewController = self.maplyViewController {
-                    maplyViewController.remove(componentObject)
-                    self.myContactsLocation.componentObject = nil
-                }
-            })
-            .disposed(by: self.disposeBag)
-
-        self.setupStopSharingButton()
-    }
-
-    override func setUplocationSharingMessageTextView(username: String) {
-        super.setUplocationSharingMessageTextView(username: username)
-        self.locationSharingMessageTextView.text = L10n.Conversation.explanationSendingLocationTo + username
-        self.locationSharingMessageTextView.adjustHeightFromContentSize()
-    }
-
-    private func setupStopSharingButton() {
-        self.stopSharingButton.setTitle(L10n.Actions.stopLocationSharing, for: .normal)
-        self.stopSharingButton.backgroundColor = UIColor.red
-        self.stopSharingButton.setTitleColor(UIColor.white, for: .normal)
-        self.bubble.addSubview(stopSharingButton)
-    }
-
-    override func myPositionButtonAction(sender: UIButton!) {
-        if let mapViewC = self.maplyViewController as? MaplyViewController {
-            mapViewC.animate(toPosition: self.myLocation.marker.loc, time: 0.5)
-        }
-    }
-
-    override func updateWidth(_ shouldExpand: Bool) {
-        let normalValue: CGFloat = 164
-        let extendedValue: CGFloat = 16
-        if shouldExpand {
-            self.sentBubbleLeading.constant = extendedValue
-        } else {
-            self.sentBubbleLeading.constant = normalValue
-        }
-    }
-}
diff --git a/Ring/Ring/Features/Conversations/Conversation/Cells/MessageCellLocationSharingSent.xib b/Ring/Ring/Features/Conversations/Conversation/Cells/MessageCellLocationSharingSent.xib
deleted file mode 100644
index aa413cb8462f43dcb68fdda78fc4b1c8796868ae..0000000000000000000000000000000000000000
--- a/Ring/Ring/Features/Conversations/Conversation/Cells/MessageCellLocationSharingSent.xib
+++ /dev/null
@@ -1,117 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="16097.2" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
-    <device id="retina4_7" orientation="portrait" appearance="light"/>
-    <dependencies>
-        <deployment identifier="iOS"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="16087"/>
-        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
-    </dependencies>
-    <objects>
-        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
-        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
-        <tableViewCell contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" rowHeight="253" id="3QB-g7-MaS" userLabel="Message Cell Location Sharing Sent" customClass="MessageCellLocationSharingSent" customModule="Ring" customModuleProvider="target">
-            <rect key="frame" x="0.0" y="0.0" width="510" height="240"/>
-            <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
-            <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" ambiguous="YES" tableViewCell="3QB-g7-MaS" id="Dkz-SA-3Af">
-                <rect key="frame" x="0.0" y="0.0" width="510" height="240"/>
-                <autoresizingMask key="autoresizingMask"/>
-                <subviews>
-                    <view clipsSubviews="YES" contentMode="scaleToFill" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="xVQ-Jk-Sxy" customClass="MessageBubble" customModule="Ring" customModuleProvider="target">
-                        <rect key="frame" x="164" y="8" width="330" height="220"/>
-                        <subviews>
-                            <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="PYf-Lj-ehe">
-                                <rect key="frame" x="134" y="175" width="62" height="34"/>
-                                <inset key="contentEdgeInsets" minX="8" minY="8" maxX="8" maxY="8"/>
-                                <state key="normal" title="Button">
-                                    <color key="titleColor" systemColor="systemRedColor" red="1" green="0.23137254900000001" blue="0.18823529410000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
-                                </state>
-                                <userDefinedRuntimeAttributes>
-                                    <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
-                                        <real key="value" value="15"/>
-                                    </userDefinedRuntimeAttribute>
-                                </userDefinedRuntimeAttributes>
-                                <connections>
-                                    <action selector="stopSharingButton:" destination="3QB-g7-MaS" eventType="touchUpInside" id="9px-PV-vvz"/>
-                                </connections>
-                            </button>
-                            <textView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleToFill" fixedFrame="YES" scrollEnabled="NO" editable="NO" textAlignment="center" selectable="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Wd9-VO-GSo">
-                                <rect key="frame" x="0.0" y="0.0" width="330" height="56"/>
-                                <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
-                                <color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
-                                <color key="textColor" systemColor="labelColor" cocoaTouchSystemColor="darkTextColor"/>
-                                <fontDescription key="fontDescription" type="system" pointSize="14"/>
-                                <textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
-                                <userDefinedRuntimeAttributes>
-                                    <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
-                                        <real key="value" value="0.0"/>
-                                    </userDefinedRuntimeAttribute>
-                                </userDefinedRuntimeAttributes>
-                            </textView>
-                        </subviews>
-                        <color key="backgroundColor" systemColor="systemGray4Color" red="0.81960784310000001" green="0.81960784310000001" blue="0.83921568629999999" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
-                        <constraints>
-                            <constraint firstItem="PYf-Lj-ehe" firstAttribute="centerY" secondItem="xVQ-Jk-Sxy" secondAttribute="bottom" constant="-28" id="SPy-c9-P2P"/>
-                            <constraint firstItem="PYf-Lj-ehe" firstAttribute="centerX" secondItem="xVQ-Jk-Sxy" secondAttribute="centerX" id="hQD-IF-ddy"/>
-                            <constraint firstAttribute="height" constant="220" id="hS0-Te-OEU"/>
-                        </constraints>
-                        <userDefinedRuntimeAttributes>
-                            <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
-                                <integer key="value" value="15"/>
-                            </userDefinedRuntimeAttribute>
-                        </userDefinedRuntimeAttributes>
-                    </view>
-                    <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="11/14/2016 12:34PM" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="4OM-U1-teG" userLabel="Message Time">
-                        <rect key="frame" x="178" y="9" width="154" height="21"/>
-                        <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
-                        <fontDescription key="fontDescription" type="system" pointSize="17"/>
-                        <nil key="textColor"/>
-                        <nil key="highlightedColor"/>
-                    </label>
-                    <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Wm5-ce-Sf6" userLabel="Left Divider">
-                        <rect key="frame" x="31" y="19" width="131" height="1"/>
-                        <color key="backgroundColor" red="0.94117647059999998" green="0.94117647059999998" blue="0.94117647059999998" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
-                        <constraints>
-                            <constraint firstAttribute="height" constant="1" id="dEi-Ni-etd"/>
-                        </constraints>
-                    </view>
-                    <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="WgT-u7-Mgl" userLabel="Right Divider">
-                        <rect key="frame" x="348" y="19" width="131" height="1"/>
-                        <color key="backgroundColor" red="0.94117647059999998" green="0.94117647059999998" blue="0.94117647059999998" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
-                        <constraints>
-                            <constraint firstAttribute="height" constant="1" id="9kZ-1u-mwB"/>
-                        </constraints>
-                    </view>
-                </subviews>
-                <color key="tintColor" name="controlColor" catalog="System" colorSpace="catalog"/>
-                <constraints>
-                    <constraint firstAttribute="trailingMargin" secondItem="WgT-u7-Mgl" secondAttribute="trailing" constant="16" id="6Dc-L8-sJC"/>
-                    <constraint firstItem="WgT-u7-Mgl" firstAttribute="centerY" secondItem="4OM-U1-teG" secondAttribute="centerY" id="ALc-pa-7ZW"/>
-                    <constraint firstItem="4OM-U1-teG" firstAttribute="top" secondItem="Dkz-SA-3Af" secondAttribute="topMargin" constant="-2" id="CbK-m1-TUR"/>
-                    <constraint firstItem="Wm5-ce-Sf6" firstAttribute="leading" secondItem="Dkz-SA-3Af" secondAttribute="leadingMargin" constant="16" id="Faa-N7-gPP"/>
-                    <constraint firstItem="WgT-u7-Mgl" firstAttribute="leading" secondItem="4OM-U1-teG" secondAttribute="trailing" constant="16" id="Foe-Zm-1oU"/>
-                    <constraint firstItem="Wm5-ce-Sf6" firstAttribute="centerY" secondItem="4OM-U1-teG" secondAttribute="centerY" id="Q4u-AX-3D6"/>
-                    <constraint firstAttribute="bottom" secondItem="xVQ-Jk-Sxy" secondAttribute="bottom" constant="8" id="Qbn-zO-KWj"/>
-                    <constraint firstItem="xVQ-Jk-Sxy" firstAttribute="top" secondItem="Dkz-SA-3Af" secondAttribute="top" constant="8" id="R6Q-PY-A3m"/>
-                    <constraint firstItem="Wm5-ce-Sf6" firstAttribute="trailing" secondItem="4OM-U1-teG" secondAttribute="leading" constant="-16" id="dlX-Gh-ImE"/>
-                    <constraint firstItem="xVQ-Jk-Sxy" firstAttribute="leading" secondItem="Dkz-SA-3Af" secondAttribute="leading" constant="164" id="qxE-d6-psE"/>
-                    <constraint firstAttribute="trailing" secondItem="xVQ-Jk-Sxy" secondAttribute="trailing" constant="16" id="uTe-7R-qUz"/>
-                    <constraint firstItem="4OM-U1-teG" firstAttribute="centerX" secondItem="Dkz-SA-3Af" secondAttribute="centerX" id="zxy-XJ-QAl"/>
-                </constraints>
-            </tableViewCellContentView>
-            <connections>
-                <outlet property="bubble" destination="xVQ-Jk-Sxy" id="dRd-NH-FPh"/>
-                <outlet property="bubbleBottomConstraint" destination="Qbn-zO-KWj" id="hKY-TA-wId"/>
-                <outlet property="bubbleHeight" destination="hS0-Te-OEU" id="oJg-9j-oa8"/>
-                <outlet property="bubbleTopConstraint" destination="R6Q-PY-A3m" id="IQA-QC-eV0"/>
-                <outlet property="leftDivider" destination="Wm5-ce-Sf6" id="EaQ-1G-8Db"/>
-                <outlet property="locationSharingMessageTextView" destination="Wd9-VO-GSo" id="Eoh-Sh-rsG"/>
-                <outlet property="messageLabelMarginConstraint" destination="CbK-m1-TUR" id="8qD-tP-8QW"/>
-                <outlet property="rightDivider" destination="WgT-u7-Mgl" id="k10-3V-ZLw"/>
-                <outlet property="sentBubbleLeading" destination="qxE-d6-psE" id="wIa-XC-C9H"/>
-                <outlet property="stopSharingButton" destination="PYf-Lj-ehe" id="qXH-bz-cAH"/>
-                <outlet property="timeLabel" destination="4OM-U1-teG" id="ub4-Z8-CsM"/>
-            </connections>
-            <point key="canvasLocation" x="-411.19999999999999" y="-45.877061469265371"/>
-        </tableViewCell>
-    </objects>
-</document>
diff --git a/Ring/Ring/Features/Conversations/Conversation/ConversationViewController.swift b/Ring/Ring/Features/Conversations/Conversation/ConversationViewController.swift
index 879df0805267e50c9271f5d037fa8553283a5e59..7958b6fe93383504e880ec04060f47801b84efe8 100644
--- a/Ring/Ring/Features/Conversations/Conversation/ConversationViewController.swift
+++ b/Ring/Ring/Features/Conversations/Conversation/ConversationViewController.swift
@@ -281,10 +281,7 @@ class ConversationViewController: UIViewController,
         alert.addAction(recordVideoAction)
         alert.addAction(recordAudioAction)
         alert.addAction(documentsAction)
-        // TODO: fix location sharing with a new API
-        if false {
-            alert.addAction(locationSharingAction())
-        }
+        alert.addAction(locationSharingAction())
         alert.addAction(cancelAction)
         alert.popoverPresentationController?.sourceView = self.view
         alert.popoverPresentationController?.permittedArrowDirections = UIPopoverArrowDirection()
@@ -837,12 +834,6 @@ extension ConversationViewController {
             .subscribe(onNext: { [weak self, weak cell] (shouldDelete) in
                 guard shouldDelete, let self = self, let cell = cell, let messageId = cell.messageId else { return }
 
-                if cell as? MessageCellLocationSharing != nil {
-                    self.tableView.isScrollEnabled = true
-                    if cell as? MessageCellLocationSharingSent != nil {
-                        self.viewModel.stopSendingLocation()
-                    }
-                }
                 self.isExecutingDeleteMessage = true
                 self.viewModel.deleteLocationMessage(messageId: messageId)
             })
@@ -866,42 +857,6 @@ extension ConversationViewController {
             })
             .disposed(by: cell.disposeBag)
     }
-
-    private func locationCellSetup(_ item: MessageViewModel, _ cell: MessageCell) {
-        guard item.isLocationSharingBubble, let cell = cell as? MessageCellLocationSharing else { return }
-
-        cell.locationTapped
-            .observe(on: MainScheduler.instance)
-            .subscribe(onNext: { [weak self, weak cell] (locationTapped) in
-                guard locationTapped.0, let self = self, let cell = cell else { return }
-
-                let expanding = locationTapped.1
-
-                if let index = self.tableView.indexPath(for: cell) {
-                    cell.expandHeight(expanding,
-                                      self.tableView.frame.height - self.tableView.contentInset.top - self.tableView.contentInset.bottom)
-                    self.tableView.performBatchUpdates({
-                        self.tableView.updateConstraintsIfNeeded()
-                        UIView.animate(withDuration: 0.4) {
-                            cell.updateWidth(expanding)
-                            cell.layoutIfNeeded()
-                        }
-                    }, completion: { [weak cell] _ in cell?.onAnimationCompletion() })
-
-                    if expanding {
-                        self.tableView.scrollToRow(at: index, at: UITableView.ScrollPosition.top, animated: true)
-                    }
-                    self.tableView.isScrollEnabled = !expanding
-
-                    cell.locationTapped.accept((false, expanding))
-                } else {
-                    self.log.warning("[ConversationViewController] locationCellSetup, something went weird, let's retry")
-                    self.tableView.isScrollEnabled = true
-                    cell.locationTapped.accept((true, expanding)) // retry
-                }
-            })
-            .disposed(by: cell.disposeBag)
-    }
 }
 
 // MARK: Location sharing
diff --git a/Ring/Ring/Features/Conversations/Conversation/ConversationViewModel.swift b/Ring/Ring/Features/Conversations/Conversation/ConversationViewModel.swift
index b6ef69f9f9ad5c5f6d2366b308f9a7b82c4c8707..f4954bceadd955e0a0cad4af7c79e8711a0d3d51 100644
--- a/Ring/Ring/Features/Conversations/Conversation/ConversationViewModel.swift
+++ b/Ring/Ring/Features/Conversations/Conversation/ConversationViewModel.swift
@@ -27,7 +27,7 @@ import RxSwift
 import RxCocoa
 import SwiftyBeaver
 
-// swiftlint:disable file_length
+// swiftlint:disable file_length, type_body_length
 class ConversationViewModel: Stateable, ViewModel {
 
     /// Logger
@@ -151,7 +151,6 @@ class ConversationViewModel: Stateable, ViewModel {
     var conversation: BehaviorRelay<ConversationModel>! {
         didSet {
             self.subscribeUnreadMessages()
-            self.subscribeLocationServiceLocationReceived()
             self.subscribeProfileServiceMyPhoto()
 
             guard let account = self.accountService.getAccount(fromAccountId: self.conversation.value.accountId) else { return }
@@ -473,8 +472,6 @@ class ConversationViewModel: Stateable, ViewModel {
         //        self.messages.accept(conversationsMsg)
     }
 
-    var myLocation: Observable<CLLocation?> { return self.locationSharingService.currentLocation.asObservable() }
-
     var myContactsLocation = BehaviorSubject<CLLocationCoordinate2D?>(value: nil)
     let shouldDismiss = BehaviorRelay<Bool>(value: false)
     func openFullScreenPreview(parentView: UIViewController, viewModel: PlayerViewModel?, image: UIImage?, initialFrame: CGRect, delegate: PreviewViewControllerDelegate) {
@@ -518,21 +515,6 @@ class ConversationViewModel: Stateable, ViewModel {
 // MARK: Conversation didSet functions
 extension ConversationViewModel {
 
-    private func subscribeLocationServiceLocationReceived() {
-        self.locationSharingService
-            .peerUriAndLocationReceived
-            .subscribe(onNext: { [weak self] tuple in
-                guard let self = self, let peerUri = tuple.0, let conversation = self.conversation,
-                      let jamiId = conversation.value.getParticipants().first?.jamiId else { return }
-                let coordinates = tuple.1
-                let hash = JamiURI(from: peerUri).hash
-                if hash == jamiId {
-                    self.myContactsLocation.onNext(coordinates)
-                }
-            })
-            .disposed(by: self.disposeBag)
-    }
-
     private func subscribeProfileServiceMyPhoto() {
         guard let account = self.accountService.currentAccount else { return }
         self.profileService
@@ -633,8 +615,8 @@ extension ConversationViewModel {
     func isAlreadySharingLocation() -> Bool {
         guard let account = self.accountService.currentAccount,
               let jamiId = self.conversation.value.getParticipants().first?.jamiId else { return true }
-        return self.locationSharingService.isAlreadySharing(accountId: account.id,
-                                                            contactUri: jamiId)
+        return self.locationSharingService.isAlreadySharingMyLocation(accountId: account.id,
+                                                                      contactUri: jamiId)
     }
 
     func startSendingLocation(duration: TimeInterval) {
diff --git a/Ring/Ring/Features/Conversations/Conversation/MessageSwiftUI/ViewModels/MessagesListVM.swift b/Ring/Ring/Features/Conversations/Conversation/MessageSwiftUI/ViewModels/MessagesListVM.swift
index e86a608e483568bf73c3d168f3fac1274dc79743..2cbcfc7a2ac44e66ef685846a2f6b9f426522079 100644
--- a/Ring/Ring/Features/Conversations/Conversation/MessageSwiftUI/ViewModels/MessagesListVM.swift
+++ b/Ring/Ring/Features/Conversations/Conversation/MessageSwiftUI/ViewModels/MessagesListVM.swift
@@ -5,6 +5,7 @@
  *  Author: Kateryna Kostiuk <kateryna.kostiuk@savoirfairelinux.com>
  *  Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
  *  Author: Raphaël Brulé <raphael.brule@savoirfairelinux.com>
+ * Author: Alireza Toghiani Khorasgani alireza.toghiani@savoirfairelinux.com *
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -24,6 +25,7 @@
 import Foundation
 import RxSwift
 import RxRelay
+import RxCocoa
 
 enum MessageInfo: State {
     case updateAvatar(jamiId: String)
@@ -53,10 +55,19 @@ class MessagesListVM: ObservableObject {
         }
     }
     @Published var numberOfNewMessages: Int = 0
+    @Published var shouldShowMap: Bool = false
+    @Published var coordinates = [(CLLocationCoordinate2D, UIImage)]()
+    @Published var isMapOpened = false
+    var contactAvatar: UIImage = UIImage()
+    var currentAccountAvatar: UIImage = UIImage()
+    var myLocation: Observable<CLLocation?> { return self.locationSharingService.currentLocation.asObservable() }
+    var myContactsLocation: CLLocationCoordinate2D?
+    var myCoordinate: CLLocationCoordinate2D?
 
     var accountService: AccountsService
     var profileService: ProfilesService
     var dataTransferService: DataTransferService
+    var locationSharingService: LocationSharingService
     var conversationService: ConversationsService
     var contactsService: ContactsService
     var nameService: NameService
@@ -138,6 +149,61 @@ class MessagesListVM: ObservableObject {
         self.contactsService = injectionBag.contactsService
         self.nameService = injectionBag.nameService
         self.transferHelper = transferHelper
+        self.locationSharingService = injectionBag.locationSharingService
+        self.subscribeLocationEvents()
+    }
+
+    func subscribeLocationEvents() {
+        self.locationSharingService
+            .peerUriAndLocationReceived
+            .subscribe(onNext: { [weak self] tuple in
+                guard let self = self else { return }
+                DispatchQueue.main.async {
+                    if let coordinates = tuple.1 {
+                        self.myContactsLocation = coordinates
+                    } else {
+                        self.myContactsLocation = nil
+                    }
+                    self.updateCoordinatesList()
+                }
+            })
+            .disposed(by: self.disposeBag)
+
+        self.myLocation
+            .subscribe(onNext: { [weak self] myCurrentLocation in
+                guard let self = self else { return }
+                if let myCurrentLocation = myCurrentLocation {
+                    self.myCoordinate = myCurrentLocation.coordinate
+                } else {
+                    self.myCoordinate = nil
+                }
+                self.updateCoordinatesList()
+            })
+            .disposed(by: self.disposeBag)
+        self.subscribeUserAvatarForLocationSharing()
+    }
+
+    func subscribeUserAvatarForLocationSharing() {
+        profileService.getAccountProfile(accountId: self.conversation.accountId)
+            .subscribe(onNext: { [weak self] profile in
+                guard let self = self else { return }
+                let account = self.accountService.getAccount(fromAccountId: self.conversation.accountId)
+                self.currentAccountAvatar = UIImage.defaultJamiAvatarFor(profileName: profile.alias, account: account)
+                self.updateCoordinatesList()
+            })
+            .disposed(by: self.disposeBag)
+    }
+
+    private func updateCoordinatesList() {
+        var coordinates = [(CLLocationCoordinate2D, UIImage)]()
+        if let myContactsLocation = self.myContactsLocation {
+            coordinates.append((myContactsLocation, self.contactAvatar))
+        }
+        if let myLocation = self.myCoordinate {
+            coordinates.append((myLocation, self.currentAccountAvatar))
+        }
+        self.coordinates = coordinates
+        self.shouldShowMap = self.isAlreadySharingLocation()
     }
 
     private func insert(newMessage: MessageModel) -> Bool {
@@ -468,6 +534,7 @@ class MessagesListVM: ObservableObject {
 
     private func updateAvatar(image: UIImage, id: String, message: MessageContainerModel) {
         self.avatars.set(value: image, for: id)
+        self.updateContacLocationSharingImage()
         message.updateAvatar(image: image)
         if var lastReadAvatars = self.lastRead.get(key: message.id) as? [String: UIImage] {
             if var _ = lastReadAvatars[id] {
@@ -504,7 +571,7 @@ class MessagesListVM: ObservableObject {
                     self.updateAvatar(image: image, id: id, message: message)
                 }
             })
-            .disposed(by: message.disposeBag)
+            .disposed(by: disposeBag)
         self.nameService.lookupAddress(withAccount: self.conversation.accountId, nameserver: "", address: id)
     }
 
@@ -565,3 +632,76 @@ class MessagesListVM: ObservableObject {
         messageModel.updateRead(avatars: newValue)
     }
 }
+
+// MARK: Location sharing
+// swiftlint:disable body_length
+extension MessagesListVM {
+
+    func updateContacLocationSharingImage() {
+        if let jamiId = self.conversation.getParticipants().first?.jamiId {
+            if let avatar = self.avatars.get(key: jamiId) as? UIImage {
+                DispatchQueue.main.async { [weak self] in
+                    self?.contactAvatar = avatar
+                    self?.updateCoordinatesList()
+                }
+            }
+        }
+    }
+
+    func isAlreadySharingLocation() -> Bool {
+        guard let account = self.accountService.currentAccount,
+              let jamiId = self.conversation.getParticipants().first?.jamiId else { return true }
+        return self.locationSharingService.isAlreadySharing(accountId: account.id,
+                                                            contactUri: jamiId) || self.locationSharingService.isAlreadySharingMyLocation(accountId: account.id, contactUri: jamiId)
+    }
+
+    func isAlreadySharingMyLocation() -> Bool {
+        guard let account = self.accountService.currentAccount,
+              let jamiId = self.conversation.getParticipants().first?.jamiId else { return true }
+        return self.locationSharingService.isAlreadySharingMyLocation(accountId: account.id, contactUri: jamiId)
+    }
+
+    func startSendingLocation(duration: TimeInterval) {
+        guard let account = self.accountService.currentAccount,
+              let jamiId = self.conversation.getParticipants().first?.jamiId else { return }
+        self.locationSharingService.startSharingLocation(from: account.id,
+                                                         to: jamiId,
+                                                         duration: duration)
+    }
+
+    func stopSendingLocation() {
+        guard let account = self.accountService.currentAccount,
+              let jamiId = self.conversation.getParticipants().first?.jamiId else { return }
+        self.locationSharingService.stopSharingLocation(accountId: account.id,
+                                                        contactUri: jamiId)
+    }
+
+    func getMyLocationSharingRemainedTime() -> Int {
+        guard let account = self.accountService.currentAccount,
+              let jamiId = self.conversation.getParticipants().first?.jamiId else { return 0}
+        return self.locationSharingService.getMyLocationSharingRemainedTime(accountId: account.id, contactUri: jamiId)
+    }
+
+    func getMyLocationSharingRemainedTimeText() -> String {
+        let remainingTime = getMyLocationSharingRemainedTime()
+        let hours = remainingTime / 60
+        let minutes = remainingTime % 60
+
+        let hourString = hours == 1 ? "hour" : "hours"
+        let minuteString = minutes == 1 ? "minute" : "minutes"
+
+        if hours == 0 {
+            if minutes == 0 {
+                return "0 minutes"
+            } else {
+                return "\(minutes) \(minuteString)"
+            }
+        } else {
+            if minutes == 0 {
+                return "\(hours) \(hourString)"
+            } else {
+                return "\(hours) \(hourString), \(minutes) \(minuteString)"
+            }
+        }
+    }
+}
diff --git a/Ring/Ring/Features/Conversations/Conversation/MessageSwiftUI/Views/LocationSharingView.swift b/Ring/Ring/Features/Conversations/Conversation/MessageSwiftUI/Views/LocationSharingView.swift
new file mode 100644
index 0000000000000000000000000000000000000000..d8889d4abca8023f4adb1b36e918eeb3c9f54c44
--- /dev/null
+++ b/Ring/Ring/Features/Conversations/Conversation/MessageSwiftUI/Views/LocationSharingView.swift
@@ -0,0 +1,173 @@
+/*
+ *  Copyright (C) 2022-2023 Savoir-faire Linux Inc.
+ *
+ * Author: Alireza Toghiani Khorasgani alireza.toghiani@savoirfairelinux.com *
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
+ */
+
+import SwiftUI
+
+// swiftlint:disable closure_body_length
+struct LocationSharingView: View {
+
+    @StateObject var model: MessagesListVM
+    @Binding var coordinates: [(CLLocationCoordinate2D, UIImage)]
+    @SwiftUI.State private var showCopyrightAlert = false
+    @SwiftUI.State private var viewCornerRadius: CGFloat = 15
+
+    var navigationBarHeight: CGFloat {
+        UINavigationController.navBarHeight() + ( UIApplication.shared.windows.first?.windowScene?.statusBarManager?.statusBarFrame.height ?? 0) + 80
+    }
+
+    var body: some View {
+        HStack {
+            if model.isMapOpened {
+                VStack {
+                    ZStack(alignment: .center) {
+                        VStack(spacing: 0) {
+                            HStack {
+                                Spacer()
+                                    .frame(width: 20)
+                                Button {
+                                    model.isMapOpened = false
+                                } label: {
+                                    Image(systemName: "xmark")
+                                        .foregroundColor(.white)
+                                        .font(.system(size: 20, weight: .semibold))
+                                }
+                                Spacer()
+                                    .frame(width: 20)
+                                Text("Location Sharing")
+                                    .fontWeight(.semibold)
+                                    .font(.title3)
+                                    .foregroundColor(.white)
+                                Spacer()
+                            }
+                            .frame(width: UIScreen.main.bounds.size.width, height: 60)
+                            .background(Color(UIColor.darkGray))
+                            .cornerRadius(radius: viewCornerRadius, corners: [.topLeft, .topRight])
+                            ZStack(alignment: .bottom) {
+                                MapView(coordinates: $coordinates)
+                                createCopyrigtButton()
+                                    .padding(.all, 5)
+                            }
+                        }
+
+                        VStack {
+                            Spacer()
+                            Text(model.getMyLocationSharingRemainedTimeText())
+                                .fontWeight(.semibold)
+                                .font(.caption)
+                                .padding([.leading, .trailing], 15)
+                                .padding([.top, .bottom], 5)
+                                .background(Color.black)
+                                .foregroundColor(.white)
+                                .cornerRadius(8)
+
+                            if model.isAlreadySharingMyLocation() {
+                                Button {
+                                    model.stopSendingLocation()
+                                    model.isMapOpened = false
+                                } label: {
+                                    HStack {
+                                        Image(systemName: "paperplane.fill")
+                                            .foregroundColor(.black)
+                                        Text(L10n.Actions.stopLocationSharing)
+                                            .font(.callout)
+                                    }
+                                    .padding([.leading, .trailing], 15)
+                                    .padding([.top, .bottom], 15)
+                                    .background(Color.red)
+                                    .foregroundColor(.black)
+                                    .cornerRadius(20)
+                                }
+                                .padding(.bottom, 10)
+                            }
+                        }
+                    }
+                    .frame(width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.height - navigationBarHeight)
+                }
+            } else {
+                ZStack(alignment: .center) {
+                    MapView(coordinates: $coordinates)
+                        .frame(width: 250, height: 150)
+                        .cornerRadius(viewCornerRadius)
+                        .onTapGesture {
+                            model.isMapOpened = true
+                        }
+                    if model.isAlreadySharingMyLocation() {
+                        VStack {
+                            Spacer()
+                            HStack {
+                                Spacer()
+                                Button {
+                                    model.stopSendingLocation()
+                                    model.isMapOpened = false
+                                } label: {
+                                    Text(L10n.Actions.stopLocationSharing)
+                                        .fontWeight(.semibold)
+                                        .font(.caption)
+                                        .padding([.leading, .trailing], 15)
+                                        .padding([.top, .bottom], 5)
+                                        .background(Color.red)
+                                        .foregroundColor(.white)
+                                        .cornerRadius(8)
+                                }
+                                Spacer()
+                            }
+                            .padding(.all, 10)
+                        }
+                    }
+                    createCopyrigtButton()
+                        .padding(.all, 5)
+                }
+                .frame(width: 200, height: 150)
+            }
+        }
+        .alert(isPresented: $showCopyrightAlert) {
+            Alert(title: Text("OpenStreetMap"), message: Text("Map data © OpenStreetMap contributors"), primaryButton: .default(Text("Open in Safari")) {
+                showCopyrightAlert = false
+                if let url = URL(string: "https://www.openstreetmap.org/copyright"),
+                   UIApplication.shared.canOpenURL(url) {
+                    UIApplication.shared.open(url)
+                }
+            }, secondaryButton: .cancel())
+        }
+    }
+
+    func createCopyrigtButton() -> some View {
+        return VStack {
+            Spacer()
+            HStack {
+                Spacer()
+                Button {
+                    showCopyrightAlert = true
+                } label: {
+                    Image(systemName: "info")
+                        .renderingMode(.template)
+                        .resizable()
+                        .aspectRatio(contentMode: .fit)
+                        .foregroundColor(.white)
+                        .padding(4)
+                        .frame(width: 15, height: 15)
+                        .background(Color(UIColor.darkGray))
+                        .clipShape(Circle())
+                        .frame(width: 30, height: 30)
+                }
+            }
+        }
+    }
+}
diff --git a/Ring/Ring/Features/Conversations/Conversation/MessageSwiftUI/Views/MapView.swift b/Ring/Ring/Features/Conversations/Conversation/MessageSwiftUI/Views/MapView.swift
new file mode 100644
index 0000000000000000000000000000000000000000..c7c8e5767210c7d3243271091c430f1ff0eb3ea1
--- /dev/null
+++ b/Ring/Ring/Features/Conversations/Conversation/MessageSwiftUI/Views/MapView.swift
@@ -0,0 +1,123 @@
+/*
+ *  Copyright (C) 2022-2023 Savoir-faire Linux Inc.
+ *
+ * Author: Alireza Toghiani Khorasgani alireza.toghiani@savoirfairelinux.com *
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
+ */
+
+import SwiftUI
+import MapKit
+
+class LocationSharingAnnotation: NSObject, MKAnnotation {
+    var avatar: UIImage!
+    var coordinate: CLLocationCoordinate2D
+
+    init(coordinate: CLLocationCoordinate2D) {
+        self.coordinate = coordinate
+    }
+}
+
+class MapViewWrapper: NSObject {
+    let mapView: MapView
+
+    init(mapView: MapView) {
+        self.mapView = mapView
+    }
+}
+
+struct MapView: UIViewRepresentable {
+    @Binding var coordinates: [(CLLocationCoordinate2D, UIImage)]
+
+    func makeUIView(context: Context) -> MKMapView {
+        let mapView = MKMapView()
+
+        mapView.delegate = context.coordinator
+        // Add an OpenStreetMap tile overlay to the map view.
+        let urlTemplate = "https://tile.openstreetmap.org/{z}/{x}/{y}.png"
+        let overlay = MKTileOverlay(urlTemplate: urlTemplate)
+        overlay.canReplaceMapContent = true
+        mapView.addOverlay(overlay, level: .aboveLabels)
+
+        addPinsAndZoom(mapView: mapView)
+        return mapView
+    }
+
+    func updateUIView(_ view: MKMapView, context: Context) {
+        addPinsAndZoom(mapView: view)
+    }
+
+    func addPinsAndZoom(mapView: MKMapView) {
+        mapView.removeAnnotations(mapView.annotations)
+        for coordinate in coordinates {
+            let annotation = LocationSharingAnnotation(coordinate: coordinate.0)
+            annotation.avatar = coordinate.1
+            mapView.addAnnotation(annotation)
+        }
+        if let firstCoordinate = coordinates.first {
+            let span = MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta: 0.01)
+            let region = MKCoordinateRegion(center: firstCoordinate.0, span: span)
+            mapView.setRegion(region, animated: true)
+        }
+    }
+}
+
+extension MapView {
+    class Coordinator: NSObject, MKMapViewDelegate {
+
+        func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
+            if overlay is MKTileOverlay {
+                let renderer = MKTileOverlayRenderer(overlay: overlay)
+                return renderer
+            } else {
+                return MKTileOverlayRenderer()
+            }
+        }
+
+        func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
+            guard let customAnnotation = annotation as? LocationSharingAnnotation else {
+                return nil
+            }
+
+            let reuseId = customAnnotation.avatar?.description ?? customAnnotation.description
+
+            var anView = mapView.dequeueReusableAnnotationView(withIdentifier: reuseId)
+            if anView == nil {
+                anView = MKAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
+            } else {
+                anView?.annotation = customAnnotation
+            }
+
+            let imageWidth = 35
+            let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: imageWidth, height: imageWidth))
+            imageView.image = customAnnotation.avatar
+            imageView.layer.cornerRadius = imageView.layer.frame.size.width / 2
+            imageView.layer.masksToBounds = true
+            anView?.addSubview(imageView)
+
+            return anView
+        }
+    }
+
+    func makeCoordinator() -> Coordinator {
+        Coordinator()
+    }
+}
+
+struct MapView_Previews: PreviewProvider {
+    static var previews: some View {
+        MapView(coordinates: .init(projectedValue: .constant([(CLLocationCoordinate2D(latitude: 37.785834, longitude: -122.406417), UIImage())])))
+    }
+}
diff --git a/Ring/Ring/Features/Conversations/Conversation/MessageSwiftUI/Views/MessagesListView.swift b/Ring/Ring/Features/Conversations/Conversation/MessageSwiftUI/Views/MessagesListView.swift
index aa61d82e3c45479289d7a119d8a094e743a9b70c..6e47a4a092e6651fa1b91c8a09d0416eed3101ee 100644
--- a/Ring/Ring/Features/Conversations/Conversation/MessageSwiftUI/Views/MessagesListView.swift
+++ b/Ring/Ring/Features/Conversations/Conversation/MessageSwiftUI/Views/MessagesListView.swift
@@ -2,6 +2,7 @@
  *  Copyright (C) 2022 Savoir-faire Linux Inc.
  *
  *  Author: Kateryna Kostiuk <kateryna.kostiuk@savoirfairelinux.com>
+ *  Author: Alireza Toghiani Khorasgani alireza.toghiani@savoirfairelinux.com
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -43,6 +44,7 @@ struct ScrollViewOffsetPreferenceKey: PreferenceKey {
     }
 }
 
+// swiftlint:disable closure_body_length
 struct MessagesListView: View {
     @StateObject var model: MessagesListVM
     @SwiftUI.State var showScrollToLatestButton = false
@@ -57,82 +59,87 @@ struct MessagesListView: View {
     @SwiftUI.State private var screenHeight: CGFloat = 0
 
     var body: some View {
-        ZStack(alignment: .bottomTrailing) {
-            ScrollViewReader { scrollView in
-                ScrollView(showsIndicators: false) {
-                    // update scroll offset
-                    GeometryReader { proxy in
-                        let offset = proxy.frame(in: .named("scroll")).minY
-                        Color.clear.preference(key: ScrollViewOffsetPreferenceKey.self, value: offset)
-                    }
-                    LazyVStack(spacing: 0) {
-                        // scroll to the bottom
-                        Text("")
-                            .id("lastMessage")
-                        // messages
-                        ForEach(model.messagesModels) { message in
-                            MessageRowView(messageModel: message, onLongPress: {(frame, message) in
-                                if showContextMenu == true {
-                                    return
-                                }
-                                model.hideNavigationBar.accept(true)
-                                contextMenuModel.presentingMessage = message
-                                contextMenuModel.messageFrame = frame
-                                if let topController = topVC() {
-                                    contextMenuModel.currentSnapshot = UIImage.makeSnapshot(from: topController.view)
-                                }
-                                showContextMenu = true
-                            }, model: message.messageRow)
+        ZStack(alignment: .top) {
+            ZStack(alignment: .bottomTrailing) {
+                ScrollViewReader { scrollView in
+                    ScrollView(showsIndicators: false) {
+                        // update scroll offset
+                        GeometryReader { proxy in
+                            let offset = proxy.frame(in: .named("scroll")).minY
+                            Color.clear.preference(key: ScrollViewOffsetPreferenceKey.self, value: offset)
                         }
-                        .flipped()
-                        // load more
-                        Text("")
-                            .onAppear(perform: {
-                                DispatchQueue.global(qos: .background)
-                                    .asyncAfter(deadline: DispatchTime(uptimeNanoseconds: 10)) {
-                                        self.model.loadMore()
+                        LazyVStack(spacing: 0) {
+                            // scroll to the bottom
+                            Text("")
+                                .id("lastMessage")
+                            // messages
+                            ForEach(model.messagesModels) { message in
+                                MessageRowView(messageModel: message, onLongPress: {(frame, message) in
+                                    if showContextMenu == true {
+                                        return
                                     }
-                            })
-                    }
-                    .listRowBackground(Color.clear)
-                    .onReceive(model.$scrollToId, perform: { (scrollToId) in
-                        guard scrollToId != nil else { return }
-                        scrollView.scrollTo("lastMessage")
-                        DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
-                            model.scrollToId = nil
+                                    model.hideNavigationBar.accept(true)
+                                    contextMenuModel.presentingMessage = message
+                                    contextMenuModel.messageFrame = frame
+                                    if let topController = topVC() {
+                                        contextMenuModel.currentSnapshot = UIImage.makeSnapshot(from: topController.view)
+                                    }
+                                    showContextMenu = true
+                                }, model: message.messageRow)
+                            }
+                            .flipped()
+                            // load more
+                            Text("")
+                                .onAppear(perform: {
+                                    DispatchQueue.global(qos: .background)
+                                        .asyncAfter(deadline: DispatchTime(uptimeNanoseconds: 10)) {
+                                            self.model.loadMore()
+                                        }
+                                })
                         }
-                    })
-                }
-                .onPreferenceChange(ScrollViewOffsetPreferenceKey.self) { value in
-                    DispatchQueue.main.async {
-                        let scrollOffset = value ?? 0
-                        let atTheBottom = scrollOffset < scrollReserved
-                        if atTheBottom != model.atTheBottom {
-                            model.atTheBottom = atTheBottom
+                        .listRowBackground(Color.clear)
+                        .onReceive(model.$scrollToId, perform: { (scrollToId) in
+                            guard scrollToId != nil else { return }
+                            scrollView.scrollTo("lastMessage")
+                            DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
+                                model.scrollToId = nil
+                            }
+                        })
+                    }
+                    .onPreferenceChange(ScrollViewOffsetPreferenceKey.self) { value in
+                        DispatchQueue.main.async {
+                            let scrollOffset = value ?? 0
+                            let atTheBottom = scrollOffset < scrollReserved
+                            if atTheBottom != model.atTheBottom {
+                                model.atTheBottom = atTheBottom
+                            }
                         }
                     }
                 }
+                .flipped()
+                if !model.atTheBottom {
+                    createScrollToBottmView()
+                }
             }
-            .flipped()
-            if !model.atTheBottom {
-                createScrollToBottmView()
+            .overlay(showContextMenu && contextMenuModel.presentingMessage != nil ? makeOverlay() : nil)
+            // hide navigation bar when presenting context menu
+            .onChange(of: showContextMenu) { newValue in
+                model.hideNavigationBar.accept(newValue)
             }
-        }
-        .overlay(showContextMenu && contextMenuModel.presentingMessage != nil ? makeOverlay() : nil)
-        // hide navigation bar when presenting context menu
-        .onChange(of: showContextMenu) { newValue in
-            model.hideNavigationBar.accept(newValue)
-        }
-        // hide context menu overly when device is rotated
-        .onReceive(NotificationCenter.default.publisher(for: UIDevice.orientationDidChangeNotification)) { _ in
-            if screenHeight != UIScreen.main.bounds.size.height && screenHeight != 0 {
+            // hide context menu overly when device is rotated
+            .onReceive(NotificationCenter.default.publisher(for: UIDevice.orientationDidChangeNotification)) { _ in
+                if screenHeight != UIScreen.main.bounds.size.height && screenHeight != 0 {
+                    screenHeight = UIScreen.main.bounds.size.height
+                    showContextMenu = false
+                }
+            }
+            .onAppear(perform: {
                 screenHeight = UIScreen.main.bounds.size.height
-                showContextMenu = false
+            })
+            if model.shouldShowMap {
+                LocationSharingView(model: model, coordinates: $model.coordinates)
             }
         }
-        .onAppear(perform: {
-            screenHeight = UIScreen.main.bounds.size.height
-        })
     }
 
     func makeOverlay() -> some View {
diff --git a/Ring/Ring/Services/ConversationsManager.swift b/Ring/Ring/Services/ConversationsManager.swift
index ec277819790149ec15cb22e043f43bd2c70b1193..b52368c1d8b741ea99ead2207ad0b2cf5d7812c3 100644
--- a/Ring/Ring/Services/ConversationsManager.swift
+++ b/Ring/Ring/Services/ConversationsManager.swift
@@ -3,6 +3,7 @@
  *
  *  Author: Kateryna Kostiuk <kateryna.kostiuk@savoirfairelinux.com>
  *  Author: Raphaël Brulé <raphael.brule@savoirfairelinux.com>
+ * Author: Alireza Toghiani Khorasgani alireza.toghiani@savoirfairelinux.com *
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -72,10 +73,7 @@ class ConversationsManager {
         self.subscribeFileTransferEvents()
         self.subscribeCallsEvents()
         self.subscribeContactsEvents()
-        // TODO: fix location sharing with a new API
-        if false {
-            self.subscribeLocationSharingEvent()
-        }
+        self.subscribeLocationSharingEvent()
         self.subscribeCallsProviderEvents()
         self.controlAccountsState()
     }
diff --git a/Ring/Ring/Services/LocationSharingService.swift b/Ring/Ring/Services/LocationSharingService.swift
index 833a53ddb090dede794cbaf7cfb5397d8a9b44d3..d4fde66433bf3634bb8ce5ac6324ca6732a1ece5 100644
--- a/Ring/Ring/Services/LocationSharingService.swift
+++ b/Ring/Ring/Services/LocationSharingService.swift
@@ -22,10 +22,9 @@ import RxSwift
 import RxCocoa
 import SwiftyBeaver
 
-// swiftlint:disable redundant_string_enum_value
 enum SerializableLocationTypes: String {
-    case position = "position"
-    case stop = "stop"
+    case position = "Position"
+    case stop = "Stop"
 }
 // swiftlint:enable redundant_string_enum_value
 
@@ -45,19 +44,19 @@ private class LocationSharingInstanceDictionary<T: LocationSharingInstance> {
     var isEmpty: Bool { return self.instances.isEmpty }
 
     private func key(_ accountId: String, _ contactUri: String) -> String {
-        return accountId + contactUri
+        return accountId + contactUri.replacingOccurrences(of: "ring:", with: "")
     }
 
     func get(_ accountId: String, _ contactUri: String) -> T? {
-        return self.instances[key(accountId, contactUri)]
+        return self.instances[key(accountId, contactUri.replacingOccurrences(of: "ring:", with: ""))]
     }
 
     func insertOrUpdate(_ instance: T) {
-        self.instances[key(instance.accountId, instance.contactUri)] = instance
+        self.instances[key(instance.accountId, instance.contactUri.replacingOccurrences(of: "ring:", with: ""))] = instance
     }
 
     func remove(_ accountId: String, _ contactUri: String) -> T? {
-        return self.instances.removeValue(forKey: key(accountId, contactUri))
+        return self.instances.removeValue(forKey: key(accountId, contactUri.replacingOccurrences(of: "ring:", with: "")))
     }
 
     func asArray() -> [T] {
@@ -79,6 +78,11 @@ private class OutgoingLocationSharingInstance: LocationSharingInstance {
 
     private let locationSharingService: LocationSharingService
     let duration: TimeInterval
+    var remainingTime: Int {
+        let nowTime = Date()
+        guard let sharingTime = endSharingTimer?.fireDate else { return 0 }
+        return Int(round(sharingTime.timeIntervalSince(nowTime) / 60))
+    }
 
     private var endSharingTimer: Timer?
 
@@ -136,7 +140,7 @@ class LocationSharingService: NSObject {
     private let outgoingInstances = LocationSharingInstanceDictionary<OutgoingLocationSharingInstance>()
 
     // Receiving my contact's location
-    let peerUriAndLocationReceived = BehaviorRelay<(String?, CLLocationCoordinate2D?)>(value: (nil, nil))
+    let peerUriAndLocationReceived = BehaviorRelay<(String?, CLLocationCoordinate2D?, Int?)>(value: (nil, nil, nil))
     private let incomingInstances = LocationSharingInstanceDictionary<IncomingLocationSharingInstance>()
 
     var receivingService: Disposable?
@@ -213,9 +217,17 @@ class LocationSharingService: NSObject {
 extension LocationSharingService {
 
     func isAlreadySharing(accountId: String, contactUri: String) -> Bool {
+        return self.incomingInstances.get(accountId, contactUri) != nil
+    }
+
+    func isAlreadySharingMyLocation(accountId: String, contactUri: String) -> Bool {
         return self.outgoingInstances.get(accountId, contactUri) != nil
     }
 
+    func getMyLocationSharingRemainedTime(accountId: String, contactUri: String) -> Int {
+        return Int(self.outgoingInstances.get(accountId, contactUri)?.remainingTime ?? 0)
+    }
+
     func startSharingLocation(from accountId: String, to recipientUri: String, duration: TimeInterval) {
         guard !self.isAlreadySharing(accountId: accountId, contactUri: recipientUri) else { return }
 
@@ -298,7 +310,7 @@ extension LocationSharingService {
 
         if incomingData.type == nil || incomingData.type == SerializableLocationTypes.position.rawValue {
             // TODO: altitude?
-            let peerUriAndData = (peerUri, CLLocationCoordinate2D(latitude: incomingData.lat!, longitude: incomingData.long!))
+            let peerUriAndData = (peerUri, CLLocationCoordinate2D(latitude: incomingData.lat!, longitude: incomingData.long!), Int(incomingData.time) / 60000)
             self.peerUriAndLocationReceived.accept(peerUriAndData)
 
         } else if incomingData.type == SerializableLocationTypes.stop.rawValue {
@@ -307,7 +319,7 @@ extension LocationSharingService {
     }
 
     func stopReceivingLocation(accountId: String, contactUri: String) {
-        self.peerUriAndLocationReceived.accept((contactUri, nil))
+        self.peerUriAndLocationReceived.accept((contactUri, nil, nil))
 
         self.triggerDeleteLocation(accountId: accountId, peerUri: contactUri, incoming: true, shouldRefreshConversations: true)
 
diff --git a/Ring/WhirlyGlobeMaply b/Ring/WhirlyGlobeMaply
deleted file mode 160000
index 07a710bf6deffda8222a7a7864eb855e95aa73b3..0000000000000000000000000000000000000000
--- a/Ring/WhirlyGlobeMaply
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 07a710bf6deffda8222a7a7864eb855e95aa73b3
diff --git a/Ring/fetch-dependencies.sh b/Ring/fetch-dependencies.sh
index 3e2c2ecbb6d8dd89a93eb7c28b0e978aa343fc45..6dc4250305743c9bd274bf176f9e4d1e0057e61b 100755
--- a/Ring/fetch-dependencies.sh
+++ b/Ring/fetch-dependencies.sh
@@ -6,11 +6,3 @@
 
 # Bootstrap Carthage
 carthage bootstrap --use-xcframeworks --platform iOS --no-use-binaries --cache-builds
-
-############################################
-## DOWNLOAD WHIRLYGLOBEMAPLY DEPENDENCIES ##
-############################################
-
-cd WhirlyGlobeMaply
-git submodule init
-git submodule update