session-ios/Session/Emoji/EmojiWithSkinTones.swift

123 lines
4.3 KiB
Swift
Raw Normal View History

2022-08-17 08:41:01 +02:00
// Copyright © 2022 Rangeproof Pty Ltd. All rights reserved.
2022-06-10 08:51:37 +02:00
Merge branch 'feature/database-refactor' into emoji-reacts # Conflicts: # Session.xcodeproj/project.pbxproj # Session/Conversations/Context Menu/ContextMenuVC+Action.swift # Session/Conversations/Context Menu/ContextMenuVC+ActionView.swift # Session/Conversations/Context Menu/ContextMenuVC.swift # Session/Conversations/ConversationVC+Interaction.swift # Session/Conversations/ConversationVC.swift # Session/Conversations/ConversationViewItem.h # Session/Conversations/ConversationViewItem.m # Session/Conversations/Message Cells/Content Views/LinkPreviewView.swift # Session/Conversations/Message Cells/MessageCell.swift # Session/Conversations/Message Cells/VisibleMessageCell.swift # Session/Conversations/Views & Modals/BodyTextView.swift # Session/Meta/Translations/en.lproj/Localizable.strings # Session/Shared/UserCell.swift # SessionMessagingKit/Jobs/MessageSendJob.swift # SessionMessagingKit/Messages/Signal/TSMessage.h # SessionMessagingKit/Messages/Signal/TSMessage.m # SessionMessagingKit/Messages/Visible Messages/VisibleMessage.swift # SessionMessagingKit/Open Groups/OpenGroupAPIV2.swift # SessionMessagingKit/Sending & Receiving/MessageReceiver+Handling.swift # SessionMessagingKit/Sending & Receiving/Notifications/NotificationsProtocol.h # SessionMessagingKit/Sending & Receiving/Pollers/OpenGroupPollerV2.swift # SessionMessagingKit/Utilities/General.swift # SessionNotificationServiceExtension/NSENotificationPresenter.swift # SignalUtilitiesKit/Utilities/DisplayableText.swift # SignalUtilitiesKit/Utilities/NoopNotificationsManager.swift # SignalUtilitiesKit/Utilities/Notification+Loki.swift
2022-07-25 07:39:56 +02:00
import Foundation
import GRDB
import DifferenceKit
import SessionMessagingKit
public struct EmojiWithSkinTones: Hashable, Equatable, ContentEquatable, ContentIdentifiable {
2022-06-10 08:51:37 +02:00
let baseEmoji: Emoji
let skinTones: [Emoji.SkinTone]?
Merge branch 'feature/database-refactor' into emoji-reacts # Conflicts: # Session.xcodeproj/project.pbxproj # Session/Conversations/Context Menu/ContextMenuVC+Action.swift # Session/Conversations/Context Menu/ContextMenuVC+ActionView.swift # Session/Conversations/Context Menu/ContextMenuVC.swift # Session/Conversations/ConversationVC+Interaction.swift # Session/Conversations/ConversationVC.swift # Session/Conversations/ConversationViewItem.h # Session/Conversations/ConversationViewItem.m # Session/Conversations/Message Cells/Content Views/LinkPreviewView.swift # Session/Conversations/Message Cells/MessageCell.swift # Session/Conversations/Message Cells/VisibleMessageCell.swift # Session/Conversations/Views & Modals/BodyTextView.swift # Session/Meta/Translations/en.lproj/Localizable.strings # Session/Shared/UserCell.swift # SessionMessagingKit/Jobs/MessageSendJob.swift # SessionMessagingKit/Messages/Signal/TSMessage.h # SessionMessagingKit/Messages/Signal/TSMessage.m # SessionMessagingKit/Messages/Visible Messages/VisibleMessage.swift # SessionMessagingKit/Open Groups/OpenGroupAPIV2.swift # SessionMessagingKit/Sending & Receiving/MessageReceiver+Handling.swift # SessionMessagingKit/Sending & Receiving/Notifications/NotificationsProtocol.h # SessionMessagingKit/Sending & Receiving/Pollers/OpenGroupPollerV2.swift # SessionMessagingKit/Utilities/General.swift # SessionNotificationServiceExtension/NSENotificationPresenter.swift # SignalUtilitiesKit/Utilities/DisplayableText.swift # SignalUtilitiesKit/Utilities/NoopNotificationsManager.swift # SignalUtilitiesKit/Utilities/Notification+Loki.swift
2022-07-25 07:39:56 +02:00
2022-06-10 08:51:37 +02:00
init(baseEmoji: Emoji, skinTones: [Emoji.SkinTone]? = nil) {
self.baseEmoji = baseEmoji
// Deduplicate skin tones, while preserving order. This allows for
// multi-skin tone emoji, where if you have for example the permutation
// [.dark, .dark], it is consolidated to just [.dark], to be initialized
// with either variant and result in the correct emoji.
self.skinTones = skinTones?.reduce(into: [Emoji.SkinTone]()) { result, skinTone in
guard !result.contains(skinTone) else { return }
result.append(skinTone)
}
}
var rawValue: String {
if let skinTones = skinTones {
return baseEmoji.emojiPerSkinTonePermutation?[skinTones] ?? baseEmoji.rawValue
} else {
return baseEmoji.rawValue
}
}
2022-06-20 07:31:54 +02:00
var normalized: EmojiWithSkinTones {
switch (baseEmoji, skinTones) {
case (let base, nil) where base.normalized != base:
return EmojiWithSkinTones(baseEmoji: base.normalized)
default:
return self
}
}
var isNormalized: Bool { self == normalized }
2022-06-10 08:51:37 +02:00
}
extension Emoji {
Merge branch 'feature/database-refactor' into emoji-reacts # Conflicts: # Session.xcodeproj/project.pbxproj # Session/Conversations/Context Menu/ContextMenuVC+Action.swift # Session/Conversations/Context Menu/ContextMenuVC+ActionView.swift # Session/Conversations/Context Menu/ContextMenuVC.swift # Session/Conversations/ConversationVC+Interaction.swift # Session/Conversations/ConversationVC.swift # Session/Conversations/ConversationViewItem.h # Session/Conversations/ConversationViewItem.m # Session/Conversations/Message Cells/Content Views/LinkPreviewView.swift # Session/Conversations/Message Cells/MessageCell.swift # Session/Conversations/Message Cells/VisibleMessageCell.swift # Session/Conversations/Views & Modals/BodyTextView.swift # Session/Meta/Translations/en.lproj/Localizable.strings # Session/Shared/UserCell.swift # SessionMessagingKit/Jobs/MessageSendJob.swift # SessionMessagingKit/Messages/Signal/TSMessage.h # SessionMessagingKit/Messages/Signal/TSMessage.m # SessionMessagingKit/Messages/Visible Messages/VisibleMessage.swift # SessionMessagingKit/Open Groups/OpenGroupAPIV2.swift # SessionMessagingKit/Sending & Receiving/MessageReceiver+Handling.swift # SessionMessagingKit/Sending & Receiving/Notifications/NotificationsProtocol.h # SessionMessagingKit/Sending & Receiving/Pollers/OpenGroupPollerV2.swift # SessionMessagingKit/Utilities/General.swift # SessionNotificationServiceExtension/NSENotificationPresenter.swift # SignalUtilitiesKit/Utilities/DisplayableText.swift # SignalUtilitiesKit/Utilities/NoopNotificationsManager.swift # SignalUtilitiesKit/Utilities/Notification+Loki.swift
2022-07-25 07:39:56 +02:00
static func getRecent(_ db: Database, withDefaultEmoji: Bool) throws -> [String] {
let recentReactionEmoji: [String] = (db[.recentReactionEmoji]?
.components(separatedBy: ","))
.defaulting(to: [])
// No need to continue if we don't want the default emoji to pad out the list
guard withDefaultEmoji else { return recentReactionEmoji }
// Add in our default emoji if desired
2022-08-17 02:15:24 +02:00
let defaultEmoji = ["😂", "🥰", "😢", "😡", "😮", "😈"]
Merge branch 'feature/database-refactor' into emoji-reacts # Conflicts: # Session.xcodeproj/project.pbxproj # Session/Conversations/Context Menu/ContextMenuVC+Action.swift # Session/Conversations/Context Menu/ContextMenuVC+ActionView.swift # Session/Conversations/Context Menu/ContextMenuVC.swift # Session/Conversations/ConversationVC+Interaction.swift # Session/Conversations/ConversationVC.swift # Session/Conversations/ConversationViewItem.h # Session/Conversations/ConversationViewItem.m # Session/Conversations/Message Cells/Content Views/LinkPreviewView.swift # Session/Conversations/Message Cells/MessageCell.swift # Session/Conversations/Message Cells/VisibleMessageCell.swift # Session/Conversations/Views & Modals/BodyTextView.swift # Session/Meta/Translations/en.lproj/Localizable.strings # Session/Shared/UserCell.swift # SessionMessagingKit/Jobs/MessageSendJob.swift # SessionMessagingKit/Messages/Signal/TSMessage.h # SessionMessagingKit/Messages/Signal/TSMessage.m # SessionMessagingKit/Messages/Visible Messages/VisibleMessage.swift # SessionMessagingKit/Open Groups/OpenGroupAPIV2.swift # SessionMessagingKit/Sending & Receiving/MessageReceiver+Handling.swift # SessionMessagingKit/Sending & Receiving/Notifications/NotificationsProtocol.h # SessionMessagingKit/Sending & Receiving/Pollers/OpenGroupPollerV2.swift # SessionMessagingKit/Utilities/General.swift # SessionNotificationServiceExtension/NSENotificationPresenter.swift # SignalUtilitiesKit/Utilities/DisplayableText.swift # SignalUtilitiesKit/Utilities/NoopNotificationsManager.swift # SignalUtilitiesKit/Utilities/Notification+Loki.swift
2022-07-25 07:39:56 +02:00
.filter { !recentReactionEmoji.contains($0) }
return Array(recentReactionEmoji
.appending(contentsOf: defaultEmoji)
.prefix(6))
}
static func addRecent(_ db: Database, emoji: String) {
// Add/move the emoji to the start of the most recent list
db[.recentReactionEmoji] = (db[.recentReactionEmoji]?
.components(separatedBy: ","))
.defaulting(to: [])
.filter { $0 != emoji }
.inserting(emoji, at: 0)
.prefix(6)
.joined(separator: ",")
}
2022-06-10 08:51:37 +02:00
Merge branch 'feature/database-refactor' into emoji-reacts # Conflicts: # Session.xcodeproj/project.pbxproj # Session/Conversations/Context Menu/ContextMenuVC+Action.swift # Session/Conversations/Context Menu/ContextMenuVC+ActionView.swift # Session/Conversations/Context Menu/ContextMenuVC.swift # Session/Conversations/ConversationVC+Interaction.swift # Session/Conversations/ConversationVC.swift # Session/Conversations/ConversationViewItem.h # Session/Conversations/ConversationViewItem.m # Session/Conversations/Message Cells/Content Views/LinkPreviewView.swift # Session/Conversations/Message Cells/MessageCell.swift # Session/Conversations/Message Cells/VisibleMessageCell.swift # Session/Conversations/Views & Modals/BodyTextView.swift # Session/Meta/Translations/en.lproj/Localizable.strings # Session/Shared/UserCell.swift # SessionMessagingKit/Jobs/MessageSendJob.swift # SessionMessagingKit/Messages/Signal/TSMessage.h # SessionMessagingKit/Messages/Signal/TSMessage.m # SessionMessagingKit/Messages/Visible Messages/VisibleMessage.swift # SessionMessagingKit/Open Groups/OpenGroupAPIV2.swift # SessionMessagingKit/Sending & Receiving/MessageReceiver+Handling.swift # SessionMessagingKit/Sending & Receiving/Notifications/NotificationsProtocol.h # SessionMessagingKit/Sending & Receiving/Pollers/OpenGroupPollerV2.swift # SessionMessagingKit/Utilities/General.swift # SessionNotificationServiceExtension/NSENotificationPresenter.swift # SignalUtilitiesKit/Utilities/DisplayableText.swift # SignalUtilitiesKit/Utilities/NoopNotificationsManager.swift # SignalUtilitiesKit/Utilities/Notification+Loki.swift
2022-07-25 07:39:56 +02:00
static func allSendableEmojiByCategoryWithPreferredSkinTones(_ db: Database) -> [Category: [EmojiWithSkinTones]] {
return Category.allCases
.reduce(into: [Category: [EmojiWithSkinTones]]()) { result, category in
result[category] = category.normalizedEmoji
.filter { $0.available }
.map { $0.withPreferredSkinTones(db) }
}
2022-06-10 08:51:37 +02:00
}
Merge branch 'feature/database-refactor' into emoji-reacts # Conflicts: # Session.xcodeproj/project.pbxproj # Session/Conversations/Context Menu/ContextMenuVC+Action.swift # Session/Conversations/Context Menu/ContextMenuVC+ActionView.swift # Session/Conversations/Context Menu/ContextMenuVC.swift # Session/Conversations/ConversationVC+Interaction.swift # Session/Conversations/ConversationVC.swift # Session/Conversations/ConversationViewItem.h # Session/Conversations/ConversationViewItem.m # Session/Conversations/Message Cells/Content Views/LinkPreviewView.swift # Session/Conversations/Message Cells/MessageCell.swift # Session/Conversations/Message Cells/VisibleMessageCell.swift # Session/Conversations/Views & Modals/BodyTextView.swift # Session/Meta/Translations/en.lproj/Localizable.strings # Session/Shared/UserCell.swift # SessionMessagingKit/Jobs/MessageSendJob.swift # SessionMessagingKit/Messages/Signal/TSMessage.h # SessionMessagingKit/Messages/Signal/TSMessage.m # SessionMessagingKit/Messages/Visible Messages/VisibleMessage.swift # SessionMessagingKit/Open Groups/OpenGroupAPIV2.swift # SessionMessagingKit/Sending & Receiving/MessageReceiver+Handling.swift # SessionMessagingKit/Sending & Receiving/Notifications/NotificationsProtocol.h # SessionMessagingKit/Sending & Receiving/Pollers/OpenGroupPollerV2.swift # SessionMessagingKit/Utilities/General.swift # SessionNotificationServiceExtension/NSENotificationPresenter.swift # SignalUtilitiesKit/Utilities/DisplayableText.swift # SignalUtilitiesKit/Utilities/NoopNotificationsManager.swift # SignalUtilitiesKit/Utilities/Notification+Loki.swift
2022-07-25 07:39:56 +02:00
private func withPreferredSkinTones(_ db: Database) -> EmojiWithSkinTones {
guard let rawSkinTones: String = db[.emojiPreferredSkinTones(emoji: rawValue)] else {
2022-06-10 08:51:37 +02:00
return EmojiWithSkinTones(baseEmoji: self, skinTones: nil)
}
Merge branch 'feature/database-refactor' into emoji-reacts # Conflicts: # Session.xcodeproj/project.pbxproj # Session/Conversations/Context Menu/ContextMenuVC+Action.swift # Session/Conversations/Context Menu/ContextMenuVC+ActionView.swift # Session/Conversations/Context Menu/ContextMenuVC.swift # Session/Conversations/ConversationVC+Interaction.swift # Session/Conversations/ConversationVC.swift # Session/Conversations/ConversationViewItem.h # Session/Conversations/ConversationViewItem.m # Session/Conversations/Message Cells/Content Views/LinkPreviewView.swift # Session/Conversations/Message Cells/MessageCell.swift # Session/Conversations/Message Cells/VisibleMessageCell.swift # Session/Conversations/Views & Modals/BodyTextView.swift # Session/Meta/Translations/en.lproj/Localizable.strings # Session/Shared/UserCell.swift # SessionMessagingKit/Jobs/MessageSendJob.swift # SessionMessagingKit/Messages/Signal/TSMessage.h # SessionMessagingKit/Messages/Signal/TSMessage.m # SessionMessagingKit/Messages/Visible Messages/VisibleMessage.swift # SessionMessagingKit/Open Groups/OpenGroupAPIV2.swift # SessionMessagingKit/Sending & Receiving/MessageReceiver+Handling.swift # SessionMessagingKit/Sending & Receiving/Notifications/NotificationsProtocol.h # SessionMessagingKit/Sending & Receiving/Pollers/OpenGroupPollerV2.swift # SessionMessagingKit/Utilities/General.swift # SessionNotificationServiceExtension/NSENotificationPresenter.swift # SignalUtilitiesKit/Utilities/DisplayableText.swift # SignalUtilitiesKit/Utilities/NoopNotificationsManager.swift # SignalUtilitiesKit/Utilities/Notification+Loki.swift
2022-07-25 07:39:56 +02:00
return EmojiWithSkinTones(
baseEmoji: self,
skinTones: rawSkinTones
.split(separator: ",")
.compactMap { SkinTone(rawValue: String($0)) }
)
2022-06-10 08:51:37 +02:00
}
Merge branch 'feature/database-refactor' into emoji-reacts # Conflicts: # Session.xcodeproj/project.pbxproj # Session/Conversations/Context Menu/ContextMenuVC+Action.swift # Session/Conversations/Context Menu/ContextMenuVC+ActionView.swift # Session/Conversations/Context Menu/ContextMenuVC.swift # Session/Conversations/ConversationVC+Interaction.swift # Session/Conversations/ConversationVC.swift # Session/Conversations/ConversationViewItem.h # Session/Conversations/ConversationViewItem.m # Session/Conversations/Message Cells/Content Views/LinkPreviewView.swift # Session/Conversations/Message Cells/MessageCell.swift # Session/Conversations/Message Cells/VisibleMessageCell.swift # Session/Conversations/Views & Modals/BodyTextView.swift # Session/Meta/Translations/en.lproj/Localizable.strings # Session/Shared/UserCell.swift # SessionMessagingKit/Jobs/MessageSendJob.swift # SessionMessagingKit/Messages/Signal/TSMessage.h # SessionMessagingKit/Messages/Signal/TSMessage.m # SessionMessagingKit/Messages/Visible Messages/VisibleMessage.swift # SessionMessagingKit/Open Groups/OpenGroupAPIV2.swift # SessionMessagingKit/Sending & Receiving/MessageReceiver+Handling.swift # SessionMessagingKit/Sending & Receiving/Notifications/NotificationsProtocol.h # SessionMessagingKit/Sending & Receiving/Pollers/OpenGroupPollerV2.swift # SessionMessagingKit/Utilities/General.swift # SessionNotificationServiceExtension/NSENotificationPresenter.swift # SignalUtilitiesKit/Utilities/DisplayableText.swift # SignalUtilitiesKit/Utilities/NoopNotificationsManager.swift # SignalUtilitiesKit/Utilities/Notification+Loki.swift
2022-07-25 07:39:56 +02:00
func setPreferredSkinTones(_ db: Database, preferredSkinTonePermutation: [SkinTone]?) {
db[.emojiPreferredSkinTones(emoji: rawValue)] = preferredSkinTonePermutation
.map { preferredSkinTonePermutation in
preferredSkinTonePermutation
.map { $0.rawValue }
.joined(separator: ",")
}
2022-06-10 08:51:37 +02:00
}
init?(_ string: String) {
guard let emojiWithSkinTonePermutation = EmojiWithSkinTones(rawValue: string) else { return nil }
self = emojiWithSkinTonePermutation.baseEmoji
}
}
// MARK: -
extension String {
// This is slightly more accurate than String.isSingleEmoji,
// but slower.
//
// * This will reject "lone modifiers".
// * This will reject certain edge cases such as 🌈.
var isSingleEmojiUsingEmojiWithSkinTones: Bool {
EmojiWithSkinTones(rawValue: self) != nil
}
}