Merge commit '5a8506c3a4bcea0fe4b6695f8e5a7a0cccec00cf'

# Conflicts:
#	submodules/GalleryUI/Sources/Items/UniversalVideoGalleryItem.swift
This commit is contained in:
Isaac 2024-09-20 23:33:29 +08:00
commit 8430789c5d
32 changed files with 153 additions and 46 deletions

View File

@ -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.";

View File

@ -147,7 +147,7 @@ public final class BrowserBookmarksScreen: ViewController {
}, openLargeEmojiInfo: { _, _, _ in
}, openJoinLink: { _ in
}, openWebView: { _, _, _, _ in
}, activateAdAction: { _, _ in
}, activateAdAction: { _, _, _, _ in
}, openRequestedPeerSelection: { _, _, _, _ in
}, saveMediaToFiles: { _ in
}, openNoAdsDemo: {
@ -167,6 +167,7 @@ public final class BrowserBookmarksScreen: ViewController {
}, navigateToStory: { _, _ in
}, attemptedNavigationToPrivateQuote: { _ in
}, forceUpdateWarpContents: {
}, playShakeAnimation: {
}, automaticMediaDownloadSettings: MediaAutoDownloadSettings.defaultSettings, pollActionState: ChatInterfacePollActionState(), stickerSettings: ChatInterfaceStickerSettings(), presentationContext: ChatPresentationContext(context: context, backgroundNode: nil))

View File

