| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177 |
- //
- // EmotionHelper.swift
- // TUILiveKit
- //
- // Created by krabyu on 2024/4/3.
- //
- import UIKit
- class EmotionHelper {
- static let shared = {
- EmotionHelper()
- }()
- private init() {
- useDefaultEmotions()
- }
- var emotions: [Emotion] = []
- private var cacheTotalImageDictionary: [String: UIImage] = [:]
- private var cacheAttributedDictionary: [String: NSAttributedString] = [:]
- private var regularExpression: NSRegularExpression = try! NSRegularExpression(pattern: "\\[[a-zA-Z0-9_\\u4e00-\\u9fa5]+\\]", options: [])
- func useDefaultEmotions() {
- createTotalEmotions()
- cacheTotalImage()
- }
- func setEmotions(emotions: [Emotion]) {
- self.emotions = emotions
- cacheTotalImageDictionary = [:]
- cacheTotalImage()
- }
- func cacheTotalImage() {
- if cacheTotalImageDictionary.count == 0 {
- var emotionImageDictionary: [String: UIImage] = [:]
- for emotion in emotions {
- if emotion.image.size.width != 0 {
- emotion.image = UIImage(named: emotion.identifier, in: tuiRoomKitBundle(), compatibleWith: nil) ?? UIImage()
- }
- emotionImageDictionary[emotion.displayName] = emotion.image
- }
- cacheTotalImageDictionary = emotionImageDictionary
- }
- }
- func obtainImagesAttributedString(byText text: String, font: UIFont) -> NSMutableAttributedString {
- let matches = regularExpression.matches(in: text, range: NSRange(location: 0, length: text.count))
- let intactAttributedString = NSMutableAttributedString(string: text)
- for match in matches.reversed() {
- guard let emojiRange = Range(match.range, in: text) else { return NSMutableAttributedString(string: "") }
- let emojiKey = String(text[emojiRange])
- var useCache = true
- if #available(iOS 15.0, *) {
- // Cached NSAttributedString cannot be used on ios15, only one expression will appear, but it can be used on ios14 and before.
- useCache = false
- }
- let imageAttributedString = obtainImageAttributedString(byImageKey: emojiKey, font: font, useCache: useCache)
- intactAttributedString.replaceCharacters(in: match.range, with: imageAttributedString)
- }
- // Fixed an issue where font changed due to inserting AttributeString;
- // Prevents the textView font from getting smaller after inserting an expression
- intactAttributedString.addAttribute(.font, value: font, range: NSRange(location: 0, length: intactAttributedString.length))
- intactAttributedString.addAttribute(.foregroundColor, value: UIColor.tui_color(withHex: "D5E0F2"), range: NSRange(location: 0, length: intactAttributedString.length))
- return intactAttributedString
- }
- func obtainImageAttributedString(byImageKey imageKey: String, font: UIFont, useCache: Bool) -> NSAttributedString {
- if !useCache {
- let image = cacheTotalImageDictionary[imageKey]
- if image == nil {
- return NSAttributedString(string: "")
- }
- let emotionAttachment = EmotionAttachment()
- emotionAttachment.displayText = imageKey
- emotionAttachment.image = image
- emotionAttachment.bounds = CGRect(x: 0, y: font.descender, width: font.lineHeight, height: font.lineHeight)
- let imageAttributedString = NSAttributedString(attachment: emotionAttachment)
- return imageAttributedString
- }
- let keyFont = String(format: "%@%.1f", imageKey, font.pointSize)
- if let result = cacheAttributedDictionary[keyFont] {
- return result
- }
- guard let image = cacheTotalImageDictionary[imageKey] else {
- return NSAttributedString(string: "")
- }
- let emotionAttachment = EmotionAttachment()
- emotionAttachment.displayText = imageKey
- emotionAttachment.image = image
- emotionAttachment.bounds = CGRect(x: 0, y: font.descender, width: font.lineHeight, height: font.lineHeight)
- let result = NSAttributedString(attachment: emotionAttachment)
- cacheAttributedDictionary[keyFont] = result
- return result
- }
- private func createTotalEmotions() {
- emotions = []
- emotions.append(Emotion(identifier: "room_floatChat_emoji_0", displayName: "[TUIEmoji_Smile]"))
- emotions.append(Emotion(identifier: "room_floatChat_emoji_1", displayName: "[TUIEmoji_Expect]"))
- emotions.append(Emotion(identifier: "room_floatChat_emoji_2", displayName: "[TUIEmoji_Blink]"))
- emotions.append(Emotion(identifier: "room_floatChat_emoji_3", displayName: "[TUIEmoji_Guffaw]"))
- emotions.append(Emotion(identifier: "room_floatChat_emoji_4", displayName: "[TUIEmoji_KindSmile]"))
- emotions.append(Emotion(identifier: "room_floatChat_emoji_5", displayName: "[TUIEmoji_Haha]"))
- emotions.append(Emotion(identifier: "room_floatChat_emoji_6", displayName: "[TUIEmoji_Cheerful]"))
- emotions.append(Emotion(identifier: "room_floatChat_emoji_7", displayName: "[TUIEmoji_Speechless]"))
- emotions.append(Emotion(identifier: "room_floatChat_emoji_8", displayName: "[TUIEmoji_Amazed]"))
- emotions.append(Emotion(identifier: "room_floatChat_emoji_9", displayName: "[TUIEmoji_Sorrow]"))
- emotions.append(Emotion(identifier: "room_floatChat_emoji_10", displayName: "[TUIEmoji_Complacent]"))
- emotions.append(Emotion(identifier: "room_floatChat_emoji_11", displayName: "[TUIEmoji_Silly]"))
- emotions.append(Emotion(identifier: "room_floatChat_emoji_12", displayName: "[TUIEmoji_Lustful]"))
- emotions.append(Emotion(identifier: "room_floatChat_emoji_13", displayName: "[TUIEmoji_Giggle]"))
- emotions.append(Emotion(identifier: "room_floatChat_emoji_14", displayName: "[TUIEmoji_Kiss]"))
- emotions.append(Emotion(identifier: "room_floatChat_emoji_15", displayName: "[TUIEmoji_Wail]"))
- emotions.append(Emotion(identifier: "room_floatChat_emoji_16", displayName: "[TUIEmoji_TearsLaugh]"))
- emotions.append(Emotion(identifier: "room_floatChat_emoji_17", displayName: "[TUIEmoji_Trapped]"))
- emotions.append(Emotion(identifier: "room_floatChat_emoji_18", displayName: "[TUIEmoji_Mask]"))
- emotions.append(Emotion(identifier: "room_floatChat_emoji_19", displayName: "[TUIEmoji_Fear]"))
- emotions.append(Emotion(identifier: "room_floatChat_emoji_20", displayName: "[TUIEmoji_BareTeeth]"))
- emotions.append(Emotion(identifier: "room_floatChat_emoji_21", displayName: "[TUIEmoji_FlareUp]"))
- emotions.append(Emotion(identifier: "room_floatChat_emoji_22", displayName: "[TUIEmoji_Yawn]"))
- emotions.append(Emotion(identifier: "room_floatChat_emoji_23", displayName: "[TUIEmoji_Tact]"))
- emotions.append(Emotion(identifier: "room_floatChat_emoji_24", displayName: "[TUIEmoji_Stareyes]"))
- emotions.append(Emotion(identifier: "room_floatChat_emoji_25", displayName: "[TUIEmoji_ShutUp]"))
- emotions.append(Emotion(identifier: "room_floatChat_emoji_26", displayName: "[TUIEmoji_Sigh]"))
- emotions.append(Emotion(identifier: "room_floatChat_emoji_27", displayName: "[TUIEmoji_Hehe]"))
- emotions.append(Emotion(identifier: "room_floatChat_emoji_28", displayName: "[TUIEmoji_Silent]"))
- emotions.append(Emotion(identifier: "room_floatChat_emoji_29", displayName: "[TUIEmoji_Surprised]"))
- emotions.append(Emotion(identifier: "room_floatChat_emoji_30", displayName: "[TUIEmoji_Askance]"))
- emotions.append(Emotion(identifier: "room_floatChat_emoji_31", displayName: "[TUIEmoji_Ok]"))
- emotions.append(Emotion(identifier: "room_floatChat_emoji_32", displayName: "[TUIEmoji_Shit]"))
- emotions.append(Emotion(identifier: "room_floatChat_emoji_33", displayName: "[TUIEmoji_Monster]"))
- emotions.append(Emotion(identifier: "room_floatChat_emoji_34", displayName: "[TUIEmoji_Daemon]"))
- emotions.append(Emotion(identifier: "room_floatChat_emoji_35", displayName: "[TUIEmoji_Rage]"))
- emotions.append(Emotion(identifier: "room_floatChat_emoji_36", displayName: "[TUIEmoji_Fool]"))
- emotions.append(Emotion(identifier: "room_floatChat_emoji_37", displayName: "[TUIEmoji_Pig]"))
- emotions.append(Emotion(identifier: "room_floatChat_emoji_38", displayName: "[TUIEmoji_Cow]"))
- emotions.append(Emotion(identifier: "room_floatChat_emoji_39", displayName: "[TUIEmoji_Ai]"))
- emotions.append(Emotion(identifier: "room_floatChat_emoji_40", displayName: "[TUIEmoji_Skull]"))
- emotions.append(Emotion(identifier: "room_floatChat_emoji_41", displayName: "[TUIEmoji_Bombs]"))
- emotions.append(Emotion(identifier: "room_floatChat_emoji_42", displayName: "[TUIEmoji_Coffee]"))
- emotions.append(Emotion(identifier: "room_floatChat_emoji_43", displayName: "[TUIEmoji_Cake]"))
- emotions.append(Emotion(identifier: "room_floatChat_emoji_44", displayName: "[TUIEmoji_Beer]"))
- emotions.append(Emotion(identifier: "room_floatChat_emoji_45", displayName: "[TUIEmoji_Flower]"))
- emotions.append(Emotion(identifier: "room_floatChat_emoji_46", displayName: "[TUIEmoji_Watermelon]"))
- emotions.append(Emotion(identifier: "room_floatChat_emoji_47", displayName: "[TUIEmoji_Rich]"))
- emotions.append(Emotion(identifier: "room_floatChat_emoji_48", displayName: "[TUIEmoji_Heart]"))
- emotions.append(Emotion(identifier: "room_floatChat_emoji_49", displayName: "[TUIEmoji_Moon]"))
- emotions.append(Emotion(identifier: "room_floatChat_emoji_50", displayName: "[TUIEmoji_Sun]"))
- emotions.append(Emotion(identifier: "room_floatChat_emoji_51", displayName: "[TUIEmoji_Star]"))
- emotions.append(Emotion(identifier: "room_floatChat_emoji_52", displayName: "[TUIEmoji_RedPacket]"))
- emotions.append(Emotion(identifier: "room_floatChat_emoji_53", displayName: "[TUIEmoji_Celebrate]"))
- emotions.append(Emotion(identifier: "room_floatChat_emoji_54", displayName: "[TUIEmoji_Bless]"))
- emotions.append(Emotion(identifier: "room_floatChat_emoji_55", displayName: "[TUIEmoji_Fortune]"))
- emotions.append(Emotion(identifier: "room_floatChat_emoji_56", displayName: "[TUIEmoji_Convinced]"))
- emotions.append(Emotion(identifier: "room_floatChat_emoji_57", displayName: "[TUIEmoji_Prohibit]"))
- emotions.append(Emotion(identifier: "room_floatChat_emoji_58", displayName: "[TUIEmoji_666]"))
- emotions.append(Emotion(identifier: "room_floatChat_emoji_59", displayName: "[TUIEmoji_857]"))
- emotions.append(Emotion(identifier: "room_floatChat_emoji_60", displayName: "[TUIEmoji_Knife]"))
- emotions.append(Emotion(identifier: "room_floatChat_emoji_61", displayName: "[TUIEmoji_Like]"))
- for emotion in emotions {
- emotion.image = UIImage(named: emotion.identifier, in: tuiRoomKitBundle(), compatibleWith: nil) ?? UIImage()
- }
- }
- }
|