Attachment menu improvements

This commit is contained in:
Ilya Laktyushin
2022-02-27 04:07:09 +04:00
parent 82104445dd
commit 7b8c90fbdc
17 changed files with 337 additions and 69 deletions

View File

@@ -240,7 +240,44 @@ struct LocationPickerState {
}
}
private class LocationContext: NSObject, CLLocationManagerDelegate {
private let locationManager: CLLocationManager
private let accessSink = ValuePipe<CLAuthorizationStatus>()
override init() {
self.locationManager = CLLocationManager()
super.init()
self.locationManager.delegate = self
}
func locationAccess() -> Signal<CLAuthorizationStatus, NoError> {
let initialStatus: CLAuthorizationStatus
if #available(iOS 14.0, *) {
initialStatus = self.locationManager.authorizationStatus
} else {
initialStatus = CLLocationManager.authorizationStatus()
}
return .single(initialStatus)
|> then(
self.accessSink.signal()
)
}
@available(iOS 14.0, *)
func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
self.accessSink.putNext(manager.authorizationStatus)
}
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
self.accessSink.putNext(status)
}
}
final class LocationPickerControllerNode: ViewControllerTracingNode, CLLocationManagerDelegate {
private weak var controller: LocationPickerController?
private let context: AccountContext
private var presentationData: PresentationData
private let presentationDataPromise: Promise<PresentationData>
@@ -248,6 +285,8 @@ final class LocationPickerControllerNode: ViewControllerTracingNode, CLLocationM
private let interaction: LocationPickerInteraction
private let locationManager: LocationManager
private let locationContext: LocationContext
private let listNode: ListView
private let emptyResultsTextNode: ImmediateTextNode
private let headerNode: LocationMapHeaderNode
@@ -257,6 +296,10 @@ final class LocationPickerControllerNode: ViewControllerTracingNode, CLLocationM
private let optionsNode: LocationOptionsNode
private(set) var searchContainerNode: LocationSearchContainerNode?
private var placeholderBackgroundNode: NavigationBackgroundNode?
private var placeholderNode: LocationPlaceholderNode?
private var locationAccessDenied = true
private var enqueuedTransitions: [LocationPickerTransaction] = []
private var disposable: Disposable?
@@ -271,7 +314,8 @@ final class LocationPickerControllerNode: ViewControllerTracingNode, CLLocationM
var beganInteractiveDragging: () -> Void = {}
init(context: AccountContext, presentationData: PresentationData, mode: LocationPickerMode, interaction: LocationPickerInteraction, locationManager: LocationManager) {
init(controller: LocationPickerController, context: AccountContext, presentationData: PresentationData, mode: LocationPickerMode, interaction: LocationPickerInteraction, locationManager: LocationManager) {
self.controller = controller
self.context = context
self.presentationData = presentationData
self.presentationDataPromise = Promise(presentationData)
@@ -279,6 +323,8 @@ final class LocationPickerControllerNode: ViewControllerTracingNode, CLLocationM
self.interaction = interaction
self.locationManager = locationManager
self.locationContext = LocationContext()
self.state = LocationPickerState()
self.statePromise = Promise(self.state)
@@ -448,8 +494,8 @@ final class LocationPickerControllerNode: ViewControllerTracingNode, CLLocationM
let previousAnnotations = Atomic<[LocationPinAnnotation]>(value: [])
let previousEntries = Atomic<[LocationPickerEntry]?>(value: nil)
self.disposable = (combineLatest(self.presentationDataPromise.get(), self.statePromise.get(), userLocation, venues, foundVenues)
|> deliverOnMainQueue).start(next: { [weak self] presentationData, state, userLocation, venues, foundVenuesAndLocation in
self.disposable = (combineLatest(self.presentationDataPromise.get(), self.statePromise.get(), userLocation, venues, foundVenues, self.locationContext.locationAccess())
|> deliverOnMainQueue).start(next: { [weak self] presentationData, state, userLocation, venues, foundVenuesAndLocation, access in
if let strongSelf = self {
let (foundVenues, foundVenuesLocation) = foundVenuesAndLocation ?? (nil, nil)
@@ -589,6 +635,18 @@ final class LocationPickerControllerNode: ViewControllerTracingNode, CLLocationM
if let (layout, navigationBarHeight) = strongSelf.validLayout {
var updateLayout = false
let transition: ContainedViewLayoutTransition = .animated(duration: 0.45, curve: .spring)
if [.denied, .restricted].contains(access) {
if !strongSelf.locationAccessDenied {
strongSelf.locationAccessDenied = true
updateLayout = true
}
} else {
if strongSelf.locationAccessDenied {
strongSelf.locationAccessDenied = false
updateLayout = true
}
}
if previousState.displayingMapModeOptions != state.displayingMapModeOptions {
updateLayout = true
@@ -892,6 +950,49 @@ final class LocationPickerControllerNode: ViewControllerTracingNode, CLLocationM
searchContainerNode.frame = CGRect(origin: CGPoint(), size: layout.size)
searchContainerNode.containerLayoutUpdated(ContainerViewLayout(size: layout.size, metrics: LayoutMetrics(), deviceMetrics: layout.deviceMetrics, intrinsicInsets: layout.intrinsicInsets, safeInsets: layout.safeInsets, additionalInsets: layout.additionalInsets, statusBarHeight: nil, inputHeight: layout.inputHeight, inputHeightIsInteractivellyChanging: layout.inputHeightIsInteractivellyChanging, inVoiceOver: layout.inVoiceOver), navigationBarHeight: navigationHeight, transition: transition)
}
if self.locationAccessDenied {
self.controller?.navigationBar?.updateBackgroundAlpha(0.0, transition: .immediate)
Queue.mainQueue().after(0.2) {
self.controller?.updateTabBarAlpha(0.0, .immediate)
}
var placeholderTransition = transition
let placeholderNode: LocationPlaceholderNode
let backgroundNode: NavigationBackgroundNode
if let current = self.placeholderNode, let background = self.placeholderBackgroundNode {
placeholderNode = current
backgroundNode = background
backgroundNode.updateColor(color: self.presentationData.theme.rootController.tabBar.backgroundColor, transition: .immediate)
} else {
backgroundNode = NavigationBackgroundNode(color: self.presentationData.theme.rootController.tabBar.backgroundColor)
if let navigationBar = self.controller?.navigationBar {
self.insertSubnode(backgroundNode, belowSubnode: navigationBar)
} else {
self.addSubnode(backgroundNode)
}
self.placeholderBackgroundNode = backgroundNode
placeholderNode = LocationPlaceholderNode(content: .intro)
placeholderNode.settingsPressed = { [weak self] in
self?.context.sharedContext.applicationBindings.openSettings()
}
self.insertSubnode(placeholderNode, aboveSubnode: backgroundNode)
self.placeholderNode = placeholderNode
placeholderTransition = .immediate
}
placeholderNode.update(layout: layout, theme: self.presentationData.theme, strings: self.presentationData.strings, transition: placeholderTransition)
placeholderTransition.updateFrame(node: placeholderNode, frame: CGRect(origin: CGPoint(), size: layout.size))
let placeholderFrame = CGRect(origin: CGPoint(), size: layout.size)
backgroundNode.update(size: placeholderFrame.size, transition: placeholderTransition)
placeholderTransition.updateFrame(node: placeholderNode, frame: placeholderFrame)
} else if let placeholderNode = self.placeholderNode {
self.placeholderNode = nil
placeholderNode.removeFromSupernode()
}
}
func updateSendActionHighlight(_ highlighted: Bool) {