mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Add proximity alert toasts
This commit is contained in:
parent
7666f05864
commit
db42d63c40
@ -38,6 +38,7 @@ static_library(
|
|||||||
"//submodules/LiveLocationTimerNode:LiveLocationTimerNode",
|
"//submodules/LiveLocationTimerNode:LiveLocationTimerNode",
|
||||||
"//submodules/TelegramNotices:TelegramNotices",
|
"//submodules/TelegramNotices:TelegramNotices",
|
||||||
"//submodules/TooltipUI:TooltipUI",
|
"//submodules/TooltipUI:TooltipUI",
|
||||||
|
"//submodules/UndoUI:UndoUI",
|
||||||
],
|
],
|
||||||
frameworks = [
|
frameworks = [
|
||||||
"$SDKROOT/System/Library/Frameworks/Foundation.framework",
|
"$SDKROOT/System/Library/Frameworks/Foundation.framework",
|
||||||
|
@ -39,6 +39,7 @@ swift_library(
|
|||||||
"//submodules/LiveLocationTimerNode:LiveLocationTimerNode",
|
"//submodules/LiveLocationTimerNode:LiveLocationTimerNode",
|
||||||
"//submodules/TelegramNotices:TelegramNotices",
|
"//submodules/TelegramNotices:TelegramNotices",
|
||||||
"//submodules/TooltipUI:TooltipUI",
|
"//submodules/TooltipUI:TooltipUI",
|
||||||
|
"//submodules/UndoUI:UndoUI",
|
||||||
],
|
],
|
||||||
visibility = [
|
visibility = [
|
||||||
"//visibility:public",
|
"//visibility:public",
|
||||||
|
@ -195,6 +195,8 @@ class LocationDistancePickerScreenNode: ViewControllerTracingNode, UIScrollViewD
|
|||||||
private let unitLabelNode: ImmediateTextNode
|
private let unitLabelNode: ImmediateTextNode
|
||||||
private let smallUnitLabelNode: ImmediateTextNode
|
private let smallUnitLabelNode: ImmediateTextNode
|
||||||
|
|
||||||
|
private var pickerTimer: SwiftSignalKit.Timer?
|
||||||
|
|
||||||
private var containerLayout: (ContainerViewLayout, CGFloat)?
|
private var containerLayout: (ContainerViewLayout, CGFloat)?
|
||||||
|
|
||||||
private var distancesDisposable: Disposable?
|
private var distancesDisposable: Disposable?
|
||||||
@ -321,6 +323,8 @@ class LocationDistancePickerScreenNode: ViewControllerTracingNode, UIScrollViewD
|
|||||||
|
|
||||||
deinit {
|
deinit {
|
||||||
self.distancesDisposable?.dispose()
|
self.distancesDisposable?.dispose()
|
||||||
|
|
||||||
|
self.pickerTimer?.invalidate()
|
||||||
}
|
}
|
||||||
|
|
||||||
func setupPickerView() {
|
func setupPickerView() {
|
||||||
@ -345,6 +349,18 @@ class LocationDistancePickerScreenNode: ViewControllerTracingNode, UIScrollViewD
|
|||||||
self.contentContainerNode.addSubnode(self.unitLabelNode)
|
self.contentContainerNode.addSubnode(self.unitLabelNode)
|
||||||
self.contentContainerNode.addSubnode(self.smallUnitLabelNode)
|
self.contentContainerNode.addSubnode(self.smallUnitLabelNode)
|
||||||
|
|
||||||
|
self.pickerTimer?.invalidate()
|
||||||
|
|
||||||
|
let pickerTimer = SwiftSignalKit.Timer(timeout: 0.4, repeat: true, completion: { [weak self] in
|
||||||
|
if let strongSelf = self {
|
||||||
|
if strongSelf.update() {
|
||||||
|
strongSelf.updateDoneButtonTitle()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, queue: Queue.mainQueue())
|
||||||
|
self.pickerTimer = pickerTimer
|
||||||
|
pickerTimer.start()
|
||||||
|
|
||||||
self.updateDoneButtonTitle()
|
self.updateDoneButtonTitle()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -414,7 +430,8 @@ class LocationDistancePickerScreenNode: ViewControllerTracingNode, UIScrollViewD
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fileprivate func update() {
|
var previousReportedValue: Int32?
|
||||||
|
fileprivate func update() -> Bool {
|
||||||
if let pickerView = self.pickerView {
|
if let pickerView = self.pickerView {
|
||||||
let selectedLargeRow = pickerView.selectedRow(inComponent: 0)
|
let selectedLargeRow = pickerView.selectedRow(inComponent: 0)
|
||||||
var selectedSmallRow = pickerView.selectedRow(inComponent: 1)
|
var selectedSmallRow = pickerView.selectedRow(inComponent: 1)
|
||||||
@ -429,7 +446,16 @@ class LocationDistancePickerScreenNode: ViewControllerTracingNode, UIScrollViewD
|
|||||||
if !self.usesMetricSystem {
|
if !self.usesMetricSystem {
|
||||||
value = Int32(Double(value) * 1.60934)
|
value = Int32(Double(value) * 1.60934)
|
||||||
}
|
}
|
||||||
self.updated?(value)
|
|
||||||
|
if let previousReportedValue = self.previousReportedValue, value == previousReportedValue {
|
||||||
|
return false
|
||||||
|
} else {
|
||||||
|
self.updated?(value)
|
||||||
|
self.previousReportedValue = value
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@ import SyncCore
|
|||||||
import Postbox
|
import Postbox
|
||||||
import SwiftSignalKit
|
import SwiftSignalKit
|
||||||
import TelegramPresentationData
|
import TelegramPresentationData
|
||||||
|
import TelegramStringFormatting
|
||||||
import AccountContext
|
import AccountContext
|
||||||
import AppBundle
|
import AppBundle
|
||||||
import CoreLocation
|
import CoreLocation
|
||||||
@ -14,6 +15,7 @@ import PresentationDataUtils
|
|||||||
import OpenInExternalAppUI
|
import OpenInExternalAppUI
|
||||||
import ShareController
|
import ShareController
|
||||||
import DeviceAccess
|
import DeviceAccess
|
||||||
|
import UndoUI
|
||||||
|
|
||||||
public class LocationViewParams {
|
public class LocationViewParams {
|
||||||
let sendLiveLocation: (TelegramMediaMap) -> Void
|
let sendLiveLocation: (TelegramMediaMap) -> Void
|
||||||
@ -202,6 +204,21 @@ public final class LocationViewController: ViewController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
strongSelf.present(
|
||||||
|
UndoOverlayController(
|
||||||
|
presentationData: strongSelf.presentationData,
|
||||||
|
content: .setProximityAlert(
|
||||||
|
title: strongSelf.presentationData.strings.Location_ProximityAlertCancelled,
|
||||||
|
text: "",
|
||||||
|
cancelled: true
|
||||||
|
),
|
||||||
|
elevatedLayout: false,
|
||||||
|
action: { action in
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
),
|
||||||
|
in: .current
|
||||||
|
)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
DeviceAccess.authorizeAccess(to: .location(.live), locationManager: strongSelf.locationManager, presentationData: strongSelf.presentationData, present: { c, a in
|
DeviceAccess.authorizeAccess(to: .location(.live), locationManager: strongSelf.locationManager, presentationData: strongSelf.presentationData, present: { c, a in
|
||||||
@ -254,6 +271,30 @@ public final class LocationViewController: ViewController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
var text: String
|
||||||
|
let distanceString = shortStringForDistance(strings: strongSelf.presentationData.strings, distance: distance)
|
||||||
|
if let compactDisplayTitle = compactDisplayTitle {
|
||||||
|
text = strongSelf.presentationData.strings.Location_ProximityAlertSetText(compactDisplayTitle, distanceString).0
|
||||||
|
} else {
|
||||||
|
text = strongSelf.presentationData.strings.Location_ProximityAlertSetTextGroup(distanceString).0
|
||||||
|
}
|
||||||
|
|
||||||
|
strongSelf.present(
|
||||||
|
UndoOverlayController(
|
||||||
|
presentationData: strongSelf.presentationData,
|
||||||
|
content: .setProximityAlert(
|
||||||
|
title: strongSelf.presentationData.strings.Location_ProximityAlertSetTitle,
|
||||||
|
text: text,
|
||||||
|
cancelled: false
|
||||||
|
),
|
||||||
|
elevatedLayout: false,
|
||||||
|
action: { action in
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
),
|
||||||
|
in: .current
|
||||||
|
)
|
||||||
} else {
|
} 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: {
|
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()
|
completion()
|
||||||
@ -293,6 +334,42 @@ public final class LocationViewController: ViewController {
|
|||||||
|> deliverOnMainQueue).start(next: { coordinate in
|
|> deliverOnMainQueue).start(next: { coordinate in
|
||||||
params.sendLiveLocation(TelegramMediaMap(coordinate: coordinate, liveBroadcastingTimeout: 30 * 60, proximityNotificationRadius: distance))
|
params.sendLiveLocation(TelegramMediaMap(coordinate: coordinate, liveBroadcastingTimeout: 30 * 60, proximityNotificationRadius: distance))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
var text: String
|
||||||
|
let distanceString = shortStringForDistance(strings: strongSelf.presentationData.strings, distance: distance)
|
||||||
|
if let compactDisplayTitle = compactDisplayTitle {
|
||||||
|
text = strongSelf.presentationData.strings.Location_ProximityAlertSetText(compactDisplayTitle, distanceString).0
|
||||||
|
} else {
|
||||||
|
text = strongSelf.presentationData.strings.Location_ProximityAlertSetTextGroup(distanceString).0
|
||||||
|
}
|
||||||
|
|
||||||
|
strongSelf.present(
|
||||||
|
UndoOverlayController(
|
||||||
|
presentationData: strongSelf.presentationData,
|
||||||
|
content: .setProximityAlert(
|
||||||
|
title: strongSelf.presentationData.strings.Location_ProximityAlertSetTitle,
|
||||||
|
text: text,
|
||||||
|
cancelled: false
|
||||||
|
),
|
||||||
|
elevatedLayout: false,
|
||||||
|
action: { action in
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
),
|
||||||
|
in: .current
|
||||||
|
)
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
let _ = (context.account.postbox.loadedPeerWithId(subject.id.peerId)
|
let _ = (context.account.postbox.loadedPeerWithId(subject.id.peerId)
|
||||||
|> deliverOnMainQueue).start(next: { peer in
|
|> deliverOnMainQueue).start(next: { peer in
|
||||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -21,6 +21,7 @@ public enum UndoOverlayContent {
|
|||||||
case chatAddedToFolder(chatTitle: String, folderTitle: String)
|
case chatAddedToFolder(chatTitle: String, folderTitle: String)
|
||||||
case chatRemovedFromFolder(chatTitle: String, folderTitle: String)
|
case chatRemovedFromFolder(chatTitle: String, folderTitle: String)
|
||||||
case messagesUnpinned(title: String, text: String, undo: Bool, isHidden: Bool)
|
case messagesUnpinned(title: String, text: String, undo: Bool, isHidden: Bool)
|
||||||
|
case setProximityAlert(title: String, text: String, cancelled: Bool)
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum UndoOverlayAction {
|
public enum UndoOverlayAction {
|
||||||
|
@ -221,7 +221,7 @@ final class UndoOverlayControllerNode: ViewControllerTracingNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
displayUndo = undo
|
displayUndo = undo
|
||||||
self.originalRemainingSeconds = undo ? 5 : 5
|
self.originalRemainingSeconds = 5
|
||||||
case let .emoji(path, text):
|
case let .emoji(path, text):
|
||||||
self.iconNode = nil
|
self.iconNode = nil
|
||||||
self.iconCheckNode = nil
|
self.iconCheckNode = nil
|
||||||
@ -388,6 +388,23 @@ final class UndoOverlayControllerNode: ViewControllerTracingNode {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
case let .setProximityAlert(title, text, cancelled):
|
||||||
|
self.iconNode = nil
|
||||||
|
self.iconCheckNode = nil
|
||||||
|
self.animationNode = AnimationNode(animation: cancelled ? "anim_proximity_cancelled" : "anim_proximity_set", colors: [:], scale: 0.45)
|
||||||
|
self.animatedStickerNode = nil
|
||||||
|
|
||||||
|
let body = MarkdownAttributeSet(font: Font.regular(14.0), textColor: .white)
|
||||||
|
let bold = MarkdownAttributeSet(font: Font.semibold(14.0), textColor: .white)
|
||||||
|
let link = MarkdownAttributeSet(font: Font.regular(14.0), textColor: undoTextColor)
|
||||||
|
let attributedText = parseMarkdownIntoAttributedString(text, attributes: MarkdownAttributes(body: body, bold: bold, link: link, linkAttribute: { _ in return nil }), textAlignment: .natural)
|
||||||
|
self.titleNode.attributedText = NSAttributedString(string: title, font: Font.semibold(14.0), textColor: .white)
|
||||||
|
if !text.isEmpty {
|
||||||
|
self.textNode.attributedText = attributedText
|
||||||
|
}
|
||||||
|
|
||||||
|
displayUndo = false
|
||||||
|
self.originalRemainingSeconds = 3
|
||||||
}
|
}
|
||||||
|
|
||||||
self.remainingSeconds = self.originalRemainingSeconds
|
self.remainingSeconds = self.originalRemainingSeconds
|
||||||
@ -416,7 +433,7 @@ final class UndoOverlayControllerNode: ViewControllerTracingNode {
|
|||||||
switch content {
|
switch content {
|
||||||
case .removedChat:
|
case .removedChat:
|
||||||
self.panelWrapperNode.addSubnode(self.timerTextNode)
|
self.panelWrapperNode.addSubnode(self.timerTextNode)
|
||||||
case .archivedChat, .hidArchive, .revealedArchive, .succeed, .emoji, .swipeToReply, .actionSucceeded, .stickersModified, .chatAddedToFolder, .chatRemovedFromFolder, .messagesUnpinned:
|
case .archivedChat, .hidArchive, .revealedArchive, .succeed, .emoji, .swipeToReply, .actionSucceeded, .stickersModified, .chatAddedToFolder, .chatRemovedFromFolder, .messagesUnpinned, .setProximityAlert:
|
||||||
break
|
break
|
||||||
case .dice:
|
case .dice:
|
||||||
self.panelWrapperNode.clipsToBounds = true
|
self.panelWrapperNode.clipsToBounds = true
|
||||||
|
Loading…
x
Reference in New Issue
Block a user