Location view fixes

This commit is contained in:
Ilya Laktyushin
2020-10-28 23:51:05 +04:00
parent c27ebb4787
commit 2f13d11224
10 changed files with 3969 additions and 3909 deletions

View File

@@ -28,16 +28,18 @@ final class LocationDistancePickerScreen: ViewController {
private let context: AccountContext
private let style: LocationDistancePickerScreenStyle
private let distances: Signal<[Double], NoError>
private let compactDisplayTitle: String?
private let updated: (Int32?) -> Void
private let completion: (Int32, @escaping () -> Void) -> Void
private let willDismiss: () -> Void
private var presentationDataDisposable: Disposable?
init(context: AccountContext, style: LocationDistancePickerScreenStyle, distances: Signal<[Double], NoError>, updated: @escaping (Int32?) -> Void, completion: @escaping (Int32, @escaping () -> Void) -> Void, willDismiss: @escaping () -> Void) {
init(context: AccountContext, style: LocationDistancePickerScreenStyle, compactDisplayTitle: String?, distances: Signal<[Double], NoError>, updated: @escaping (Int32?) -> Void, completion: @escaping (Int32, @escaping () -> Void) -> Void, willDismiss: @escaping () -> Void) {
self.context = context
self.style = style
self.distances = distances
self.compactDisplayTitle = compactDisplayTitle
self.updated = updated
self.completion = completion
self.willDismiss = willDismiss
@@ -67,7 +69,7 @@ final class LocationDistancePickerScreen: ViewController {
}
override public func loadDisplayNode() {
self.displayNode = LocationDistancePickerScreenNode(context: self.context, style: self.style, distances: self.distances)
self.displayNode = LocationDistancePickerScreenNode(context: self.context, style: self.style, compactDisplayTitle: self.compactDisplayTitle, distances: self.distances)
self.controllerNode.updated = { [weak self] distance in
guard let strongSelf = self else {
return
@@ -173,6 +175,7 @@ class LocationDistancePickerScreenNode: ViewControllerTracingNode, UIScrollViewD
private let context: AccountContext
private let controllerStyle: LocationDistancePickerScreenStyle
private var presentationData: PresentationData
private var compactDisplayTitle: String?
private var distances: [Double] = []
private let dimNode: ASDisplayNode
@@ -186,6 +189,8 @@ class LocationDistancePickerScreenNode: ViewControllerTracingNode, UIScrollViewD
private let cancelButton: HighlightableButtonNode
private let doneButton: SolidRoundedButtonNode
private let measureButtonTitleNode: ImmediateTextNode
private var pickerView: TimerPickerView?
private let unitLabelNode: ImmediateTextNode
private let smallUnitLabelNode: ImmediateTextNode
@@ -199,11 +204,12 @@ class LocationDistancePickerScreenNode: ViewControllerTracingNode, UIScrollViewD
var dismiss: (() -> Void)?
var cancel: (() -> Void)?
init(context: AccountContext, style: LocationDistancePickerScreenStyle, distances: Signal<[Double], NoError>) {
init(context: AccountContext, style: LocationDistancePickerScreenStyle, compactDisplayTitle: String?, distances: Signal<[Double], NoError>) {
self.context = context
self.controllerStyle = style
self.presentationData = context.sharedContext.currentPresentationData.with { $0 }
self.compactDisplayTitle = compactDisplayTitle
self.wrappingScrollNode = ASScrollNode()
self.wrappingScrollNode.view.alwaysBounceVertical = true
self.wrappingScrollNode.view.delaysContentTouches = false
@@ -256,9 +262,10 @@ class LocationDistancePickerScreenNode: ViewControllerTracingNode, UIScrollViewD
self.doneButton.title = self.presentationData.strings.Conversation_Timer_Send
self.unitLabelNode = ImmediateTextNode()
self.smallUnitLabelNode = ImmediateTextNode()
self.measureButtonTitleNode = ImmediateTextNode()
super.init()
self.backgroundColor = nil
@@ -368,8 +375,26 @@ class LocationDistancePickerScreenNode: ViewControllerTracingNode, UIScrollViewD
if !self.usesMetricSystem {
value = Int32(Double(value) * 1.60934)
}
let distance = stringForDistance(strings: self.presentationData.strings, distance: CLLocationDistance(value))
self.doneButton.title = self.presentationData.strings.Location_ProximityNotification_Notify(distance).0
var formattedValue = String(format: "%0.1f", CGFloat(value) / 1000.0)
if value == 50 {
formattedValue = formattedValue.replacingOccurrences(of: ".1", with: "0.05")
}
let distance = self.usesMetricSystem ? "\(formattedValue) \(self.presentationData.strings.Location_ProximityNotification_DistanceKM)" : "\(formattedValue) \(self.presentationData.strings.Location_ProximityNotification_DistanceMI)"
let shortTitle = self.presentationData.strings.Location_ProximityNotification_Notify(distance).0
var longTitle: String?
if let displayTitle = self.compactDisplayTitle, let (layout, _) = self.containerLayout {
let title = self.presentationData.strings.Location_ProximityNotification_NotifyLong(displayTitle, distance).0
let width = horizontalContainerFillingSizeForLayout(layout: layout, sideInset: layout.safeInsets.left)
self.measureButtonTitleNode.attributedText = NSAttributedString(string: title, font: Font.regular(14.0), textColor: .black)
let titleSize = self.measureButtonTitleNode.updateLayout(CGSize(width: width * 2.0, height: 50.0))
if titleSize.width < width - 70.0 {
longTitle = title
}
}
self.doneButton.title = longTitle ?? shortTitle
self.textNode.attributedText = NSAttributedString(string: self.presentationData.strings.Location_ProximityNotification_AlreadyClose(distance).0, font: Font.regular(14.0), textColor: self.presentationData.theme.actionSheet.secondaryTextColor)
if let (layout, navigationBarHeight) = self.containerLayout {
@@ -540,6 +565,7 @@ class LocationDistancePickerScreenNode: ViewControllerTracingNode, UIScrollViewD
}
func containerLayoutUpdated(_ layout: ContainerViewLayout, navigationBarHeight: CGFloat, transition: ContainedViewLayoutTransition) {
var hadValidLayout = self.containerLayout != nil
self.containerLayout = (layout, navigationBarHeight)
var insets = layout.insets(options: [.statusBar, .input])
@@ -595,5 +621,9 @@ class LocationDistancePickerScreenNode: ViewControllerTracingNode, UIScrollViewD
transition.updateFrame(node: self.smallUnitLabelNode, frame: CGRect(origin: CGPoint(x: floor(pickerFrame.width / 4.0 * 3.0) + 50.0, y: floor(pickerFrame.center.y - smallUnitLabelSize.height / 2.0)), size: smallUnitLabelSize))
transition.updateFrame(node: self.contentContainerNode, frame: contentContainerFrame)
if !hadValidLayout {
self.updateDoneButtonTitle()
}
}
}

View File

@@ -178,7 +178,7 @@ final class LocationLiveListItemNode: ListViewItemNode {
var subtitle = timeString
if let distance = item.distance {
let distanceString = item.presentationData.strings.Map_DistanceAway(stringForDistance(strings: item.presentationData.strings, distance: distance)).0
let distanceString = item.presentationData.strings.Map_DistanceAway(shortStringForDistance(strings: item.presentationData.strings, distance: Int32(distance))).0
subtitle = "\(timeString)\(distanceString)"
}

View File

@@ -483,7 +483,8 @@ final class LocationMapNode: ASDisplayNode, MKMapViewDelegate {
}
var userLocation: Signal<CLLocation?, NoError> {
return self.locationPromise.get()
return .single(self.currentUserLocation)
|> then (self.locationPromise.get())
}
var mapCenterCoordinate: CLLocationCoordinate2D? {

View File

@@ -212,46 +212,58 @@ public final class LocationViewController: ViewController {
}
strongSelf.controllerNode.setProximityIndicator(radius: 0)
let controller = LocationDistancePickerScreen(context: context, style: .default, distances: strongSelf.controllerNode.headerNode.mapNode.distancesToAllAnnotations, updated: { [weak self] distance in
guard let strongSelf = self else {
return
}
strongSelf.controllerNode.setProximityIndicator(radius: distance)
}, completion: { [weak self] distance, completion in
let _ = (strongSelf.context.account.postbox.loadedPeerWithId(strongSelf.subject.id.peerId)
|> deliverOnMainQueue).start(next: { [weak self] peer in
guard let strongSelf = self else {
return
}
if let messageId = messageId {
strongSelf.controllerNode.updateState { state in
var state = state
state.updatingProximityRadius = distance
return state
var compactDisplayTitle: String?
if let peer = peer as? TelegramUser {
compactDisplayTitle = peer.compactDisplayTitle
}
let controller = LocationDistancePickerScreen(context: context, style: .default, compactDisplayTitle: compactDisplayTitle, distances: strongSelf.controllerNode.headerNode.mapNode.distancesToAllAnnotations, updated: { [weak self] distance in
guard let strongSelf = self else {
return
}
strongSelf.controllerNode.setProximityIndicator(radius: distance)
}, completion: { [weak self] distance, completion in
guard let strongSelf = self else {
return
}
let _ = requestEditLiveLocation(postbox: context.account.postbox, network: context.account.network, stateManager: context.account.stateManager, messageId: messageId, stop: false, coordinate: nil, heading: nil, proximityNotificationRadius: distance).start(completed: { [weak self] in
guard let strongSelf = self else {
return
}
if let messageId = messageId {
strongSelf.controllerNode.updateState { state in
var state = state
state.updatingProximityRadius = nil
state.updatingProximityRadius = distance
return state
}
})
} else {
strongSelf.present(textAlertController(context: strongSelf.context, title: strongSelf.presentationData.strings.Location_LiveLocationRequired_Title, text: strongSelf.presentationData.strings.Location_LiveLocationRequired_Description, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Location_LiveLocationRequired_ShareLocation, action: {
completion()
strongSelf.interaction?.sendLiveLocation(distance)
}), TextAlertAction(type: .genericAction, title: strongSelf.presentationData.strings.Common_Cancel, action: {})], actionLayout: .vertical), in: .window(.root))
}
completion()
}, willDismiss: { [weak self] in
if let strongSelf = self {
strongSelf.controllerNode.setProximityIndicator(radius: nil)
}
let _ = requestEditLiveLocation(postbox: context.account.postbox, network: context.account.network, stateManager: context.account.stateManager, messageId: messageId, stop: false, coordinate: nil, heading: nil, proximityNotificationRadius: distance).start(completed: { [weak self] in
guard let strongSelf = self else {
return
}
strongSelf.controllerNode.updateState { state in
var state = state
state.updatingProximityRadius = nil
return state
}
})
} else {
strongSelf.present(textAlertController(context: strongSelf.context, title: strongSelf.presentationData.strings.Location_LiveLocationRequired_Title, text: strongSelf.presentationData.strings.Location_LiveLocationRequired_Description, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Location_LiveLocationRequired_ShareLocation, action: {
completion()
strongSelf.interaction?.sendLiveLocation(distance)
}), TextAlertAction(type: .genericAction, title: strongSelf.presentationData.strings.Common_Cancel, action: {})], actionLayout: .vertical), in: .window(.root))
}
completion()
}, willDismiss: { [weak self] in
if let strongSelf = self {
strongSelf.controllerNode.setProximityIndicator(radius: nil)
}
})
strongSelf.present(controller, in: .window(.root))
})
strongSelf.present(controller, in: .window(.root))
}
}
}, updateSendActionHighlight: { [weak self] highlighted in

View File

@@ -48,7 +48,7 @@ private enum LocationViewEntryId: Hashable {
private enum LocationViewEntry: Comparable, Identifiable {
case info(PresentationTheme, TelegramMediaMap, String?, Double?, Double?)
case toggleLiveLocation(PresentationTheme, String, String, CLLocationCoordinate2D?, Double?, Double?)
case toggleLiveLocation(PresentationTheme, String, String, Double?, Double?)
case liveLocation(PresentationTheme, PresentationDateTimeFormat, PresentationPersonNameOrder, Message, Double?, Int)
var stableId: LocationViewEntryId {
@@ -70,8 +70,8 @@ private enum LocationViewEntry: Comparable, Identifiable {
} else {
return false
}
case let .toggleLiveLocation(lhsTheme, lhsTitle, lhsSubtitle, lhsCoordinate, lhsBeginTimestamp, lhsTimeout):
if case let .toggleLiveLocation(rhsTheme, rhsTitle, rhsSubtitle, rhsCoordinate, rhsBeginTimestamp, rhsTimeout) = rhs, lhsTheme === rhsTheme, lhsTitle == rhsTitle, lhsSubtitle == rhsSubtitle, lhsCoordinate == rhsCoordinate, lhsBeginTimestamp == rhsBeginTimestamp, lhsTimeout == rhsTimeout {
case let .toggleLiveLocation(lhsTheme, lhsTitle, lhsSubtitle, lhsBeginTimestamp, lhsTimeout):
if case let .toggleLiveLocation(rhsTheme, rhsTitle, rhsSubtitle, rhsBeginTimestamp, rhsTimeout) = rhs, lhsTheme === rhsTheme, lhsTitle == rhsTitle, lhsSubtitle == rhsSubtitle, lhsBeginTimestamp == rhsBeginTimestamp, lhsTimeout == rhsTimeout {
return true
} else {
return false
@@ -132,7 +132,7 @@ private enum LocationViewEntry: Comparable, Identifiable {
}, getDirections: {
interaction?.requestDirections()
})
case let .toggleLiveLocation(_, title, subtitle, coordinate, beginTimstamp, timeout):
case let .toggleLiveLocation(_, title, subtitle, beginTimstamp, timeout):
let beginTimeAndTimeout: (Double, Double)?
if let beginTimstamp = beginTimstamp, let timeout = timeout {
beginTimeAndTimeout = (beginTimstamp, timeout)
@@ -149,7 +149,11 @@ private enum LocationViewEntry: Comparable, Identifiable {
interaction?.updateSendActionHighlight(highlight)
})
case let .liveLocation(_, dateTimeFormat, nameDisplayOrder, message, distance, _):
return LocationLiveListItem(presentationData: ItemListPresentationData(presentationData), dateTimeFormat: dateTimeFormat, nameDisplayOrder: nameDisplayOrder, context: context, message: message, distance: distance, action: {}, longTapAction: {})
return LocationLiveListItem(presentationData: ItemListPresentationData(presentationData), dateTimeFormat: dateTimeFormat, nameDisplayOrder: nameDisplayOrder, context: context, message: message, distance: distance, action: {
if let location = getLocation(from: message) {
interaction?.goToCoordinate(location.coordinate)
}
}, longTapAction: {})
}
}
}
@@ -277,10 +281,10 @@ final class LocationViewControllerNode: ViewControllerTracingNode, CLLocationMan
return messages
}
setupProximityNotificationImpl = { [weak self] reset in
setupProximityNotificationImpl = { reset in
let _ = (liveLocations
|> take(1)
|> deliverOnMainQueue).start(next: { [weak self] messages in
|> deliverOnMainQueue).start(next: { messages in
var ownMessageId: MessageId?
for message in messages {
if message.localTags.contains(.OutgoingLiveLocation) {
@@ -369,7 +373,7 @@ final class LocationViewControllerNode: ViewControllerTracingNode, CLLocationMan
if let channel = subject.author as? TelegramChannel, case .broadcast = channel.info, activeOwnLiveLocation == nil {
} else {
entries.append(.toggleLiveLocation(presentationData.theme, title, subtitle, userLocation?.coordinate, beginTime, timeout))
entries.append(.toggleLiveLocation(presentationData.theme, title, subtitle, beginTime, timeout))
}
var sortedLiveLocations: [Message] = []