Reimplement normal emoji completion

BUG: 460632
This commit is contained in:
Tobias Fella
2022-11-26 02:41:50 +01:00
parent f27b64edef
commit dd0300d025
10 changed files with 40 additions and 13 deletions

View File

@@ -49,7 +49,7 @@ set_package_properties(Qt${QT_MAJOR_VERSION} PROPERTIES
TYPE REQUIRED
PURPOSE "Basic application components"
)
find_package(KF5 ${KF5_MIN_VERSION} COMPONENTS Kirigami2 I18n Notifications Config CoreAddons Sonnet)
find_package(KF5 ${KF5_MIN_VERSION} COMPONENTS Kirigami2 I18n Notifications Config CoreAddons Sonnet ItemModels)
set_package_properties(KF5 PROPERTIES
TYPE REQUIRED
PURPOSE "Basic application components"

View File

@@ -90,7 +90,7 @@ else()
endif()
target_include_directories(neochat PRIVATE ${CMAKE_BINARY_DIR})
target_link_libraries(neochat PUBLIC Qt::Core Qt::Quick Qt::Qml Qt::Gui Qt::Multimedia Qt::Network Qt::QuickControls2 KF5::I18n KF5::Kirigami2 KF5::Notifications KF5::ConfigCore KF5::ConfigGui KF5::CoreAddons KF5::SonnetCore Quotient cmark::cmark ${QTKEYCHAIN_LIBRARIES})
target_link_libraries(neochat PUBLIC Qt::Core Qt::Quick Qt::Qml Qt::Gui Qt::Multimedia Qt::Network Qt::QuickControls2 KF5::I18n KF5::Kirigami2 KF5::Notifications KF5::ConfigCore KF5::ConfigGui KF5::CoreAddons KF5::SonnetCore KF5::ItemModels Quotient cmark::cmark ${QTKEYCHAIN_LIBRARIES})
if(TARGET QCoro5::Coro)
target_link_libraries(neochat PUBLIC QCoro5::Coro)
else()

View File

@@ -235,7 +235,7 @@ void ChatDocumentHandler::complete(int index)
m_room->mentions()->push_back({cursor, alias, 0, 0, alias});
m_highlighter->rehighlight();
} else if (m_completionModel->autoCompletionType() == ChatDocumentHandler::Emoji) {
auto shortcode = m_completionModel->data(m_completionModel->index(index, 0), CompletionModel::Text).toString();
auto shortcode = m_completionModel->data(m_completionModel->index(index, 0), CompletionModel::ReplacedText).toString();
auto text = m_room->chatBoxText();
auto at = text.lastIndexOf(QLatin1Char(':'));
QTextCursor cursor(document()->textDocument());

View File

@@ -8,6 +8,7 @@
#include "chatdocumenthandler.h"
#include "completionproxymodel.h"
#include "customemojimodel.h"
#include "emojimodel.h"
#include "neochatroom.h"
#include "roomlistmodel.h"
#include "userlistmodel.h"
@@ -16,11 +17,14 @@ CompletionModel::CompletionModel(QObject *parent)
: QAbstractListModel(parent)
, m_filterModel(new CompletionProxyModel())
, m_userListModel(new UserListModel(this))
, m_emojiModel(new KConcatenateRowsProxyModel(this))
{
connect(this, &CompletionModel::textChanged, this, &CompletionModel::updateCompletion);
connect(this, &CompletionModel::roomChanged, this, [this]() {
m_userListModel->setRoom(m_room);
});
m_emojiModel->addSourceModel(&CustomEmojiModel::instance());
m_emojiModel->addSourceModel(&EmojiModel::instance());
}
QString CompletionModel::text() const
@@ -90,11 +94,14 @@ QVariant CompletionModel::data(const QModelIndex &index, int role) const
}
if (m_autoCompletionType == ChatDocumentHandler::Emoji) {
if (role == Text) {
return m_filterModel->data(filterIndex, CustomEmojiModel::Name);
return m_filterModel->data(filterIndex, CustomEmojiModel::DisplayRole);
}
if (role == Icon) {
return m_filterModel->data(filterIndex, CustomEmojiModel::MxcUrl);
}
if (role == ReplacedText) {
return m_filterModel->data(filterIndex, CustomEmojiModel::ReplacedTextRole);
}
}
return {};
@@ -140,7 +147,7 @@ void CompletionModel::updateCompletion()
&& (m_fullText.indexOf(QLatin1Char(':'), 1) == -1
|| (m_fullText.indexOf(QLatin1Char(' ')) != -1 && m_fullText.indexOf(QLatin1Char(':'), 1) > m_fullText.indexOf(QLatin1Char(' '), 1)))) {
m_autoCompletionType = ChatDocumentHandler::Emoji;
m_filterModel->setSourceModel(&CustomEmojiModel::instance());
m_filterModel->setSourceModel(m_emojiModel);
m_filterModel->setFilterRole(CustomEmojiModel::Name);
m_filterModel->setSecondaryFilterRole(-1);
m_filterModel->setFullText(m_fullText);

View File

@@ -5,6 +5,8 @@
#include <QSortFilterProxyModel>
#include <KConcatenateRowsProxyModel>
#include "chatdocumenthandler.h"
class CompletionProxyModel;
@@ -64,4 +66,5 @@ private:
UserListModel *m_userListModel;
RoomListModel *m_roomListModel;
KConcatenateRowsProxyModel *m_emojiModel;
};

