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

@ -5840,6 +5840,7 @@ Any member of this group will be able to see messages in the channel.";
"Notification.ProximityReached" = "%1$@ is now within %2$@ from %3$@";
"Notification.ProximityReachedYou" = "%1$@ is now within %2$@ from you";
"Notification.ProximityYouReached" = "You are now within %1$@ from %2$@";
"Location.ProximityNotification.Title" = "Proximity Alert";
"Location.ProximityNotification.Notify" = "Notify me within %@";

View File

@ -5,6 +5,7 @@ import Display
import TelegramPresentationData
private let textFont = Font.with(size: 13.0, design: .round, traits: [.bold])
private let smallTextFont = Font.with(size: 11.0, design: .round, traits: [.bold])
private class ChatMessageLiveLocationTimerNodeParams: NSObject {
let backgroundColor: UIColor
@ -119,10 +120,16 @@ public final class ChatMessageLiveLocationTimerNode: ASDisplayNode {
path.lineCapStyle = .round
path.stroke()
let attributes: [NSAttributedString.Key: Any] = [.font: textFont, .foregroundColor: parameters.foregroundColor]
let attributes: [NSAttributedString.Key: Any] = [.font: parameters.string.count > 2 ? smallTextFont : textFont, .foregroundColor: parameters.foregroundColor]
let nsString = parameters.string as NSString
let size = nsString.size(withAttributes: attributes)
nsString.draw(at: CGPoint(x: floor((bounds.size.width - size.width) / 2.0), y: floor((bounds.size.height - size.height) / 2.0)), withAttributes: attributes)
var offset: CGFloat = 0.0
if parameters.string.count > 2 {
offset = UIScreenPixel
}
nsString.draw(at: CGPoint(x: floor((bounds.size.width - size.width) / 2.0), y: floor((bounds.size.height - size.height) / 2.0) + offset), withAttributes: attributes)
}
}
}

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,10 +204,11 @@ 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
@ -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,7 +212,18 @@ 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
let _ = (strongSelf.context.account.postbox.loadedPeerWithId(strongSelf.subject.id.peerId)
|> deliverOnMainQueue).start(next: { [weak self] peer in
guard let strongSelf = self else {
return
}
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
}
@ -252,6 +263,7 @@ public final class LocationViewController: ViewController {
}
})
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] = []

View File

@ -444,7 +444,9 @@ public func universalServiceMessageString(presentationData: (PresentationTheme,
attributedString = nil
case let .geoProximityReached(fromId, toId, distance):
let distanceString = stringForDistance(strings: strings, distance: Double(distance))
if toId == accountPeerId {
if fromId == accountPeerId {
attributedString = addAttributesToStringWithRanges(strings.Notification_ProximityYouReached(distanceString, message.peers[toId]?.displayTitle(strings: strings, displayOrder: nameDisplayOrder) ?? ""), body: bodyAttributes, argumentAttributes: peerMentionsAttributes(primaryTextColor: primaryTextColor, peerIds: [(1, toId)]))
} else if toId == accountPeerId {
attributedString = addAttributesToStringWithRanges(strings.Notification_ProximityReachedYou(message.peers[fromId]?.displayTitle(strings: strings, displayOrder: nameDisplayOrder) ?? "", distanceString), body: bodyAttributes, argumentAttributes: peerMentionsAttributes(primaryTextColor: primaryTextColor, peerIds: [(0, fromId)]))
} else {
attributedString = addAttributesToStringWithRanges(strings.Notification_ProximityReached(message.peers[fromId]?.displayTitle(strings: strings, displayOrder: nameDisplayOrder) ?? "", distanceString, message.peers[toId]?.displayTitle(strings: strings, displayOrder: nameDisplayOrder) ?? ""), body: bodyAttributes, argumentAttributes: peerMentionsAttributes(primaryTextColor: primaryTextColor, peerIds: [(0, fromId), (2, toId)]))