mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-24 07:05:35 +00:00
Story search
This commit is contained in:
@@ -5,8 +5,6 @@ import Display
|
||||
import SwiftSignalKit
|
||||
import MapKit
|
||||
|
||||
let defaultMapSpan = MKCoordinateSpan(latitudeDelta: 0.016, longitudeDelta: 0.016)
|
||||
let viewMapSpan = MKCoordinateSpan(latitudeDelta: 0.008, longitudeDelta: 0.008)
|
||||
private let pinOffset = CGPoint(x: 0.0, y: 33.0)
|
||||
|
||||
public enum LocationMapMode {
|
||||
@@ -128,7 +126,10 @@ private func generateProximityDim(size: CGSize) -> UIImage {
|
||||
})!
|
||||
}
|
||||
|
||||
final class LocationMapNode: ASDisplayNode, MKMapViewDelegate {
|
||||
public final class LocationMapNode: ASDisplayNode, MKMapViewDelegate {
|
||||
public static let defaultMapSpan = MKCoordinateSpan(latitudeDelta: 0.016, longitudeDelta: 0.016)
|
||||
public static let viewMapSpan = MKCoordinateSpan(latitudeDelta: 0.008, longitudeDelta: 0.008)
|
||||
|
||||
class ProximityCircleRenderer: MKCircleRenderer {
|
||||
override func draw(_ mapRect: MKMapRect, zoomScale: MKZoomScale, in context: CGContext) {
|
||||
super.draw(mapRect, zoomScale: zoomScale, in: context)
|
||||
@@ -204,7 +205,7 @@ final class LocationMapNode: ASDisplayNode, MKMapViewDelegate {
|
||||
}
|
||||
|
||||
private var circleOverlay: MKCircle?
|
||||
var activeProximityRadius: Double? {
|
||||
public var activeProximityRadius: Double? {
|
||||
didSet {
|
||||
if let activeProximityRadius = self.activeProximityRadius {
|
||||
if let circleOverlay = self.circleOverlay {
|
||||
@@ -225,7 +226,7 @@ final class LocationMapNode: ASDisplayNode, MKMapViewDelegate {
|
||||
}
|
||||
}
|
||||
|
||||
override init() {
|
||||
override public init() {
|
||||
self.pickerAnnotationContainerView = PickerAnnotationContainerView()
|
||||
self.pickerAnnotationContainerView.isHidden = true
|
||||
|
||||
@@ -236,7 +237,7 @@ final class LocationMapNode: ASDisplayNode, MKMapViewDelegate {
|
||||
})
|
||||
}
|
||||
|
||||
override func didLoad() {
|
||||
override public func didLoad() {
|
||||
super.didLoad()
|
||||
|
||||
self.headingArrowView = UIImageView()
|
||||
@@ -292,7 +293,7 @@ final class LocationMapNode: ASDisplayNode, MKMapViewDelegate {
|
||||
}
|
||||
}
|
||||
|
||||
var trackingMode: LocationTrackingMode = .none {
|
||||
public var trackingMode: LocationTrackingMode = .none {
|
||||
didSet {
|
||||
self.mapView?.userTrackingMode = self.trackingMode.userTrackingMode
|
||||
if self.trackingMode == .followWithHeading && self.headingArrowView?.image != nil {
|
||||
@@ -303,11 +304,18 @@ final class LocationMapNode: ASDisplayNode, MKMapViewDelegate {
|
||||
}
|
||||
}
|
||||
|
||||
var topPadding: CGFloat = 0.0
|
||||
var mapOffset: CGFloat = 0.0
|
||||
func setMapCenter(coordinate: CLLocationCoordinate2D, radius: Double, insets: UIEdgeInsets, offset: CGFloat, animated: Bool = false) {
|
||||
var hasValidLayout: Bool = false
|
||||
var pendingSetMapCenter: (coordinate: CLLocationCoordinate2D, span: MKCoordinateSpan, offset: CGPoint, isUserLocation: Bool, hidePicker: Bool, animated: Bool)?
|
||||
|
||||
public func setMapCenter(coordinate: CLLocationCoordinate2D, radius: Double, insets: UIEdgeInsets, offset: CGFloat, animated: Bool = false) {
|
||||
self.mapOffset = offset
|
||||
self.ignoreRegionChanges = true
|
||||
|
||||
var insets = insets
|
||||
insets.top += self.topPadding
|
||||
|
||||
let mapRect = MKMapRect(region: MKCoordinateRegion(center: coordinate, latitudinalMeters: radius * 2.0, longitudinalMeters: radius * 2.0))
|
||||
self.mapView?.setVisibleMapRect(mapRect, edgePadding: insets, animated: animated)
|
||||
self.ignoreRegionChanges = false
|
||||
@@ -315,16 +323,34 @@ final class LocationMapNode: ASDisplayNode, MKMapViewDelegate {
|
||||
self.proximityDimView.center = CGPoint(x: self.bounds.midX, y: self.bounds.midY + offset)
|
||||
}
|
||||
|
||||
func setMapCenter(coordinate: CLLocationCoordinate2D, span: MKCoordinateSpan = defaultMapSpan, offset: CGPoint = CGPoint(), isUserLocation: Bool = false, hidePicker: Bool = false, animated: Bool = false) {
|
||||
public func setMapCenter(coordinate: CLLocationCoordinate2D, span: MKCoordinateSpan = defaultMapSpan, offset: CGPoint = CGPoint(), isUserLocation: Bool = false, hidePicker: Bool = false, animated: Bool = false) {
|
||||
self.pendingSetMapCenter = (
|
||||
coordinate, span, offset, isUserLocation, hidePicker, animated
|
||||
)
|
||||
|
||||
if self.hasValidLayout {
|
||||
self.applyPendingSetMapCenter()
|
||||
}
|
||||
}
|
||||
|
||||
private func applyPendingSetMapCenter() {
|
||||
if !self.hasValidLayout {
|
||||
return
|
||||
}
|
||||
guard let (coordinate, span, offset, isUserLocation, hidePicker, animated) = self.pendingSetMapCenter else {
|
||||
return
|
||||
}
|
||||
self.pendingSetMapCenter = nil
|
||||
|
||||
let region = MKCoordinateRegion(center: coordinate, span: span)
|
||||
self.ignoreRegionChanges = true
|
||||
if offset == CGPoint() {
|
||||
if offset == CGPoint() && self.topPadding == 0.0 {
|
||||
self.mapView?.setRegion(region, animated: animated)
|
||||
} else {
|
||||
let mapRect = MKMapRect(region: region)
|
||||
self.mapView?.setVisibleMapRect(mapRect, edgePadding: UIEdgeInsets(top: offset.y, left: offset.x, bottom: 0.0, right: 0.0), animated: animated)
|
||||
self.mapView?.setVisibleMapRect(mapRect, edgePadding: UIEdgeInsets(top: offset.y + self.topPadding, left: offset.x, bottom: 0.0, right: 0.0), animated: animated)
|
||||
}
|
||||
self.ignoreRegionChanges = false
|
||||
self.ignoreRegionChanges = false
|
||||
|
||||
if isUserLocation {
|
||||
if !self.returnedToUserLocation {
|
||||
@@ -339,7 +365,7 @@ final class LocationMapNode: ASDisplayNode, MKMapViewDelegate {
|
||||
}
|
||||
}
|
||||
|
||||
func mapView(_ mapView: MKMapView, regionWillChangeAnimated animated: Bool) {
|
||||
public func mapView(_ mapView: MKMapView, regionWillChangeAnimated animated: Bool) {
|
||||
guard !self.ignoreRegionChanges, let scrollView = mapView.subviews.first, let gestureRecognizers = scrollView.gestureRecognizers else {
|
||||
return
|
||||
}
|
||||
@@ -356,7 +382,7 @@ final class LocationMapNode: ASDisplayNode, MKMapViewDelegate {
|
||||
}
|
||||
}
|
||||
|
||||
func mapView(_ mapView: MKMapView, regionDidChangeAnimated animated: Bool) {
|
||||
public func mapView(_ mapView: MKMapView, regionDidChangeAnimated animated: Bool) {
|
||||
let wasDragging = self.isDragging
|
||||
if self.isDragging {
|
||||
self.isDragging = false
|
||||
@@ -372,7 +398,7 @@ final class LocationMapNode: ASDisplayNode, MKMapViewDelegate {
|
||||
}
|
||||
}
|
||||
|
||||
func mapView(_ mapView: MKMapView, didUpdate userLocation: MKUserLocation) {
|
||||
public func mapView(_ mapView: MKMapView, didUpdate userLocation: MKUserLocation) {
|
||||
guard let location = userLocation.location else {
|
||||
return
|
||||
}
|
||||
@@ -380,11 +406,11 @@ final class LocationMapNode: ASDisplayNode, MKMapViewDelegate {
|
||||
self.locationPromise.set(.single(location))
|
||||
}
|
||||
|
||||
func mapView(_ mapView: MKMapView, didFailToLocateUserWithError error: Error) {
|
||||
public func mapView(_ mapView: MKMapView, didFailToLocateUserWithError error: Error) {
|
||||
self.locationPromise.set(.single(nil))
|
||||
}
|
||||
|
||||
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
|
||||
public func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
|
||||
if annotation === mapView.userLocation {
|
||||
return nil
|
||||
}
|
||||
@@ -400,7 +426,7 @@ final class LocationMapNode: ASDisplayNode, MKMapViewDelegate {
|
||||
return nil
|
||||
}
|
||||
|
||||
func mapView(_ mapView: MKMapView, didAdd views: [MKAnnotationView]) {
|
||||
public func mapView(_ mapView: MKMapView, didAdd views: [MKAnnotationView]) {
|
||||
for view in views {
|
||||
if view.annotation is MKUserLocation {
|
||||
self.defaultUserLocationAnnotation = view.annotation
|
||||
@@ -424,7 +450,7 @@ final class LocationMapNode: ASDisplayNode, MKMapViewDelegate {
|
||||
}
|
||||
}
|
||||
|
||||
func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
|
||||
public func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
|
||||
guard let annotation = view.annotation as? LocationPinAnnotation else {
|
||||
return
|
||||
}
|
||||
@@ -440,7 +466,7 @@ final class LocationMapNode: ASDisplayNode, MKMapViewDelegate {
|
||||
}
|
||||
}
|
||||
|
||||
func mapView(_ mapView: MKMapView, didDeselect view: MKAnnotationView) {
|
||||
public func mapView(_ mapView: MKMapView, didDeselect view: MKAnnotationView) {
|
||||
if let view = view as? LocationPinAnnotationView {
|
||||
Queue.mainQueue().after(0.2) {
|
||||
view.setZPosition(view.defaultZPosition)
|
||||
@@ -459,7 +485,7 @@ final class LocationMapNode: ASDisplayNode, MKMapViewDelegate {
|
||||
}
|
||||
}
|
||||
|
||||
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
|
||||
public func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
|
||||
if let circle = overlay as? MKCircle {
|
||||
let renderer = ProximityCircleRenderer(circle: circle)
|
||||
renderer.fillColor = .clear
|
||||
@@ -472,7 +498,7 @@ final class LocationMapNode: ASDisplayNode, MKMapViewDelegate {
|
||||
}
|
||||
}
|
||||
|
||||
var distancesToAllAnnotations: Signal<[Double], NoError> {
|
||||
public var distancesToAllAnnotations: Signal<[Double], NoError> {
|
||||
let poll = Signal<[LocationPinAnnotation], NoError> { [weak self] subscriber in
|
||||
if let strongSelf = self {
|
||||
subscriber.putNext(strongSelf.annotations)
|
||||
@@ -497,30 +523,30 @@ final class LocationMapNode: ASDisplayNode, MKMapViewDelegate {
|
||||
}
|
||||
}
|
||||
|
||||
var currentUserLocation: CLLocation? {
|
||||
public var currentUserLocation: CLLocation? {
|
||||
return self.mapView?.userLocation.location
|
||||
}
|
||||
|
||||
var userLocation: Signal<CLLocation?, NoError> {
|
||||
public var userLocation: Signal<CLLocation?, NoError> {
|
||||
return .single(self.currentUserLocation)
|
||||
|> then (self.locationPromise.get())
|
||||
}
|
||||
|
||||
var mapCenterCoordinate: CLLocationCoordinate2D? {
|
||||
public var mapCenterCoordinate: CLLocationCoordinate2D? {
|
||||
guard let mapView = self.mapView else {
|
||||
return nil
|
||||
}
|
||||
return mapView.convert(CGPoint(x: (mapView.frame.width + pinOffset.x) / 2.0, y: (mapView.frame.height + pinOffset.y) / 2.0), toCoordinateFrom: mapView)
|
||||
}
|
||||
|
||||
var mapSpan: MKCoordinateSpan? {
|
||||
public var mapSpan: MKCoordinateSpan? {
|
||||
guard let mapView = self.mapView else {
|
||||
return nil
|
||||
}
|
||||
return mapView.region.span
|
||||
}
|
||||
|
||||
func resetAnnotationSelection() {
|
||||
public func resetAnnotationSelection() {
|
||||
guard let mapView = self.mapView else {
|
||||
return
|
||||
}
|
||||
@@ -529,8 +555,8 @@ final class LocationMapNode: ASDisplayNode, MKMapViewDelegate {
|
||||
}
|
||||
}
|
||||
|
||||
var pickerAnnotationView: LocationPinAnnotationView? = nil
|
||||
var hasPickerAnnotation: Bool = false {
|
||||
public var pickerAnnotationView: LocationPinAnnotationView? = nil
|
||||
public var hasPickerAnnotation: Bool = false {
|
||||
didSet {
|
||||
if self.hasPickerAnnotation, let annotation = self.userLocationAnnotation {
|
||||
let pickerAnnotationView = LocationPinAnnotationView(annotation: annotation)
|
||||
@@ -544,7 +570,7 @@ final class LocationMapNode: ASDisplayNode, MKMapViewDelegate {
|
||||
}
|
||||
}
|
||||
|
||||
func switchToPicking(raise: Bool = false, animated: Bool) {
|
||||
public func switchToPicking(raise: Bool = false, animated: Bool) {
|
||||
guard self.hasPickerAnnotation else {
|
||||
return
|
||||
}
|
||||
@@ -561,8 +587,8 @@ final class LocationMapNode: ASDisplayNode, MKMapViewDelegate {
|
||||
self.resetScheduledPin()
|
||||
}
|
||||
|
||||
var customUserLocationAnnotationView: LocationPinAnnotationView? = nil
|
||||
var userLocationAnnotation: LocationPinAnnotation? = nil {
|
||||
public var customUserLocationAnnotationView: LocationPinAnnotationView? = nil
|
||||
public var userLocationAnnotation: LocationPinAnnotation? = nil {
|
||||
didSet {
|
||||
if let annotation = self.userLocationAnnotation {
|
||||
self.customUserLocationAnnotationView?.removeFromSuperview()
|
||||
@@ -582,7 +608,7 @@ final class LocationMapNode: ASDisplayNode, MKMapViewDelegate {
|
||||
}
|
||||
}
|
||||
|
||||
var userHeading: CGFloat? = nil {
|
||||
public var userHeading: CGFloat? = nil {
|
||||
didSet {
|
||||
if let heading = self.userHeading {
|
||||
self.headingArrowView?.isHidden = false
|
||||
@@ -594,7 +620,7 @@ final class LocationMapNode: ASDisplayNode, MKMapViewDelegate {
|
||||
}
|
||||
}
|
||||
|
||||
var annotations: [LocationPinAnnotation] = [] {
|
||||
public var annotations: [LocationPinAnnotation] = [] {
|
||||
didSet {
|
||||
guard let mapView = self.mapView else {
|
||||
return
|
||||
@@ -709,7 +735,7 @@ final class LocationMapNode: ASDisplayNode, MKMapViewDelegate {
|
||||
self.pinDisposable.set(nil)
|
||||
}
|
||||
|
||||
func showAll(animated: Bool = true) {
|
||||
public func showAll(animated: Bool = true) {
|
||||
guard let mapView = self.mapView else {
|
||||
return
|
||||
}
|
||||
@@ -736,11 +762,17 @@ final class LocationMapNode: ASDisplayNode, MKMapViewDelegate {
|
||||
}
|
||||
}
|
||||
|
||||
func updateLayout(size: CGSize) {
|
||||
self.proximityDimView.frame = CGRect(origin: CGPoint(x: 0.0, y: self.mapOffset), size: size)
|
||||
public func updateLayout(size: CGSize, topPadding: CGFloat) {
|
||||
self.hasValidLayout = true
|
||||
|
||||
self.topPadding = topPadding
|
||||
|
||||
self.proximityDimView.frame = CGRect(origin: CGPoint(x: 0.0, y: self.topPadding + self.mapOffset), size: size)
|
||||
self.pickerAnnotationContainerView.frame = CGRect(x: 0.0, y: floorToScreenPixels((size.height - size.width) / 2.0), width: size.width, height: size.width)
|
||||
if let pickerAnnotationView = self.pickerAnnotationView {
|
||||
pickerAnnotationView.center = CGPoint(x: self.pickerAnnotationContainerView.frame.width / 2.0, y: self.pickerAnnotationContainerView.frame.height / 2.0)
|
||||
}
|
||||
|
||||
self.applyPendingSetMapCenter()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user