import Foundation import UIKit import Postbox import SwiftSignalKit import AsyncDisplayKit import TelegramCore import Display import TelegramUIPreferences import AccountContext import TextSelectionNode import ContextUI import ChatInterfaceState import UndoUI import TelegramPresentationData import ChatPresentationInterfaceState import TextFormat struct ChatInterfaceHighlightedState: Equatable { let messageStableId: UInt32 static func ==(lhs: ChatInterfaceHighlightedState, rhs: ChatInterfaceHighlightedState) -> Bool { return lhs.messageStableId == rhs.messageStableId } } struct ChatInterfaceStickerSettings: Equatable { let loopAnimatedStickers: Bool public init(loopAnimatedStickers: Bool) { self.loopAnimatedStickers = loopAnimatedStickers } public init(stickerSettings: StickerSettings) { self.loopAnimatedStickers = stickerSettings.loopAnimatedStickers } static func ==(lhs: ChatInterfaceStickerSettings, rhs: ChatInterfaceStickerSettings) -> Bool { return lhs.loopAnimatedStickers == rhs.loopAnimatedStickers } } struct ChatInterfacePollActionState: Equatable { var pollMessageIdsInProgress: [MessageId: [Data]] = [:] } public enum ChatControllerInteractionSwipeAction { case none case reply } public enum ChatControllerInteractionReaction { case `default` case reaction(MessageReaction.Reaction) } struct UnreadMessageRangeKey: Hashable { var peerId: PeerId var namespace: MessageId.Namespace } public final class ChatControllerInteraction { let openMessage: (Message, ChatControllerInteractionOpenMessageMode) -> Bool let openPeer: (PeerId?, ChatControllerInteractionNavigateToPeer, MessageReference?, Bool, Peer?) -> Void let openPeerMention: (String) -> Void let openMessageContextMenu: (Message, Bool, ASDisplayNode, CGRect, UIGestureRecognizer?, CGPoint?) -> Void let updateMessageReaction: (Message, ChatControllerInteractionReaction) -> Void let openMessageReactionContextMenu: (Message, ContextExtractedContentContainingView, ContextGesture?, MessageReaction.Reaction) -> Void let activateMessagePinch: (PinchSourceContainerNode) -> Void let openMessageContextActions: (Message, ASDisplayNode, CGRect, ContextGesture?) -> Void let navigateToMessage: (MessageId, MessageId) -> Void let navigateToMessageStandalone: (MessageId) -> Void let tapMessage: ((Message) -> Void)? let clickThroughMessage: () -> Void let toggleMessagesSelection: ([MessageId], Bool) -> Void let sendCurrentMessage: (Bool) -> Void let sendMessage: (String) -> Void let sendSticker: (FileMediaReference, Bool, Bool, String?, Bool, UIView, CGRect, CALayer?) -> Bool let sendEmoji: (String, ChatTextInputTextCustomEmojiAttribute) -> Void let sendGif: (FileMediaReference, UIView, CGRect, Bool, Bool) -> Bool let sendBotContextResultAsGif: (ChatContextResultCollection, ChatContextResult, UIView, CGRect, Bool) -> Bool let requestMessageActionCallback: (MessageId, MemoryBuffer?, Bool, Bool) -> Void let requestMessageActionUrlAuth: (String, MessageActionUrlSubject) -> Void let activateSwitchInline: (PeerId?, String) -> Void let openUrl: (String, Bool, Bool?, Message?) -> Void let shareCurrentLocation: () -> Void let shareAccountContact: () -> Void let sendBotCommand: (MessageId?, String) -> Void let openInstantPage: (Message, ChatMessageItemAssociatedData?) -> Void let openWallpaper: (Message) -> Void let openTheme: (Message) -> Void let openHashtag: (String?, String) -> Void let updateInputState: ((ChatTextInputState) -> ChatTextInputState) -> Void let updateInputMode: ((ChatInputMode) -> ChatInputMode) -> Void let openMessageShareMenu: (MessageId) -> Void let presentController: (ViewController, Any?) -> Void let presentControllerInCurrent: (ViewController, Any?) -> Void let navigationController: () -> NavigationController? let chatControllerNode: () -> ASDisplayNode? let presentGlobalOverlayController: (ViewController, Any?) -> Void let callPeer: (PeerId, Bool) -> Void let longTap: (ChatControllerInteractionLongTapAction, Message?) -> Void let openCheckoutOrReceipt: (MessageId) -> Void let openSearch: () -> Void let setupReply: (MessageId) -> Void let canSetupReply: (Message) -> ChatControllerInteractionSwipeAction let navigateToFirstDateMessage: (Int32, Bool) -> Void let requestRedeliveryOfFailedMessages: (MessageId) -> Void let addContact: (String) -> Void let rateCall: (Message, CallId, Bool) -> Void let requestSelectMessagePollOptions: (MessageId, [Data]) -> Void let requestOpenMessagePollResults: (MessageId, MediaId) -> Void let openAppStorePage: () -> Void let displayMessageTooltip: (MessageId, String, ASDisplayNode?, CGRect?) -> Void let seekToTimecode: (Message, Double, Bool) -> Void let scheduleCurrentMessage: () -> Void let sendScheduledMessagesNow: ([MessageId]) -> Void let editScheduledMessagesTime: ([MessageId]) -> Void let performTextSelectionAction: (UInt32, NSAttributedString, TextSelectionAction) -> Void let displayImportedMessageTooltip: (ASDisplayNode) -> Void let displaySwipeToReplyHint: () -> Void let dismissReplyMarkupMessage: (Message) -> Void let openMessagePollResults: (MessageId, Data) -> Void let openPollCreation: (Bool?) -> Void let displayPollSolution: (TelegramMediaPollResults.Solution, ASDisplayNode) -> Void let displayPsa: (String, ASDisplayNode) -> Void let displayDiceTooltip: (TelegramMediaDice) -> Void let animateDiceSuccess: (Bool, Bool) -> Void let displayPremiumStickerTooltip: (TelegramMediaFile, Message) -> Void let openPeerContextMenu: (Peer, MessageId?, ASDisplayNode, CGRect, ContextGesture?) -> Void let openMessageReplies: (MessageId, Bool, Bool) -> Void let openReplyThreadOriginalMessage: (Message) -> Void let openMessageStats: (MessageId) -> Void let editMessageMedia: (MessageId, Bool) -> Void let copyText: (String) -> Void let displayUndo: (UndoOverlayContent) -> Void let isAnimatingMessage: (UInt32) -> Bool let getMessageTransitionNode: () -> ChatMessageTransitionNode? let updateChoosingSticker: (Bool) -> Void let commitEmojiInteraction: (MessageId, String, EmojiInteraction, TelegramMediaFile) -> Void let openLargeEmojiInfo: (String, String?, TelegramMediaFile) -> Void let openJoinLink: (String) -> Void let openWebView: (String, String, Bool, Bool) -> Void let requestMessageUpdate: (MessageId) -> Void let cancelInteractiveKeyboardGestures: () -> Void let dismissTextInput: () -> Void var canPlayMedia: Bool = false var hiddenMedia: [MessageId: [Media]] = [:] var expandedTranslationMessageStableIds: Set = Set() var selectionState: ChatInterfaceSelectionState? var highlightedState: ChatInterfaceHighlightedState? var contextHighlightedState: ChatInterfaceHighlightedState? var automaticMediaDownloadSettings: MediaAutoDownloadSettings var pollActionState: ChatInterfacePollActionState var currentPollMessageWithTooltip: MessageId? var currentPsaMessageWithTooltip: MessageId? var stickerSettings: ChatInterfaceStickerSettings var searchTextHighightState: (String, [MessageIndex])? var unreadMessageRange: [UnreadMessageRangeKey: Range] = [:] var seenOneTimeAnimatedMedia = Set() var currentMessageWithLoadingReplyThread: MessageId? var updatedPresentationData: (initial: PresentationData, signal: Signal)? let presentationContext: ChatPresentationContext var playNextOutgoingGift: Bool = false init( openMessage: @escaping (Message, ChatControllerInteractionOpenMessageMode) -> Bool, openPeer: @escaping (PeerId?, ChatControllerInteractionNavigateToPeer, MessageReference?, Bool, Peer?) -> Void, openPeerMention: @escaping (String) -> Void, openMessageContextMenu: @escaping (Message, Bool, ASDisplayNode, CGRect, UIGestureRecognizer?, CGPoint?) -> Void, openMessageReactionContextMenu: @escaping (Message, ContextExtractedContentContainingView, ContextGesture?, MessageReaction.Reaction) -> Void, updateMessageReaction: @escaping (Message, ChatControllerInteractionReaction) -> Void, activateMessagePinch: @escaping (PinchSourceContainerNode) -> Void, openMessageContextActions: @escaping (Message, ASDisplayNode, CGRect, ContextGesture?) -> Void, navigateToMessage: @escaping (MessageId, MessageId) -> Void, navigateToMessageStandalone: @escaping (MessageId) -> Void, tapMessage: ((Message) -> Void)?, clickThroughMessage: @escaping () -> Void, toggleMessagesSelection: @escaping ([MessageId], Bool) -> Void, sendCurrentMessage: @escaping (Bool) -> Void, sendMessage: @escaping (String) -> Void, sendSticker: @escaping (FileMediaReference, Bool, Bool, String?, Bool, UIView, CGRect, CALayer?) -> Bool, sendEmoji: @escaping (String, ChatTextInputTextCustomEmojiAttribute) -> Void, sendGif: @escaping (FileMediaReference, UIView, CGRect, Bool, Bool) -> Bool, sendBotContextResultAsGif: @escaping (ChatContextResultCollection, ChatContextResult, UIView, CGRect, Bool) -> Bool, requestMessageActionCallback: @escaping (MessageId, MemoryBuffer?, Bool, Bool) -> Void, requestMessageActionUrlAuth: @escaping (String, MessageActionUrlSubject) -> Void, activateSwitchInline: @escaping (PeerId?, String) -> Void, openUrl: @escaping (String, Bool, Bool?, Message?) -> Void, shareCurrentLocation: @escaping () -> Void, shareAccountContact: @escaping () -> Void, sendBotCommand: @escaping (MessageId?, String) -> Void, openInstantPage: @escaping (Message, ChatMessageItemAssociatedData?) -> Void, openWallpaper: @escaping (Message) -> Void, openTheme: @escaping (Message) -> Void, openHashtag: @escaping (String?, String) -> Void, updateInputState: @escaping ((ChatTextInputState) -> ChatTextInputState) -> Void, updateInputMode: @escaping ((ChatInputMode) -> ChatInputMode) -> Void, openMessageShareMenu: @escaping (MessageId) -> Void, presentController: @escaping (ViewController, Any?) -> Void, presentControllerInCurrent: @escaping (ViewController, Any?) -> Void, navigationController: @escaping () -> NavigationController?, chatControllerNode: @escaping () -> ASDisplayNode?, presentGlobalOverlayController: @escaping (ViewController, Any?) -> Void, callPeer: @escaping (PeerId, Bool) -> Void, longTap: @escaping (ChatControllerInteractionLongTapAction, Message?) -> Void, openCheckoutOrReceipt: @escaping (MessageId) -> Void, openSearch: @escaping () -> Void, setupReply: @escaping (MessageId) -> Void, canSetupReply: @escaping (Message) -> ChatControllerInteractionSwipeAction, navigateToFirstDateMessage: @escaping(Int32, Bool) ->Void, requestRedeliveryOfFailedMessages: @escaping (MessageId) -> Void, addContact: @escaping (String) -> Void, rateCall: @escaping (Message, CallId, Bool) -> Void, requestSelectMessagePollOptions: @escaping (MessageId, [Data]) -> Void, requestOpenMessagePollResults: @escaping (MessageId, MediaId) -> Void, openAppStorePage: @escaping () -> Void, displayMessageTooltip: @escaping (MessageId, String, ASDisplayNode?, CGRect?) -> Void, seekToTimecode: @escaping (Message, Double, Bool) -> Void, scheduleCurrentMessage: @escaping () -> Void, sendScheduledMessagesNow: @escaping ([MessageId]) -> Void, editScheduledMessagesTime: @escaping ([MessageId]) -> Void, performTextSelectionAction: @escaping (UInt32, NSAttributedString, TextSelectionAction) -> Void, displayImportedMessageTooltip: @escaping (ASDisplayNode) -> Void, displaySwipeToReplyHint: @escaping () -> Void, dismissReplyMarkupMessage: @escaping (Message) -> Void, openMessagePollResults: @escaping (MessageId, Data) -> Void, openPollCreation: @escaping (Bool?) -> Void, displayPollSolution: @escaping (TelegramMediaPollResults.Solution, ASDisplayNode) -> Void, displayPsa: @escaping (String, ASDisplayNode) -> Void, displayDiceTooltip: @escaping (TelegramMediaDice) -> Void, animateDiceSuccess: @escaping (Bool, Bool) -> Void, displayPremiumStickerTooltip: @escaping (TelegramMediaFile, Message) -> Void, openPeerContextMenu: @escaping (Peer, MessageId?, ASDisplayNode, CGRect, ContextGesture?) -> Void, openMessageReplies: @escaping (MessageId, Bool, Bool) -> Void, openReplyThreadOriginalMessage: @escaping (Message) -> Void, openMessageStats: @escaping (MessageId) -> Void, editMessageMedia: @escaping (MessageId, Bool) -> Void, copyText: @escaping (String) -> Void, displayUndo: @escaping (UndoOverlayContent) -> Void, isAnimatingMessage: @escaping (UInt32) -> Bool, getMessageTransitionNode: @escaping () -> ChatMessageTransitionNode?, updateChoosingSticker: @escaping (Bool) -> Void, commitEmojiInteraction: @escaping (MessageId, String, EmojiInteraction, TelegramMediaFile) -> Void, openLargeEmojiInfo: @escaping (String, String?, TelegramMediaFile) -> Void, openJoinLink: @escaping (String) -> Void, openWebView: @escaping (String, String, Bool, Bool) -> Void, requestMessageUpdate: @escaping (MessageId) -> Void, cancelInteractiveKeyboardGestures: @escaping () -> Void, dismissTextInput: @escaping () -> Void, automaticMediaDownloadSettings: MediaAutoDownloadSettings, pollActionState: ChatInterfacePollActionState, stickerSettings: ChatInterfaceStickerSettings, presentationContext: ChatPresentationContext ) { self.openMessage = openMessage self.openPeer = openPeer self.openPeerMention = openPeerMention self.openMessageContextMenu = openMessageContextMenu self.openMessageReactionContextMenu = openMessageReactionContextMenu self.updateMessageReaction = updateMessageReaction self.activateMessagePinch = activateMessagePinch self.openMessageContextActions = openMessageContextActions self.navigateToMessage = navigateToMessage self.navigateToMessageStandalone = navigateToMessageStandalone self.tapMessage = tapMessage self.clickThroughMessage = clickThroughMessage self.toggleMessagesSelection = toggleMessagesSelection self.sendCurrentMessage = sendCurrentMessage self.sendMessage = sendMessage self.sendSticker = sendSticker self.sendEmoji = sendEmoji self.sendGif = sendGif self.sendBotContextResultAsGif = sendBotContextResultAsGif self.requestMessageActionCallback = requestMessageActionCallback self.requestMessageActionUrlAuth = requestMessageActionUrlAuth self.activateSwitchInline = activateSwitchInline self.openUrl = openUrl self.shareCurrentLocation = shareCurrentLocation self.shareAccountContact = shareAccountContact self.sendBotCommand = sendBotCommand self.openInstantPage = openInstantPage self.openWallpaper = openWallpaper self.openTheme = openTheme self.openHashtag = openHashtag self.updateInputState = updateInputState self.updateInputMode = updateInputMode self.openMessageShareMenu = openMessageShareMenu self.presentController = presentController self.presentControllerInCurrent = presentControllerInCurrent self.navigationController = navigationController self.chatControllerNode = chatControllerNode self.presentGlobalOverlayController = presentGlobalOverlayController self.callPeer = callPeer self.longTap = longTap self.openCheckoutOrReceipt = openCheckoutOrReceipt self.openSearch = openSearch self.setupReply = setupReply self.canSetupReply = canSetupReply self.navigateToFirstDateMessage = navigateToFirstDateMessage self.requestRedeliveryOfFailedMessages = requestRedeliveryOfFailedMessages self.addContact = addContact self.rateCall = rateCall self.requestSelectMessagePollOptions = requestSelectMessagePollOptions self.requestOpenMessagePollResults = requestOpenMessagePollResults self.openPollCreation = openPollCreation self.displayPollSolution = displayPollSolution self.displayPsa = displayPsa self.openAppStorePage = openAppStorePage self.displayMessageTooltip = displayMessageTooltip self.seekToTimecode = seekToTimecode self.scheduleCurrentMessage = scheduleCurrentMessage self.sendScheduledMessagesNow = sendScheduledMessagesNow self.editScheduledMessagesTime = editScheduledMessagesTime self.performTextSelectionAction = performTextSelectionAction self.displayImportedMessageTooltip = displayImportedMessageTooltip self.displaySwipeToReplyHint = displaySwipeToReplyHint self.dismissReplyMarkupMessage = dismissReplyMarkupMessage self.openMessagePollResults = openMessagePollResults self.displayDiceTooltip = displayDiceTooltip self.animateDiceSuccess = animateDiceSuccess self.displayPremiumStickerTooltip = displayPremiumStickerTooltip self.openPeerContextMenu = openPeerContextMenu self.openMessageReplies = openMessageReplies self.openReplyThreadOriginalMessage = openReplyThreadOriginalMessage self.openMessageStats = openMessageStats self.editMessageMedia = editMessageMedia self.copyText = copyText self.displayUndo = displayUndo self.isAnimatingMessage = isAnimatingMessage self.getMessageTransitionNode = getMessageTransitionNode self.updateChoosingSticker = updateChoosingSticker self.commitEmojiInteraction = commitEmojiInteraction self.openLargeEmojiInfo = openLargeEmojiInfo self.openJoinLink = openJoinLink self.openWebView = openWebView self.requestMessageUpdate = requestMessageUpdate self.cancelInteractiveKeyboardGestures = cancelInteractiveKeyboardGestures self.dismissTextInput = dismissTextInput self.automaticMediaDownloadSettings = automaticMediaDownloadSettings self.pollActionState = pollActionState self.stickerSettings = stickerSettings self.presentationContext = presentationContext } }