vector-im/element-ios/issues/5298 - Displaying a modal when tapping on a location in the timeline.

This commit is contained in:
Stefan Ceriu
2021-12-20 17:33:59 +02:00
committed by Stefan Ceriu
parent 17f9639173
commit 2ef67f3ed2
11 changed files with 110 additions and 65 deletions
@@ -23,7 +23,8 @@ struct LocationSharingCoordinatorParameters {
let navigationRouter: NavigationRouterType
let roomDataSource: MXKRoomDataSource
let mediaManager: MXMediaManager
let user: MXUser
let avatarData: AvatarInputProtocol
let location: CLLocationCoordinate2D?
}
final class LocationSharingCoordinator: Coordinator {
@@ -51,12 +52,10 @@ final class LocationSharingCoordinator: Coordinator {
@available(iOS 14.0, *)
init(parameters: LocationSharingCoordinatorParameters) {
self.parameters = parameters
let avatarData = AvatarInput(mxContentUri: parameters.user.avatarUrl,
matrixItemId: parameters.user.userId,
displayName: parameters.user.displayname)
let viewModel = LocationSharingViewModel(tileServerMapURL: BuildSettings.tileServerMapURL, avatarData: avatarData)
let viewModel = LocationSharingViewModel(tileServerMapURL: BuildSettings.tileServerMapURL,
avatarData: parameters.avatarData,
location: parameters.location)
let view = LocationSharingView(context: viewModel.context)
.addDependency(AvatarService.instantiate(mediaManager: parameters.mediaManager))
@@ -48,8 +48,17 @@ enum LocationSharingViewModelResult {
struct LocationSharingViewState: BindableState {
let tileServerMapURL: URL
let avatarData: AvatarInputProtocol
var shareButtonEnabled: Bool = true
let location: CLLocationCoordinate2D?
var showLoadingIndicator: Bool = false
var shareButtonVisible: Bool {
(location == nil)
}
var shareButtonEnabled: Bool {
!showLoadingIndicator
}
let errorSubject = PassthroughSubject<LocationSharingViewError, Never>()
@@ -30,18 +30,13 @@ class LocationSharingViewModel: LocationSharingViewModelType {
// MARK: Public
let tileServerMapURL: URL
let avatarData: AvatarInputProtocol
var completion: ((LocationSharingViewModelResult) -> Void)?
// MARK: - Setup
init(tileServerMapURL: URL, avatarData: AvatarInputProtocol) {
self.tileServerMapURL = tileServerMapURL
self.avatarData = avatarData
super.init(initialViewState: LocationSharingViewState(tileServerMapURL: tileServerMapURL, avatarData: avatarData))
init(tileServerMapURL: URL, avatarData: AvatarInputProtocol, location: CLLocationCoordinate2D? = nil) {
let viewState = LocationSharingViewState(tileServerMapURL: tileServerMapURL, avatarData: avatarData, location: location)
super.init(initialViewState: viewState)
state.errorSubject.sink { [weak self] error in
guard let self = self else { return }
@@ -95,10 +90,8 @@ class LocationSharingViewModel: LocationSharingViewModelType {
case .startLoading:
state.showLoadingIndicator = true
state.shareButtonEnabled = false
case .stopLoading(let error):
state.showLoadingIndicator = false
state.shareButtonEnabled = true
if error != nil {
state.bindings.alertInfo = ErrorAlertInfo(id: .locationSharingError,
@@ -26,6 +26,8 @@ struct LocationSharingMapView: UIViewRepresentable {
let tileServerMapURL: URL
let avatarData: AvatarInputProtocol
let location: CLLocationCoordinate2D?
let errorSubject: PassthroughSubject<LocationSharingViewError, Never>
@Binding var userLocation: CLLocationCoordinate2D?
@@ -35,8 +37,17 @@ struct LocationSharingMapView: UIViewRepresentable {
mapView.logoView.isHidden = true
mapView.attributionButton.isHidden = true
mapView.showsUserLocation = true
mapView.userTrackingMode = .follow
if let location = location {
mapView.setCenter(location, zoomLevel: Constants.mapZoomLevel, animated: false)
let pointAnnotation = MGLPointAnnotation()
pointAnnotation.coordinate = location
mapView.addAnnotation(pointAnnotation)
} else {
mapView.showsUserLocation = true
mapView.userTrackingMode = .follow
}
return mapView
}
@@ -70,10 +81,6 @@ class LocationSharingMapViewCoordinator: NSObject, MGLMapViewDelegate {
// MARK: - MGLMapViewDelegate
func mapView(_ mapView: MGLMapView, viewFor annotation: MGLAnnotation) -> MGLAnnotationView? {
guard let _ = annotation as? MGLUserLocation else {
return nil
}
return UserLocationAnnotatonView(avatarData: avatarData)
}
@@ -34,6 +34,7 @@ struct LocationSharingView: View {
NavigationView {
LocationSharingMapView(tileServerMapURL: context.viewState.tileServerMapURL,
avatarData: context.viewState.avatarData,
location: context.viewState.location,
errorSubject: context.viewState.errorSubject,
userLocation: $context.userLocation)
.toolbar {
@@ -48,10 +49,12 @@ struct LocationSharingView: View {
.foregroundColor(theme.colors.primaryContent)
}
ToolbarItem(placement: .navigationBarTrailing) {
Button(VectorL10n.locationSharingShareAction, action: {
context.send(viewAction: .share)
})
.disabled(!context.viewState.shareButtonEnabled)
if context.viewState.shareButtonVisible {
Button(VectorL10n.locationSharingShareAction, action: {
context.send(viewAction: .share)
})
.disabled(!context.viewState.shareButtonEnabled)
}
}
}
.navigationBarTitleDisplayMode(.inline)