commit c7baa153aff8e4d643dd8a3a58bb226a1d3890b6
parent ff654c4e117aa1fe2b5a4efe113fac8dc53a3f80
Author: William Casarin <jb55@jb55.com>
Date: Mon, 17 Jul 2023 10:16:39 -0700
posting: add some functions for appending mention tags
These are easy-to-test functions for appending user tags to attributed
strings. We will use these in the next couple of commits to replace the
existing buggy functionality.
Diffstat:
1 file changed, 48 insertions(+), 0 deletions(-)
diff --git a/damus/Views/Posting/UserSearch.swift b/damus/Views/Posting/UserSearch.swift
@@ -97,6 +97,54 @@ struct UserSearch_Previews: PreviewProvider {
}
}
+/// Pad an attributed string: `@jb55` -> ` @jb55 `
+func pad_attr_string(tag: NSAttributedString, before: Bool = true) -> NSAttributedString {
+ let new_tag = NSMutableAttributedString(string: "")
+ if before {
+ new_tag.append(.init(string: " "))
+ }
+
+ new_tag.append(tag)
+ new_tag.append(.init(string: " "))
+ return new_tag
+}
+
+/// Checks if whitespace precedes a tag. Useful to add spacing if we don't have it.
+func whitespace_precedes_tag(tag: NSAttributedString, post: NSMutableAttributedString, word_range: NSRange) -> Bool {
+ if word_range.location == 0 { // If the range starts at the very beginning of the post, there's nothing preceding it.
+ return true
+ }
+
+ // Range for the character preceding the tag
+ let precedingCharacterRange = NSRange(location: word_range.location - 1, length: 1)
+
+ // Get the preceding character
+ let precedingCharacter = post.attributedSubstring(from: precedingCharacterRange)
+
+ // Check if the preceding character is a whitespace character
+ return precedingCharacter.string.rangeOfCharacter(from: CharacterSet.whitespaces) != nil
+}
+
+struct AppendedTag {
+ let post: NSMutableAttributedString
+ let tag: NSAttributedString
+}
+
+/// Appends a user tag (eg: @jb55) to a post. This handles adding additional padding as well.
+func append_user_tag(tag: NSAttributedString, post: NSMutableAttributedString, word_range: NSRange) -> AppendedTag {
+ let new_post = NSMutableAttributedString(attributedString: post)
+
+ // If we have a non-empty post and the last character is not whitespace, append a space
+ // This prevents issues such as users typing cc@will and have it expand to ccnostr:bech32...
+ let should_prepad = !whitespace_precedes_tag(tag: tag, post: post, word_range: word_range)
+ let tag = pad_attr_string(tag: tag, before: should_prepad)
+
+ new_post.replaceCharacters(in: word_range, with: tag)
+
+ return AppendedTag(post: new_post, tag: tag)
+}
+
+/// Generate a mention attributed string, including the internal damus:nostr: link
func user_tag_attr_string(profile: Profile?, pubkey: String) -> NSMutableAttributedString {
let display_name = Profile.displayName(profile: profile, pubkey: pubkey)
let name = display_name.username.truncate(maxLength: 50)