UI: Enable first-party YouTube Chat features in OBS

Unlock the full feature set of the YouTube Chat dock in OBS by removing
custom scripting/CSS logic. Enable the signed-in experience for live
streaming content creators while also sharing login credentials with the
YouTube Control panel dock.

This will allow OBS users to utilize features _already_ supported in the
YouTube Chat plugin, such as

* creating polls
* managing Q&A sessions
* a rich emoji set in the input panel
* emoji fountains
* moderation tools

and many more. These features are available to users who are logged-in
to YouTube Chat and/or the YouTube Control panel.
This commit is contained in:
Suman Manjunath
2024-06-03 20:16:49 +00:00
committed by Ryan Foster
parent 492309c504
commit 9b8fa0f0ca
3 changed files with 44 additions and 16 deletions

View File

@@ -138,14 +138,6 @@ bool YoutubeAuth::LoadInternal()
return implicit ? !token.empty() : !refresh_token.empty();
}
#ifdef BROWSER_AVAILABLE
static const char *ytchat_script = "\
const obsCSS = document.createElement('style');\
obsCSS.innerHTML = \"#panel-pages.yt-live-chat-renderer {display: none;}\
yt-live-chat-viewer-engagement-message-renderer {display: none;}\";\
document.querySelector('head').appendChild(obsCSS);";
#endif
void YoutubeAuth::LoadUI()
{
if (uiLoaded)
@@ -171,7 +163,6 @@ void YoutubeAuth::LoadUI()
browser = cef->create_widget(chat, YOUTUBE_CHAT_PLACEHOLDER_URL,
panel_cookies);
browser->setStartupScript(ytchat_script);
chat->SetWidget(browser);
main->AddDockWidget(chat, Qt::RightDockWidgetArea);
@@ -219,6 +210,7 @@ void YoutubeAuth::ResetChat()
{
#ifdef BROWSER_AVAILABLE
if (chat && chat->cefWidget) {
chat->SetApiChatId("");
chat->cefWidget->setURL(YOUTUBE_CHAT_PLACEHOLDER_URL);
}
#endif
@@ -399,13 +391,44 @@ void YoutubeChatDock::SetWidget(QCefWidget *widget_)
setWidget(widget);
cefWidget.reset(widget_);
QWidget::connect(cefWidget.get(), &QCefWidget::urlChanged, this,
&YoutubeChatDock::YoutubeCookieCheck);
}
void YoutubeChatDock::SetApiChatId(const std::string &id)
{
this->apiChatId = id;
QMetaObject::invokeMethod(this, "EnableChatInput",
Qt::QueuedConnection);
QMetaObject::invokeMethod(this, "EnableChatInput", Qt::QueuedConnection,
Q_ARG(bool, !id.empty()));
}
void YoutubeChatDock::YoutubeCookieCheck()
{
QPointer<YoutubeChatDock> this_ = this;
auto cb = [this_](bool currentlyLoggedIn) {
bool previouslyLoggedIn = this_->isLoggedIn;
this_->isLoggedIn = currentlyLoggedIn;
bool loginStateChanged =
(currentlyLoggedIn && !previouslyLoggedIn) ||
(!currentlyLoggedIn && previouslyLoggedIn);
if (loginStateChanged) {
QMetaObject::invokeMethod(
this_, "EnableChatInput", Qt::QueuedConnection,
Q_ARG(bool, !currentlyLoggedIn));
OBSBasic *main = OBSBasic::Get();
if (main->GetYouTubeAppDock() != nullptr) {
QMetaObject::invokeMethod(
main->GetYouTubeAppDock(),
"SettingsUpdated", Qt::QueuedConnection,
Q_ARG(bool, !currentlyLoggedIn));
}
}
};
if (panel_cookies) {
panel_cookies->CheckForCookie("https://www.youtube.com", "SID",
cb);
}
}
void YoutubeChatDock::SendChatMessage()
@@ -442,9 +465,10 @@ void YoutubeChatDock::ShowErrorMessage(const QString &error)
QTStr("YouTube.Chat.Error.Text").arg(error));
}
void YoutubeChatDock::EnableChatInput()
void YoutubeChatDock::EnableChatInput(bool visible)
{
lineEdit->setVisible(true);
sendButton->setVisible(true);
bool setVisible = visible && !isLoggedIn;
lineEdit->setVisible(setVisible);
sendButton->setVisible(setVisible);
}
#endif

View File

@@ -16,6 +16,7 @@ class YoutubeChatDock : public BrowserDock {
private:
std::string apiChatId;
bool isLoggedIn;
LineEditAutoResize *lineEdit;
QPushButton *sendButton;
QHBoxLayout *chatLayout;
@@ -26,9 +27,10 @@ public:
void SetApiChatId(const std::string &id);
private slots:
void YoutubeCookieCheck();
void SendChatMessage();
void ShowErrorMessage(const QString &error);
void EnableChatInput();
void EnableChatInput(bool visible);
};
#endif

View File

@@ -16,7 +16,6 @@ public:
void AccountConnected();
void AccountDisconnected();
void SettingsUpdated(bool cleanup = false);
void Update();
void BroadcastCreated(const char *stream_id);
@@ -28,6 +27,9 @@ public:
static YoutubeApiWrappers *GetYTApi();
static void CleanupYouTubeUrls();
public slots:
void SettingsUpdated(bool cleanup = false);
protected:
void IngestionStarted(const char *stream_id, streaming_mode_t mode);
void IngestionStopped(const char *stream_id, streaming_mode_t mode);