2018-08-11 12:47:03 +02:00
|
|
|
#include "Toasts.hpp"
|
|
|
|
|
|
|
|
#include "Application.hpp"
|
2018-08-19 19:02:49 +02:00
|
|
|
#include "common/DownloadManager.hpp"
|
2018-08-19 15:09:00 +02:00
|
|
|
#include "common/NetworkRequest.hpp"
|
2018-08-11 12:47:03 +02:00
|
|
|
#include "controllers/notifications/NotificationController.hpp"
|
|
|
|
#include "providers/twitch/TwitchChannel.hpp"
|
2018-08-19 15:09:00 +02:00
|
|
|
#include "providers/twitch/TwitchCommon.hpp"
|
2019-09-15 13:02:02 +02:00
|
|
|
#include "providers/twitch/TwitchIrcServer.hpp"
|
2020-03-14 12:13:57 +01:00
|
|
|
#include "providers/twitch/api/Helix.hpp"
|
2018-11-25 15:02:48 +01:00
|
|
|
#include "singletons/Paths.hpp"
|
2019-04-22 09:03:52 +02:00
|
|
|
#include "util/StreamLink.hpp"
|
2019-04-27 10:12:51 +02:00
|
|
|
#include "widgets/helper/CommonTexts.hpp"
|
2018-08-11 12:47:03 +02:00
|
|
|
|
2018-08-12 18:54:32 +02:00
|
|
|
#ifdef Q_OS_WIN
|
|
|
|
|
2018-08-29 19:25:37 +02:00
|
|
|
# include <wintoastlib.h>
|
2018-08-11 16:11:51 +02:00
|
|
|
|
2018-08-12 18:54:32 +02:00
|
|
|
#endif
|
|
|
|
|
2018-08-11 16:11:51 +02:00
|
|
|
#include <QDesktopServices>
|
2018-08-19 15:09:00 +02:00
|
|
|
#include <QFileInfo>
|
|
|
|
#include <QNetworkAccessManager>
|
|
|
|
#include <QNetworkReply>
|
2018-08-11 16:11:51 +02:00
|
|
|
#include <QUrl>
|
|
|
|
|
|
|
|
#include <cstdlib>
|
|
|
|
|
2018-08-11 12:47:03 +02:00
|
|
|
namespace chatterino {
|
|
|
|
|
2019-05-01 23:21:12 +02:00
|
|
|
std::map<ToastReaction, QString> Toasts::reactionToString = {
|
|
|
|
{ToastReaction::OpenInBrowser, OPEN_IN_BROWSER},
|
|
|
|
{ToastReaction::OpenInPlayer, OPEN_PLAYER_IN_BROWSER},
|
|
|
|
{ToastReaction::OpenInStreamlink, OPEN_IN_STREAMLINK},
|
|
|
|
{ToastReaction::DontOpen, DONT_OPEN}};
|
2019-04-27 13:47:13 +02:00
|
|
|
|
2018-08-12 18:54:32 +02:00
|
|
|
bool Toasts::isEnabled()
|
|
|
|
{
|
2018-09-01 13:01:54 +02:00
|
|
|
#ifdef Q_OS_WIN
|
2018-08-12 18:54:32 +02:00
|
|
|
return WinToastLib::WinToast::isCompatible() &&
|
2018-08-29 19:25:37 +02:00
|
|
|
getSettings()->notificationToast;
|
2019-05-08 08:51:14 +02:00
|
|
|
#else
|
2018-09-01 13:01:54 +02:00
|
|
|
return false;
|
2019-05-08 08:51:14 +02:00
|
|
|
#endif
|
2018-08-12 18:54:32 +02:00
|
|
|
}
|
|
|
|
|
2019-05-01 23:21:12 +02:00
|
|
|
QString Toasts::findStringFromReaction(const ToastReaction &reaction)
|
2019-04-27 13:47:13 +02:00
|
|
|
{
|
|
|
|
auto iterator = Toasts::reactionToString.find(reaction);
|
|
|
|
if (iterator != Toasts::reactionToString.end())
|
|
|
|
{
|
|
|
|
return iterator->second;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return DONT_OPEN;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-04-27 18:15:41 +02:00
|
|
|
QString Toasts::findStringFromReaction(
|
|
|
|
const pajlada::Settings::Setting<int> &value)
|
|
|
|
{
|
|
|
|
int i = static_cast<int>(value);
|
2019-05-01 23:21:12 +02:00
|
|
|
return Toasts::findStringFromReaction(static_cast<ToastReaction>(i));
|
2019-04-27 18:15:41 +02:00
|
|
|
}
|
|
|
|
|
2018-08-12 18:54:32 +02:00
|
|
|
void Toasts::sendChannelNotification(const QString &channelName, Platform p)
|
2018-08-11 12:47:03 +02:00
|
|
|
{
|
2018-09-30 19:15:17 +02:00
|
|
|
#ifdef Q_OS_WIN
|
|
|
|
auto sendChannelNotification = [this, channelName, p] {
|
|
|
|
this->sendWindowsNotification(channelName, p);
|
|
|
|
};
|
|
|
|
#else
|
|
|
|
auto sendChannelNotification = [] {
|
|
|
|
// Unimplemented for OSX and Linux
|
|
|
|
};
|
|
|
|
#endif
|
2018-08-19 19:02:49 +02:00
|
|
|
// Fetch user profile avatar
|
2018-10-21 13:43:02 +02:00
|
|
|
if (p == Platform::Twitch)
|
|
|
|
{
|
2018-08-31 18:18:05 +02:00
|
|
|
QFileInfo check_file(getPaths()->twitchProfileAvatars + "/twitch/" +
|
|
|
|
channelName + ".png");
|
2018-10-21 13:43:02 +02:00
|
|
|
if (check_file.exists() && check_file.isFile())
|
|
|
|
{
|
2018-09-30 19:15:17 +02:00
|
|
|
sendChannelNotification();
|
2018-10-21 13:43:02 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-03-14 12:13:57 +01:00
|
|
|
getHelix()->getUserByName(
|
2018-09-30 19:15:17 +02:00
|
|
|
channelName,
|
2020-03-14 12:13:57 +01:00
|
|
|
[channelName, sendChannelNotification](const auto &user) {
|
2018-08-19 19:02:49 +02:00
|
|
|
DownloadManager *manager = new DownloadManager();
|
2020-03-14 12:13:57 +01:00
|
|
|
manager->setFile(user.profileImageUrl, channelName);
|
2018-09-30 19:15:17 +02:00
|
|
|
manager->connect(manager,
|
|
|
|
&DownloadManager::downloadComplete,
|
|
|
|
sendChannelNotification);
|
2020-03-14 12:13:57 +01:00
|
|
|
},
|
|
|
|
[] {
|
|
|
|
// on failure
|
2018-08-19 19:02:49 +02:00
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
2018-08-11 12:47:03 +02:00
|
|
|
}
|
|
|
|
|
2018-08-11 16:11:51 +02:00
|
|
|
#ifdef Q_OS_WIN
|
|
|
|
|
|
|
|
class CustomHandler : public WinToastLib::IWinToastHandler
|
|
|
|
{
|
2018-08-19 15:09:00 +02:00
|
|
|
private:
|
|
|
|
QString channelName_;
|
|
|
|
Platform platform_;
|
|
|
|
|
2018-08-11 16:11:51 +02:00
|
|
|
public:
|
2018-08-19 15:09:00 +02:00
|
|
|
CustomHandler(QString channelName, Platform p)
|
|
|
|
: channelName_(channelName)
|
|
|
|
, platform_(p)
|
|
|
|
{
|
|
|
|
}
|
2018-08-11 16:11:51 +02:00
|
|
|
void toastActivated() const
|
|
|
|
{
|
2018-08-19 15:09:00 +02:00
|
|
|
QString link;
|
2019-05-10 23:31:10 +02:00
|
|
|
auto toastReaction =
|
|
|
|
static_cast<ToastReaction>(getSettings()->openFromToast.getValue());
|
|
|
|
|
|
|
|
switch (toastReaction)
|
2019-04-22 09:03:52 +02:00
|
|
|
{
|
2019-05-01 23:21:12 +02:00
|
|
|
case ToastReaction::OpenInBrowser:
|
2019-04-27 13:47:13 +02:00
|
|
|
if (platform_ == Platform::Twitch)
|
|
|
|
{
|
|
|
|
link = "http://www.twitch.tv/" + channelName_;
|
|
|
|
}
|
|
|
|
QDesktopServices::openUrl(QUrl(link));
|
|
|
|
break;
|
2019-05-01 23:21:12 +02:00
|
|
|
case ToastReaction::OpenInPlayer:
|
2019-04-27 13:47:13 +02:00
|
|
|
if (platform_ == Platform::Twitch)
|
|
|
|
{
|
|
|
|
link = "https://player.twitch.tv/?channel=" + channelName_;
|
|
|
|
}
|
|
|
|
QDesktopServices::openUrl(QUrl(link));
|
|
|
|
break;
|
2019-09-26 00:51:05 +02:00
|
|
|
case ToastReaction::OpenInStreamlink: {
|
2019-04-27 13:47:13 +02:00
|
|
|
openStreamlinkForChannel(channelName_);
|
|
|
|
break;
|
2019-04-22 09:03:52 +02:00
|
|
|
}
|
2019-04-27 13:47:13 +02:00
|
|
|
// the fourth and last option is "don't open"
|
|
|
|
// in this case obviously nothing should happen
|
2019-04-22 09:03:52 +02:00
|
|
|
}
|
2018-08-11 16:11:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void toastActivated(int actionIndex) const
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void toastFailed() const
|
|
|
|
{
|
|
|
|
}
|
2018-08-19 15:09:00 +02:00
|
|
|
|
2018-08-11 16:11:51 +02:00
|
|
|
void toastDismissed(WinToastDismissalReason state) const
|
|
|
|
{
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2018-08-12 18:54:32 +02:00
|
|
|
void Toasts::sendWindowsNotification(const QString &channelName, Platform p)
|
2018-08-11 16:11:51 +02:00
|
|
|
{
|
|
|
|
WinToastLib::WinToastTemplate templ = WinToastLib::WinToastTemplate(
|
2018-08-29 23:39:02 +02:00
|
|
|
WinToastLib::WinToastTemplate::ImageAndText03);
|
2018-08-19 15:09:00 +02:00
|
|
|
QString str = channelName + " is live!";
|
2018-08-11 16:11:51 +02:00
|
|
|
std::string utf8_text = str.toUtf8().constData();
|
|
|
|
std::wstring widestr = std::wstring(utf8_text.begin(), utf8_text.end());
|
|
|
|
|
|
|
|
templ.setTextField(widestr, WinToastLib::WinToastTemplate::FirstLine);
|
2019-05-01 23:21:12 +02:00
|
|
|
if (static_cast<ToastReaction>(getSettings()->openFromToast.getValue()) !=
|
|
|
|
ToastReaction::DontOpen)
|
2019-04-27 10:12:51 +02:00
|
|
|
{
|
2019-04-27 18:15:41 +02:00
|
|
|
QString mode =
|
|
|
|
Toasts::findStringFromReaction(getSettings()->openFromToast);
|
2019-04-27 10:12:51 +02:00
|
|
|
mode = mode.toLower();
|
2019-04-22 09:03:52 +02:00
|
|
|
|
2019-04-27 10:12:51 +02:00
|
|
|
templ.setTextField(L"Click here to " + mode.toStdWString(),
|
2019-04-22 09:03:52 +02:00
|
|
|
WinToastLib::WinToastTemplate::SecondLine);
|
|
|
|
}
|
|
|
|
|
2018-08-19 15:09:00 +02:00
|
|
|
QString Path;
|
2018-10-21 13:43:02 +02:00
|
|
|
if (p == Platform::Twitch)
|
|
|
|
{
|
2018-08-29 23:39:02 +02:00
|
|
|
Path = getPaths()->twitchProfileAvatars + "/twitch/" + channelName +
|
|
|
|
".png";
|
2018-08-19 15:09:00 +02:00
|
|
|
}
|
|
|
|
std::string temp_Utf8 = Path.toUtf8().constData();
|
|
|
|
std::wstring imagePath = std::wstring(temp_Utf8.begin(), temp_Utf8.end());
|
|
|
|
templ.setImagePath(imagePath);
|
2018-10-21 13:43:02 +02:00
|
|
|
if (getSettings()->notificationPlaySound)
|
|
|
|
{
|
2018-08-12 20:21:21 +02:00
|
|
|
templ.setAudioOption(
|
|
|
|
WinToastLib::WinToastTemplate::AudioOption::Silent);
|
|
|
|
}
|
2018-08-11 16:11:51 +02:00
|
|
|
WinToastLib::WinToast::instance()->setAppName(L"Chatterino2");
|
|
|
|
int mbstowcs(wchar_t * aumi_version, const char *CHATTERINO_VERSION,
|
|
|
|
size_t size);
|
|
|
|
std::string(CHATTERINO_VERSION);
|
|
|
|
std::wstring aumi_version =
|
|
|
|
std::wstring(CHATTERINO_VERSION.begin(), CHATTERINO_VERSION.end());
|
|
|
|
WinToastLib::WinToast::instance()->setAppUserModelId(
|
|
|
|
WinToastLib::WinToast::configureAUMI(L"", L"Chatterino 2", L"",
|
|
|
|
aumi_version));
|
|
|
|
WinToastLib::WinToast::instance()->initialize();
|
2018-08-19 15:09:00 +02:00
|
|
|
WinToastLib::WinToast::instance()->showToast(
|
|
|
|
templ, new CustomHandler(channelName, p));
|
2018-08-11 16:11:51 +02:00
|
|
|
}
|
2018-08-19 15:09:00 +02:00
|
|
|
|
2018-08-11 16:11:51 +02:00
|
|
|
#endif
|
2018-08-19 15:09:00 +02:00
|
|
|
|
2018-08-11 12:47:03 +02:00
|
|
|
} // namespace chatterino
|