@ -177,7 +177,7 @@ private enum ChatListRecentEntry: Comparable, Identifiable {
}
let status: ContactsPeerItemStatus
if primaryPeer.id.isReplies {
if primaryPeer.id.isRepliesOrVerificationCodes {
status = .none
} else if case let .user(user) = primaryPeer {
let servicePeer = isServicePeer(primaryPeer._asPeer())

View File

@ -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)) {
@ -2548,7 +2548,7 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode {
if !ignoreForwardedIcon {
if case .savedMessagesChats = item.chatListLocation {
displayForwardedIcon = false
} else if let forwardInfo = message.forwardInfo, !forwardInfo.flags.contains(.isImported) {
} else if let forwardInfo = message.forwardInfo, !forwardInfo.flags.contains(.isImported) && !message.id.peerId.isVerificationCodes {
displayForwardedIcon = true
} else if let _ = message.attributes.first(where: { $0 is ReplyStoryAttribute }) {
displayStoryReplyIcon = true

View File

@ -2298,7 +2298,7 @@ public final class ChatListNode: ListView {
guard !filter.contains(.onlyPrivateChats) || peer.peerId.namespace == Namespaces.Peer.CloudUser else { return false }
if let peer = peer.peer {
if peer.id.isReplies {
if peer.id.isRepliesOrVerificationCodes {
return false
}
@ -4249,7 +4249,7 @@ private func statusStringForPeerType(accountPeerId: EnginePeer.Id, strings: Pres
}
}
if peer.id.isReplies {
if peer.id.isReplies || peer.id.isVerificationCodes {
return nil
} else if case let .user(user) = peer {
if user.botInfo != nil || user.flags.contains(.isSupport) {

View File

@ -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

View File

@ -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))

View File

@ -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<UITouch>, with event: UIEvent) {
super.touchesBegan(touches, with: event)
@ -68,9 +74,12 @@ public final class WindowPanRecognizer: UIGestureRecognizer {
override public func touchesEnded(_ touches: Set<UITouch>, 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<UITouch>, with event: UIEvent) {
super.touchesCancelled(touches, with: event)
self.state = .cancelled
if let touch = touches.first {
self.ended?(touch.location(in: self.view), nil)
}

View File

@ -867,8 +867,11 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode {
}
self.overlayContentNode.action = { [weak self] toLandscape in
self?.updateControlsVisibility(!toLandscape)
self?.updateOrientation(toLandscape ? .landscapeRight : .portrait)
guard let self else {
return
}
self.updateControlsVisibility(!toLandscape)
self.updateOrientation(toLandscape ? .landscapeRight : .portrait)
}
self.statusButtonNode.addSubnode(self.statusNode)
@ -881,7 +884,6 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode {
if !strongSelf.isPaused {
strongSelf.didPause = true
}
strongSelf.videoNode?.togglePlayPause()
}
}
@ -1016,6 +1018,14 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode {
}
override func contentTapAction() -> Bool {
if case let .message(message, _) = self.item?.contentInfo, let _ = message.adAttribute {
self.item?.performAction(.ad(message.id))
return true
}
return false
}
override func screenFrameUpdated(_ frame: CGRect) {
let center = frame.midX - self.frame.width / 2.0
self.subnodeTransform = CATransform3DMakeTranslation(-center * 0.16, 0.0, 0.0)
@ -1268,10 +1278,8 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode {
}
}
let status = messageMediaFileStatus(context: item.context, messageId: message.id, file: file)
if !isWebpage {
if !NativeVideoContent.isHLSVideo(file: file) {
scrubberView.setFetchStatusSignal(status, strings: self.presentationData.strings, decimalSeparator: self.presentationData.dateTimeFormat.decimalSeparator, fileSize: file.size)
}
if !isWebpage && message.adAttribute == nil && !NativeVideoContent.isHLSVideo(file: file) {
scrubberView.setFetchStatusSignal(status, strings: self.presentationData.strings, decimalSeparator: self.presentationData.dateTimeFormat.decimalSeparator, fileSize: file.size)
}
self.requiresDownload = !isMediaStreamable(message: message, media: file)

View File

@ -59,12 +59,19 @@ open class ZoomableContentGalleryItemNode: GalleryItemNode, ASScrollViewDelegate
self.addSubnode(self.scrollNode)
}
open func contentTapAction() -> Bool {
return false
}
@objc open func contentTap(_ recognizer: TapLongTapOrDoubleTapGestureRecognizer) {
if recognizer.state == .ended {
if let (gesture, location) = recognizer.lastRecognizedGestureAndLocation {
let pointInNode = self.scrollNode.view.convert(location, to: self.view)
if pointInNode.x < 44.0 || pointInNode.x > self.frame.width - 44.0 {
} else {
if self.contentTapAction() {
return
}
switch gesture {
case .tap:
self.toggleControlsVisibility()

View File

@ -445,7 +445,7 @@ public class ItemListAvatarAndNameInfoItemNode: ListViewItemNode, ItemListItemNo
} else if peer.flags.contains(.isSupport), !servicePeer {
statusText = item.presentationData.strings.Bot_GenericSupportStatus
statusColor = item.presentationData.theme.list.itemSecondaryTextColor
} else if peer.id.isReplies {
} else if peer.id.isRepliesOrVerificationCodes {
statusText = ""
statusColor = item.presentationData.theme.list.itemPrimaryTextColor
} else if let _ = peer.botInfo {

View File

@ -520,6 +520,9 @@ public extension EnginePeer {
if peer.id.isReplies {
return true
}
if peer.id.isVerificationCodes {
return true
}
return (peer.id.namespace == Namespaces.Peer.CloudUser && (peer.id.id._internalGetInt64Value() == 777000 || peer.id.id._internalGetInt64Value() == 333000))
}
return false

View File

@ -424,12 +424,24 @@ public func isServicePeer(_ peer: Peer) -> Bool {
if peer.id.isReplies {
return true
}
if peer.id.isVerificationCodes {
return true
}
return (peer.id.namespace == Namespaces.Peer.CloudUser && (peer.id.id._internalGetInt64Value() == 777000 || peer.id.id._internalGetInt64Value() == 333000))
}
return false
}
public extension PeerId {
var isTelegramNotifications: Bool {
if self.namespace == Namespaces.Peer.CloudUser {
if self.id._internalGetInt64Value() == 777000 {
return true
}
}
return false
}
var isReplies: Bool {
if self.namespace == Namespaces.Peer.CloudUser {
if self.id._internalGetInt64Value() == 708513 || self.id._internalGetInt64Value() == 1271266957 {
@ -439,11 +451,26 @@ public extension PeerId {
return false
}
var isVerificationCodes: Bool {
if self.namespace == Namespaces.Peer.CloudUser {
if self.id._internalGetInt64Value() == 489000 {
return true
}
}
return false
}
var isRepliesOrVerificationCodes: Bool {
return self.isReplies || self.isVerificationCodes
}
func isRepliesOrSavedMessages(accountPeerId: PeerId) -> Bool {
if accountPeerId == self {
return true
} else if self.isReplies {
return true
} else if self.isVerificationCodes {
return true
} else {
return false
}

View File

@ -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,

View File

@ -1641,7 +1641,7 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
if let _ = sourceReference {
needsShareButton = true
}
} else if item.message.id.peerId.isReplies {
} else if item.message.id.peerId.isRepliesOrVerificationCodes {
needsShareButton = false
} else if incoming {
if let _ = sourceReference {

View File

@ -754,8 +754,10 @@ public final class ChatMessageAvatarHeaderNodeImpl: ListViewItemHeaderNode, Chat
if self.peerId.namespace == Namespaces.Peer.Empty, case let .message(_, _, id, _, _, _, _) = self.messageReference?.content {
self.controllerInteraction?.displayMessageTooltip(id, self.presentationData.strings.Conversation_ForwardAuthorHiddenTooltip, false, self, self.avatarNode.frame)
} else if let peer = self.peer {
if let adMessageId = self.adMessageId {
self.controllerInteraction?.activateAdAction(adMessageId, nil)
if peer.id.isVerificationCodes {
self.controllerInteraction?.playShakeAnimation()
} else if let adMessageId = self.adMessageId {
self.controllerInteraction?.activateAdAction(adMessageId, nil, false, false)
} else {
if let channel = peer as? TelegramChannel, case .broadcast = channel.info {
self.controllerInteraction?.openPeer(EnginePeer(peer), .chat(textInputState: nil, subject: nil, peekData: nil), self.messageReference, .default)

View File

@ -298,6 +298,9 @@ public final class ChatMessageItemImpl: ChatMessageItem, CustomStringConvertible
effectiveAuthor = TelegramUser(id: PeerId(namespace: Namespaces.Peer.Empty, id: PeerId.Id._internalFromInt64Value(Int64(authorSignature.persistentHashValue % 32))), accessHash: nil, firstName: authorSignature, lastName: nil, username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [], emojiStatus: nil, usernames: [], storiesHidden: nil, nameColor: nil, backgroundEmojiId: nil, profileColor: nil, profileBackgroundEmojiId: nil, subscriberCount: nil)
}
}
if peerId.isVerificationCodes && effectiveAuthor == nil {
effectiveAuthor = content.firstMessage.author
}
displayAuthorInfo = incoming && effectiveAuthor != nil
} else {
effectiveAuthor = content.firstMessage.author

View File

@ -167,7 +167,7 @@ final class ChatMessageNotificationItemNode: NotificationItemNode {
}
}
var avatarPeer = peer
if firstMessage.id.peerId.isReplies, let author = firstMessage.forwardInfo?.author {
if firstMessage.id.peerId.isRepliesOrVerificationCodes, let author = firstMessage.forwardInfo?.author {
avatarPeer = EnginePeer(author)
}
self.avatarNode.setPeer(context: item.context, theme: presentationData.theme, peer: avatarPeer, overrideImage: peer.id == item.context.account.peerId ? .savedMessagesIcon : nil, emptyColor: presentationData.theme.list.mediaPlaceholderColor)

View File

@ -118,7 +118,7 @@ public final class ChatMessageWebpageBubbleContentNode: ChatMessageBubbleContent
self.contentNode.activateAction = { [weak self] in
if let strongSelf = self, let item = strongSelf.item {
if let _ = item.message.adAttribute {
item.controllerInteraction.activateAdAction(item.message.id, strongSelf.contentNode.makeProgress())
item.controllerInteraction.activateAdAction(item.message.id, strongSelf.contentNode.makeProgress(), false, false)
} else {
var webPageContent: TelegramMediaWebpageLoadedContent?
for media in item.message.media {

View File

@ -616,7 +616,7 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode {
}, openLargeEmojiInfo: { _, _, _ in
}, openJoinLink: { _ in
}, openWebView: { _, _, _, _ in
}, activateAdAction: { _, _ in
}, activateAdAction: { _, _, _, _ in
}, openRequestedPeerSelection: { _, _, _, _ in
}, saveMediaToFiles: { _ in
}, openNoAdsDemo: {
@ -637,6 +637,7 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode {
}, navigateToStory: { _, _ in
}, attemptedNavigationToPrivateQuote: { _ in
}, forceUpdateWarpContents: {
}, playShakeAnimation: {
}, automaticMediaDownloadSettings: self.automaticMediaDownloadSettings,
pollActionState: ChatInterfacePollActionState(), stickerSettings: ChatInterfaceStickerSettings(), presentationContext: ChatPresentationContext(context: context, backgroundNode: self.backgroundNode))
self.controllerInteraction = controllerInteraction

View File

@ -473,7 +473,7 @@ public final class ChatSendGroupMediaMessageContextPreview: UIView, ChatSendMess
}, openLargeEmojiInfo: { _, _, _ in
}, openJoinLink: { _ in
}, openWebView: { _, _, _, _ in
}, activateAdAction: { _, _ in
}, activateAdAction: { _, _, _, _ in
}, openRequestedPeerSelection: { _, _, _, _ in
}, saveMediaToFiles: { _ in
}, openNoAdsDemo: {
@ -493,6 +493,7 @@ public final class ChatSendGroupMediaMessageContextPreview: UIView, ChatSendMess
}, navigateToStory: { _, _ in
}, attemptedNavigationToPrivateQuote: { _ in
}, forceUpdateWarpContents: {
}, playShakeAnimation: {
}, automaticMediaDownloadSettings: MediaAutoDownloadSettings.defaultSettings,
pollActionState: ChatInterfacePollActionState(), stickerSettings: ChatInterfaceStickerSettings(), presentationContext: ChatPresentationContext(context: self.context, backgroundNode: self.wallpaperBackgroundNode))

View File

@ -252,7 +252,7 @@ public final class ChatControllerInteraction: ChatControllerInteractionProtocol
public let openLargeEmojiInfo: (String, String?, TelegramMediaFile) -> Void
public let openJoinLink: (String) -> Void
public let openWebView: (String, String, Bool, ChatOpenWebViewSource) -> Void
public let activateAdAction: (EngineMessage.Id, Promise<Bool>?) -> Void
public let activateAdAction: (EngineMessage.Id, Promise<Bool>?, Bool, Bool) -> Void
public let openRequestedPeerSelection: (EngineMessage.Id, ReplyMarkupButtonRequestPeerType, Int32, Int32) -> Void
public let saveMediaToFiles: (EngineMessage.Id) -> Void
public let openNoAdsDemo: () -> Void
@ -273,6 +273,7 @@ public final class ChatControllerInteraction: ChatControllerInteractionProtocol
public let navigateToStory: (Message, StoryId) -> Void
public let attemptedNavigationToPrivateQuote: (Peer?) -> Void
public let forceUpdateWarpContents: () -> Void
public let playShakeAnimation: () -> Void
public var canPlayMedia: Bool = false
public var hiddenMedia: [MessageId: [Media]] = [:]
@ -382,7 +383,7 @@ public final class ChatControllerInteraction: ChatControllerInteractionProtocol
openLargeEmojiInfo: @escaping (String, String?, TelegramMediaFile) -> Void,
openJoinLink: @escaping (String) -> Void,
openWebView: @escaping (String, String, Bool, ChatOpenWebViewSource) -> Void,
activateAdAction: @escaping (EngineMessage.Id, Promise<Bool>?) -> Void,
activateAdAction: @escaping (EngineMessage.Id, Promise<Bool>?, Bool, Bool) -> Void,
openRequestedPeerSelection: @escaping (EngineMessage.Id, ReplyMarkupButtonRequestPeerType, Int32, Int32) -> Void,
saveMediaToFiles: @escaping (EngineMessage.Id) -> Void,
openNoAdsDemo: @escaping () -> Void,
@ -402,6 +403,7 @@ public final class ChatControllerInteraction: ChatControllerInteractionProtocol
navigateToStory: @escaping (Message, StoryId) -> Void,
attemptedNavigationToPrivateQuote: @escaping (Peer?) -> Void,
forceUpdateWarpContents: @escaping () -> Void,
playShakeAnimation: @escaping () -> Void,
automaticMediaDownloadSettings: MediaAutoDownloadSettings,
pollActionState: ChatInterfacePollActionState,
stickerSettings: ChatInterfaceStickerSettings,
@ -512,6 +514,7 @@ public final class ChatControllerInteraction: ChatControllerInteractionProtocol
self.navigateToStory = navigateToStory
self.attemptedNavigationToPrivateQuote = attemptedNavigationToPrivateQuote
self.forceUpdateWarpContents = forceUpdateWarpContents
self.playShakeAnimation = playShakeAnimation
self.automaticMediaDownloadSettings = automaticMediaDownloadSettings

View File

@ -299,7 +299,11 @@ public final class ChatTitleView: UIView, NavigationBarTitleView {
}
}
}
isEnabled = isEnabledValue
if peerView.peerId.isVerificationCodes {
isEnabled = false
} else {
isEnabled = isEnabledValue
}
}
case let .replyThread(type, count):
let textFont = titleFont
@ -435,7 +439,7 @@ public final class ChatTitleView: UIView, NavigationBarTitleView {
switch titleContent {
case let .peer(peerView, _, _, isScheduledMessages, _, _, _):
if let peer = peerView.peer {
if peer.id == self.context.account.peerId || isScheduledMessages || peer.id.isReplies {
if peer.id == self.context.account.peerId || isScheduledMessages || peer.id.isRepliesOrVerificationCodes {
inputActivitiesAllowed = false
}
}
@ -540,7 +544,7 @@ public final class ChatTitleView: UIView, NavigationBarTitleView {
state = .info(string, .generic)
} else if let peer = peerView.peer {
let servicePeer = isServicePeer(peer)
if peer.id == self.context.account.peerId || isScheduledMessages || peer.id.isReplies {
if peer.id == self.context.account.peerId || isScheduledMessages || peer.id.isRepliesOrVerificationCodes {
let string = NSAttributedString(string: "", font: subtitleFont, textColor: titleTheme.rootController.navigationBar.secondaryTextColor)
state = .info(string, .generic)
} else if let user = peer as? TelegramUser {

View File

@ -3472,7 +3472,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
}, openLargeEmojiInfo: { _, _, _ in
}, openJoinLink: { _ in
}, openWebView: { _, _, _, _ in
}, activateAdAction: { _, _ in
}, activateAdAction: { _, _, _, _ in
}, openRequestedPeerSelection: { _, _, _, _ in
}, saveMediaToFiles: { _ in
}, openNoAdsDemo: {
@ -3492,6 +3492,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
}, navigateToStory: { _, _ in
}, attemptedNavigationToPrivateQuote: { _ in
}, forceUpdateWarpContents: {
}, playShakeAnimation: {
}, automaticMediaDownloadSettings: MediaAutoDownloadSettings.defaultSettings,
pollActionState: ChatInterfacePollActionState(), stickerSettings: ChatInterfaceStickerSettings(), presentationContext: ChatPresentationContext(context: context, backgroundNode: nil))
self.hiddenMediaDisposable = context.sharedContext.mediaManager.galleryHiddenMediaManager.hiddenIds().startStrict(next: { [weak self] ids in

View File

@ -1280,6 +1280,15 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
standalone = true
}
if let adAttribute = message.attributes.first(where: { $0 is AdMessageAttribute }) as? AdMessageAttribute {
if let file = message.media.first(where: { $0 is TelegramMediaFile}) as? TelegramMediaFile, file.isVideo && !file.isAnimated {
strongSelf.chatDisplayNode.historyNode.adMessagesContext?.markAction(opaqueId: adAttribute.opaqueId, media: true, fullscreen: false)
} else {
strongSelf.controllerInteraction?.activateAdAction(message.id, nil, true, false)
return true
}
}
return context.sharedContext.openChatMessage(OpenChatMessageParams(context: context, updatedPresentationData: strongSelf.updatedPresentationData, chatLocation: openChatLocation, chatFilterTag: chatFilterTag, chatLocationContextHolder: strongSelf.chatLocationContextHolder, message: message, mediaIndex: params.mediaIndex, standalone: standalone, reverseMessageGalleryOrder: false, mode: mode, navigationController: strongSelf.effectiveNavigationController, dismissInput: {
self?.chatDisplayNode.dismissInput()
}, present: { c, a, i in
@ -1391,7 +1400,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}
}, openAd: { [weak self] messageId in
if let strongSelf = self {
strongSelf.controllerInteraction?.activateAdAction(messageId, nil)
strongSelf.controllerInteraction?.activateAdAction(messageId, nil, true, true)
}
}, addContact: { [weak self] phoneNumber in
if let strongSelf = self {
@ -3903,7 +3912,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
return
}
self.openWebApp(buttonText: buttonText, url: url, simple: simple, source: source)
}, activateAdAction: { [weak self] messageId, progress in
}, activateAdAction: { [weak self] messageId, progress, media, fullscreen in
guard let self, let message = self.chatDisplayNode.historyNode.messageInCurrentHistoryView(messageId), let adAttribute = message.adAttribute else {
return
}
@ -3917,7 +3926,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}
}
self.chatDisplayNode.historyNode.adMessagesContext?.markAction(opaqueId: adAttribute.opaqueId, media: false, fullscreen: false)
self.chatDisplayNode.historyNode.adMessagesContext?.markAction(opaqueId: adAttribute.opaqueId, media: media, fullscreen: fullscreen)
self.controllerInteraction?.openUrl(ChatControllerInteraction.OpenUrl(url: adAttribute.url, concealed: false, external: true, progress: progress))
}, openRequestedPeerSelection: { [weak self] messageId, peerType, buttonId, maxQuantity in
guard let self else {
@ -4618,6 +4627,11 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
return
}
self.chatDisplayNode.forceUpdateWarpContents()
}, playShakeAnimation: { [weak self] in
guard let self else {
return
}
self.playShakeAnimation()
}, automaticMediaDownloadSettings: self.automaticMediaDownloadSettings, pollActionState: ChatInterfacePollActionState(), stickerSettings: self.stickerSettings, presentationContext: ChatPresentationContext(context: context, backgroundNode: self.chatBackgroundNode))
controllerInteraction.enableFullTranslucency = context.sharedContext.energyUsageSettings.fullTranslucency
@ -7772,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 {

View File

@ -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 {

View File

@ -298,7 +298,7 @@ func canReplyInChat(_ chatPresentationInterfaceState: ChatPresentationInterfaceS
return false
}
guard !peer.id.isReplies else {
guard !peer.id.isRepliesOrVerificationCodes else {
return false
}
switch chatPresentationInterfaceState.mode {
@ -725,7 +725,7 @@ func contextMenuForChatPresentationInterfaceState(chatPresentationInterfaceState
}
}
if Namespaces.Message.allNonRegular.contains(message.id.namespace) || message.id.peerId.isReplies {
if Namespaces.Message.allNonRegular.contains(message.id.namespace) || message.id.peerId.isRepliesOrVerificationCodes {
canReply = false
canPin = false
} else if messages[0].flags.intersection([.Failed, .Unsent]).isEmpty {

View File

@ -137,7 +137,7 @@ func inputPanelForChatPresentationIntefaceState(_ chatPresentationInterfaceState
var displayInputTextPanel = false
if let peer = chatPresentationInterfaceState.renderedPeer?.peer {
if peer.id.isReplies {
if peer.id.isRepliesOrVerificationCodes {
if let currentPanel = (currentPanel as? ChatChannelSubscriberInputPanelNode) ?? (currentSecondaryPanel as? ChatChannelSubscriberInputPanelNode) {
return (currentPanel, nil)
} else {

View File

@ -171,7 +171,7 @@ func rightNavigationButtonForChatInterfaceState(context: AccountContext, present
}
}
if case let .peer(peerId) = presentationInterfaceState.chatLocation {
if peerId.isReplies {
if peerId.isRepliesOrVerificationCodes {
if hasMessages {
if case .search = currentButton?.action {
return currentButton

View File

@ -165,7 +165,7 @@ final class OverlayAudioPlayerControllerNode: ViewControllerTracingNode, ASGestu
}, openLargeEmojiInfo: { _, _, _ in
}, openJoinLink: { _ in
}, openWebView: { _, _, _, _ in
}, activateAdAction: { _, _ in
}, activateAdAction: { _, _, _, _ in
}, openRequestedPeerSelection: { _, _, _, _ in
}, saveMediaToFiles: { _ in
}, openNoAdsDemo: {
@ -185,6 +185,7 @@ final class OverlayAudioPlayerControllerNode: ViewControllerTracingNode, ASGestu
}, navigateToStory: { _, _ in
}, attemptedNavigationToPrivateQuote: { _ in
}, forceUpdateWarpContents: {
}, playShakeAnimation: {
}, automaticMediaDownloadSettings: MediaAutoDownloadSettings.defaultSettings, pollActionState: ChatInterfacePollActionState(), stickerSettings: ChatInterfaceStickerSettings(), presentationContext: ChatPresentationContext(context: context, backgroundNode: nil))
self.dimNode = ASDisplayNode()

View File

@ -1776,7 +1776,7 @@ public final class SharedAccountContextImpl: SharedAccountContext {
}, openLargeEmojiInfo: { _, _, _ in
}, openJoinLink: { _ in
}, openWebView: { _, _, _, _ in
}, activateAdAction: { _, _ in
}, activateAdAction: { _, _, _, _ in
}, openRequestedPeerSelection: { _, _, _, _ in
}, saveMediaToFiles: { _ in
}, openNoAdsDemo: {
@ -1796,6 +1796,7 @@ public final class SharedAccountContextImpl: SharedAccountContext {
}, navigateToStory: { _, _ in
}, attemptedNavigationToPrivateQuote: { _ in
}, forceUpdateWarpContents: {
}, playShakeAnimation: {
}, automaticMediaDownloadSettings: MediaAutoDownloadSettings.defaultSettings,
pollActionState: ChatInterfacePollActionState(), stickerSettings: ChatInterfaceStickerSettings(), presentationContext: ChatPresentationContext(context: context, backgroundNode: backgroundNode as? WallpaperBackgroundNode))

View File

@ -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<PeerId> = Set(), media: Media?, isStory: Bool = false) -> Bool {
public func shouldDownloadMediaAutomatically(settings: MediaAutoDownloadSettings, peerType: MediaAutoDownloadPeerType, networkType: MediaAutoDownloadNetworkType, authorPeerId: PeerId? = nil, contactsPeerIds: Set<PeerId> = 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
}