mirror of https://github.com/oxen-io/session-ios
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
123 lines
5.1 KiB
Swift
123 lines
5.1 KiB
Swift
// Copyright © 2022 Rangeproof Pty Ltd. All rights reserved.
|
|
|
|
import Foundation
|
|
import GRDB
|
|
import SessionUIKit
|
|
import SessionMessagingKit
|
|
|
|
public enum MentionUtilities {
|
|
public static func highlightMentionsNoAttributes(
|
|
in string: String,
|
|
threadVariant: SessionThread.Variant,
|
|
currentUserPublicKey: String,
|
|
currentUserBlinded15PublicKey: String?,
|
|
currentUserBlinded25PublicKey: String?
|
|
) -> String {
|
|
/// **Note:** We are returning the string here so the 'textColor' and 'primaryColor' values are irrelevant
|
|
return highlightMentions(
|
|
in: string,
|
|
threadVariant: threadVariant,
|
|
currentUserPublicKey: currentUserPublicKey,
|
|
currentUserBlinded15PublicKey: currentUserBlinded15PublicKey,
|
|
currentUserBlinded25PublicKey: currentUserBlinded25PublicKey,
|
|
isOutgoingMessage: false,
|
|
textColor: .black,
|
|
theme: .classicDark,
|
|
primaryColor: Theme.PrimaryColor.green,
|
|
attributes: [:]
|
|
).string
|
|
}
|
|
|
|
public static func highlightMentions(
|
|
in string: String,
|
|
threadVariant: SessionThread.Variant,
|
|
currentUserPublicKey: String?,
|
|
currentUserBlinded15PublicKey: String?,
|
|
currentUserBlinded25PublicKey: String?,
|
|
isOutgoingMessage: Bool,
|
|
textColor: UIColor,
|
|
theme: Theme,
|
|
primaryColor: Theme.PrimaryColor,
|
|
attributes: [NSAttributedString.Key: Any]
|
|
) -> NSAttributedString {
|
|
guard
|
|
let regex: NSRegularExpression = try? NSRegularExpression(pattern: "@[0-9a-fA-F]{66}", options: []) // stringlint:disable
|
|
else {
|
|
return NSAttributedString(string: string)
|
|
}
|
|
|
|
var string = string
|
|
var lastMatchEnd: Int = 0
|
|
var mentions: [(range: NSRange, isCurrentUser: Bool)] = []
|
|
let currentUserPublicKeys: Set<String> = [
|
|
currentUserPublicKey,
|
|
currentUserBlinded15PublicKey,
|
|
currentUserBlinded25PublicKey
|
|
]
|
|
.compactMap { $0 }
|
|
.asSet()
|
|
|
|
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 @
|
|
let isCurrentUser: Bool = currentUserPublicKeys.contains(publicKey)
|
|
|
|
guard let targetString: String = {
|
|
guard !isCurrentUser else { return "onionRoutingPathYou".localized() }
|
|
guard let displayName: String = Profile.displayNameNoFallback(id: publicKey, threadVariant: threadVariant) else {
|
|
lastMatchEnd = (match.range.location + match.range.length)
|
|
return nil
|
|
}
|
|
|
|
return displayName
|
|
}()
|
|
else { continue }
|
|
|
|
string = string.replacingCharacters(in: range, with: "@\(targetString)") // stringlint:disable
|
|
lastMatchEnd = (match.range.location + targetString.utf16.count)
|
|
|
|
mentions.append((
|
|
// + 1 to include the @
|
|
range: NSRange(location: match.range.location, length: targetString.utf16.count + 1),
|
|
isCurrentUser: isCurrentUser
|
|
))
|
|
}
|
|
|
|
let sizeDiff: CGFloat = (Values.smallFontSize / Values.mediumFontSize)
|
|
let result: NSMutableAttributedString = NSMutableAttributedString(string: string, attributes: attributes)
|
|
mentions.forEach { mention in
|
|
result.addAttribute(.font, value: UIFont.boldSystemFont(ofSize: Values.smallFontSize), range: mention.range)
|
|
|
|
if mention.isCurrentUser {
|
|
// Note: The designs don't match with the dynamic sizing so these values need to be calculated
|
|
// to maintain a "rounded rect" effect rather than a "pill" effect
|
|
result.addAttribute(.currentUserMentionBackgroundCornerRadius, value: (8 * sizeDiff), range: mention.range)
|
|
result.addAttribute(.currentUserMentionBackgroundPadding, value: (3 * sizeDiff), range: mention.range)
|
|
result.addAttribute(.currentUserMentionBackgroundColor, value: primaryColor.color, range: mention.range)
|
|
result.addAttribute(
|
|
.foregroundColor,
|
|
value: UIColor.black, // Note: This text should always be black
|
|
range: mention.range
|
|
)
|
|
}
|
|
else {
|
|
result.addAttribute(
|
|
.foregroundColor,
|
|
value: (isOutgoingMessage || theme.interfaceStyle == .light ?
|
|
textColor :
|
|
primaryColor.color
|
|
),
|
|
range: mention.range
|
|
)
|
|
}
|
|
}
|
|
|
|
return result
|
|
}
|
|
}
|