mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
196 lines
8.5 KiB
Swift
196 lines
8.5 KiB
Swift
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
|
|
let setupProximityNotification: () -> Void
|
|
|
|
init(toggleMapModeSelection: @escaping () -> Void, updateMapMode: @escaping (LocationMapMode) -> Void, goToUserLocation: @escaping () -> Void, goToCoordinate: @escaping (CLLocationCoordinate2D) -> Void, requestDirections: @escaping () -> Void, share: @escaping () -> Void, setupProximityNotification: @escaping () -> Void) {
|
|
self.toggleMapModeSelection = toggleMapModeSelection
|
|
self.updateMapMode = updateMapMode
|
|
self.goToUserLocation = goToUserLocation
|
|
self.goToCoordinate = goToCoordinate
|
|
self.requestDirections = requestDirections
|
|
self.share = share
|
|
self.setupProximityNotification = setupProximityNotification
|
|
}
|
|
}
|
|
|
|
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)
|
|
}, setupProximityNotification: { [weak self] in
|
|
guard let strongSelf = self else {
|
|
return
|
|
}
|
|
|
|
})
|
|
|
|
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()
|
|
}
|
|
}
|
|
|