From c99d257b7407d6c95afc65506bf0757f6a93318e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rapha=C3=ABl=20Brul=C3=A9?=
 <raphael.brule@savoirfairelinux.com>
Date: Thu, 13 Aug 2020 13:34:36 -0400
Subject: [PATCH] location sharing: ui improvements

Each location sharing bubble shows both users of
the conversation if both are sharing location at
the same time.

Change-Id: Iea6fc4ae790b1c786434a634cd506990f4bbbdc5
---
 .../Cells/MessageCellLocationSharing.swift    | 10 +++--
 .../MessageCellLocationSharingReceived.swift  | 37 ++++++++++++++----
 .../MessageCellLocationSharingSent.swift      | 39 +++++++++++++++----
 .../Conversation/ConversationViewModel.swift  |  3 +-
 .../Services/LocationSharingService.swift     |  3 ++
 5 files changed, 73 insertions(+), 19 deletions(-)

diff --git a/Ring/Ring/Features/Conversations/Conversation/Cells/MessageCellLocationSharing.swift b/Ring/Ring/Features/Conversations/Conversation/Cells/MessageCellLocationSharing.swift
index 88aee01ea..e17626169 100644
--- a/Ring/Ring/Features/Conversations/Conversation/Cells/MessageCellLocationSharing.swift
+++ b/Ring/Ring/Features/Conversations/Conversation/Cells/MessageCellLocationSharing.swift
@@ -24,6 +24,8 @@ 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()
 
@@ -159,9 +161,11 @@ extension MessageCellLocationSharing {
                                  imageData: Data?,
                                  username: String?,
                                  marker: MaplyScreenMarker,
-                                 markerDump: MaplyComponentObject?) -> MaplyComponentObject? {
+                                 markerDump: MaplyComponentObject?,
+                                 tryToAnimateToMarker: Bool = true) -> MaplyComponentObject? {
         // only the first time
-        if markerDump != nil {
+        if markerDump == nil {
+            marker.layoutImportance = MAXFLOAT
             if let imageData = imageData, let circledImage = UIImage(data: imageData)?.circleMasked {
                 marker.image = circledImage
             } else {
@@ -183,7 +187,7 @@ extension MessageCellLocationSharing {
             }
             dumpToReturn = self.maplyViewController!.addScreenMarkers([marker], desc: nil)
 
-            if !locationTapped.value.1 {
+            if tryToAnimateToMarker && !locationTapped.value.1 {
                 mapViewC.animate(toPosition: maplyCoordonate, time: 0.1)
             }
         }
diff --git a/Ring/Ring/Features/Conversations/Conversation/Cells/MessageCellLocationSharingReceived.swift b/Ring/Ring/Features/Conversations/Conversation/Cells/MessageCellLocationSharingReceived.swift
index b6abef26c..28803428f 100644
--- a/Ring/Ring/Features/Conversations/Conversation/Cells/MessageCellLocationSharingReceived.swift
+++ b/Ring/Ring/Features/Conversations/Conversation/Cells/MessageCellLocationSharingReceived.swift
@@ -23,8 +23,10 @@ import Reusable
 
 class MessageCellLocationSharingReceived: MessageCellLocationSharing {
 
-    private var myContactsLocationMarker = MaplyScreenMarker()
-    private var markerComponentObject: MaplyComponentObject?
+    /// 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!
@@ -32,15 +34,36 @@ class MessageCellLocationSharingReceived: MessageCellLocationSharing {
     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.markerComponentObject = self.updateLocationAndMarker(location: location,
-                                                                                    imageData: conversationViewModel?.profileImageData.value,
-                                                                                    username: conversationViewModel?.userName.value,
-                                                                                    marker: self.myContactsLocationMarker,
-                                                                                    markerDump: self.markerComponentObject)
+                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)
     }
diff --git a/Ring/Ring/Features/Conversations/Conversation/Cells/MessageCellLocationSharingSent.swift b/Ring/Ring/Features/Conversations/Conversation/Cells/MessageCellLocationSharingSent.swift
index 78a3777ce..7ca933235 100644
--- a/Ring/Ring/Features/Conversations/Conversation/Cells/MessageCellLocationSharingSent.swift
+++ b/Ring/Ring/Features/Conversations/Conversation/Cells/MessageCellLocationSharingSent.swift
@@ -24,8 +24,10 @@ import RxCocoa
 
 class MessageCellLocationSharingSent: MessageCellLocationSharing {
 
-    private var myLocationMarker = MaplyScreenMarker()
-    private var markerComponentObject: MaplyComponentObject?
+    /// 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!
 
@@ -37,15 +39,36 @@ class MessageCellLocationSharingSent: MessageCellLocationSharing {
     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.markerComponentObject = self.updateLocationAndMarker(location: location,
-                                                                          imageData: conversationViewModel?.myOwnProfileImageData,
-                                                                          username: conversationViewModel?.userName.value,
-                                                                          marker: self.myLocationMarker,
-                                                                          markerDump: self.markerComponentObject)
+                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)
 
@@ -61,7 +84,7 @@ class MessageCellLocationSharingSent: MessageCellLocationSharing {
 
     override func myPositionButtonAction(sender: UIButton!) {
         if let mapViewC = self.maplyViewController as? MaplyViewController {
-            mapViewC.animate(toPosition: self.myLocationMarker.loc, time: 0.5)
+            mapViewC.animate(toPosition: self.myLocation.marker.loc, time: 0.5)
         }
     }
 
diff --git a/Ring/Ring/Features/Conversations/Conversation/ConversationViewModel.swift b/Ring/Ring/Features/Conversations/Conversation/ConversationViewModel.swift
index c791050cb..79a41f7f8 100644
--- a/Ring/Ring/Features/Conversations/Conversation/ConversationViewModel.swift
+++ b/Ring/Ring/Features/Conversations/Conversation/ConversationViewModel.swift
@@ -111,7 +111,8 @@ class ConversationViewModel: Stateable, ViewModel {
         self.locationSharingService
             .peerUriAndLocationReceived
             .subscribe(onNext: { [weak self] tuple in
-                guard let self = self, let peerUri = tuple.0, let coordinates = tuple.1, let conversation = self.conversation else { return }
+                guard let self = self, let peerUri = tuple.0, let conversation = self.conversation else { return }
+                let coordinates = tuple.1
                 if peerUri == conversation.value.participantUri {
                     self.myContactsLocation.onNext(coordinates)
                 }
diff --git a/Ring/Ring/Services/LocationSharingService.swift b/Ring/Ring/Services/LocationSharingService.swift
index 363c7edae..f574db8f9 100644
--- a/Ring/Ring/Services/LocationSharingService.swift
+++ b/Ring/Ring/Services/LocationSharingService.swift
@@ -250,6 +250,7 @@ extension LocationSharingService {
 
         if self.outgoingInstances.isEmpty {
             self.locationManager.stopUpdatingLocation()
+            self.currentLocation.accept(nil)
         }
 
         self.triggerDeleteLocation(accountId: accountId, peerUri: contactUri, incoming: false, shouldRefreshConversations: true)
@@ -304,6 +305,8 @@ extension LocationSharingService {
     }
 
     func stopReceivingLocation(accountId: String, contactUri: String) {
+        self.peerUriAndLocationReceived.accept((contactUri, nil))
+
         self.triggerDeleteLocation(accountId: accountId, peerUri: contactUri, incoming: true, shouldRefreshConversations: true)
 
         _ = self.incomingInstances.remove(accountId, contactUri)
-- 
GitLab