File indexing completed on 2024-05-12 05:04:18
0001 // SPDX-FileCopyrightText: 2017 Konstantinos Sideris <siderisk@auth.gr> 0002 // SPDX-FileCopyrightText: 2023 Joshua Goins <josh@redstrate.com> 0003 // SPDX-License-Identifier: GPL-3.0-or-later 0004 0005 #include "emojimodel.h" 0006 0007 #include <KLocalizedString> 0008 0009 #include "abstractaccount.h" 0010 #include "emojitones.h" 0011 0012 using namespace Qt::Literals::StringLiterals; 0013 0014 QHash<EmojiModel::Category, QVariantList> EmojiModel::_emojis; 0015 0016 EmojiModel::EmojiModel(QObject *parent) 0017 : QObject(parent) 0018 { 0019 if (_emojis.isEmpty()) { 0020 #include "emojis.h" 0021 } 0022 } 0023 0024 QVariantList EmojiModel::filterModel(AbstractAccount *account, const QString &filter) 0025 { 0026 return filterCustomModel(account, filter) + filterModelNoCustom(filter); 0027 } 0028 0029 QVariantList EmojiModel::emojis(AbstractAccount *account, Category category) const 0030 { 0031 if (category == History) { 0032 QVariantList list; 0033 for (const auto &historicEmoji : history(account)) { 0034 for (const auto &emojiCategory : _emojis) { 0035 for (const auto &emoji : emojiCategory) { 0036 if (qvariant_cast<Emoji>(emoji).shortName == historicEmoji) { 0037 list.append(emoji); 0038 } 0039 } 0040 } 0041 0042 for (const auto &customEmoji : filterCustomModel(account, {})) { 0043 if (qvariant_cast<CustomEmoji>(customEmoji).shortcode == historicEmoji) { 0044 list.append(customEmoji); 0045 } 0046 } 0047 } 0048 0049 return list; 0050 } else if (category == Custom) { 0051 return filterCustomModel(account, {}); 0052 } 0053 0054 return _emojis[category]; 0055 } 0056 0057 QVariantList EmojiModel::tones(const QString &baseEmoji) const 0058 { 0059 if (baseEmoji.endsWith("tone"_L1)) { 0060 return EmojiTones::_tones.values(baseEmoji.split(":"_L1)[0]); 0061 } 0062 0063 return EmojiTones::_tones.values(baseEmoji); 0064 } 0065 0066 QStringList EmojiModel::history(AbstractAccount *account) const 0067 { 0068 if (account == nullptr) { 0069 return {}; 0070 } 0071 0072 AccountConfig config(account->settingsGroupName()); 0073 return config.lastUsedEmojis(); 0074 } 0075 0076 QVariantList EmojiModel::filterModelNoCustom(const QString &filter) 0077 { 0078 QVariantList result; 0079 0080 for (const auto &e : _emojis.values()) { 0081 for (const auto &variant : e) { 0082 const auto &emoji = qvariant_cast<Emoji>(variant); 0083 if (emoji.shortName.contains(filter, Qt::CaseInsensitive)) { 0084 result.append(variant); 0085 } 0086 } 0087 } 0088 0089 return result; 0090 } 0091 0092 void EmojiModel::emojiUsed(AbstractAccount *account, const QString &shortcode) 0093 { 0094 if (account == nullptr) { 0095 return; 0096 } 0097 0098 auto list = history(account).toVector(); 0099 0100 // Remove previous instances of this emoji 0101 auto it = list.begin(); 0102 while (it != list.end()) { 0103 if ((*it) == shortcode) { 0104 it = list.erase(it); 0105 } else { 0106 it++; 0107 } 0108 } 0109 0110 list.push_front(shortcode); 0111 0112 // sigh, QList didn't have resize until 6.0. 0113 if (list.size() > 100) { 0114 list.resize(100); 0115 } 0116 0117 AccountConfig config(account->settingsGroupName()); 0118 config.setLastUsedEmojis(list.toList()); 0119 config.save(); 0120 0121 Q_EMIT historyChanged(); 0122 } 0123 0124 QVariantList EmojiModel::categories() const 0125 { 0126 return QVariantList{ 0127 {QVariantMap{ 0128 {QStringLiteral("category"), EmojiModel::History}, 0129 {QStringLiteral("name"), i18nc("Previously used emojis", "History")}, 0130 {QStringLiteral("emoji"), QStringLiteral("⌛️")}, 0131 }}, 0132 {QVariantMap{ 0133 {QStringLiteral("category"), EmojiModel::Custom}, 0134 {QStringLiteral("name"), i18nc("'Custom' is a category of emoji", "Custom")}, 0135 {QStringLiteral("emoji"), QStringLiteral("🖼️")}, 0136 }}, 0137 {QVariantMap{ 0138 {QStringLiteral("category"), EmojiModel::Smileys}, 0139 {QStringLiteral("name"), i18nc("'Smileys' is a category of emoji", "Smileys")}, 0140 {QStringLiteral("emoji"), QStringLiteral("😏")}, 0141 }}, 0142 {QVariantMap{ 0143 {QStringLiteral("category"), EmojiModel::People}, 0144 {QStringLiteral("name"), i18nc("'People' is a category of emoji", "People")}, 0145 {QStringLiteral("emoji"), QStringLiteral("🙋♂️")}, 0146 }}, 0147 {QVariantMap{ 0148 {QStringLiteral("category"), EmojiModel::Nature}, 0149 {QStringLiteral("name"), i18nc("'Nature' is a category of emoji", "Nature")}, 0150 {QStringLiteral("emoji"), QStringLiteral("🌲")}, 0151 }}, 0152 {QVariantMap{ 0153 {QStringLiteral("category"), EmojiModel::Food}, 0154 {QStringLiteral("name"), i18nc("'Food' is a category of emoji", "Food")}, 0155 {QStringLiteral("emoji"), QStringLiteral("🍛")}, 0156 }}, 0157 {QVariantMap{ 0158 {QStringLiteral("category"), EmojiModel::Activities}, 0159 {QStringLiteral("name"), i18nc("'Activities' is a category of emoji", "Activities")}, 0160 {QStringLiteral("emoji"), QStringLiteral("🚁")}, 0161 }}, 0162 {QVariantMap{ 0163 {QStringLiteral("category"), EmojiModel::Travel}, 0164 {QStringLiteral("name"), i18nc("'Travel' is a category of emoji", "Travel")}, 0165 {QStringLiteral("emoji"), QStringLiteral("🚅")}, 0166 }}, 0167 {QVariantMap{ 0168 {QStringLiteral("category"), EmojiModel::Objects}, 0169 {QStringLiteral("name"), i18nc("'Objects' is a category of emoji", "Objects")}, 0170 {QStringLiteral("emoji"), QStringLiteral("💡")}, 0171 }}, 0172 {QVariantMap{ 0173 {QStringLiteral("category"), EmojiModel::Symbols}, 0174 {QStringLiteral("name"), i18nc("'Symbols' is a category of emoji", "Symbols")}, 0175 {QStringLiteral("emoji"), QStringLiteral("🔣")}, 0176 }}, 0177 {QVariantMap{ 0178 {QStringLiteral("category"), EmojiModel::Flags}, 0179 {QStringLiteral("name"), i18nc("'Flags' is a category of emoji", "Flags")}, 0180 {QStringLiteral("emoji"), QStringLiteral("🏁")}, 0181 }}, 0182 }; 0183 } 0184 0185 QVariantList EmojiModel::filterCustomModel(AbstractAccount *account, const QString &filter) 0186 { 0187 if (account == nullptr) { 0188 return {}; 0189 } 0190 0191 QVariantList result; 0192 for (const auto &emoji : account->customEmojis()) { 0193 if (emoji.shortcode.contains(filter, Qt::CaseInsensitive)) { 0194 result.append(QVariant::fromValue(emoji)); 0195 } 0196 } 0197 0198 return result; 0199 } 0200 0201 #include "moc_emojimodel.cpp"