UI: Add ability to send messages to YouTube chat

master
gxalpha 2022-05-08 16:50:36 +02:00 committed by Ryan Foster
parent 49dfc113c1
commit 3513c78be2
4 changed files with 125 additions and 10 deletions

View File

@ -141,7 +141,7 @@ void YoutubeAuth::LoadUI()
QSize size = main->frameSize();
QPoint pos = main->pos();
chat.reset(new BrowserDock());
chat.reset(new YoutubeChatDock());
chat->setObjectName("ytChat");
chat->resize(300, 600);
chat->setMinimumSize(200, 300);
@ -173,16 +173,18 @@ void YoutubeAuth::LoadUI()
uiLoaded = true;
}
void YoutubeAuth::SetChatId(QString &chat_id)
void YoutubeAuth::SetChatId(const QString &chat_id,
const std::string &api_chat_id)
{
#ifdef BROWSER_AVAILABLE
QString chat_url = QString(YOUTUBE_CHAT_POPOUT_URL).arg(chat_id);
if (chat && chat->cefWidget) {
chat->cefWidget->setURL(chat_url.toStdString());
chat->SetApiChatId(api_chat_id);
}
#else
UNUSED_PARAMETER(chat_id);
UNUSED_PARAMETER(chat_id, api_chat_id);
#endif
}
@ -322,3 +324,83 @@ std::shared_ptr<Auth> YoutubeAuth::Login(QWidget *owner,
config_save_safe(config, "tmp", nullptr);
return auth;
}
#ifdef BROWSER_AVAILABLE
void YoutubeChatDock::SetWidget(QCefWidget *widget_)
{
lineEdit = new LineEditAutoResize();
lineEdit->setVisible(false);
lineEdit->setMaxLength(200);
lineEdit->setPlaceholderText(QTStr("YouTube.Chat.Input.Placeholder"));
sendButton = new QPushButton(QTStr("YouTube.Chat.Input.Send"));
sendButton->setVisible(false);
chatLayout = new QHBoxLayout();
chatLayout->setMargin(0);
chatLayout->addWidget(lineEdit, 1);
chatLayout->addWidget(sendButton);
QVBoxLayout *layout = new QVBoxLayout();
layout->setMargin(0);
layout->addWidget(widget_, 1);
layout->addLayout(chatLayout);
QWidget *widget = new QWidget();
widget->setLayout(layout);
setWidget(widget);
QWidget::connect(lineEdit, SIGNAL(returnPressed()), this,
SLOT(SendChatMessage()));
QWidget::connect(sendButton, SIGNAL(pressed()), this,
SLOT(SendChatMessage()));
cefWidget.reset(widget_);
}
void YoutubeChatDock::SetApiChatId(const std::string &id)
{
this->apiChatId = id;
QMetaObject::invokeMethod(this, "EnableChatInput",
Qt::QueuedConnection);
}
void YoutubeChatDock::SendChatMessage()
{
const QString message = lineEdit->text();
if (message == "")
return;
OBSBasic *main = OBSBasic::Get();
YoutubeApiWrappers *apiYouTube(
dynamic_cast<YoutubeApiWrappers *>(main->GetAuth()));
ExecuteFuncSafeBlock([&]() {
lineEdit->setText("");
lineEdit->setPlaceholderText(
QTStr("YouTube.Chat.Input.Sending"));
if (apiYouTube->SendChatMessage(apiChatId, message)) {
os_sleep_ms(3000);
} else {
QString error = apiYouTube->GetLastError();
apiYouTube->GetTranslatedError(error);
QMetaObject::invokeMethod(
this, "ShowErrorMessage", Qt::QueuedConnection,
Q_ARG(const QString &, error));
}
lineEdit->setPlaceholderText(
QTStr("YouTube.Chat.Input.Placeholder"));
});
}
void YoutubeChatDock::ShowErrorMessage(const QString &error)
{
QMessageBox::warning(this, QTStr("YouTube.Chat.Error.Title"),
QTStr("YouTube.Chat.Error.Text").arg(error));
}
void YoutubeChatDock::EnableChatInput()
{
lineEdit->setVisible(true);
sendButton->setVisible(true);
}
#endif

