diff --git a/src/messages/messageelement.hpp b/src/messages/messageelement.hpp index 2f281c121..79a78897e 100644 --- a/src/messages/messageelement.hpp +++ b/src/messages/messageelement.hpp @@ -169,7 +169,6 @@ public: // b) which size it wants class EmoteElement : public MessageElement { - const util::EmoteData data; std::unique_ptr textElement; public: @@ -177,6 +176,8 @@ public: ~EmoteElement() override = default; void addToContainer(MessageLayoutContainer &container, MessageElement::Flags flags) override; + + const util::EmoteData data; }; // contains a text, formated depending on the preferences diff --git a/src/singletons/emotemanager.cpp b/src/singletons/emotemanager.cpp index 3cd841f01..a1a781fbe 100644 --- a/src/singletons/emotemanager.cpp +++ b/src/singletons/emotemanager.cpp @@ -135,8 +135,12 @@ void EmoteManager::reloadBTTVChannelEmotes(const QString &channelName, link = link.replace("{{id}}", id).replace("{{image}}", "1x"); - auto emote = this->getBTTVChannelEmoteFromCaches().getOrAdd(id, [&code, &link] { - return util::EmoteData(new Image(link, 1, code, code + "
Channel BTTV Emote")); + auto emote = this->getBTTVChannelEmoteFromCaches().getOrAdd(id, [&id, &code, &link] { + util::EmoteData emoteData( + new Image(link, 1, code, code + "
Channel BTTV Emote")); + emoteData.pageLink = "https://manage.betterttv.net/emotes/" + id; + + return emoteData; }); this->bttvChannelEmotes.insert(code, emote); @@ -182,9 +186,11 @@ void EmoteManager::reloadFFZChannelEmotes(const QString &channelName, QJsonObject urls = emoteObject.value("urls").toObject(); - auto emote = this->getFFZChannelEmoteFromCaches().getOrAdd(id, [&code, &urls] { + auto emote = this->getFFZChannelEmoteFromCaches().getOrAdd(id, [id, &code, &urls] { util::EmoteData emoteData; FillInFFZEmoteData(urls, code, code + "
Channel FFZ Emote", emoteData); + emoteData.pageLink = + QString("https://www.frankerfacez.com/emoticon/%1-%2").arg(id).arg(code); return emoteData; }); @@ -483,6 +489,7 @@ void EmoteManager::loadBTTVEmotes() code + "
Global BTTV Emote"); emoteData.image3x = new Image(GetBTTVEmoteLink(urlTemplate, id, "3x"), 0.25, code, code + "
Global BTTV Emote"); + emoteData.pageLink = "https://manage.betterttv.net/emotes/" + id; this->bttvGlobalEmotes.insert(code, emoteData); codes.push_back(code.toStdString()); @@ -510,10 +517,13 @@ void EmoteManager::loadFFZEmotes() QJsonObject object = emote.toObject(); QString code = object.value("name").toString(); + int id = object.value("id").toInt(); QJsonObject urls = object.value("urls").toObject(); util::EmoteData emoteData; FillInFFZEmoteData(urls, code, code + "
Global FFZ Emote", emoteData); + emoteData.pageLink = + QString("https://www.frankerfacez.com/emoticon/%1-%2").arg(id).arg(code); this->ffzGlobalEmotes.insert(code, emoteData); codes.push_back(code.toStdString()); diff --git a/src/util/emotemap.hpp b/src/util/emotemap.hpp index 478169097..774a3a84f 100644 --- a/src/util/emotemap.hpp +++ b/src/util/emotemap.hpp @@ -23,6 +23,9 @@ struct EmoteData { messages::Image *image1x = nullptr; messages::Image *image2x = nullptr; messages::Image *image3x = nullptr; + + // Link to the emote page i.e. https://www.frankerfacez.com/emoticon/144722-pajaCringe + QString pageLink; }; using EmoteMap = ConcurrentMap; diff --git a/src/widgets/helper/channelview.cpp b/src/widgets/helper/channelview.cpp index 95055e6b2..a62e0b51a 100644 --- a/src/widgets/helper/channelview.cpp +++ b/src/widgets/helper/channelview.cpp @@ -883,6 +883,56 @@ void ChannelView::mouseReleaseEvent(QMouseEvent *event) return; } + const auto &creator = hoverLayoutElement->getCreator(); + auto creatorFlags = creator.getFlags(); + + if ((creatorFlags & (MessageElement::Flags::EmoteImages | MessageElement::Flags::EmojiImage)) != + 0) { + if (event->button() == Qt::RightButton) { + static QMenu *menu = new QMenu; + menu->clear(); + + const auto &emoteElement = static_cast(creator); + + // TODO: We might want to add direct "Open image" variants alongside the Copy actions + + if (emoteElement.data.image1x != nullptr) { + menu->addAction("Copy 1x link", [url = emoteElement.data.image1x->getUrl()] { + QApplication::clipboard()->setText(url); // + }); + } + if (emoteElement.data.image2x != nullptr) { + menu->addAction("Copy 2x link", [url = emoteElement.data.image2x->getUrl()] { + QApplication::clipboard()->setText(url); // + }); + } + if (emoteElement.data.image3x != nullptr) { + menu->addAction("Copy 3x link", [url = emoteElement.data.image3x->getUrl()] { + QApplication::clipboard()->setText(url); // + }); + } + + if ((creatorFlags & MessageElement::Flags::BttvEmote) != 0) { + menu->addSeparator(); + QString emotePageLink = emoteElement.data.pageLink; + menu->addAction("Copy BTTV emote link", [emotePageLink] { + QApplication::clipboard()->setText(emotePageLink); // + }); + } else if ((creatorFlags & MessageElement::Flags::FfzEmote) != 0) { + menu->addSeparator(); + QString emotePageLink = emoteElement.data.pageLink; + menu->addAction("Copy FFZ emote link", [emotePageLink] { + QApplication::clipboard()->setText(emotePageLink); // + }); + } + + menu->move(QCursor::pos()); + menu->show(); + + return; + } + } + auto &link = hoverLayoutElement->getLink(); if (event->button() != Qt::LeftButton || !app->settings->linksDoubleClickOnly) { this->handleLinkClick(event, link, layout.get());