Fix detecting mentions while typing
This commit is contained in:
parent
cad074bcc3
commit
7d47f1f259
|
@ -101,6 +101,9 @@ private struct NewMainTextViewRepresentable: UIViewRepresentable {
|
|||
}
|
||||
}
|
||||
|
||||
// laxer than the CharacterCounter regex, because we want to find mentions that are being typed but aren't yet complete (e.g., "@a@b")
|
||||
private let mentionRegex = try! NSRegularExpression(pattern: "(@[a-z0-9_]+)(?:@[a-z0-9\\-\\.]+)?", options: .caseInsensitive)
|
||||
|
||||
private final class WrappedTextViewCoordinator: NSObject {
|
||||
private static let attachment: NSTextAttachment = {
|
||||
let font = UIFont.systemFont(ofSize: 20)
|
||||
|
@ -149,6 +152,7 @@ private final class WrappedTextViewCoordinator: NSObject {
|
|||
private func updateAttributes(in textView: UITextView) {
|
||||
let str = NSMutableAttributedString(attributedString: textView.attributedText!)
|
||||
var changed = false
|
||||
var cursorOffset = 0
|
||||
|
||||
// remove existing mentions that aren't valid
|
||||
str.enumerateAttribute(.mention, in: NSRange(location: 0, length: str.length), options: .reverse) { value, range, stop in
|
||||
|
@ -157,18 +161,19 @@ private final class WrappedTextViewCoordinator: NSObject {
|
|||
if hasTextAttachment {
|
||||
substr = String(substr.dropFirst())
|
||||
}
|
||||
if CharacterCounter.mention.numberOfMatches(in: substr, range: NSRange(location: 0, length: substr.utf16.count)) == 0 {
|
||||
if mentionRegex.numberOfMatches(in: substr, range: NSRange(location: 0, length: substr.utf16.count)) == 0 {
|
||||
changed = true
|
||||
str.removeAttribute(.mention, range: range)
|
||||
str.removeAttribute(.foregroundColor, range: range)
|
||||
if hasTextAttachment {
|
||||
str.deleteCharacters(in: NSRange(location: range.location, length: 1))
|
||||
cursorOffset -= 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// add mentions for those missing
|
||||
let mentionMatches = CharacterCounter.mention.matches(in: str.string, range: NSRange(location: 0, length: str.length))
|
||||
let mentionMatches = mentionRegex.matches(in: str.string, range: NSRange(location: 0, length: str.length))
|
||||
for match in mentionMatches.reversed() {
|
||||
var attributeRange = NSRange()
|
||||
let attribute = str.attribute(.mention, at: match.range.location, effectiveRange: &attributeRange)
|
||||
|
@ -179,6 +184,7 @@ private final class WrappedTextViewCoordinator: NSObject {
|
|||
if attribute == nil {
|
||||
str.insert(NSAttributedString(attachment: Self.attachment), at: match.range.location)
|
||||
newAttributeRange = NSRange(location: match.range.location, length: match.range.length + 1)
|
||||
cursorOffset += 1
|
||||
} else {
|
||||
newAttributeRange = match.range
|
||||
}
|
||||
|
@ -190,7 +196,11 @@ private final class WrappedTextViewCoordinator: NSObject {
|
|||
}
|
||||
|
||||
if changed {
|
||||
let selection = textView.selectedRange
|
||||
|
||||
textView.attributedText = str
|
||||
|
||||
textView.selectedRange = NSRange(location: selection.location + cursorOffset, length: selection.length)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue