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; @@ -182,6 +179,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" 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 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("\"%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(-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; }