Merge pull request #6232 from vector-im/maximee/6202_lls_improve_detection_pin_drop

[Location sharing] Improve detection of user panning on the map (PSF-1050)
This commit is contained in:
MaximeEvrard42 2022-06-02 17:31:50 +02:00 committed by GitHub
commit cf556e2592
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 33 additions and 16 deletions

View file

@ -39,6 +39,7 @@ enum LocationSharingViewAction {
case goToUserLocation case goToUserLocation
case startLiveSharing case startLiveSharing
case shareLiveLocation(timeout: LiveLocationSharingTimeout) case shareLiveLocation(timeout: LiveLocationSharingTimeout)
case userDidPan
} }
enum LocationSharingViewModelResult { enum LocationSharingViewModelResult {
@ -70,9 +71,7 @@ struct LocationSharingViewState: BindableState {
var highlightedAnnotation: LocationAnnotation? var highlightedAnnotation: LocationAnnotation?
/// Indicates whether the user has moved around the map to drop a pin somewhere other than their current location /// Indicates whether the user has moved around the map to drop a pin somewhere other than their current location
var isPinDropSharing: Bool { var isPinDropSharing: Bool = false
return bindings.pinLocation != nil
}
var showLoadingIndicator: Bool = false var showLoadingIndicator: Bool = false

View file

@ -78,12 +78,16 @@ class LocationSharingViewModel: LocationSharingViewModelType, LocationSharingVie
completion?(.share(latitude: pinLocation.latitude, longitude: pinLocation.longitude, coordinateType: .pin)) completion?(.share(latitude: pinLocation.latitude, longitude: pinLocation.longitude, coordinateType: .pin))
case .goToUserLocation: case .goToUserLocation:
state.bindings.pinLocation = nil state.showsUserLocation = true
state.isPinDropSharing = false
case .startLiveSharing: case .startLiveSharing:
self.startLiveLocationSharing() self.startLiveLocationSharing()
case .shareLiveLocation(let timeout): case .shareLiveLocation(let timeout):
state.bindings.showingTimerSelector = false state.bindings.showingTimerSelector = false
completion?(.shareLiveLocation(timeout: timeout.rawValue)) completion?(.shareLiveLocation(timeout: timeout.rawValue))
case .userDidPan:
state.showsUserLocation = false
state.isPinDropSharing = true
} }
} }

View file

