diff --git a/resources/qml/Completer.qml b/resources/qml/Completer.qml
index 6bde67fa..c58cda14 100644
--- a/resources/qml/Completer.qml
+++ b/resources/qml/Completer.qml
@@ -69,10 +69,7 @@ Popup {
onCompleterNameChanged: {
if (completerName) {
- if (completerName == "user")
- completer = TimelineManager.completerFor(completerName, room.roomId);
- else
- completer = TimelineManager.completerFor(completerName);
+ completer = TimelineManager.completerFor(completerName, room.roomId);
completer.setSearchString("");
} else {
completer = undefined;
@@ -183,6 +180,39 @@ Popup {
}
DelegateChoice {
+ roleValue: "customEmoji"
+
+ RowLayout {
+ id: del
+
+ anchors.centerIn: parent
+ spacing: rowSpacing
+
+ Avatar {
+ height: popup.avatarHeight
+ width: popup.avatarWidth
+ displayName: model.shortcode
+ //userid: model.shortcode
+ url: model.url.replace("mxc://", "image://MxcImage/")
+ onClicked: popup.completionClicked(completer.completionAt(model.index))
+ crop: false
+ }
+
+ Label {
+ text: model.shortcode
+ color: model.index == popup.currentIndex ? Nheko.colors.highlightedText : Nheko.colors.text
+ }
+
+ Label {
+ text: "(" + model.packname + ")"
+ color: model.index == popup.currentIndex ? Nheko.colors.highlightedText : Nheko.colors.buttonText
+ }
+
+ }
+
+ }
+
+ DelegateChoice {
roleValue: "room"
RowLayout {
diff --git a/resources/qml/MessageInput.qml b/resources/qml/MessageInput.qml
index 0d38d026..e5317605 100644
--- a/resources/qml/MessageInput.qml
+++ b/resources/qml/MessageInput.qml
@@ -101,6 +101,7 @@ Rectangle {
}
function openCompleter(pos, type) {
+ if (popup.opened) return;
completerTriggeredAt = pos;
popup.completerName = type;
popup.open();
@@ -166,13 +167,12 @@ Rectangle {
messageInput.text = room.input.nextText();
} else if (event.key == Qt.Key_At) {
messageInput.openCompleter(selectionStart, "user");
- popup.open();
} else if (event.key == Qt.Key_Colon) {
messageInput.openCompleter(selectionStart, "emoji");
- popup.open();
} else if (event.key == Qt.Key_NumberSign) {
messageInput.openCompleter(selectionStart, "roomAliases");
- popup.open();
+ } else if (event.text == "~") {
+ messageInput.openCompleter(selectionStart, "customEmoji");
} else if (event.key == Qt.Key_Escape && popup.opened) {
popup.completerName = "";
popup.close();
@@ -214,6 +214,9 @@ Rectangle {
} else if (t == ':') {
messageInput.openCompleter(pos, "emoji");
return ;
+ } else if (t == '~') {
+ messageInput.openCompleter(pos, "customEmoji");
+ return ;
}
pos = pos - 1;
}
diff --git a/src/Cache.cpp b/src/Cache.cpp
index dd26157c..6db768d3 100644
--- a/src/Cache.cpp
+++ b/src/Cache.cpp
@@ -3580,24 +3580,26 @@ Cache::getImagePacks(const std::string &room_id, std::optional<bool> stickers)
auto addPack = [&infos, stickers](const mtx::events::msc2545::ImagePack &pack,
const std::string &source_room,
const std::string &state_key) {
- if (!pack.pack || !stickers.has_value() ||
- (stickers.value() ? pack.pack->is_sticker() : pack.pack->is_emoji())) {
- ImagePackInfo info;
- info.source_room = source_room;
- info.state_key = state_key;
- info.pack.pack = pack.pack;
+ bool pack_matches = !stickers.has_value() ||
+ (stickers.value() ? pack.pack->is_sticker() : pack.pack->is_emoji());
- for (const auto &img : pack.images) {
- if (stickers.has_value() && img.second.overrides_usage() &&
- (stickers ? !img.second.is_sticker() : !img.second.is_emoji()))
- continue;
+ ImagePackInfo info;
+ info.source_room = source_room;
+ info.state_key = state_key;
+ info.pack.pack = pack.pack;
- info.pack.images.insert(img);
- }
+ for (const auto &img : pack.images) {
+ if (stickers.has_value() &&
+ (img.second.overrides_usage()
+ ? (!stickers.value() ? img.second.is_sticker() : img.second.is_emoji())
+ : !pack_matches))
+ continue;
- if (!info.pack.images.empty())
- infos.push_back(std::move(info));
+ info.pack.images.insert(img);
}
+
+ if (!info.pack.images.empty())
+ infos.push_back(std::move(info));
};
// packs from account data
diff --git a/src/CombinedImagePackModel.cpp b/src/CombinedImagePackModel.cpp
index 9a52f810..2a8959c0 100644
--- a/src/CombinedImagePackModel.cpp
+++ b/src/CombinedImagePackModel.cpp
@@ -56,7 +56,9 @@ CombinedImagePackModel::data(const QModelIndex &index, int role) const
if (hasIndex(index.row(), index.column(), index.parent())) {
switch (role) {
case CompletionModel::CompletionRole:
- return QString::fromStdString(images[index.row()].image.url);
+ return QString("<img data-mx-emoticon height=32 src=\"%1\" alt=\"%2\" title=\"%2\">")
+ .arg(QString::fromStdString(images[index.row()].image.url).toHtmlEscaped(),
+ images[index.row()].shortcode);
case Roles::Url:
return QString::fromStdString(images[index.row()].image.url);
case CompletionModel::SearchRole:
diff --git a/src/timeline/TimelineViewManager.cpp b/src/timeline/TimelineViewManager.cpp
index 9303ee40..eb30fe8c 100644
--- a/src/timeline/TimelineViewManager.cpp
+++ b/src/timeline/TimelineViewManager.cpp
@@ -550,6 +550,11 @@ TimelineViewManager::completerFor(QString completerName, QString roomId)
auto proxy = new CompletionProxyModel(stickerModel, 1, static_cast<size_t>(-1) / 4);
stickerModel->setParent(proxy);
return proxy;
+ } else if (completerName == "customEmoji") {
+ auto stickerModel = new CombinedImagePackModel(roomId.toStdString(), false);
+ auto proxy = new CompletionProxyModel(stickerModel);
+ stickerModel->setParent(proxy);
+ return proxy;
}
return nullptr;
}
|