View File

@@ -134,6 +134,8 @@ QVariant CustomEmojiModel::data(const QModelIndex &idx, int role) const
case Roles::ModelData:
return QVariant::fromValue(Emoji(QStringLiteral("image://mxc/") + data.url.mid(6), data.name, true));
case Roles::Name:
case Roles::DisplayRole:
case Roles::ReplacedTextRole:
return data.name;
case Roles::ImageURL:
return QUrl(QStringLiteral("image://mxc/") + data.url.mid(6));

View File

@@ -19,10 +19,12 @@ class CustomEmojiModel : public QAbstractListModel
public:
enum Roles {
Name,
Name = Qt::DisplayRole,
ImageURL,
ModelData, // for emulating the regular emoji model's usage, otherwise the UI code would get too complicated
MxcUrl,
MxcUrl = 50,
DisplayRole = 51,
ReplacedTextRole = 52,
};
Q_ENUM(Roles);

View File

@@ -39,10 +39,15 @@ QVariant EmojiModel::data(const QModelIndex &index, int role) const
}
auto emoji = category[row].value<Emoji>();
switch (role) {
case TextRole:
return emoji.shortName;
case ShortNameRole:
return QStringLiteral(":%1:").arg(emoji.shortName);
case UnicodeRole:
case ReplacedTextRole:
return emoji.unicode;
case InvalidRole:
return QStringLiteral("invalid");
case DisplayRole:
return QStringLiteral("%2 :%1:").arg(emoji.shortName, emoji.unicode);
}
}
return {};
@@ -50,7 +55,7 @@ QVariant EmojiModel::data(const QModelIndex &index, int role) const
QHash<int, QByteArray> EmojiModel::roleNames() const
{
return {{TextRole, "text"}, {UnicodeRole, "unicode"}};
return {{ShortNameRole, "shortName"}, {UnicodeRole, "unicode"}};
}
QMultiHash<QString, QVariant> EmojiModel::_tones = {

View File

@@ -51,11 +51,18 @@ class EmojiModel : public QAbstractListModel
Q_PROPERTY(QVariantList categories READ categories CONSTANT)
public:
explicit EmojiModel(QObject *parent = nullptr);
static EmojiModel &instance()
{
static EmojiModel _instance;
return _instance;
}
enum RoleNames {
TextRole = Qt::DisplayRole,
ShortNameRole = Qt::DisplayRole,
UnicodeRole,
InvalidRole = 50,
DisplayRole = 51,
ReplacedTextRole = 52,
};
Q_ENUM(RoleNames);
@@ -100,4 +107,5 @@ private:
// TODO: Port away from QSettings
QSettings m_settings;
EmojiModel(QObject *parent = nullptr);
};

View File

@@ -203,7 +203,7 @@ int main(int argc, char *argv[])
qmlRegisterSingletonInstance("org.kde.neochat", 1, 0, "FileType", &fileTypeSingleton);
qmlRegisterSingletonInstance("org.kde.neochat", 1, 0, "LoginHelper", login);
qmlRegisterSingletonInstance("org.kde.neochat", 1, 0, "UrlHelper", &urlHelper);
qmlRegisterSingletonInstance("org.kde.neochat", 1, 0, "EmojiModel", new EmojiModel(&app));
qmlRegisterSingletonInstance("org.kde.neochat", 1, 0, "EmojiModel", &EmojiModel::instance());
#ifdef QUOTIENT_07
qmlRegisterSingletonInstance("org.kde.neochat", 1, 0, "AccountRegistry", &Quotient::Accounts);
#else