mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-22 22:25:57 +00:00
[WIP] Quotes
This commit is contained in:
@@ -38,6 +38,7 @@ import SolidRoundedButtonNode
|
||||
import TooltipUI
|
||||
import ChatTextInputMediaRecordingButton
|
||||
import ChatContextQuery
|
||||
import ChatInputTextNode
|
||||
|
||||
private let accessoryButtonFont = Font.medium(14.0)
|
||||
private let counterFont = Font.with(size: 14.0, design: .regular, traits: [.monospacedNumbers])
|
||||
@@ -468,7 +469,7 @@ final class ChatTextViewForOverlayContent: UIView, ChatInputPanelViewForOverlayC
|
||||
}
|
||||
}
|
||||
|
||||
class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate, ChatInputTextNodeDelegate {
|
||||
let clippingNode: ASDisplayNode
|
||||
var textPlaceholderNode: ImmediateTextNode
|
||||
var textLockIconNode: ASImageNode?
|
||||
@@ -476,7 +477,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
var slowmodePlaceholderNode: ChatTextInputSlowmodePlaceholderNode?
|
||||
let textInputContainerBackgroundNode: ASImageNode
|
||||
let textInputContainer: ASDisplayNode
|
||||
var textInputNode: EditableTextNode?
|
||||
var textInputNode: ChatInputTextNode?
|
||||
var dustNode: InvisibleInkDustNode?
|
||||
var customEmojiContainerView: CustomEmojiContainerView?
|
||||
|
||||
@@ -557,7 +558,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
var storedInputLanguage: String?
|
||||
var effectiveInputLanguage: String? {
|
||||
if let textInputNode = textInputNode, textInputNode.isFirstResponder() {
|
||||
return textInputNode.textInputMode.primaryLanguage
|
||||
return textInputNode.textInputMode?.primaryLanguage
|
||||
} else {
|
||||
return self.storedInputLanguage
|
||||
}
|
||||
@@ -673,7 +674,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
textInputNode.selectedRange = NSMakeRange(state.selectionRange.lowerBound, state.selectionRange.count)
|
||||
|
||||
if let presentationInterfaceState = self.presentationInterfaceState {
|
||||
refreshChatTextInputAttributes(textInputNode, theme: presentationInterfaceState.theme, baseFontSize: baseFontSize, spoilersRevealed: self.spoilersRevealed, availableEmojis: (self.context?.animatedEmojiStickers.keys).flatMap(Set.init) ?? Set(), emojiViewProvider: self.emojiViewProvider)
|
||||
refreshChatTextInputAttributes(textInputNode.textView, theme: presentationInterfaceState.theme, baseFontSize: baseFontSize, spoilersRevealed: self.spoilersRevealed, availableEmojis: (self.context?.animatedEmojiStickers.keys).flatMap(Set.init) ?? Set(), emojiViewProvider: self.emojiViewProvider)
|
||||
}
|
||||
|
||||
self.updatingInputState = false
|
||||
@@ -704,12 +705,12 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
baseFontSize = max(minInputFontSize, presentationInterfaceState.fontSize.baseDisplaySize)
|
||||
}
|
||||
textInputNode.attributedText = NSAttributedString(string: value, font: Font.regular(baseFontSize), textColor: textColor)
|
||||
self.editableTextNodeDidUpdateText(textInputNode)
|
||||
self.chatInputTextNodeDidUpdateText()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private let textInputViewInternalInsets = UIEdgeInsets(top: 1.0, left: 13.0, bottom: 1.0, right: 13.0)
|
||||
private let textInputViewInternalInsets: UIEdgeInsets
|
||||
private let accessoryButtonSpacing: CGFloat = 0.0
|
||||
private let accessoryButtonInset: CGFloat = 2.0
|
||||
|
||||
@@ -726,6 +727,8 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
init(context: AccountContext, presentationInterfaceState: ChatPresentationInterfaceState, presentationContext: ChatPresentationContext?, presentController: @escaping (ViewController) -> Void) {
|
||||
self.presentationInterfaceState = presentationInterfaceState
|
||||
self.presentationContext = presentationContext
|
||||
|
||||
self.textInputViewInternalInsets = UIEdgeInsets(top: 1.0, left: 13.0, bottom: 1.0, right: 13.0)
|
||||
|
||||
var hasSpoilers = true
|
||||
if presentationInterfaceState.chatLocation.peerId?.namespace == Namespaces.Peer.SecretChat {
|
||||
@@ -1024,6 +1027,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
self.statusDisposable.dispose()
|
||||
self.startingBotDisposable.dispose()
|
||||
self.tooltipController?.dismiss()
|
||||
self.currentEmojiSuggestion?.disposable.dispose()
|
||||
}
|
||||
|
||||
func loadTextInputNodeIfNeeded() {
|
||||
@@ -1033,13 +1037,20 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
}
|
||||
|
||||
private func loadTextInputNode() {
|
||||
let textInputNode = EditableChatTextNode()
|
||||
let textInputNode = ChatInputTextNode()
|
||||
textInputNode.initialPrimaryLanguage = self.presentationInterfaceState?.interfaceState.inputLanguage
|
||||
var textColor: UIColor = .black
|
||||
var tintColor: UIColor = .blue
|
||||
var baseFontSize: CGFloat = 17.0
|
||||
var keyboardAppearance: UIKeyboardAppearance = UIKeyboardAppearance.default
|
||||
if let presentationInterfaceState = self.presentationInterfaceState {
|
||||
textInputNode.textView.theme = ChatInputTextView.Theme(
|
||||
quote: ChatInputTextView.Theme.Quote(
|
||||
background: presentationInterfaceState.theme.list.itemAccentColor.withMultipliedAlpha(presentationInterfaceState.theme.overallDarkAppearance ? 0.2 : 0.1),
|
||||
foreground: presentationInterfaceState.theme.list.itemAccentColor
|
||||
)
|
||||
)
|
||||
|
||||
textColor = presentationInterfaceState.theme.chat.inputPanel.inputTextColor
|
||||
tintColor = presentationInterfaceState.theme.list.itemAccentColor
|
||||
baseFontSize = max(minInputFontSize, presentationInterfaceState.fontSize.baseDisplaySize)
|
||||
@@ -1053,7 +1064,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
paragraphStyle.maximumLineHeight = 20.0
|
||||
paragraphStyle.minimumLineHeight = 20.0
|
||||
|
||||
textInputNode.typingAttributes = [NSAttributedString.Key.font.rawValue: Font.regular(max(minInputFontSize, baseFontSize)), NSAttributedString.Key.foregroundColor.rawValue: textColor, NSAttributedString.Key.paragraphStyle.rawValue: paragraphStyle]
|
||||
textInputNode.textView.typingAttributes = [NSAttributedString.Key.font: Font.regular(max(minInputFontSize, baseFontSize)), NSAttributedString.Key.foregroundColor: textColor, NSAttributedString.Key.paragraphStyle: paragraphStyle]
|
||||
textInputNode.clipsToBounds = false
|
||||
textInputNode.textView.clipsToBounds = false
|
||||
textInputNode.delegate = self
|
||||
@@ -1079,7 +1090,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
}
|
||||
|
||||
if let presentationInterfaceState = self.presentationInterfaceState {
|
||||
refreshChatTextInputTypingAttributes(textInputNode, theme: presentationInterfaceState.theme, baseFontSize: baseFontSize)
|
||||
refreshChatTextInputTypingAttributes(textInputNode.textView, theme: presentationInterfaceState.theme, baseFontSize: baseFontSize)
|
||||
textInputNode.textContainerInset = calculateTextFieldRealInsets(presentationInterfaceState: presentationInterfaceState, accessoryButtonsWidth: accessoryButtonsWidth)
|
||||
}
|
||||
|
||||
@@ -1087,6 +1098,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
let textInputFrame = self.textInputContainer.frame
|
||||
|
||||
textInputNode.frame = CGRect(origin: CGPoint(x: self.textInputViewInternalInsets.left, y: self.textInputViewInternalInsets.top), size: CGSize(width: textInputFrame.size.width - (self.textInputViewInternalInsets.left + self.textInputViewInternalInsets.right), height: textInputFrame.size.height - self.textInputViewInternalInsets.top - self.textInputViewInternalInsets.bottom))
|
||||
textInputNode.updateLayout(size: textInputNode.bounds.size)
|
||||
textInputNode.view.layoutIfNeeded()
|
||||
self.updateSpoiler()
|
||||
}
|
||||
@@ -1167,8 +1179,11 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
let textFieldHeight: CGFloat
|
||||
if let textInputNode = self.textInputNode {
|
||||
let maxTextWidth = width - textFieldInsets.left - textFieldInsets.right - self.textInputViewInternalInsets.left - self.textInputViewInternalInsets.right
|
||||
let measuredHeight = textInputNode.measure(CGSize(width: maxTextWidth, height: CGFloat.greatestFiniteMagnitude))
|
||||
let unboundTextFieldHeight = max(textFieldMinHeight, ceil(measuredHeight.height))
|
||||
|
||||
//let measuredHeight = textInputNode.measure(CGSize(width: maxTextWidth, height: CGFloat.greatestFiniteMagnitude))
|
||||
let measuredHeight = textInputNode.textHeightForWidth(maxTextWidth)
|
||||
|
||||
let unboundTextFieldHeight = max(textFieldMinHeight, ceil(measuredHeight))
|
||||
|
||||
let maxNumberOfLines = min(12, (Int(fieldMaxHeight - 11.0) - 33) / 22)
|
||||
|
||||
@@ -1595,7 +1610,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
textInputNode.attributedText = updatedText
|
||||
textInputNode.selectedRange = range
|
||||
}
|
||||
textInputNode.typingAttributes = [NSAttributedString.Key.font.rawValue: Font.regular(baseFontSize), NSAttributedString.Key.foregroundColor.rawValue: textColor]
|
||||
textInputNode.textView.typingAttributes = [NSAttributedString.Key.font: Font.regular(baseFontSize), NSAttributedString.Key.foregroundColor: textColor]
|
||||
|
||||
self.updateSpoiler()
|
||||
}
|
||||
@@ -1607,6 +1622,15 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
textInputNode.tintColorDidChange()
|
||||
}
|
||||
|
||||
if let textInputNode = self.textInputNode {
|
||||
textInputNode.textView.theme = ChatInputTextView.Theme(
|
||||
quote: ChatInputTextView.Theme.Quote(
|
||||
background: interfaceState.theme.list.itemAccentColor.withMultipliedAlpha(interfaceState.theme.overallDarkAppearance ? 0.2 : 0.1),
|
||||
foreground: interfaceState.theme.list.itemAccentColor
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
let keyboardAppearance = interfaceState.theme.rootController.keyboardColor.keyboardAppearance
|
||||
if let textInputNode = self.textInputNode, textInputNode.keyboardAppearance != keyboardAppearance {
|
||||
if textInputNode.isFirstResponder() && textInputNode.isCurrentlyEmoji() {
|
||||
@@ -1673,7 +1697,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
}
|
||||
|
||||
let dismissedButtonMessageUpdated = interfaceState.interfaceState.messageActionsState.dismissedButtonKeyboardMessageId != previousState?.interfaceState.messageActionsState.dismissedButtonKeyboardMessageId
|
||||
let replyMessageUpdated = interfaceState.interfaceState.replyMessageId != previousState?.interfaceState.replyMessageId
|
||||
let replyMessageUpdated = interfaceState.interfaceState.replyMessageSubject != previousState?.interfaceState.replyMessageSubject
|
||||
|
||||
if let peer = interfaceState.renderedPeer?.peer, previousState?.renderedPeer?.peer == nil || !peer.isEqual(previousState!.renderedPeer!.peer!) || previousState?.interfaceState.silentPosting != interfaceState.interfaceState.silentPosting || themeUpdated || !self.initializedPlaceholder || previousState?.keyboardButtonsMessage?.id != interfaceState.keyboardButtonsMessage?.id || previousState?.keyboardButtonsMessage?.visibleReplyMarkupPlaceholder != interfaceState.keyboardButtonsMessage?.visibleReplyMarkupPlaceholder || dismissedButtonMessageUpdated || replyMessageUpdated || (previousState?.interfaceState.editMessage == nil) != (interfaceState.interfaceState.editMessage == nil) {
|
||||
self.initializedPlaceholder = true
|
||||
@@ -1705,7 +1729,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
}
|
||||
|
||||
if let keyboardButtonsMessage = interfaceState.keyboardButtonsMessage, interfaceState.interfaceState.messageActionsState.dismissedButtonKeyboardMessageId != keyboardButtonsMessage.id {
|
||||
if keyboardButtonsMessage.requestsSetupReply && keyboardButtonsMessage.id != interfaceState.interfaceState.replyMessageId {
|
||||
if keyboardButtonsMessage.requestsSetupReply && keyboardButtonsMessage.id != interfaceState.interfaceState.replyMessageSubject?.messageId {
|
||||
} else {
|
||||
if let placeholderValue = interfaceState.keyboardButtonsMessage?.visibleReplyMarkupPlaceholder, !placeholderValue.isEmpty {
|
||||
placeholder = placeholderValue
|
||||
@@ -2255,6 +2279,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
let textFieldFrame = CGRect(origin: CGPoint(x: self.textInputViewInternalInsets.left, y: self.textInputViewInternalInsets.top), size: CGSize(width: textInputFrame.size.width - (self.textInputViewInternalInsets.left + self.textInputViewInternalInsets.right), height: textInputFrame.size.height - self.textInputViewInternalInsets.top - textInputViewInternalInsets.bottom))
|
||||
let shouldUpdateLayout = textFieldFrame.size != textInputNode.frame.size
|
||||
transition.updateFrame(node: textInputNode, frame: textFieldFrame)
|
||||
textInputNode.updateLayout(size: textFieldFrame.size)
|
||||
self.updateInputField(textInputFrame: textFieldFrame, transition: Transition(transition))
|
||||
if shouldUpdateLayout {
|
||||
textInputNode.layout()
|
||||
@@ -2513,24 +2538,28 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
return prevInputPanelNode is ChatRecordingPreviewInputPanelNode
|
||||
}
|
||||
|
||||
@objc func editableTextNodeDidUpdateText(_ editableTextNode: ASEditableTextNode) {
|
||||
func chatInputTextNodeDidUpdateText() {
|
||||
if let textInputNode = self.textInputNode, let presentationInterfaceState = self.presentationInterfaceState {
|
||||
let baseFontSize = max(minInputFontSize, presentationInterfaceState.fontSize.baseDisplaySize)
|
||||
refreshChatTextInputAttributes(textInputNode, theme: presentationInterfaceState.theme, baseFontSize: baseFontSize, spoilersRevealed: self.spoilersRevealed, availableEmojis: (self.context?.animatedEmojiStickers.keys).flatMap(Set.init) ?? Set(), emojiViewProvider: self.emojiViewProvider)
|
||||
refreshChatTextInputTypingAttributes(textInputNode, theme: presentationInterfaceState.theme, baseFontSize: baseFontSize)
|
||||
refreshChatTextInputAttributes(textInputNode.textView, theme: presentationInterfaceState.theme, baseFontSize: baseFontSize, spoilersRevealed: self.spoilersRevealed, availableEmojis: (self.context?.animatedEmojiStickers.keys).flatMap(Set.init) ?? Set(), emojiViewProvider: self.emojiViewProvider)
|
||||
refreshChatTextInputTypingAttributes(textInputNode.textView, theme: presentationInterfaceState.theme, baseFontSize: baseFontSize)
|
||||
|
||||
self.updateSpoiler()
|
||||
|
||||
let inputTextState = self.inputTextState
|
||||
|
||||
self.interfaceInteraction?.updateTextInputStateAndMode({ _, inputMode in return (inputTextState, inputMode) })
|
||||
self.interfaceInteraction?.updateInputLanguage({ _ in return textInputNode.textInputMode.primaryLanguage })
|
||||
self.interfaceInteraction?.updateInputLanguage({ _ in return textInputNode.textInputMode?.primaryLanguage })
|
||||
self.updateTextNodeText(animated: true)
|
||||
|
||||
self.updateCounterTextNode(transition: .immediate)
|
||||
}
|
||||
}
|
||||
|
||||
@objc func editableTextNodeDidUpdateText(_ editableTextNode: ASEditableTextNode) {
|
||||
self.chatInputTextNodeDidUpdateText()
|
||||
}
|
||||
|
||||
private func updateSpoiler() {
|
||||
guard let textInputNode = self.textInputNode, let presentationInterfaceState = self.presentationInterfaceState else {
|
||||
return
|
||||
@@ -2678,7 +2707,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
|
||||
textInputNode.textView.isScrollEnabled = false
|
||||
|
||||
refreshChatTextInputAttributes(textInputNode, theme: presentationInterfaceState.theme, baseFontSize: baseFontSize, spoilersRevealed: self.spoilersRevealed, availableEmojis: (self.context?.animatedEmojiStickers.keys).flatMap(Set.init) ?? Set(), emojiViewProvider: self.emojiViewProvider)
|
||||
refreshChatTextInputAttributes(textInputNode.textView, theme: presentationInterfaceState.theme, baseFontSize: baseFontSize, spoilersRevealed: self.spoilersRevealed, availableEmojis: (self.context?.animatedEmojiStickers.keys).flatMap(Set.init) ?? Set(), emojiViewProvider: self.emojiViewProvider)
|
||||
|
||||
textInputNode.attributedText = textAttributedStringForStateText(self.inputTextState.inputText, fontSize: baseFontSize, textColor: textColor, accentTextColor: accentTextColor, writingDirection: nil, spoilersRevealed: self.spoilersRevealed, availableEmojis: (self.context?.animatedEmojiStickers.keys).flatMap(Set.init) ?? Set(), emojiViewProvider: self.emojiViewProvider)
|
||||
|
||||
@@ -2783,6 +2812,8 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
} else {
|
||||
beginRequest = true
|
||||
suggestionContext = CurrentEmojiSuggestion(localPosition: trackingPosition, position: emojiSuggestionPosition, disposable: MetaDisposable(), value: nil)
|
||||
|
||||
self.currentEmojiSuggestion?.disposable.dispose()
|
||||
self.currentEmojiSuggestion = suggestionContext
|
||||
}
|
||||
suggestionContext.localPosition = trackingPosition
|
||||
@@ -3442,13 +3473,17 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
}
|
||||
}
|
||||
|
||||
@objc func editableTextNodeShouldReturn(_ editableTextNode: ASEditableTextNode) -> Bool {
|
||||
func chatInputTextNodeShouldReturn() -> Bool {
|
||||
if self.actionButtons.sendButton.supernode != nil && !self.actionButtons.sendButton.isHidden && !self.actionButtons.sendContainerNode.alpha.isZero {
|
||||
self.sendButtonPressed()
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
@objc func editableTextNodeShouldReturn(_ editableTextNode: ASEditableTextNode) -> Bool {
|
||||
return self.chatInputTextNodeShouldReturn()
|
||||
}
|
||||
|
||||
private func applyUpdateSendButtonIcon() {
|
||||
if let interfaceState = self.presentationInterfaceState {
|
||||
let sendButtonHasApplyIcon = interfaceState.interfaceState.editMessage != nil
|
||||
@@ -3468,7 +3503,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
}
|
||||
}
|
||||
|
||||
@objc func editableTextNodeDidChangeSelection(_ editableTextNode: ASEditableTextNode, fromSelectedRange: NSRange, toSelectedRange: NSRange, dueToEditing: Bool) {
|
||||
func chatInputTextNodeDidChangeSelection(dueToEditing: Bool) {
|
||||
if !dueToEditing && !self.updatingInputState {
|
||||
let inputTextState = self.inputTextState
|
||||
self.interfaceInteraction?.updateTextInputStateAndMode({ _, inputMode in return (inputTextState, inputMode) })
|
||||
@@ -3480,7 +3515,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
}
|
||||
|
||||
let baseFontSize = max(minInputFontSize, presentationInterfaceState.fontSize.baseDisplaySize)
|
||||
refreshChatTextInputTypingAttributes(textInputNode, theme: presentationInterfaceState.theme, baseFontSize: baseFontSize)
|
||||
refreshChatTextInputTypingAttributes(textInputNode.textView, theme: presentationInterfaceState.theme, baseFontSize: baseFontSize)
|
||||
|
||||
self.updateSpoilersRevealed()
|
||||
|
||||
@@ -3488,7 +3523,11 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
}
|
||||
}
|
||||
|
||||
@objc func editableTextNodeDidBeginEditing(_ editableTextNode: ASEditableTextNode) {
|
||||
@objc func editableTextNodeDidChangeSelection(_ editableTextNode: ASEditableTextNode, fromSelectedRange: NSRange, toSelectedRange: NSRange, dueToEditing: Bool) {
|
||||
self.chatInputTextNodeDidChangeSelection(dueToEditing: dueToEditing)
|
||||
}
|
||||
|
||||
func chatInputTextNodeDidBeginEditing() {
|
||||
guard let interfaceInteraction = self.interfaceInteraction, let presentationInterfaceState = self.presentationInterfaceState else {
|
||||
return
|
||||
}
|
||||
@@ -3509,9 +3548,17 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
self.inputMenu.activate()
|
||||
}
|
||||
|
||||
@objc func editableTextNodeDidBeginEditing(_ editableTextNode: ASEditableTextNode) {
|
||||
self.chatInputTextNodeDidBeginEditing()
|
||||
}
|
||||
|
||||
var skipPresentationInterfaceStateUpdate = false
|
||||
func editableTextNodeDidFinishEditing(_ editableTextNode: ASEditableTextNode) {
|
||||
self.storedInputLanguage = editableTextNode.textInputMode.primaryLanguage
|
||||
func chatInputTextNodeDidFinishEditing() {
|
||||
guard let editableTextNode = self.textInputNode else {
|
||||
return
|
||||
}
|
||||
|
||||
self.storedInputLanguage = editableTextNode.textInputMode?.primaryLanguage
|
||||
self.inputMenu.deactivate()
|
||||
self.dismissedEmojiSuggestionPosition = nil
|
||||
|
||||
@@ -3535,6 +3582,13 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
}
|
||||
}
|
||||
|
||||
func editableTextNodeDidFinishEditing(_ editableTextNode: ASEditableTextNode) {
|
||||
self.chatInputTextNodeDidFinishEditing()
|
||||
}
|
||||
|
||||
func chatInputTextNodeBackspaceWhileEmpty() {
|
||||
}
|
||||
|
||||
func editableTextNodeTarget(forAction action: Selector) -> ASEditableTextNodeTargetForAction? {
|
||||
if action == makeSelectorFromString("_accessibilitySpeak:") {
|
||||
if case .format = self.inputMenu.state {
|
||||
@@ -3610,8 +3664,12 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
return nil
|
||||
}
|
||||
|
||||
@available(iOS 16.0, *)
|
||||
func editableTextNodeMenu(_ editableTextNode: ASEditableTextNode, forTextRange textRange: NSRange, suggestedActions: [UIMenuElement]) -> UIMenu {
|
||||
@available(iOS 13.0, *)
|
||||
func chatInputTextNodeMenu(forTextRange textRange: NSRange, suggestedActions: [UIMenuElement]) -> UIMenu {
|
||||
guard let editableTextNode = self.textInputNode else {
|
||||
return UIMenu(children: [])
|
||||
}
|
||||
|
||||
var actions = suggestedActions
|
||||
|
||||
if editableTextNode.attributedText == nil || editableTextNode.attributedText!.length == 0 || editableTextNode.selectedRange.length == 0 {
|
||||
@@ -3678,6 +3736,11 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
return UIMenu(children: actions)
|
||||
}
|
||||
|
||||
@available(iOS 16.0, *)
|
||||
func editableTextNodeMenu(_ editableTextNode: ASEditableTextNode, forTextRange textRange: NSRange, suggestedActions: [UIMenuElement]) -> UIMenu {
|
||||
return chatInputTextNodeMenu(forTextRange: textRange, suggestedActions: suggestedActions)
|
||||
}
|
||||
|
||||
private var currentSpeechHolder: SpeechSynthesizerHolder?
|
||||
@objc func _accessibilitySpeak(_ sender: Any) {
|
||||
var text = ""
|
||||
@@ -3776,7 +3839,11 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
self.updateSpoilersRevealed(animated: animated)
|
||||
}
|
||||
|
||||
@objc func editableTextNode(_ editableTextNode: ASEditableTextNode, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
|
||||
func chatInputTextNode(shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
|
||||
guard let editableTextNode = self.textInputNode else {
|
||||
return false
|
||||
}
|
||||
|
||||
self.updateActivity()
|
||||
var cleanText = text
|
||||
let removeSequences: [String] = ["\u{202d}", "\u{202c}"]
|
||||
@@ -3810,7 +3877,11 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
return true
|
||||
}
|
||||
|
||||
@objc func editableTextNodeShouldCopy(_ editableTextNode: ASEditableTextNode) -> Bool {
|
||||
@objc func editableTextNode(_ editableTextNode: ASEditableTextNode, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
|
||||
return self.chatInputTextNode(shouldChangeTextIn: range, replacementText: text)
|
||||
}
|
||||
|
||||
func chatInputTextNodeShouldCopy() -> Bool {
|
||||
self.interfaceInteraction?.updateTextInputStateAndMode { current, inputMode in
|
||||
storeInputTextInPasteboard(current.inputText.attributedSubstring(from: NSMakeRange(current.selectionRange.lowerBound, current.selectionRange.count)))
|
||||
return (current, inputMode)
|
||||
@@ -3818,7 +3889,11 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
return false
|
||||
}
|
||||
|
||||
@objc func editableTextNodeShouldPaste(_ editableTextNode: ASEditableTextNode) -> Bool {
|
||||
@objc func editableTextNodeShouldCopy(_ editableTextNode: ASEditableTextNode) -> Bool {
|
||||
return self.chatInputTextNodeShouldCopy()
|
||||
}
|
||||
|
||||
func chatInputTextNodeShouldPaste() -> Bool {
|
||||
let pasteboard = UIPasteboard.general
|
||||
|
||||
var attributedString: NSAttributedString?
|
||||
@@ -3889,6 +3964,10 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
|
||||
return true
|
||||
}
|
||||
|
||||
@objc func editableTextNodeShouldPaste(_ editableTextNode: ASEditableTextNode) -> Bool {
|
||||
return self.chatInputTextNodeShouldPaste()
|
||||
}
|
||||
|
||||
@objc func sendButtonPressed() {
|
||||
if let textInputNode = self.textInputNode, let presentationInterfaceState = self.presentationInterfaceState, let editMessage = presentationInterfaceState.interfaceState.editMessage, let inputTextMaxLength = editMessage.inputTextMaxLength {
|
||||
let textCount = Int32(textInputNode.textView.text.count)
|
||||
|
||||
Reference in New Issue
Block a user