diff --git a/Telegram/Telegram-iOS/en.lproj/Localizable.strings b/Telegram/Telegram-iOS/en.lproj/Localizable.strings index 2eb8b2e591..27c0caee78 100644 --- a/Telegram/Telegram-iOS/en.lproj/Localizable.strings +++ b/Telegram/Telegram-iOS/en.lproj/Localizable.strings @@ -12939,3 +12939,5 @@ Sorry for the inconvenience."; "Notification.StarsGiveaway.Subtitle" = "You won a prize in a giveaway organized by **%1$@**.\n\nYour prize is **%2$@**."; "Notification.StarsGiveaway.Subtitle.Stars_1" = "%@ Star"; "Notification.StarsGiveaway.Subtitle.Stars_any" = "%@ Stars"; + +"VerificationCodes.DescriptionText" = "This chat is used to receive verification codes from third-party services."; diff --git a/submodules/ChatListUI/Sources/Node/ChatListItem.swift b/submodules/ChatListUI/Sources/Node/ChatListItem.swift index b86e567d5c..8628c5f602 100644 --- a/submodules/ChatListUI/Sources/Node/ChatListItem.swift +++ b/submodules/ChatListUI/Sources/Node/ChatListItem.swift @@ -576,7 +576,7 @@ private enum RevealOptionKey: Int32 { } private func canArchivePeer(id: EnginePeer.Id, accountPeerId: EnginePeer.Id) -> Bool { - if id.namespace == Namespaces.Peer.CloudUser && id.id._internalGetInt64Value() == 777000 { + if id.isTelegramNotifications { return false } if id == accountPeerId { @@ -913,7 +913,7 @@ private final class ChatListMediaPreviewNode: ASDisplayNode { } } -private let loginCodeRegex = try? NSRegularExpression(pattern: "[\\d\\-]{5,7}", options: []) +private let loginCodeRegex = try? NSRegularExpression(pattern: "\\b\\d{5,8}\\b", options: []) public class ChatListItemNode: ItemListRevealOptionsItemNode { final class TopicItemNode: ASDisplayNode { @@ -2371,7 +2371,7 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode { } } - if message.id.peerId.namespace == Namespaces.Peer.CloudUser && message.id.peerId.id._internalGetInt64Value() == 777000 { + if message.id.peerId.isTelegramNotifications || message.id.peerId.isVerificationCodes { if let cached = currentCustomTextEntities, cached.matches(text: message.text) { customTextEntities = cached } else if let matches = loginCodeRegex?.matches(in: message.text, options: [], range: NSMakeRange(0, (message.text as NSString).length)) { diff --git a/submodules/DeviceLocationManager/Sources/DeviceLocationManager.swift b/submodules/DeviceLocationManager/Sources/DeviceLocationManager.swift index 7f6756ad14..a3fcbc3fad 100644 --- a/submodules/DeviceLocationManager/Sources/DeviceLocationManager.swift +++ b/submodules/DeviceLocationManager/Sources/DeviceLocationManager.swift @@ -54,7 +54,7 @@ public final class DeviceLocationManager: NSObject { self.manager.delegate = self self.manager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters -// self.manager.distanceFilter = 5.0 + self.manager.distanceFilter = kCLDistanceFilterNone self.manager.activityType = .other self.manager.pausesLocationUpdatesAutomatically = false self.manager.headingFilter = 2.0 diff --git a/submodules/Display/Source/WindowContent.swift b/submodules/Display/Source/WindowContent.swift index e1bbea3b17..b716d17fb4 100644 --- a/submodules/Display/Source/WindowContent.swift +++ b/submodules/Display/Source/WindowContent.swift @@ -231,6 +231,16 @@ private func layoutMetricsForScreenSize(size: CGSize, orientation: UIInterfaceOr } public final class WindowKeyboardGestureRecognizerDelegate: NSObject, UIGestureRecognizerDelegate { + public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool { + if let view = gestureRecognizer.view { + let location = touch.location(in: gestureRecognizer.view) + if location.y > view.bounds.height - 44.0 { + return false + } + } + return true + } + public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool { return true } @@ -1299,7 +1309,7 @@ public class Window1 { } } - @objc func panGesture(_ recognizer: UIPanGestureRecognizer) { + @objc func panGesture(_ recognizer: WindowPanRecognizer) { switch recognizer.state { case .began: self.panGestureBegan(location: recognizer.location(in: recognizer.view)) diff --git a/submodules/Display/Source/WindowPanRecognizer.swift b/submodules/Display/Source/WindowPanRecognizer.swift index 53ed394912..7ef93a5ca6 100644 --- a/submodules/Display/Source/WindowPanRecognizer.swift +++ b/submodules/Display/Source/WindowPanRecognizer.swift @@ -7,6 +7,7 @@ public final class WindowPanRecognizer: UIGestureRecognizer { public var ended: ((CGPoint, CGPoint?) -> Void)? private var previousPoints: [(CGPoint, Double)] = [] + private var previousVelocity: CGFloat = 0.0 override public func reset() { super.reset() @@ -45,6 +46,11 @@ public final class WindowPanRecognizer: UIGestureRecognizer { } } + func velocity(in view: UIView?) -> CGPoint { + let point = CGPoint(x: 0.0, y: self.previousVelocity) + return self.view?.convert(point, to: view) ?? .zero + } + override public func touchesBegan(_ touches: Set, with event: UIEvent) { super.touchesBegan(touches, with: event) @@ -68,9 +74,12 @@ public final class WindowPanRecognizer: UIGestureRecognizer { override public func touchesEnded(_ touches: Set, with event: UIEvent) { super.touchesEnded(touches, with: event) + self.state = .ended + if let touch = touches.first { let location = touch.location(in: self.view) self.addPoint(location) + self.previousVelocity = self.estimateVerticalVelocity() self.ended?(location, CGPoint(x: 0.0, y: self.estimateVerticalVelocity())) } } @@ -78,6 +87,8 @@ public final class WindowPanRecognizer: UIGestureRecognizer { override public func touchesCancelled(_ touches: Set, with event: UIEvent) { super.touchesCancelled(touches, with: event) + self.state = .cancelled + if let touch = touches.first { self.ended?(touch.location(in: self.view), nil) } diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageAttachedContentNode/Sources/ChatMessageAttachedContentNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageAttachedContentNode/Sources/ChatMessageAttachedContentNode.swift index 6ef71e157f..bcac257337 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageAttachedContentNode/Sources/ChatMessageAttachedContentNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageAttachedContentNode/Sources/ChatMessageAttachedContentNode.swift @@ -221,6 +221,8 @@ public final class ChatMessageAttachedContentNode: ASDisplayNode { } } + let isAd = message.adAttribute != nil + var isReplyThread = false if case .replyThread = chatLocation { isReplyThread = true @@ -352,7 +354,7 @@ public final class ChatMessageAttachedContentNode: ASDisplayNode { contentFileValue = file } - if shouldDownloadMediaAutomatically(settings: automaticDownloadSettings, peerType: associatedData.automaticDownloadPeerType, networkType: associatedData.automaticDownloadNetworkType, authorPeerId: message.author?.id, contactsPeerIds: associatedData.contactsPeerIds, media: file) { + if shouldDownloadMediaAutomatically(settings: automaticDownloadSettings, peerType: associatedData.automaticDownloadPeerType, networkType: associatedData.automaticDownloadNetworkType, authorPeerId: message.author?.id, contactsPeerIds: associatedData.contactsPeerIds, media: file, isAd: isAd) { contentMediaAutomaticDownload = .full } else if shouldPredownloadMedia(settings: automaticDownloadSettings, peerType: associatedData.automaticDownloadPeerType, networkType: associatedData.automaticDownloadNetworkType, media: file) { contentMediaAutomaticDownload = .prefetch @@ -404,7 +406,7 @@ public final class ChatMessageAttachedContentNode: ASDisplayNode { } else { let contentMode: InteractiveMediaNodeContentMode = contentMediaAspectFilled ? .aspectFill : .aspectFit - let automaticDownload = shouldDownloadMediaAutomatically(settings: automaticDownloadSettings, peerType: associatedData.automaticDownloadPeerType, networkType: associatedData.automaticDownloadNetworkType, authorPeerId: message.author?.id, contactsPeerIds: associatedData.contactsPeerIds, media: contentMediaValue) + let automaticDownload = shouldDownloadMediaAutomatically(settings: automaticDownloadSettings, peerType: associatedData.automaticDownloadPeerType, networkType: associatedData.automaticDownloadNetworkType, authorPeerId: message.author?.id, contactsPeerIds: associatedData.contactsPeerIds, media: contentMediaValue, isAd: isAd) let (_, initialImageWidth, refineLayout) = makeContentMedia( context, @@ -435,7 +437,7 @@ public final class ChatMessageAttachedContentNode: ASDisplayNode { let contentFileContinueLayout: ChatMessageInteractiveFileNode.ContinueLayout? if let contentFileValue { - let automaticDownload = shouldDownloadMediaAutomatically(settings: automaticDownloadSettings, peerType: associatedData.automaticDownloadPeerType, networkType: associatedData.automaticDownloadNetworkType, authorPeerId: message.author?.id, contactsPeerIds: associatedData.contactsPeerIds, media: contentFileValue) + let automaticDownload = shouldDownloadMediaAutomatically(settings: automaticDownloadSettings, peerType: associatedData.automaticDownloadPeerType, networkType: associatedData.automaticDownloadNetworkType, authorPeerId: message.author?.id, contactsPeerIds: associatedData.contactsPeerIds, media: contentFileValue, isAd: isAd) let (_, refineLayout) = makeContentFile(ChatMessageInteractiveFileNode.Arguments( context: context, diff --git a/submodules/TelegramUI/Sources/ChatController.swift b/submodules/TelegramUI/Sources/ChatController.swift index c3d1f77ce9..3a8317ab07 100644 --- a/submodules/TelegramUI/Sources/ChatController.swift +++ b/submodules/TelegramUI/Sources/ChatController.swift @@ -7786,10 +7786,10 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G return false } }) - } else if peerId.namespace == Namespaces.Peer.CloudUser && peerId.id._internalGetInt64Value() == 777000 { + } else if peerId.isTelegramNotifications { self.screenCaptureManager = ScreenCaptureDetectionManager(check: { [weak self] in if let strongSelf = self, strongSelf.traceVisibility() { - let loginCodeRegex = try? NSRegularExpression(pattern: "[\\d\\-]{5,7}", options: []) + let loginCodeRegex = try? NSRegularExpression(pattern: "\\b\\d{5,7}\\b", options: []) var loginCodesToInvalidate: [String] = [] strongSelf.chatDisplayNode.historyNode.forEachVisibleMessageItemNode({ itemNode in if let text = itemNode.item?.message.text, let matches = loginCodeRegex?.matches(in: text, options: [], range: NSMakeRange(0, (text as NSString).length)), let match = matches.first { diff --git a/submodules/TelegramUI/Sources/ChatHistoryEntriesForView.swift b/submodules/TelegramUI/Sources/ChatHistoryEntriesForView.swift index 0c8f47b758..7b756fe096 100644 --- a/submodules/TelegramUI/Sources/ChatHistoryEntriesForView.swift +++ b/submodules/TelegramUI/Sources/ChatHistoryEntriesForView.swift @@ -446,6 +446,8 @@ func chatHistoryEntriesForView( } if case let .peer(peerId) = location, peerId.isReplies { entries.insert(.ChatInfoEntry("", presentationData.strings.RepliesChat_DescriptionText, nil, nil, presentationData), at: 0) + } else if case let .peer(peerId) = location, peerId.isVerificationCodes { + entries.insert(.ChatInfoEntry("", presentationData.strings.VerificationCodes_DescriptionText, nil, nil, presentationData), at: 0) } else if let cachedPeerData = cachedPeerData as? CachedUserData, let botInfo = cachedPeerData.botInfo, !botInfo.description.isEmpty { entries.insert(.ChatInfoEntry(presentationData.strings.Bot_DescriptionTitle, botInfo.description, botInfo.photo, botInfo.video, presentationData), at: 0) } else { diff --git a/submodules/TelegramUIPreferences/Sources/MediaAutoDownloadSettings.swift b/submodules/TelegramUIPreferences/Sources/MediaAutoDownloadSettings.swift index 5e2beb637c..fc8fceb504 100644 --- a/submodules/TelegramUIPreferences/Sources/MediaAutoDownloadSettings.swift +++ b/submodules/TelegramUIPreferences/Sources/MediaAutoDownloadSettings.swift @@ -564,7 +564,10 @@ public func isAutodownloadEnabledForAnyPeerType(category: MediaAutoDownloadCateg return category.contacts || category.otherPrivate || category.groups || category.channels } -public func shouldDownloadMediaAutomatically(settings: MediaAutoDownloadSettings, peerType: MediaAutoDownloadPeerType, networkType: MediaAutoDownloadNetworkType, authorPeerId: PeerId? = nil, contactsPeerIds: Set = Set(), media: Media?, isStory: Bool = false) -> Bool { +public func shouldDownloadMediaAutomatically(settings: MediaAutoDownloadSettings, peerType: MediaAutoDownloadPeerType, networkType: MediaAutoDownloadNetworkType, authorPeerId: PeerId? = nil, contactsPeerIds: Set = Set(), media: Media?, isStory: Bool = false, isAd: Bool = false) -> Bool { + if isAd { + return true + } if (networkType == .cellular && !settings.cellular.enabled) || (networkType == .wifi && !settings.wifi.enabled) { return false }