@ -59,12 +59,18 @@ struct LocationSharingMapView: UIViewRepresentable {
/// Publish view errors if any /// Publish view errors if any
let errorSubject: PassthroughSubject<LocationSharingViewError, Never> let errorSubject: PassthroughSubject<LocationSharingViewError, Never>
/// Called when the user pan on the map
var userDidPan: (() -> Void)?
// MARK: - UIViewRepresentable // MARK: - UIViewRepresentable
func makeUIView(context: Context) -> MGLMapView { func makeUIView(context: Context) -> MGLMapView {
let mapView = self.makeMapView() let mapView = self.makeMapView()
mapView.delegate = context.coordinator mapView.delegate = context.coordinator
let panGesture = UIPanGestureRecognizer(target: context.coordinator, action: #selector(context.coordinator.didPan))
panGesture.delegate = context.coordinator
mapView.addGestureRecognizer(panGesture)
return mapView return mapView
} }
@ -77,7 +83,7 @@ struct LocationSharingMapView: UIViewRepresentable {
mapView.setCenter(highlightedAnnotation.coordinate, zoomLevel: Constants.mapZoomLevel, animated: false) mapView.setCenter(highlightedAnnotation.coordinate, zoomLevel: Constants.mapZoomLevel, animated: false)
} }
if self.showsUserLocation && mapCenterCoordinate == nil { if self.showsUserLocation {
mapView.showsUserLocation = true mapView.showsUserLocation = true
mapView.userTrackingMode = .follow mapView.userTrackingMode = .follow
} else { } else {
@ -106,7 +112,7 @@ struct LocationSharingMapView: UIViewRepresentable {
@available(iOS 14, *) @available(iOS 14, *)
extension LocationSharingMapView { extension LocationSharingMapView {
class Coordinator: NSObject, MGLMapViewDelegate { class Coordinator: NSObject, MGLMapViewDelegate, UIGestureRecognizerDelegate {
// MARK: - Properties // MARK: - Properties
@ -126,7 +132,7 @@ extension LocationSharingMapView {
return LocationAnnotationView(userLocationAnnotation: userLocationAnnotation) return LocationAnnotationView(userLocationAnnotation: userLocationAnnotation)
} else if let pinLocationAnnotation = annotation as? PinLocationAnnotation { } else if let pinLocationAnnotation = annotation as? PinLocationAnnotation {
return LocationAnnotationView(pinLocationAnnotation: pinLocationAnnotation) return LocationAnnotationView(pinLocationAnnotation: pinLocationAnnotation)
} else if annotation is MGLUserLocation && locationSharingMapView.mapCenterCoordinate == nil, let currentUserAvatarData = locationSharingMapView.userAvatarData { } else if annotation is MGLUserLocation, let currentUserAvatarData = locationSharingMapView.userAvatarData {
// Replace default current location annotation view with a UserLocationAnnotatonView when the map is center on user location // Replace default current location annotation view with a UserLocationAnnotatonView when the map is center on user location
return LocationAnnotationView(avatarData: currentUserAvatarData) return LocationAnnotationView(avatarData: currentUserAvatarData)
} }
@ -158,13 +164,7 @@ extension LocationSharingMapView {
} }
func mapView(_ mapView: MGLMapView, regionDidChangeAnimated animated: Bool) { func mapView(_ mapView: MGLMapView, regionDidChangeAnimated animated: Bool) {
let mapCenterCoordinate = mapView.centerCoordinate locationSharingMapView.mapCenterCoordinate = mapView.centerCoordinate
// Prevent this function to set pinLocation when the map is openning
guard let userLocation = locationSharingMapView.userLocation,
!userLocation.isEqual(to: mapCenterCoordinate, precision: 0.0000000001) else {
return
}
locationSharingMapView.mapCenterCoordinate = mapCenterCoordinate
} }
// MARK: Callout // MARK: Callout
@ -182,11 +182,21 @@ extension LocationSharingMapView {
} }
func mapView(_ mapView: MGLMapView, tapOnCalloutFor annotation: MGLAnnotation) { func mapView(_ mapView: MGLMapView, tapOnCalloutFor annotation: MGLAnnotation) {
locationSharingMapView.onCalloutTap?(annotation) locationSharingMapView.onCalloutTap?(annotation)
// Hide the callout // Hide the callout
mapView.deselectAnnotation(annotation, animated: true) mapView.deselectAnnotation(annotation, animated: true)
} }
// MARK: UIGestureRecognizer
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return gestureRecognizer is UIPanGestureRecognizer
}
@objc
func didPan() {
locationSharingMapView.userDidPan?()
}
} }
} }

View file

@ -76,7 +76,10 @@ struct LocationSharingView: View {
showsUserLocation: context.viewState.showsUserLocation, showsUserLocation: context.viewState.showsUserLocation,
userLocation: $context.userLocation, userLocation: $context.userLocation,
mapCenterCoordinate: $context.pinLocation, mapCenterCoordinate: $context.pinLocation,
errorSubject: context.viewState.errorSubject) errorSubject: context.viewState.errorSubject,
userDidPan: {
context.send(viewAction: .userDidPan)
})
if context.viewState.isPinDropSharing { if context.viewState.isPinDropSharing {
LocationSharingMarkerView(backgroundColor: theme.colors.accent) { LocationSharingMarkerView(backgroundColor: theme.colors.accent) {
Image(uiImage: Asset.Images.locationPinIcon.image) Image(uiImage: Asset.Images.locationPinIcon.image)

1
changelog.d/6202.bugfix Normal file
View file

@ -0,0 +1 @@
Location sharing: Improve automatic detection of pin drop state