From 5253ab3f85d62e6bf2b9d069697ca31dafca150f Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Fri, 24 Aug 2018 12:56:42 +0300 Subject: [PATCH] Added tooltip to links via BTTV API. --- chatterino.pro | 2 + src/providers/bttv/BttvTooltip.cpp | 39 +++++++++++++++++++ src/providers/bttv/BttvTooltip.hpp | 17 ++++++++ src/providers/twitch/TwitchMessageBuilder.cpp | 10 ++++- src/widgets/TooltipWidget.cpp | 5 +++ src/widgets/TooltipWidget.hpp | 1 + src/widgets/helper/ChannelView.cpp | 1 + src/widgets/splits/SplitHeader.cpp | 2 + 8 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 src/providers/bttv/BttvTooltip.cpp create mode 100644 src/providers/bttv/BttvTooltip.hpp diff --git a/chatterino.pro b/chatterino.pro index 1c9cf8f11..ebe784deb 100644 --- a/chatterino.pro +++ b/chatterino.pro @@ -237,6 +237,7 @@ SOURCES += \ src/messages/Emote.cpp \ src/messages/ImageSet.cpp \ src/providers/bttv/BttvEmotes.cpp \ + src/providers/bttv/BttvTooltip.cpp \ src/providers/ffz/FfzEmotes.cpp \ src/autogenerated/ResourcesAutogen.cpp \ src/singletons/Badges.cpp \ @@ -433,6 +434,7 @@ HEADERS += \ src/messages/ImageSet.hpp \ src/common/Outcome.hpp \ src/providers/bttv/BttvEmotes.hpp \ + src/providers/bttv/BttvTooltip.hpp \ src/providers/ffz/FfzEmotes.hpp \ src/autogenerated/ResourcesAutogen.hpp \ src/singletons/Badges.hpp \ diff --git a/src/providers/bttv/BttvTooltip.cpp b/src/providers/bttv/BttvTooltip.cpp new file mode 100644 index 000000000..df3738411 --- /dev/null +++ b/src/providers/bttv/BttvTooltip.cpp @@ -0,0 +1,39 @@ +#include "providers/bttv/BttvTooltip.hpp" + +#include "common/Common.hpp" +#include "common/NetworkRequest.hpp" + +#include + +namespace chatterino { + +void BttvTooltip::getUrlTooltip(const QString url, + std::function successCallback) +{ + QString requestUrl("https://api.betterttv.net/2/link_resolver/" + + QUrl::toPercentEncoding(url, "", "/:")); + + NetworkRequest request(requestUrl); + request.setCaller(QThread::currentThread()); + request.setTimeout(30000); + request.onSuccess([successCallback](auto result) mutable -> Outcome { + auto root = result.parseJson(); + /* When tooltip is not a string, in this case, + onError runs before onSuccess, + so there is no point in doing "if" condition. */ + auto tooltip = root.value("tooltip").toString(); + successCallback(QUrl::fromPercentEncoding(tooltip.toUtf8())); + + return Success; + }); + + request.onError([successCallback](auto result) { + successCallback("No link info found"); + + return true; + }); + + request.execute(); +} + +} // namespace chatterino diff --git a/src/providers/bttv/BttvTooltip.hpp b/src/providers/bttv/BttvTooltip.hpp new file mode 100644 index 000000000..2c6b2597a --- /dev/null +++ b/src/providers/bttv/BttvTooltip.hpp @@ -0,0 +1,17 @@ +#pragma once + +#include +#include + +namespace chatterino { + +class BttvTooltip +{ +public: + static void getUrlTooltip(const QString url, + std::function callback); + +private: +}; + +} // namespace chatterino diff --git a/src/providers/twitch/TwitchMessageBuilder.cpp b/src/providers/twitch/TwitchMessageBuilder.cpp index b245c7664..b83bfd29d 100644 --- a/src/providers/twitch/TwitchMessageBuilder.cpp +++ b/src/providers/twitch/TwitchMessageBuilder.cpp @@ -8,6 +8,7 @@ #include "messages/Message.hpp" #include "providers/twitch/TwitchBadges.hpp" #include "providers/twitch/TwitchChannel.hpp" +#include "providers/bttv/BttvTooltip.hpp" #include "singletons/Emotes.hpp" #include "singletons/Resources.hpp" #include "singletons/Settings.hpp" @@ -268,12 +269,19 @@ void TwitchMessageBuilder::addTextOrEmoji(const QString &string_) link = Link(Link::Url, linkString); textColor = MessageColor(MessageColor::Link); - this->emplace(lowercaseLinkString, + auto linkMessageElement = this->emplace(lowercaseLinkString, MessageElementFlag::LowercaseLink, textColor) ->setLink(link); this->emplace(string, MessageElementFlag::OriginalLink, textColor) ->setLink(link); + + BttvTooltip::getUrlTooltip( + linkString, [linkMessageElement](QString tooltipText) { + if (!tooltipText.isEmpty()) { + linkMessageElement->setTooltip(tooltipText); + } + }); } // if (!linkString.isEmpty()) { diff --git a/src/widgets/TooltipWidget.cpp b/src/widgets/TooltipWidget.cpp index 084f729ac..5ee0b1daf 100644 --- a/src/widgets/TooltipWidget.cpp +++ b/src/widgets/TooltipWidget.cpp @@ -87,6 +87,11 @@ void TooltipWidget::setText(QString text) this->displayText_->setText(text); } +void TooltipWidget::setWordWrap(bool wrap) +{ + this->displayText_->setWordWrap(wrap); +} + void TooltipWidget::changeEvent(QEvent *) { // clear parents event diff --git a/src/widgets/TooltipWidget.hpp b/src/widgets/TooltipWidget.hpp index 7d8c95dc2..2228e5662 100644 --- a/src/widgets/TooltipWidget.hpp +++ b/src/widgets/TooltipWidget.hpp @@ -19,6 +19,7 @@ public: virtual ~TooltipWidget() override; void setText(QString text); + void setWordWrap(bool wrap); #ifdef USEWINSDK void raise(); diff --git a/src/widgets/helper/ChannelView.cpp b/src/widgets/helper/ChannelView.cpp index 2afc42e75..71c1408d7 100644 --- a/src/widgets/helper/ChannelView.cpp +++ b/src/widgets/helper/ChannelView.cpp @@ -866,6 +866,7 @@ void ChannelView::mouseMoveEvent(QMouseEvent *event) tooltipWidget->hide(); } else { tooltipWidget->moveTo(this, event->globalPos()); + tooltipWidget->setWordWrap(hoverLayoutElement->getLink().isValid()); tooltipWidget->setText(tooltip); tooltipWidget->adjustSize(); tooltipWidget->show(); diff --git a/src/widgets/splits/SplitHeader.cpp b/src/widgets/splits/SplitHeader.cpp index 611bbaace..42656fde0 100644 --- a/src/widgets/splits/SplitHeader.cpp +++ b/src/widgets/splits/SplitHeader.cpp @@ -458,6 +458,8 @@ void SplitHeader::enterEvent(QEvent *event) tooltip->moveTo(this, this->mapToGlobal(this->rect().bottomLeft()), false); tooltip->setText(this->tooltipText_); + tooltip->setWordWrap(false); + tooltip->adjustSize(); tooltip->show(); tooltip->raise(); }