From 3f2689d7d05b032603a6a233413afad402ae7d92 Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Sun, 24 Oct 2021 17:04:06 +0400 Subject: [PATCH] Location directions fixes --- .../Sources/LocationInfoListItem.swift | 59 +++++++++++++++++-- .../Sources/LocationLiveListItem.swift | 19 ++++-- .../LocationUI/Sources/LocationUtils.swift | 2 +- .../Sources/LocationViewControllerNode.swift | 14 ++++- 4 files changed, 83 insertions(+), 11 deletions(-) diff --git a/submodules/LocationUI/Sources/LocationInfoListItem.swift b/submodules/LocationUI/Sources/LocationInfoListItem.swift index 27ffe4f567..5311b04251 100644 --- a/submodules/LocationUI/Sources/LocationInfoListItem.swift +++ b/submodules/LocationUI/Sources/LocationInfoListItem.swift @@ -10,6 +10,7 @@ import ItemListUI import LocationResources import AppBundle import SolidRoundedButtonNode +import ShimmerEffect final class LocationInfoListItem: ListViewItem { let presentationData: ItemListPresentationData @@ -80,12 +81,14 @@ final class LocationInfoListItemNode: ListViewItemNode { private let venueIconNode: TransformImageNode private let buttonNode: HighlightableButtonNode + private var placeholderNode: ShimmerEffectNode? private var drivingButtonNode: SolidRoundedButtonNode? private var transitButtonNode: SolidRoundedButtonNode? private var walkingButtonNode: SolidRoundedButtonNode? private var item: LocationInfoListItem? private var layoutParams: ListViewItemLayoutParams? + private var absoluteLocation: (CGRect, CGSize)? required init() { self.backgroundNode = ASDisplayNode() @@ -305,13 +308,52 @@ final class LocationInfoListItemNode: ListViewItemNode { let directionsWidth: CGFloat = 93.0 let directionsSpacing: CGFloat = 8.0 + + if item.drivingTime == nil && item.transitTime == nil && item.walkingTime == nil { + let shimmerNode: ShimmerEffectNode + if let current = strongSelf.placeholderNode { + shimmerNode = current + } else { + shimmerNode = ShimmerEffectNode() + strongSelf.placeholderNode = shimmerNode + strongSelf.addSubnode(shimmerNode) + } + shimmerNode.frame = CGRect(origin: CGPoint(x: leftInset, y: subtitleFrame.maxY + 12.0), size: CGSize(width: contentSize.width - leftInset, height: 32.0)) + if let (rect, size) = strongSelf.absoluteLocation { + shimmerNode.updateAbsoluteRect(rect, within: size) + } + + var shapes: [ShimmerEffectNode.Shape] = [] + shapes.append(.roundedRectLine(startPoint: CGPoint(x: 0.0, y: 0.0), width: directionsWidth, diameter: 32.0)) + shapes.append(.roundedRectLine(startPoint: CGPoint(x: directionsWidth + directionsSpacing, y: 0.0), width: directionsWidth, diameter: 32.0)) + shapes.append(.roundedRectLine(startPoint: CGPoint(x: directionsWidth + directionsSpacing + directionsWidth + directionsSpacing, y: 0.0), width: directionsWidth, diameter: 32.0)) + + shimmerNode.update(backgroundColor: item.presentationData.theme.list.itemBlocksBackgroundColor, foregroundColor: item.presentationData.theme.list.mediaPlaceholderColor, shimmeringColor: item.presentationData.theme.list.itemBlocksBackgroundColor.withAlphaComponent(0.4), shapes: shapes, size: shimmerNode.frame.size) + } else if let shimmerNode = strongSelf.placeholderNode { + strongSelf.placeholderNode = nil + shimmerNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, removeOnCompletion: false, completion: { [weak shimmerNode] _ in + shimmerNode?.removeFromSupernode() + }) + } + let drivingHeight = strongSelf.drivingButtonNode?.updateLayout(width: directionsWidth, transition: .immediate) ?? 0.0 let transitHeight = strongSelf.transitButtonNode?.updateLayout(width: directionsWidth, transition: .immediate) ?? 0.0 let walkingHeight = strongSelf.walkingButtonNode?.updateLayout(width: directionsWidth, transition: .immediate) ?? 0.0 - - strongSelf.drivingButtonNode?.frame = CGRect(origin: CGPoint(x: leftInset, y: subtitleFrame.maxY + 12.0), size: CGSize(width: directionsWidth, height: drivingHeight)) - strongSelf.transitButtonNode?.frame = CGRect(origin: CGPoint(x: leftInset + directionsWidth + directionsSpacing, y: subtitleFrame.maxY + 12.0), size: CGSize(width: directionsWidth, height: transitHeight)) - strongSelf.walkingButtonNode?.frame = CGRect(origin: CGPoint(x: leftInset + directionsWidth + directionsSpacing + directionsWidth + directionsSpacing, y: subtitleFrame.maxY + 12.0), size: CGSize(width: directionsWidth, height: walkingHeight)) + + var buttonOrigin = leftInset + strongSelf.drivingButtonNode?.frame = CGRect(origin: CGPoint(x: buttonOrigin, y: subtitleFrame.maxY + 12.0), size: CGSize(width: directionsWidth, height: drivingHeight)) + + if item.drivingTime != nil { + buttonOrigin += directionsWidth + directionsSpacing + } + + strongSelf.transitButtonNode?.frame = CGRect(origin: CGPoint(x: buttonOrigin, y: subtitleFrame.maxY + 12.0), size: CGSize(width: directionsWidth, height: transitHeight)) + + if item.transitTime != nil { + buttonOrigin += directionsWidth + directionsSpacing + } + + strongSelf.walkingButtonNode?.frame = CGRect(origin: CGPoint(x: buttonOrigin, y: subtitleFrame.maxY + 12.0), size: CGSize(width: directionsWidth, height: walkingHeight)) strongSelf.buttonNode.frame = CGRect(x: 0.0, y: 0.0, width: contentSize.width, height: 72.0) strongSelf.backgroundNode.frame = CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: contentSize.width, height: contentSize.height)) @@ -332,4 +374,13 @@ final class LocationInfoListItemNode: ListViewItemNode { @objc private func buttonPressed() { self.item?.action() } + + override public func updateAbsoluteRect(_ rect: CGRect, within containerSize: CGSize) { + var rect = rect + rect.origin.y += self.insets.top + self.absoluteLocation = (rect, containerSize) + if let shimmerNode = self.placeholderNode { + shimmerNode.updateAbsoluteRect(rect, within: containerSize) + } + } } diff --git a/submodules/LocationUI/Sources/LocationLiveListItem.swift b/submodules/LocationUI/Sources/LocationLiveListItem.swift index 0e81e1c9d4..d4837c1fd5 100644 --- a/submodules/LocationUI/Sources/LocationLiveListItem.swift +++ b/submodules/LocationUI/Sources/LocationLiveListItem.swift @@ -358,10 +358,21 @@ final class LocationLiveListItemNode: ListViewItemNode { let drivingHeight = strongSelf.drivingButtonNode?.updateLayout(width: directionsWidth, transition: .immediate) ?? 0.0 let transitHeight = strongSelf.transitButtonNode?.updateLayout(width: directionsWidth, transition: .immediate) ?? 0.0 let walkingHeight = strongSelf.walkingButtonNode?.updateLayout(width: directionsWidth, transition: .immediate) ?? 0.0 - - strongSelf.drivingButtonNode?.frame = CGRect(origin: CGPoint(x: leftInset, y: subtitleFrame.maxY + 12.0), size: CGSize(width: directionsWidth, height: drivingHeight)) - strongSelf.transitButtonNode?.frame = CGRect(origin: CGPoint(x: leftInset + directionsWidth + directionsSpacing, y: subtitleFrame.maxY + 12.0), size: CGSize(width: directionsWidth, height: transitHeight)) - strongSelf.walkingButtonNode?.frame = CGRect(origin: CGPoint(x: leftInset + directionsWidth + directionsSpacing + directionsWidth + directionsSpacing, y: subtitleFrame.maxY + 12.0), size: CGSize(width: directionsWidth, height: walkingHeight)) + + var buttonOrigin = leftInset + strongSelf.drivingButtonNode?.frame = CGRect(origin: CGPoint(x: buttonOrigin, y: subtitleFrame.maxY + 12.0), size: CGSize(width: directionsWidth, height: drivingHeight)) + + if item.drivingTime != nil { + buttonOrigin += directionsWidth + directionsSpacing + } + + strongSelf.transitButtonNode?.frame = CGRect(origin: CGPoint(x: buttonOrigin, y: subtitleFrame.maxY + 12.0), size: CGSize(width: directionsWidth, height: transitHeight)) + + if item.transitTime != nil { + buttonOrigin += directionsWidth + directionsSpacing + } + + strongSelf.walkingButtonNode?.frame = CGRect(origin: CGPoint(x: buttonOrigin, y: subtitleFrame.maxY + 12.0), size: CGSize(width: directionsWidth, height: walkingHeight)) } }) }) diff --git a/submodules/LocationUI/Sources/LocationUtils.swift b/submodules/LocationUI/Sources/LocationUtils.swift index 6a03d01eee..dc99af92df 100644 --- a/submodules/LocationUI/Sources/LocationUtils.swift +++ b/submodules/LocationUI/Sources/LocationUtils.swift @@ -80,7 +80,7 @@ func stringForEstimatedDuration(strings: PresentationStrings, time: Double, form let string: String if hours >= 24 { string = strings.Map_ETADays(days) - } else if hours > 1 { + } else if hours > 0 { if hours == 1 && minutes == 0 { string = strings.Map_ETAHours(1) } else { diff --git a/submodules/LocationUI/Sources/LocationViewControllerNode.swift b/submodules/LocationUI/Sources/LocationViewControllerNode.swift index bd2ec4a05a..011d8b6eb3 100644 --- a/submodules/LocationUI/Sources/LocationViewControllerNode.swift +++ b/submodules/LocationUI/Sources/LocationViewControllerNode.swift @@ -455,13 +455,23 @@ final class LocationViewControllerNode: ViewControllerTracingNode, CLLocationMan var transitTime: Double? var walkingTime: Double? if !isLocationView && message.author?.id != context.account.peerId { + let signal = combineLatest(queue: Queue.mainQueue(), getExpectedTravelTime(coordinate: location.coordinate, transportType: .automobile), getExpectedTravelTime(coordinate: location.coordinate, transportType: .transit), getExpectedTravelTime(coordinate: location.coordinate, transportType: .walking)) + |> mapToSignal { drivingTime, transitTime, walkingTime -> Signal<(Double?, Double?, Double?), NoError> in + if drivingTime != nil && transitTime != nil && walkingTime != nil { + return .single((drivingTime, transitTime, walkingTime)) + } else { + return .single((drivingTime, transitTime, walkingTime)) + |> delay(0.3, queue: Queue.mainQueue()) + } + } + if let (previousTimestamp, maybeDrivingTime, maybeTransitTime, maybeWalkingTime) = travelTimes[message.id] { drivingTime = maybeDrivingTime transitTime = maybeTransitTime walkingTime = maybeWalkingTime if timestamp > previousTimestamp + 60.0 { - strongSelf.travelDisposables.add(combineLatest(queue: Queue.mainQueue(), getExpectedTravelTime(coordinate: location.coordinate, transportType: .automobile), getExpectedTravelTime(coordinate: location.coordinate, transportType: .transit), getExpectedTravelTime(coordinate: location.coordinate, transportType: .walking)).start(next: { [weak self] drivingTime, transitTime, walkingTime in + strongSelf.travelDisposables.add(signal.start(next: { [weak self] drivingTime, transitTime, walkingTime in guard let strongSelf = self else { return } @@ -472,7 +482,7 @@ final class LocationViewControllerNode: ViewControllerTracingNode, CLLocationMan })) } } else { - strongSelf.travelDisposables.add(combineLatest(queue: Queue.mainQueue(), getExpectedTravelTime(coordinate: location.coordinate, transportType: .automobile), getExpectedTravelTime(coordinate: location.coordinate, transportType: .transit), getExpectedTravelTime(coordinate: location.coordinate, transportType: .walking)).start(next: { [weak self] drivingTime, transitTime, walkingTime in + strongSelf.travelDisposables.add(signal.start(next: { [weak self] drivingTime, transitTime, walkingTime in guard let strongSelf = self else { return }