mirror of
https://github.com/Chatterino/chatterino2.git
synced 2024-11-21 22:24:07 +01:00
for pajlada
This commit is contained in:
parent
3d109a6ca3
commit
21c4880ace
6 changed files with 172 additions and 34 deletions
|
@ -255,7 +255,8 @@ SOURCES += \
|
||||||
src/util/FormatTime.cpp \
|
src/util/FormatTime.cpp \
|
||||||
src/util/FunctionEventFilter.cpp \
|
src/util/FunctionEventFilter.cpp \
|
||||||
src/controllers/notifications/NotificationModel.cpp \
|
src/controllers/notifications/NotificationModel.cpp \
|
||||||
src/singletons/Toasts.cpp
|
src/singletons/Toasts.cpp \
|
||||||
|
src/singletons/DownloadManager.cpp
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
src/Application.hpp \
|
src/Application.hpp \
|
||||||
|
@ -458,7 +459,8 @@ HEADERS += \
|
||||||
src/util/FunctionEventFilter.hpp \
|
src/util/FunctionEventFilter.hpp \
|
||||||
src/controllers/notifications/NotificationModel.hpp \
|
src/controllers/notifications/NotificationModel.hpp \
|
||||||
src/controllers/notifications/NotificationPhrase.hpp \
|
src/controllers/notifications/NotificationPhrase.hpp \
|
||||||
src/singletons/Toasts.hpp
|
src/singletons/Toasts.hpp \
|
||||||
|
src/singletons/DownloadManager.hpp
|
||||||
|
|
||||||
RESOURCES += \
|
RESOURCES += \
|
||||||
resources/resources.qrc \
|
resources/resources.qrc \
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include "providers/ffz/FfzEmotes.hpp"
|
#include "providers/ffz/FfzEmotes.hpp"
|
||||||
#include "providers/twitch/PubsubClient.hpp"
|
#include "providers/twitch/PubsubClient.hpp"
|
||||||
#include "providers/twitch/TwitchServer.hpp"
|
#include "providers/twitch/TwitchServer.hpp"
|
||||||
|
#include "singletons/DownloadManager.hpp"
|
||||||
#include "singletons/Fonts.hpp"
|
#include "singletons/Fonts.hpp"
|
||||||
#include "singletons/Logging.hpp"
|
#include "singletons/Logging.hpp"
|
||||||
#include "singletons/NativeMessaging.hpp"
|
#include "singletons/NativeMessaging.hpp"
|
||||||
|
@ -46,6 +47,7 @@ Application::Application(Settings &_settings, Paths &_paths)
|
||||||
, emotes(&this->emplace<Emotes>())
|
, emotes(&this->emplace<Emotes>())
|
||||||
, windows(&this->emplace<WindowManager>())
|
, windows(&this->emplace<WindowManager>())
|
||||||
|
|
||||||
|
, toasts(&this->emplace<Toasts>())
|
||||||
, accounts(&this->emplace<AccountController>())
|
, accounts(&this->emplace<AccountController>())
|
||||||
, commands(&this->emplace<CommandController>())
|
, commands(&this->emplace<CommandController>())
|
||||||
, highlights(&this->emplace<HighlightController>())
|
, highlights(&this->emplace<HighlightController>())
|
||||||
|
@ -55,7 +57,7 @@ Application::Application(Settings &_settings, Paths &_paths)
|
||||||
, moderationActions(&this->emplace<ModerationActions>())
|
, moderationActions(&this->emplace<ModerationActions>())
|
||||||
, twitch2(&this->emplace<TwitchServer>())
|
, twitch2(&this->emplace<TwitchServer>())
|
||||||
, logging(&this->emplace<Logging>())
|
, logging(&this->emplace<Logging>())
|
||||||
, toasts(&this->emplace<Toasts>())
|
, downloads(&this->emplace<DownloadManager>())
|
||||||
{
|
{
|
||||||
this->instance = this;
|
this->instance = this;
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,7 @@ class Settings;
|
||||||
class Fonts;
|
class Fonts;
|
||||||
class Resources;
|
class Resources;
|
||||||
class Toasts;
|
class Toasts;
|
||||||
|
class DownloadManager;
|
||||||
|
|
||||||
class Application
|
class Application
|
||||||
{
|
{
|
||||||
|
@ -58,6 +59,7 @@ public:
|
||||||
Emotes *const emotes{};
|
Emotes *const emotes{};
|
||||||
WindowManager *const windows{};
|
WindowManager *const windows{};
|
||||||
Toasts *const toasts{};
|
Toasts *const toasts{};
|
||||||
|
DownloadManager *const downloads{};
|
||||||
|
|
||||||
AccountController *const accounts{};
|
AccountController *const accounts{};
|
||||||
CommandController *const commands{};
|
CommandController *const commands{};
|
||||||
|
|
|
@ -39,6 +39,10 @@ TwitchChannel::TwitchChannel(const QString &name)
|
||||||
// this->refreshViewerList();
|
// this->refreshViewerList();
|
||||||
|
|
||||||
this->tabHighlightRequested.connect([](HighlightState state) {});
|
this->tabHighlightRequested.connect([](HighlightState state) {});
|
||||||
|
this->liveStatusChanged.connect([this]() {
|
||||||
|
if (this->isLive() == 1) {
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
this->managedConnect(getApp()->accounts->twitch.currentUserChanged,
|
this->managedConnect(getApp()->accounts->twitch.currentUserChanged,
|
||||||
[=] { this->setMod(false); });
|
[=] { this->setMod(false); });
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
#include "Toasts.hpp"
|
#include "Toasts.hpp"
|
||||||
|
|
||||||
#include "Application.hpp"
|
#include "Application.hpp"
|
||||||
|
#include "common/NetworkRequest.hpp"
|
||||||
#include "controllers/notifications/NotificationController.hpp"
|
#include "controllers/notifications/NotificationController.hpp"
|
||||||
#include "providers/twitch/TwitchChannel.hpp"
|
#include "providers/twitch/TwitchChannel.hpp"
|
||||||
|
#include "providers/twitch/TwitchCommon.hpp"
|
||||||
#include "providers/twitch/TwitchServer.hpp"
|
#include "providers/twitch/TwitchServer.hpp"
|
||||||
|
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
|
@ -12,6 +14,10 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <QDesktopServices>
|
#include <QDesktopServices>
|
||||||
|
#include <QFileInfo>
|
||||||
|
//#include <QtNetwork>
|
||||||
|
#include <QNetworkAccessManager>
|
||||||
|
#include <QNetworkReply>
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
@ -39,60 +45,87 @@ void Toasts::sendChannelNotification(const QString &channelName, Platform p)
|
||||||
|
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
|
|
||||||
|
/*const override void CustomToastHandler::toastActivated()
|
||||||
|
{
|
||||||
|
}*/
|
||||||
|
|
||||||
class CustomHandler : public WinToastLib::IWinToastHandler
|
class CustomHandler : public WinToastLib::IWinToastHandler
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
QString channelName_;
|
||||||
|
Platform platform_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
CustomHandler(QString channelName, Platform p)
|
||||||
|
: channelName_(channelName)
|
||||||
|
, platform_(p)
|
||||||
|
{
|
||||||
|
}
|
||||||
void toastActivated() const
|
void toastActivated() const
|
||||||
{
|
{
|
||||||
std::wcout << L"The user clicked in this toast" << std::endl;
|
QString link;
|
||||||
QString link = "http://www.google.com";
|
if (platform_ == Platform::Twitch) {
|
||||||
|
link = "http://www.twitch.tv/" + channelName_;
|
||||||
|
}
|
||||||
QDesktopServices::openUrl(QUrl(link));
|
QDesktopServices::openUrl(QUrl(link));
|
||||||
}
|
}
|
||||||
|
|
||||||
void toastActivated(int actionIndex) const
|
void toastActivated(int actionIndex) const
|
||||||
{
|
{
|
||||||
// std::wcout << L"The user clicked on button #" << actionIndex
|
|
||||||
// << L" in this toast" << std::endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void toastFailed() const
|
void toastFailed() const
|
||||||
{
|
{
|
||||||
// std::wcout << L"Error showing current toast" << std::endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void toastDismissed(WinToastDismissalReason state) const
|
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void Toasts::sendWindowsNotification(const QString &channelName, Platform p)
|
void Toasts::sendWindowsNotification(const QString &channelName, Platform p)
|
||||||
|
{
|
||||||
|
// Fetch user profile avatar
|
||||||
|
if (p == Platform::Twitch) {
|
||||||
|
QFileInfo check_file(
|
||||||
|
QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) +
|
||||||
|
"2/cache/profileAvatars/twitch/" + channelName + ".png");
|
||||||
|
if (check_file.exists() && check_file.isFile()) {
|
||||||
|
qDebug() << " OMEGA2NAM ";
|
||||||
|
this->sendActualWindowsNotification(channelName, p);
|
||||||
|
} else {
|
||||||
|
qDebug() << " OMEGA1NAM ";
|
||||||
|
this->fetchChannelAvatar(
|
||||||
|
channelName, [this, channelName, p](QString avatarLink) {
|
||||||
|
qDebug() << " OMEGANAM " << avatarLink;
|
||||||
|
this->sendActualWindowsNotification(channelName, p);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
qDebug() << " YOU'RE TOO SLOW! ";
|
||||||
|
}
|
||||||
|
|
||||||
|
void Toasts::sendActualWindowsNotification(const QString &channelName,
|
||||||
|
Platform p)
|
||||||
{
|
{
|
||||||
WinToastLib::WinToastTemplate templ = WinToastLib::WinToastTemplate(
|
WinToastLib::WinToastTemplate templ = WinToastLib::WinToastTemplate(
|
||||||
WinToastLib::WinToastTemplate::ImageAndText02);
|
WinToastLib::WinToastTemplate::ImageAndText02);
|
||||||
QString str = channelName + " has just gone live!";
|
QString str = channelName + " is live!";
|
||||||
std::string utf8_text = str.toUtf8().constData();
|
std::string utf8_text = str.toUtf8().constData();
|
||||||
std::wstring widestr = std::wstring(utf8_text.begin(), utf8_text.end());
|
std::wstring widestr = std::wstring(utf8_text.begin(), utf8_text.end());
|
||||||
|
|
||||||
templ.setTextField(widestr, WinToastLib::WinToastTemplate::FirstLine);
|
templ.setTextField(widestr, WinToastLib::WinToastTemplate::FirstLine);
|
||||||
templ.setTextField(L"Click here to open in browser",
|
templ.setTextField(L"Click here to open in browser",
|
||||||
WinToastLib::WinToastTemplate::SecondLine);
|
WinToastLib::WinToastTemplate::SecondLine);
|
||||||
|
QString Path;
|
||||||
|
if (p == Platform::Twitch) {
|
||||||
|
Path =
|
||||||
|
QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) +
|
||||||
|
"2/cache/profileAvatars/twitch/" + channelName + ".png";
|
||||||
|
}
|
||||||
|
std::string temp_Utf8 = Path.toUtf8().constData();
|
||||||
|
std::wstring imagePath = std::wstring(temp_Utf8.begin(), temp_Utf8.end());
|
||||||
|
templ.setImagePath(imagePath);
|
||||||
if (getApp()->settings->notificationPlaySound) {
|
if (getApp()->settings->notificationPlaySound) {
|
||||||
templ.setAudioOption(
|
templ.setAudioOption(
|
||||||
WinToastLib::WinToastTemplate::AudioOption::Silent);
|
WinToastLib::WinToastTemplate::AudioOption::Silent);
|
||||||
|
@ -103,17 +136,102 @@ void Toasts::sendWindowsNotification(const QString &channelName, Platform p)
|
||||||
std::string(CHATTERINO_VERSION);
|
std::string(CHATTERINO_VERSION);
|
||||||
std::wstring aumi_version =
|
std::wstring aumi_version =
|
||||||
std::wstring(CHATTERINO_VERSION.begin(), CHATTERINO_VERSION.end());
|
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::instance()->setAppUserModelId(
|
||||||
WinToastLib::WinToast::configureAUMI(L"", L"Chatterino 2", L"",
|
WinToastLib::WinToast::configureAUMI(L"", L"Chatterino 2", L"",
|
||||||
aumi_version));
|
aumi_version));
|
||||||
WinToastLib::WinToast::instance()->initialize();
|
WinToastLib::WinToast::instance()->initialize();
|
||||||
WinToastLib::WinToast::instance()->showToast(templ, new CustomHandler());
|
WinToastLib::WinToast::instance()->showToast(
|
||||||
|
templ, new CustomHandler(channelName, p));
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
/*
|
||||||
|
void Toasts::fetchChannelAvatar(const QString &channelName,
|
||||||
|
std::function<void(QString)> successCallback)
|
||||||
|
{
|
||||||
|
QString requestUrl("https://api.twitch.tv/kraken/users?login=" +
|
||||||
|
channelName);
|
||||||
|
NetworkRequest request(requestUrl, NetworkRequestType::Put);
|
||||||
|
request.setCaller(QThread::currentThread());
|
||||||
|
request.makeAuthorizedV5(getDefaultClientID());
|
||||||
|
request.setTimeout(30000);
|
||||||
|
request.onSuccess([successCallback](auto result) -> Outcome {
|
||||||
|
auto root = result.parseJson();
|
||||||
|
if (!root.value("users").isArray()) {
|
||||||
|
Log("API Error while getting user id, users is not an array");
|
||||||
|
successCallback("");
|
||||||
|
return Failure;
|
||||||
|
}
|
||||||
|
auto users = root.value("users").toArray();
|
||||||
|
if (users.size() != 1) {
|
||||||
|
Log("API Error while getting user id, users array size is not 1");
|
||||||
|
successCallback("");
|
||||||
|
return Failure;
|
||||||
|
}
|
||||||
|
if (!users[0].isObject()) {
|
||||||
|
Log("API Error while getting user id, first user is not an object");
|
||||||
|
successCallback("");
|
||||||
|
return Failure;
|
||||||
|
}
|
||||||
|
auto firstUser = users[0].toObject();
|
||||||
|
auto avatar = firstUser.value("logo");
|
||||||
|
if (!avatar.isString()) {
|
||||||
|
Log("API Error: while getting user logo, first user object `logo` "
|
||||||
|
"key "
|
||||||
|
"is not a "
|
||||||
|
"string");
|
||||||
|
successCallback("");
|
||||||
|
return Failure;
|
||||||
|
}
|
||||||
|
successCallback(avatar.toString());
|
||||||
|
return Success;
|
||||||
|
});
|
||||||
|
|
||||||
|
request.execute();
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
void Toasts::fetchChannelAvatar(const QString channelName,
|
||||||
|
std::function<void(QString)> successCallback)
|
||||||
|
{
|
||||||
|
QString requestUrl("https://api.twitch.tv/kraken/users?login=" +
|
||||||
|
channelName);
|
||||||
|
|
||||||
|
NetworkRequest request(requestUrl);
|
||||||
|
request.setCaller(QThread::currentThread());
|
||||||
|
request.makeAuthorizedV5(getDefaultClientID());
|
||||||
|
request.setTimeout(30000);
|
||||||
|
request.onSuccess([successCallback](auto result) mutable -> Outcome {
|
||||||
|
auto root = result.parseJson();
|
||||||
|
if (!root.value("users").isArray()) {
|
||||||
|
Log("API Error while getting user id, users is not an array");
|
||||||
|
successCallback("");
|
||||||
|
return Failure;
|
||||||
|
}
|
||||||
|
auto users = root.value("users").toArray();
|
||||||
|
if (users.size() != 1) {
|
||||||
|
Log("API Error while getting user id, users array size is not 1");
|
||||||
|
successCallback("");
|
||||||
|
return Failure;
|
||||||
|
}
|
||||||
|
if (!users[0].isObject()) {
|
||||||
|
Log("API Error while getting user id, first user is not an object");
|
||||||
|
successCallback("");
|
||||||
|
return Failure;
|
||||||
|
}
|
||||||
|
auto firstUser = users[0].toObject();
|
||||||
|
auto avatar = firstUser.value("logo");
|
||||||
|
if (!avatar.isString()) {
|
||||||
|
Log("API Error: while getting user avatar, first user object "
|
||||||
|
"`avatar` key "
|
||||||
|
"is not a "
|
||||||
|
"string");
|
||||||
|
successCallback("");
|
||||||
|
return Failure;
|
||||||
|
}
|
||||||
|
successCallback(avatar.toString());
|
||||||
|
return Success;
|
||||||
|
});
|
||||||
|
|
||||||
|
request.execute();
|
||||||
|
}
|
||||||
} // namespace chatterino
|
} // namespace chatterino
|
||||||
|
|
|
@ -2,7 +2,13 @@
|
||||||
|
|
||||||
#include "Application.hpp"
|
#include "Application.hpp"
|
||||||
#include "common/Singleton.hpp"
|
#include "common/Singleton.hpp"
|
||||||
|
/*
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
|
||||||
|
#include "wintoastlib.h"
|
||||||
|
|
||||||
|
#endif
|
||||||
|
*/
|
||||||
namespace chatterino {
|
namespace chatterino {
|
||||||
|
|
||||||
enum class Platform : uint8_t;
|
enum class Platform : uint8_t;
|
||||||
|
@ -16,5 +22,9 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void sendWindowsNotification(const QString &channelName, Platform p);
|
void sendWindowsNotification(const QString &channelName, Platform p);
|
||||||
|
void sendActualWindowsNotification(const QString &channelName, Platform p);
|
||||||
|
static void fetchChannelAvatar(
|
||||||
|
const QString channelName,
|
||||||
|
std::function<void(QString)> successCallback);
|
||||||
};
|
};
|
||||||
} // namespace chatterino
|
} // namespace chatterino
|
||||||
|
|
Loading…
Reference in a new issue