mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-03 16:10:20 +00:00
Force a stop before starting a new session and resend last location on new starts
This commit is contained in:
@@ -28,6 +28,8 @@ class LiveLocationManager: NSObject, LiveLocationManagerProtocol, CLLocationMana
|
|||||||
|
|
||||||
private var isUpdatingLocation = false
|
private var isUpdatingLocation = false
|
||||||
|
|
||||||
|
private var lastLocation: CLLocationCoordinate2D?
|
||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
init(clientProxy: ClientProxyProtocol,
|
init(clientProxy: ClientProxyProtocol,
|
||||||
appSettings: AppSettings,
|
appSettings: AppSettings,
|
||||||
@@ -76,10 +78,11 @@ class LiveLocationManager: NSObject, LiveLocationManagerProtocol, CLLocationMana
|
|||||||
}
|
}
|
||||||
|
|
||||||
func startLiveLocation(roomID: String, duration: Duration) async -> Result<Void, LiveLocationManagerError> {
|
func startLiveLocation(roomID: String, duration: Duration) async -> Result<Void, LiveLocationManagerError> {
|
||||||
// Stop any existing session for this room first (e.g. one started from a different device)
|
// Stop any existing session for this room first
|
||||||
// before starting a new one.
|
var didAlreadyStopLocalSession = false
|
||||||
if appSettings.liveLocationSharingTimeoutDatesByRoomID[roomID] != nil {
|
if appSettings.liveLocationSharingTimeoutDatesByRoomID[roomID] != nil {
|
||||||
await stopLiveLocation(roomID: roomID)
|
await stopLiveLocation(roomID: roomID)
|
||||||
|
didAlreadyStopLocalSession = true
|
||||||
}
|
}
|
||||||
|
|
||||||
guard case .joined(let roomProxy) = await clientProxy.roomForIdentifier(roomID) else {
|
guard case .joined(let roomProxy) = await clientProxy.roomForIdentifier(roomID) else {
|
||||||
@@ -87,6 +90,11 @@ class LiveLocationManager: NSObject, LiveLocationManagerProtocol, CLLocationMana
|
|||||||
return .failure(.roomNotJoined)
|
return .failure(.roomNotJoined)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !didAlreadyStopLocalSession {
|
||||||
|
// In case an existing session has been started from another device, let's try to stop it.
|
||||||
|
// It's a best effort thing, so we don't care if no session is present or if it fails.
|
||||||
|
_ = await roomProxy.stopLiveLocationShare()
|
||||||
|
}
|
||||||
let result = await roomProxy.startLiveLocationShare(duration: duration)
|
let result = await roomProxy.startLiveLocationShare(duration: duration)
|
||||||
|
|
||||||
guard case .success = result else {
|
guard case .success = result else {
|
||||||
@@ -97,6 +105,13 @@ class LiveLocationManager: NSObject, LiveLocationManagerProtocol, CLLocationMana
|
|||||||
let timeoutDate = Date().addingTimeInterval(TimeInterval(duration.seconds))
|
let timeoutDate = Date().addingTimeInterval(TimeInterval(duration.seconds))
|
||||||
appSettings.liveLocationSharingTimeoutDatesByRoomID[roomID] = timeoutDate
|
appSettings.liveLocationSharingTimeoutDatesByRoomID[roomID] = timeoutDate
|
||||||
|
|
||||||
|
if isUpdatingLocation, let lastLocation {
|
||||||
|
// To make sure the newly started session is in sync with the existing ones,
|
||||||
|
// we re-send the last location received by the manager.
|
||||||
|
// Otherwise we would need to wait a distance filtered update.
|
||||||
|
locationUpdateSubject.send(lastLocation)
|
||||||
|
}
|
||||||
|
|
||||||
return .success(())
|
return .success(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,6 +160,7 @@ class LiveLocationManager: NSObject, LiveLocationManagerProtocol, CLLocationMana
|
|||||||
|
|
||||||
MXLog.verbose("Received location update via delegate, sending to rooms")
|
MXLog.verbose("Received location update via delegate, sending to rooms")
|
||||||
locationUpdateSubject.send(location.coordinate)
|
locationUpdateSubject.send(location.coordinate)
|
||||||
|
lastLocation = location.coordinate
|
||||||
}
|
}
|
||||||
|
|
||||||
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
|
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
|
||||||
@@ -238,6 +254,7 @@ class LiveLocationManager: NSObject, LiveLocationManagerProtocol, CLLocationMana
|
|||||||
MXLog.info("Stopping live location updates")
|
MXLog.info("Stopping live location updates")
|
||||||
locationManager.stopUpdatingLocation()
|
locationManager.stopUpdatingLocation()
|
||||||
isUpdatingLocation = false
|
isUpdatingLocation = false
|
||||||
|
lastLocation = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
private func sendLocationToActiveRooms(_ coordinate: CLLocationCoordinate2D) async {
|
private func sendLocationToActiveRooms(_ coordinate: CLLocationCoordinate2D) async {
|
||||||
|
|||||||
@@ -28,16 +28,25 @@ final class LiveLocationManagerTests {
|
|||||||
// MARK: - startLiveLocation
|
// MARK: - startLiveLocation
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
func startLiveLocationWithNoExistingSession() async throws {
|
func startLiveLocationWithNoExistingLocalSession() async throws {
|
||||||
setUp()
|
setUp()
|
||||||
let roomProxy = makeRoomProxy(roomID: "!room:matrix.org")
|
let roomProxy = makeRoomProxy(roomID: "!room:matrix.org")
|
||||||
clientProxy.roomForIdentifierClosure = { _ in .joined(roomProxy) }
|
clientProxy.roomForIdentifierClosure = { _ in .joined(roomProxy) }
|
||||||
|
|
||||||
|
var callOrder: [String] = []
|
||||||
|
roomProxy.stopLiveLocationShareClosure = {
|
||||||
|
callOrder.append("stop")
|
||||||
|
return .success(())
|
||||||
|
}
|
||||||
|
roomProxy.startLiveLocationShareDurationClosure = { _ in
|
||||||
|
callOrder.append("start")
|
||||||
|
return .success(())
|
||||||
|
}
|
||||||
|
|
||||||
let result = await manager.startLiveLocation(roomID: "!room:matrix.org", duration: .seconds(300))
|
let result = await manager.startLiveLocation(roomID: "!room:matrix.org", duration: .seconds(300))
|
||||||
|
|
||||||
try result.get()
|
try result.get()
|
||||||
#expect(roomProxy.startLiveLocationShareDurationCalled)
|
#expect(callOrder == ["stop", "start"])
|
||||||
#expect(!roomProxy.stopLiveLocationShareCalled)
|
|
||||||
#expect(appSettings.liveLocationSharingTimeoutDatesByRoomID["!room:matrix.org"] != nil)
|
#expect(appSettings.liveLocationSharingTimeoutDatesByRoomID["!room:matrix.org"] != nil)
|
||||||
#expect(locationManagerMock.startUpdatingLocationCalled)
|
#expect(locationManagerMock.startUpdatingLocationCalled)
|
||||||
}
|
}
|
||||||
@@ -76,7 +85,7 @@ final class LiveLocationManagerTests {
|
|||||||
|
|
||||||
_ = await manager.startLiveLocation(roomID: "!room1:matrix.org", duration: .seconds(300))
|
_ = await manager.startLiveLocation(roomID: "!room1:matrix.org", duration: .seconds(300))
|
||||||
|
|
||||||
#expect(!roomProxy.stopLiveLocationShareCalled)
|
#expect(roomProxy.stopLiveLocationShareCalled)
|
||||||
#expect(appSettings.liveLocationSharingTimeoutDatesByRoomID["!room2:matrix.org"] != nil)
|
#expect(appSettings.liveLocationSharingTimeoutDatesByRoomID["!room2:matrix.org"] != nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user