mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Location view fixes
This commit is contained in:
parent
c27ebb4787
commit
2f13d11224
@ -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 %@";
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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)"
|
||||
}
|
||||
|
||||
|
@ -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? {
|
||||
|
@ -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
|
||||
|
@ -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] = []
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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)]))
|
||||
|
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user