Swiftgram/submodules/TelegramUI/Sources/ChatControllerInteraction.swift
2021-02-06 22:38:32 +04:00

349 lines
19 KiB
Swift

import Foundation
import UIKit
import Postbox
import AsyncDisplayKit
import TelegramCore
import SyncCore
import Display
import TelegramUIPreferences
import AccountContext
import TextSelectionNode
import ReactionSelectionNode
import ContextUI
import ChatInterfaceState
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
case like
case unlike
}
public final class ChatControllerInteraction {
let openMessage: (Message, ChatControllerInteractionOpenMessageMode) -> Bool
let openPeer: (PeerId?, ChatControllerInteractionNavigateToPeer, Message?) -> Void
let openPeerMention: (String) -> Void
let openMessageContextMenu: (Message, Bool, ASDisplayNode, CGRect, UIGestureRecognizer?) -> 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, String?, Bool, ASDisplayNode, CGRect) -> Bool
let sendGif: (FileMediaReference, ASDisplayNode, CGRect) -> Bool
let sendBotContextResultAsGif: (ChatContextResultCollection, ChatContextResult, ASDisplayNode, CGRect) -> Bool
let requestMessageActionCallback: (MessageId, MemoryBuffer?, Bool, Bool) -> Void
let requestMessageActionUrlAuth: (String, MessageId, Int32) -> 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 navigationController: () -> NavigationController?
let chatControllerNode: () -> ASDisplayNode?
let reactionContainerNode: () -> ReactionSelectionParentNode?
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) -> 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 updateMessageLike: (MessageId, Bool) -> Void
let openMessageReactions: (MessageId) -> 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) -> Void
let greetingStickerNode: () -> (ASDisplayNode, ASDisplayNode, ASDisplayNode, (@escaping () -> Void) -> 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 requestMessageUpdate: (MessageId) -> Void
let cancelInteractiveKeyboardGestures: () -> Void
var canPlayMedia: Bool = false
var hiddenMedia: [MessageId: [Media]] = [:]
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 seenOneTimeAnimatedMedia = Set<MessageId>()
var currentMessageWithLoadingReplyThread: MessageId?
init(
openMessage: @escaping (Message, ChatControllerInteractionOpenMessageMode) -> Bool,
openPeer: @escaping (PeerId?, ChatControllerInteractionNavigateToPeer, Message?) -> Void,
openPeerMention: @escaping (String) -> Void,
openMessageContextMenu: @escaping (Message, Bool, ASDisplayNode, CGRect, UIGestureRecognizer?) -> 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, String?, Bool, ASDisplayNode, CGRect) -> Bool,
sendGif: @escaping (FileMediaReference, ASDisplayNode, CGRect) -> Bool,
sendBotContextResultAsGif: @escaping (ChatContextResultCollection, ChatContextResult, ASDisplayNode, CGRect) -> Bool,
requestMessageActionCallback: @escaping (MessageId, MemoryBuffer?, Bool, Bool) -> Void,
requestMessageActionUrlAuth: @escaping (String, MessageId, Int32) -> 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,
navigationController: @escaping () -> NavigationController?,
chatControllerNode: @escaping () -> ASDisplayNode?,
reactionContainerNode: @escaping () -> ReactionSelectionParentNode?,
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) ->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,
updateMessageLike: @escaping (MessageId, Bool) -> Void,
openMessageReactions: @escaping (MessageId) -> 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) -> Void,
greetingStickerNode: @escaping () -> (ASDisplayNode, ASDisplayNode, ASDisplayNode, (@escaping () -> Void) -> 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,
requestMessageUpdate: @escaping (MessageId) -> Void,
cancelInteractiveKeyboardGestures: @escaping () -> Void,
automaticMediaDownloadSettings: MediaAutoDownloadSettings,
pollActionState: ChatInterfacePollActionState,
stickerSettings: ChatInterfaceStickerSettings
) {
self.openMessage = openMessage
self.openPeer = openPeer
self.openPeerMention = openPeerMention
self.openMessageContextMenu = openMessageContextMenu
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.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.navigationController = navigationController
self.chatControllerNode = chatControllerNode
self.reactionContainerNode = reactionContainerNode
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.updateMessageLike = updateMessageLike
self.openMessageReactions = openMessageReactions
self.displayImportedMessageTooltip = displayImportedMessageTooltip
self.displaySwipeToReplyHint = displaySwipeToReplyHint
self.dismissReplyMarkupMessage = dismissReplyMarkupMessage
self.openMessagePollResults = openMessagePollResults
self.displayDiceTooltip = displayDiceTooltip
self.animateDiceSuccess = animateDiceSuccess
self.greetingStickerNode = greetingStickerNode
self.openPeerContextMenu = openPeerContextMenu
self.openMessageReplies = openMessageReplies
self.openReplyThreadOriginalMessage = openReplyThreadOriginalMessage
self.openMessageStats = openMessageStats
self.editMessageMedia = editMessageMedia
self.copyText = copyText
self.requestMessageUpdate = requestMessageUpdate
self.cancelInteractiveKeyboardGestures = cancelInteractiveKeyboardGestures
self.automaticMediaDownloadSettings = automaticMediaDownloadSettings
self.pollActionState = pollActionState
self.stickerSettings = stickerSettings
}
static var `default`: ChatControllerInteraction {
return ChatControllerInteraction(openMessage: { _, _ in
return false }, openPeer: { _, _, _ in }, openPeerMention: { _ in }, openMessageContextMenu: { _, _, _, _, _ in }, openMessageContextActions: { _, _, _, _ in }, navigateToMessage: { _, _ in }, navigateToMessageStandalone: { _ in }, tapMessage: nil, clickThroughMessage: { }, toggleMessagesSelection: { _, _ in }, sendCurrentMessage: { _ in }, sendMessage: { _ in }, sendSticker: { _, _, _, _, _ in return false }, sendGif: { _, _, _ in return false }, sendBotContextResultAsGif: { _, _, _, _ in return false }, requestMessageActionCallback: { _, _, _, _ in }, requestMessageActionUrlAuth: { _, _, _ in }, activateSwitchInline: { _, _ in }, openUrl: { _, _, _, _ in }, shareCurrentLocation: {}, shareAccountContact: {}, sendBotCommand: { _, _ in }, openInstantPage: { _, _ in }, openWallpaper: { _ in }, openTheme: { _ in }, openHashtag: { _, _ in }, updateInputState: { _ in }, updateInputMode: { _ in }, openMessageShareMenu: { _ in
}, presentController: { _, _ in }, navigationController: {
return nil
}, chatControllerNode: {
return nil
}, reactionContainerNode: {
return nil
}, presentGlobalOverlayController: { _, _ in }, callPeer: { _, _ in }, longTap: { _, _ in }, openCheckoutOrReceipt: { _ in }, openSearch: { }, setupReply: { _ in
}, canSetupReply: { _ in
return .none
}, navigateToFirstDateMessage: { _ in
}, requestRedeliveryOfFailedMessages: { _ in
}, addContact: { _ in
}, rateCall: { _, _, _ in
}, requestSelectMessagePollOptions: { _, _ in
}, requestOpenMessagePollResults: { _, _ in
}, openAppStorePage: {
}, displayMessageTooltip: { _, _, _, _ in
}, seekToTimecode: { _, _, _ in
}, scheduleCurrentMessage: {
}, sendScheduledMessagesNow: { _ in
}, editScheduledMessagesTime: { _ in
}, performTextSelectionAction: { _, _, _ in
}, updateMessageLike: { _, _ in
}, openMessageReactions: { _ in
}, displayImportedMessageTooltip: { _ in
}, displaySwipeToReplyHint: {
}, dismissReplyMarkupMessage: { _ in
}, openMessagePollResults: { _, _ in
}, openPollCreation: { _ in
}, displayPollSolution: { _, _ in
}, displayPsa: { _, _ in
}, displayDiceTooltip: { _ in
}, animateDiceSuccess: { _ in
}, greetingStickerNode: {
return nil
}, openPeerContextMenu: { _, _, _, _, _ in
}, openMessageReplies: { _, _, _ in
}, openReplyThreadOriginalMessage: { _ in
}, openMessageStats: { _ in
}, editMessageMedia: { _, _ in
}, copyText: { _ in
}, requestMessageUpdate: { _ in
}, cancelInteractiveKeyboardGestures: {
}, automaticMediaDownloadSettings: MediaAutoDownloadSettings.defaultSettings,
pollActionState: ChatInterfacePollActionState(), stickerSettings: ChatInterfaceStickerSettings(loopAnimatedStickers: false))
}
}