mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-22 22:25:57 +00:00
Location view improvements
This commit is contained in:
188
submodules/LocationUI/Sources/LocationViewController.swift
Normal file
188
submodules/LocationUI/Sources/LocationViewController.swift
Normal file
@@ -0,0 +1,188 @@
|
||||
import Foundation
|
||||
import UIKit
|
||||
import Display
|
||||
import LegacyComponents
|
||||
import TelegramCore
|
||||
import SyncCore
|
||||
import Postbox
|
||||
import SwiftSignalKit
|
||||
import TelegramPresentationData
|
||||
import AccountContext
|
||||
import AppBundle
|
||||
import CoreLocation
|
||||
import PresentationDataUtils
|
||||
import OpenInExternalAppUI
|
||||
import ShareController
|
||||
|
||||
public class LocationViewParams {
|
||||
let sendLiveLocation: (TelegramMediaMap) -> Void
|
||||
let stopLiveLocation: () -> Void
|
||||
let openUrl: (String) -> Void
|
||||
let openPeer: (Peer) -> Void
|
||||
|
||||
public init(sendLiveLocation: @escaping (TelegramMediaMap) -> Void, stopLiveLocation: @escaping () -> Void, openUrl: @escaping (String) -> Void, openPeer: @escaping (Peer) -> Void) {
|
||||
self.sendLiveLocation = sendLiveLocation
|
||||
self.stopLiveLocation = stopLiveLocation
|
||||
self.openUrl = openUrl
|
||||
self.openPeer = openPeer
|
||||
}
|
||||
}
|
||||
|
||||
class LocationViewInteraction {
|
||||
let toggleMapModeSelection: () -> Void
|
||||
let updateMapMode: (LocationMapMode) -> Void
|
||||
let goToUserLocation: () -> Void
|
||||
let goToCoordinate: (CLLocationCoordinate2D) -> Void
|
||||
let requestDirections: () -> Void
|
||||
let share: () -> Void
|
||||
|
||||
init(toggleMapModeSelection: @escaping () -> Void, updateMapMode: @escaping (LocationMapMode) -> Void, goToUserLocation: @escaping () -> Void, goToCoordinate: @escaping (CLLocationCoordinate2D) -> Void, requestDirections: @escaping () -> Void, share: @escaping () -> Void) {
|
||||
self.toggleMapModeSelection = toggleMapModeSelection
|
||||
self.updateMapMode = updateMapMode
|
||||
self.goToUserLocation = goToUserLocation
|
||||
self.goToCoordinate = goToCoordinate
|
||||
self.requestDirections = requestDirections
|
||||
self.share = share
|
||||
}
|
||||
}
|
||||
|
||||
public final class LocationViewController: ViewController {
|
||||
private var controllerNode: LocationViewControllerNode {
|
||||
return self.displayNode as! LocationViewControllerNode
|
||||
}
|
||||
private let context: AccountContext
|
||||
private var mapMedia: TelegramMediaMap
|
||||
private var presentationData: PresentationData
|
||||
private var presentationDataDisposable: Disposable?
|
||||
|
||||
private var interaction: LocationViewInteraction?
|
||||
|
||||
public init(context: AccountContext, mapMedia: TelegramMediaMap, params: LocationViewParams) {
|
||||
self.context = context
|
||||
self.mapMedia = mapMedia
|
||||
|
||||
self.presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
|
||||
super.init(navigationBarPresentationData: NavigationBarPresentationData(theme: NavigationBarTheme(rootControllerTheme: self.presentationData.theme).withUpdatedSeparatorColor(.clear), strings: NavigationBarStrings(presentationStrings: self.presentationData.strings)))
|
||||
|
||||
self.navigationPresentation = .modal
|
||||
|
||||
self.title = self.presentationData.strings.Map_LocationTitle
|
||||
self.navigationItem.leftBarButtonItem = UIBarButtonItem(title: self.presentationData.strings.Common_Close, style: .plain, target: self, action: #selector(self.cancelPressed))
|
||||
self.navigationItem.rightBarButtonItem = UIBarButtonItem(image: PresentationResourcesRootController.navigationShareIcon(self.presentationData.theme), style: .plain, target: self, action: #selector(self.sharePressed))
|
||||
self.navigationItem.rightBarButtonItem?.accessibilityLabel = self.presentationData.strings.VoiceOver_MessageContextShare
|
||||
|
||||
self.presentationDataDisposable = (context.sharedContext.presentationData
|
||||
|> deliverOnMainQueue).start(next: { [weak self] presentationData in
|
||||
guard let strongSelf = self, strongSelf.presentationData.theme !== presentationData.theme else {
|
||||
return
|
||||
}
|
||||
strongSelf.presentationData = presentationData
|
||||
|
||||
strongSelf.navigationBar?.updatePresentationData(NavigationBarPresentationData(theme: NavigationBarTheme(rootControllerTheme: strongSelf.presentationData.theme).withUpdatedSeparatorColor(.clear), strings: NavigationBarStrings(presentationStrings: strongSelf.presentationData.strings)))
|
||||
|
||||
strongSelf.navigationItem.rightBarButtonItem = UIBarButtonItem(image: PresentationResourcesRootController.navigationShareIcon(strongSelf.presentationData.theme), style: .plain, target: strongSelf, action: #selector(strongSelf.sharePressed))
|
||||
|
||||
if strongSelf.isNodeLoaded {
|
||||
strongSelf.controllerNode.updatePresentationData(presentationData)
|
||||
}
|
||||
})
|
||||
|
||||
self.interaction = LocationViewInteraction(toggleMapModeSelection: { [weak self] in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
strongSelf.controllerNode.updateState { state in
|
||||
var state = state
|
||||
state.displayingMapModeOptions = !state.displayingMapModeOptions
|
||||
return state
|
||||
}
|
||||
}, updateMapMode: { [weak self] mode in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
strongSelf.controllerNode.updateState { state in
|
||||
var state = state
|
||||
state.mapMode = mode
|
||||
state.displayingMapModeOptions = false
|
||||
return state
|
||||
}
|
||||
}, goToUserLocation: { [weak self] in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
strongSelf.controllerNode.updateState { state in
|
||||
var state = state
|
||||
state.displayingMapModeOptions = false
|
||||
state.selectedLocation = .user
|
||||
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 = .coordinate(coordinate)
|
||||
return state
|
||||
}
|
||||
}, requestDirections: { [weak self] in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
strongSelf.present(OpenInActionSheetController(context: context, item: .location(location: mapMedia, withDirections: true), additionalAction: nil, openUrl: params.openUrl), in: .window(.root), with: nil)
|
||||
}, share: { [weak self] in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
let shareAction = OpenInControllerAction(title: strongSelf.presentationData.strings.Conversation_ContextMenuShare, action: {
|
||||
strongSelf.present(ShareController(context: context, subject: .mapMedia(mapMedia), externalShare: true), in: .window(.root), with: nil)
|
||||
})
|
||||
strongSelf.present(OpenInActionSheetController(context: context, item: .location(location: mapMedia, withDirections: false), additionalAction: shareAction, openUrl: params.openUrl), in: .window(.root), with: nil)
|
||||
})
|
||||
|
||||
self.scrollToTop = { [weak self] in
|
||||
if let strongSelf = self {
|
||||
strongSelf.controllerNode.scrollToTop()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
required public init(coder aDecoder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
deinit {
|
||||
self.presentationDataDisposable?.dispose()
|
||||
}
|
||||
|
||||
override public func loadDisplayNode() {
|
||||
super.loadDisplayNode()
|
||||
guard let interaction = self.interaction else {
|
||||
return
|
||||
}
|
||||
|
||||
self.displayNode = LocationViewControllerNode(context: self.context, presentationData: self.presentationData, mapMedia: self.mapMedia, interaction: interaction)
|
||||
self.displayNodeDidLoad()
|
||||
}
|
||||
|
||||
override public func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
|
||||
super.containerLayoutUpdated(layout, transition: transition)
|
||||
|
||||
self.controllerNode.containerLayoutUpdated(layout, navigationHeight: self.navigationHeight, transition: transition)
|
||||
}
|
||||
|
||||
@objc private func cancelPressed() {
|
||||
self.dismiss()
|
||||
}
|
||||
|
||||
@objc private func sharePressed() {
|
||||
self.interaction?.share()
|
||||
}
|
||||
|
||||
@objc private func showAllPressed() {
|
||||
self.dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user