Location picker fixes

This commit is contained in:
Ilya Laktyushin
2019-11-26 21:14:58 +04:00
parent 3b931cfd96
commit f4dcc9cb92
27 changed files with 4197 additions and 3784 deletions

View File

@@ -10,6 +10,8 @@ import TelegramPresentationData
import AccountContext
import AppBundle
import CoreLocation
import PresentationDataUtils
import DeviceAccess
public enum LocationPickerMode {
case share(peer: Peer?, selfPeer: Peer?, hasLiveLocation: Bool)
@@ -23,24 +25,28 @@ class LocationPickerInteraction {
let toggleMapModeSelection: () -> Void
let updateMapMode: (LocationMapMode) -> Void
let goToUserLocation: () -> Void
let goToCoordinate: (CLLocationCoordinate2D) -> Void
let openSearch: () -> Void
let updateSearchQuery: (String) -> Void
let dismissSearch: () -> Void
let dismissInput: () -> Void
let updateSendActionHighlight: (Bool) -> Void
let openHomeWorkInfo: () -> Void
init(sendLocation: @escaping (CLLocationCoordinate2D) -> Void, sendLiveLocation: @escaping (CLLocationCoordinate2D) -> Void, sendVenue: @escaping (TelegramMediaMap) -> Void, toggleMapModeSelection: @escaping () -> Void, updateMapMode: @escaping (LocationMapMode) -> Void, goToUserLocation: @escaping () -> Void, openSearch: @escaping () -> Void, updateSearchQuery: @escaping (String) -> Void, dismissSearch: @escaping () -> Void, dismissInput: @escaping () -> Void, updateSendActionHighlight: @escaping (Bool) -> Void) {
init(sendLocation: @escaping (CLLocationCoordinate2D) -> Void, sendLiveLocation: @escaping (CLLocationCoordinate2D) -> Void, sendVenue: @escaping (TelegramMediaMap) -> Void, toggleMapModeSelection: @escaping () -> Void, updateMapMode: @escaping (LocationMapMode) -> Void, goToUserLocation: @escaping () -> Void, goToCoordinate: @escaping (CLLocationCoordinate2D) -> Void, openSearch: @escaping () -> Void, updateSearchQuery: @escaping (String) -> Void, dismissSearch: @escaping () -> Void, dismissInput: @escaping () -> Void, updateSendActionHighlight: @escaping (Bool) -> Void, openHomeWorkInfo: @escaping () -> Void) {
self.sendLocation = sendLocation
self.sendLiveLocation = sendLiveLocation
self.sendVenue = sendVenue
self.toggleMapModeSelection = toggleMapModeSelection
self.updateMapMode = updateMapMode
self.goToUserLocation = goToUserLocation
self.goToCoordinate = goToCoordinate
self.openSearch = openSearch
self.updateSearchQuery = updateSearchQuery
self.dismissSearch = dismissSearch
self.dismissInput = dismissInput
self.updateSendActionHighlight = updateSendActionHighlight
self.openHomeWorkInfo = openHomeWorkInfo
}
}
@@ -56,6 +62,10 @@ public final class LocationPickerController: ViewController {
private var presentationDataDisposable: Disposable?
private var searchNavigationContentNode: LocationSearchNavigationContentNode?
private var isSearchingDisposable = MetaDisposable()
private let locationManager = CLLocationManager()
private var permissionDisposable: Disposable?
private var interaction: LocationPickerInteraction?
@@ -88,6 +98,29 @@ public final class LocationPickerController: ViewController {
strongSelf.controllerNode.updatePresentationData(presentationData)
})
self.permissionDisposable = (DeviceAccess.authorizationStatus(subject: .location(.send))
|> deliverOnMainQueue).start(next: { [weak self] next in
guard let strongSelf = self else {
return
}
switch next {
case .notDetermined:
DeviceAccess.authorizeAccess(to: .location(.send), locationManager: strongSelf.locationManager, presentationData: strongSelf.presentationData, present: { c, a in
strongSelf.present(c, in: .window(.root), with: a)
}, openSettings: {
strongSelf.context.sharedContext.applicationBindings.openSettings()
})
case .denied:
strongSelf.controllerNode.updateState { state in
var state = state
state.forceSelection = true
return state
}
default:
break
}
})
let locationWithTimeout: (CLLocationCoordinate2D, Int32?) -> TelegramMediaMap = { coordinate, timeout in
return TelegramMediaMap(latitude: coordinate.latitude, longitude: coordinate.longitude, geoPlace: nil, venue: nil, liveBroadcastingTimeout: timeout)
}
@@ -143,7 +176,12 @@ public final class LocationPickerController: ViewController {
guard let strongSelf = self else {
return
}
completion(venue, nil)
let venueType = venue.venue?.type ?? ""
if ["home", "work"].contains(venueType) {
completion(TelegramMediaMap(latitude: venue.latitude, longitude: venue.longitude, geoPlace: nil, venue: nil, liveBroadcastingTimeout: nil), nil)
} else {
completion(venue, nil)
}
strongSelf.dismiss()
}, toggleMapModeSelection: { [weak self] in
guard let strongSelf = self else {
@@ -174,6 +212,16 @@ public final class LocationPickerController: ViewController {
state.selectedLocation = .none
return state
}
}, goToCoordinate: { [weak self] coordinate in
guard let strongSelf = self else {
return
}
strongSelf.controllerNode.updateState { state in
var state = state
state.displayingMapModeOptions = false
state.selectedLocation = .location(coordinate, nil)
return state
}
}, openSearch: { [weak self] in
guard let strongSelf = self, let interaction = strongSelf.interaction, let navigationBar = strongSelf.navigationBar else {
return
@@ -186,8 +234,15 @@ public final class LocationPickerController: ViewController {
let contentNode = LocationSearchNavigationContentNode(presentationData: strongSelf.presentationData, interaction: interaction)
strongSelf.searchNavigationContentNode = contentNode
navigationBar.setContentNode(contentNode, animated: true)
strongSelf.controllerNode.activateSearch(navigationBar: navigationBar)
let isSearching = strongSelf.controllerNode.activateSearch(navigationBar: navigationBar)
contentNode.activate()
strongSelf.isSearchingDisposable.set((isSearching
|> deliverOnMainQueue).start(next: { [weak self] value in
if let strongSelf = self, let searchNavigationContentNode = strongSelf.searchNavigationContentNode {
searchNavigationContentNode.updateActivity(value)
}
}))
}, updateSearchQuery: { [weak self] query in
guard let strongSelf = self else {
return
@@ -197,6 +252,7 @@ public final class LocationPickerController: ViewController {
guard let strongSelf = self, let navigationBar = strongSelf.navigationBar else {
return
}
strongSelf.isSearchingDisposable.set(nil)
strongSelf.searchNavigationContentNode?.deactivate()
strongSelf.searchNavigationContentNode = nil
navigationBar.setContentNode(nil, animated: true)
@@ -211,6 +267,13 @@ public final class LocationPickerController: ViewController {
return
}
strongSelf.controllerNode.updateSendActionHighlight(highlighted)
}, openHomeWorkInfo: { [weak self] in
guard let strongSelf = self else {
return
}
let controller = textAlertController(context: strongSelf.context, title: strongSelf.presentationData.strings.Map_HomeAndWorkTitle, text: strongSelf.presentationData.strings.Map_HomeAndWorkInfo, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {})])
strongSelf.present(controller, in: .window(.root))
})
self.scrollToTop = { [weak self] in
@@ -228,6 +291,8 @@ public final class LocationPickerController: ViewController {
deinit {
self.presentationDataDisposable?.dispose()
self.permissionDisposable?.dispose()
self.isSearchingDisposable.dispose()
}
override public func loadDisplayNode() {