Filter consecutive newlines

This commit is contained in:
Isaac
2025-11-14 21:19:08 +08:00
parent 09ca26be9b
commit 888b12405b
3 changed files with 42 additions and 15 deletions

View File

@@ -182,6 +182,7 @@ public final class ChatTextInputPanelComponent: Component {
let insets: UIEdgeInsets let insets: UIEdgeInsets
let maxHeight: CGFloat let maxHeight: CGFloat
let maxLength: Int? let maxLength: Int?
let allowConsecutiveNewlines: Bool
let sendAction: (() -> Void)? let sendAction: (() -> Void)?
let sendContextAction: ((UIView, ContextGesture) -> Void)? let sendContextAction: ((UIView, ContextGesture) -> Void)?
@@ -206,6 +207,7 @@ public final class ChatTextInputPanelComponent: Component {
insets: UIEdgeInsets, insets: UIEdgeInsets,
maxHeight: CGFloat, maxHeight: CGFloat,
maxLength: Int?, maxLength: Int?,
allowConsecutiveNewlines: Bool,
sendAction: (() -> Void)?, sendAction: (() -> Void)?,
sendContextAction: ((UIView, ContextGesture) -> Void)? sendContextAction: ((UIView, ContextGesture) -> Void)?
) { ) {
@@ -229,6 +231,7 @@ public final class ChatTextInputPanelComponent: Component {
self.insets = insets self.insets = insets
self.maxHeight = maxHeight self.maxHeight = maxHeight
self.maxLength = maxLength self.maxLength = maxLength
self.allowConsecutiveNewlines = allowConsecutiveNewlines
self.sendAction = sendAction self.sendAction = sendAction
self.sendContextAction = sendContextAction self.sendContextAction = sendContextAction
} }
@@ -294,6 +297,9 @@ public final class ChatTextInputPanelComponent: Component {
if lhs.maxLength != rhs.maxLength { if lhs.maxLength != rhs.maxLength {
return false return false
} }
if lhs.allowConsecutiveNewlines != rhs.allowConsecutiveNewlines {
return false
}
if (lhs.sendAction == nil) != (rhs.sendAction == nil) { if (lhs.sendAction == nil) != (rhs.sendAction == nil) {
return false return false
} }
@@ -1013,6 +1019,8 @@ public final class ChatTextInputPanelComponent: Component {
} }
} }
panelNode.allowConsecutiveNewlines = component.allowConsecutiveNewlines
if let resetInputState = component.externalState.resetInputState { if let resetInputState = component.externalState.resetInputState {
component.externalState.resetInputState = nil component.externalState.resetInputState = nil
let _ = resetInputState let _ = resetInputState

View File

@@ -407,6 +407,7 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
public var customSendIsDisabled: Bool = false public var customSendIsDisabled: Bool = false
public var customInputTextMaxLength: Int? public var customInputTextMaxLength: Int?
public var customSwitchToKeyboard: (() -> Void)? public var customSwitchToKeyboard: (() -> Void)?
public var allowConsecutiveNewlines = true
private var starReactionButton: ComponentView<Empty>? private var starReactionButton: ComponentView<Empty>?
private var liveMicrophoneButton: ComponentView<Empty>? private var liveMicrophoneButton: ComponentView<Empty>?
@@ -4953,7 +4954,6 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
} }
} }
if cleanText != text {
let string = NSMutableAttributedString(attributedString: editableTextNode.attributedText ?? NSAttributedString()) let string = NSMutableAttributedString(attributedString: editableTextNode.attributedText ?? NSAttributedString())
var textColor: UIColor = .black var textColor: UIColor = .black
var accentTextColor: UIColor = .blue var accentTextColor: UIColor = .blue
@@ -4970,6 +4970,24 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
return ChatInputTextCollapsedQuoteAttachmentImpl(text: text, attributes: attributes) return ChatInputTextCollapsedQuoteAttachmentImpl(text: text, attributes: attributes)
}) })
string.replaceCharacters(in: range, with: cleanReplacementString) string.replaceCharacters(in: range, with: cleanReplacementString)
var resetText = false
if cleanText != text {
resetText = true
}
if !self.allowConsecutiveNewlines {
while string.string.range(of: "\n\n") != nil {
if let range = string.string.range(of: "\n\n") {
let rawRange = NSRange(range, in: string.string)
let firstNewline = string.attributedSubstring(from: NSRange(location: rawRange.location, length: 1))
string.replaceCharacters(in: rawRange, with: firstNewline)
resetText = true
}
}
}
if resetText {
self.textInputNode?.attributedText = string self.textInputNode?.attributedText = string
self.textInputNode?.selectedRange = NSMakeRange(range.lowerBound + cleanReplacementString.length, 0) self.textInputNode?.selectedRange = NSMakeRange(range.lowerBound + cleanReplacementString.length, 0)
self.updateTextNodeText(animated: true) self.updateTextNodeText(animated: true)

View File

@@ -1125,6 +1125,7 @@ public final class MessageInputPanelComponent: Component {
insets: UIEdgeInsets(top: 0.0, left: 0.0, bottom: component.bottomInset, right: 0.0), insets: UIEdgeInsets(top: 0.0, left: 0.0, bottom: component.bottomInset, right: 0.0),
maxHeight: availableSize.height, maxHeight: availableSize.height,
maxLength: component.maxLength, maxLength: component.maxLength,
allowConsecutiveNewlines: false,
sendAction: { [weak self] in sendAction: { [weak self] in
guard let self, let component = self.component else { guard let self, let component = self.component else {
return return