// Copyright © 2022 Rangeproof Pty Ltd. All rights reserved. import Foundation import GRDB import SessionUIKit import SessionMessagingKit public enum MentionUtilities { public static func highlightMentions(in string: String, threadVariant: SessionThread.Variant) -> String { return highlightMentions( in: string, threadVariant: threadVariant, isOutgoingMessage: false, attributes: [:] ).string // isOutgoingMessage and attributes are irrelevant } public static func highlightMentions( in string: String, threadVariant: SessionThread.Variant, isOutgoingMessage: Bool, attributes: [NSAttributedString.Key: Any] ) -> NSAttributedString { guard let regex: NSRegularExpression = try? NSRegularExpression(pattern: "@[0-9a-fA-F]{66}", options: []) else { return NSAttributedString(string: string) } var string = string var lastMatchEnd: Int = 0 var mentions: [(range: NSRange, publicKey: String)] = [] while let match: NSTextCheckingResult = regex.firstMatch( in: string, options: .withoutAnchoringBounds, range: NSRange(location: lastMatchEnd, length: string.utf16.count - lastMatchEnd) ) { guard let range: Range = Range(match.range, in: string) else { break } let publicKey: String = String(string[range].dropFirst()) // Drop the @ guard let displayName: String = Profile.displayNameNoFallback(id: publicKey, threadVariant: threadVariant) else { lastMatchEnd = (match.range.location + match.range.length) continue } string = string.replacingCharacters(in: range, with: "@\(displayName)") lastMatchEnd = (match.range.location + displayName.utf16.count) mentions.append(( // + 1 to include the @ range: NSRange(location: match.range.location, length: displayName.utf16.count + 1), publicKey: publicKey )) } let result: NSMutableAttributedString = NSMutableAttributedString(string: string, attributes: attributes) mentions.forEach { mention in // FIXME: This might break when swapping between themes let color = isOutgoingMessage ? (isLightMode ? .white : .black) : Colors.accent result.addAttribute(.foregroundColor, value: color, range: mention.range) result.addAttribute(.font, value: UIFont.boldSystemFont(ofSize: Values.smallFontSize), range: mention.range) } return result } }