2018-08-11 12:47:03 +02:00
|
|
|
#include "Toasts.hpp"
|
|
|
|
|
|
|
|
#include "Application.hpp"
|
|
|
|
#include "controllers/notifications/NotificationController.hpp"
|
|
|
|
#include "providers/twitch/TwitchChannel.hpp"
|
|
|
|
#include "providers/twitch/TwitchServer.hpp"
|
|
|
|
|
2018-08-11 16:11:51 +02:00
|
|
|
#include <wintoastlib.h>
|
|
|
|
|
|
|
|
#include <QDesktopServices>
|
|
|
|
#include <QUrl>
|
|
|
|
|
|
|
|
#include <cstdlib>
|
|
|
|
|
2018-08-11 12:47:03 +02:00
|
|
|
namespace chatterino {
|
|
|
|
|
2018-08-12 15:29:40 +02:00
|
|
|
/*
|
2018-08-11 12:47:03 +02:00
|
|
|
Toasts::Toasts()
|
|
|
|
{
|
|
|
|
}
|
2018-08-12 15:29:40 +02:00
|
|
|
*/
|
|
|
|
/*
|
2018-08-11 12:47:03 +02:00
|
|
|
void Toasts::initialize(Settings &settings, Paths &paths)
|
|
|
|
{
|
2018-08-11 16:11:51 +02:00
|
|
|
getApp()->twitch2->forEachChannel([this](ChannelPtr chn) {
|
2018-08-11 12:47:03 +02:00
|
|
|
auto twchn = dynamic_cast<TwitchChannel *>(chn.get());
|
2018-08-11 16:11:51 +02:00
|
|
|
twchn->liveStatusChanged.connect([twchn, this]() {
|
2018-08-11 12:47:03 +02:00
|
|
|
const auto streamStatus = twchn->accessStreamStatus();
|
|
|
|
if (streamStatus->live) {
|
2018-08-11 16:11:51 +02:00
|
|
|
// is live
|
|
|
|
if (getApp()->notifications->isChannelNotified(
|
|
|
|
twchn->getName()) &&
|
|
|
|
!wasChannelLive(twchn->getName())) {
|
|
|
|
sendChannelNotification(twchn->getName());
|
|
|
|
}
|
|
|
|
updateLiveChannels(twchn->getName());
|
2018-08-11 12:47:03 +02:00
|
|
|
} else {
|
2018-08-11 16:11:51 +02:00
|
|
|
// is Offline
|
|
|
|
removeFromLiveChannels(twchn->getName());
|
2018-08-11 12:47:03 +02:00
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
void Toasts::updateLiveChannels(const QString &channelName)
|
|
|
|
{
|
2018-08-11 16:11:51 +02:00
|
|
|
if (!wasChannelLive(channelName)) {
|
2018-08-11 12:47:03 +02:00
|
|
|
std::lock_guard<std::mutex> lock(mutex_);
|
|
|
|
liveChannels.push_back(channelName);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-08-11 16:11:51 +02:00
|
|
|
void Toasts::removeFromLiveChannels(const QString &channelName)
|
|
|
|
{
|
|
|
|
if (wasChannelLive(channelName)) {
|
|
|
|
std::lock_guard<std::mutex> lock(mutex_);
|
|
|
|
liveChannels.erase(
|
|
|
|
std::find(liveChannels.begin(), liveChannels.end(), channelName));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-08-11 12:47:03 +02:00
|
|
|
bool Toasts::wasChannelLive(const QString &channelName)
|
|
|
|
{
|
|
|
|
std::lock_guard<std::mutex> lock(mutex_);
|
|
|
|
for (const auto &str : liveChannels) {
|
|
|
|
if (str == channelName) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
2018-08-12 15:29:40 +02:00
|
|
|
*/
|
|
|
|
void Toasts::sendChannelNotification(const QString &channelName, int &platform)
|
2018-08-11 12:47:03 +02:00
|
|
|
{
|
2018-08-11 16:11:51 +02:00
|
|
|
#ifdef Q_OS_WIN
|
|
|
|
if (WinToastLib::WinToast::isCompatible()) {
|
2018-08-12 15:29:40 +02:00
|
|
|
sendWindowsNotification(channelName, platform);
|
2018-08-11 16:11:51 +02:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
// OSX
|
|
|
|
|
|
|
|
// LINUX
|
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
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
void toastActivated() const
|
|
|
|
{
|
|
|
|
std::wcout << L"The user clicked in this toast" << std::endl;
|
|
|
|
QString link = "http://www.google.com";
|
|
|
|
QDesktopServices::openUrl(QUrl(link));
|
|
|
|
}
|
|
|
|
|
|
|
|
void toastActivated(int actionIndex) const
|
|
|
|
{
|
|
|
|
// std::wcout << L"The user clicked on button #" << actionIndex
|
|
|
|
// << L" in this toast" << std::endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
void toastFailed() const
|
|
|
|
{
|
|
|
|
// std::wcout << L"Error showing current toast" << std::endl;
|
|
|
|
}
|
|
|
|
void toastDismissed(WinToastDismissalReason state) const
|
|
|
|
{
|
|
|
|
switch (state) {
|
|
|
|
case UserCanceled:
|
|
|
|
// std::wcout << L"The user dismissed this toast" << std::endl;
|
|
|
|
break;
|
|
|
|
case ApplicationHidden:
|
|
|
|
/*
|
|
|
|
std::wcout << L"The application hid the toast using "
|
|
|
|
L"ToastNotifier.hide()"
|
|
|
|
<< std::endl;
|
|
|
|
*/
|
|
|
|
break;
|
|
|
|
case TimedOut:
|
|
|
|
// std::wcout << L"The toast has timed out" << std::endl;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
// std::wcout << L"Toast not activated" << std::endl;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2018-08-12 15:29:40 +02:00
|
|
|
void Toasts::sendWindowsNotification(const QString &channelName, int &platform)
|
2018-08-11 16:11:51 +02:00
|
|
|
{
|
|
|
|
WinToastLib::WinToastTemplate templ = WinToastLib::WinToastTemplate(
|
|
|
|
WinToastLib::WinToastTemplate::ImageAndText02);
|
|
|
|
QString str = channelName + " has just gone live!";
|
|
|
|
std::string utf8_text = str.toUtf8().constData();
|
|
|
|
std::wstring widestr = std::wstring(utf8_text.begin(), utf8_text.end());
|
|
|
|
|
|
|
|
templ.setTextField(widestr, WinToastLib::WinToastTemplate::FirstLine);
|
|
|
|
templ.setTextField(L"Click here to open in browser",
|
|
|
|
WinToastLib::WinToastTemplate::SecondLine);
|
|
|
|
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());
|
|
|
|
// int mbstowcs(wchar_t *out, const char *in, size_t size);
|
|
|
|
/*
|
|
|
|
std::wstring aumi_version =
|
|
|
|
std::wstring(std::string(CHATTERINO_VERSION).begin(),
|
|
|
|
std::string(CHATTERINO_VERSION).end());*/
|
|
|
|
WinToastLib::WinToast::instance()->setAppUserModelId(
|
|
|
|
WinToastLib::WinToast::configureAUMI(L"", L"Chatterino 2", L"",
|
|
|
|
aumi_version));
|
|
|
|
WinToastLib::WinToast::instance()->initialize();
|
|
|
|
WinToastLib::WinToast::instance()->showToast(templ, new CustomHandler());
|
|
|
|
}
|
|
|
|
#endif
|
2018-08-11 12:47:03 +02:00
|
|
|
|
|
|
|
} // namespace chatterino
|