View File

@ -8,7 +8,27 @@
#include "auth-oauth.hpp"
#ifdef BROWSER_AVAILABLE
class BrowserDock;
#include "window-dock-browser.hpp"
#include "lineedit-autoresize.hpp"
#include <QHBoxLayout>
class YoutubeChatDock : public BrowserDock {
Q_OBJECT
private:
std::string apiChatId;
LineEditAutoResize *lineEdit;
QPushButton *sendButton;
QHBoxLayout *chatLayout;
public:
void SetWidget(QCefWidget *widget_);
void SetApiChatId(const std::string &id);
private slots:
void SendChatMessage();
void ShowErrorMessage(const QString &error);
void EnableChatInput();
};
#endif
inline const std::vector<Auth::Def> youtubeServices = {
@ -24,7 +44,7 @@ class YoutubeAuth : public OAuthStreamKey {
std::string section;
#ifdef BROWSER_AVAILABLE
QSharedPointer<BrowserDock> chat;
QSharedPointer<YoutubeChatDock> chat;
QSharedPointer<QAction> chatMenu;
#endif
@ -38,7 +58,7 @@ class YoutubeAuth : public OAuthStreamKey {
public:
YoutubeAuth(const Def &d);
void SetChatId(QString &chat_id);
void SetChatId(const QString &chat_id, const std::string &api_chat_id);
void ResetChat();
static std::shared_ptr<Auth> Login(QWidget *parent,

View File

@ -1320,6 +1320,12 @@ YouTube.Actions.AutoStartStreamingWarning.Title="Manual start required"
YouTube.Actions.AutoStartStreamingWarning="Auto-start is disabled for this event, click \"Go Live\" to start your broadcast."
YouTube.Actions.AutoStopStreamingWarning="You will not be able to reconnect.<br>Your stream will stop and you will no longer be live."
YouTube.Chat.Input.Send="Send"
YouTube.Chat.Input.Placeholder="Enter message here..."
YouTube.Chat.Input.Sending="Sending..."
YouTube.Chat.Error.Title="Error while sending message"
YouTube.Chat.Error.Text="The message couldn't be sent: %1"
# YouTube API errors in format "YouTube.Errors.<error reason>"
YouTube.Errors.liveStreamingNotEnabled="Live streaming is not enabled on the selected YouTube channel.<br/><br/>See <a href='https://www.youtube.com/features'>youtube.com/features</a> for more information."
YouTube.Errors.livePermissionBlocked="Live streaming is unavailable on the selected YouTube Channel.<br/>Please note that it may take up to 24 hours for live streaming to become available after enabling it in your channel settings.<br/><br/>See <a href='https://www.youtube.com/features'>youtube.com/features</a> for details."

View File

@ -503,10 +503,13 @@ bool OBSYoutubeActions::CreateEventAction(YoutubeApiWrappers *api,
return false;
}
if (broadcast.privacy != "private")
apiYouTube->SetChatId(broadcast.id);
else
if (broadcast.privacy != "private") {
const std::string apiLiveChatId =
json["snippet"]["liveChatId"].string_value();
apiYouTube->SetChatId(broadcast.id, apiLiveChatId);
} else {
apiYouTube->ResetChat();
}
}
return true;
@ -531,6 +534,10 @@ bool OBSYoutubeActions::ChooseAnEventAction(YoutubeApiWrappers *api,
json["items"]
.array_items()[0]["status"]["privacyStatus"]
.string_value();
std::string apiLiveChatId =
json["items"]
.array_items()[0]["snippet"]["liveChatId"]
.string_value();
stream.id = boundStreamId.c_str();
if (!stream.id.isEmpty() && apiYouTube->FindStream(stream.id, json)) {
@ -556,7 +563,7 @@ bool OBSYoutubeActions::ChooseAnEventAction(YoutubeApiWrappers *api,
}
if (broadcastPrivacy != "private")
apiYouTube->SetChatId(selectedBroadcast);
apiYouTube->SetChatId(selectedBroadcast, apiLiveChatId);
else
apiYouTube->ResetChat();