From 4f65b004ee231d1959006dfe15c75934588f377d Mon Sep 17 00:00:00 2001 From: Oleksandr Kosenko Date: Sat, 14 Dec 2024 16:21:42 -0500 Subject: [PATCH] Remember last selected event for "Manage Broadcast" dialog If we can't get event info from api - create default event --- UI/auth-restream.cpp | 102 +++++++++++---------------------- UI/auth-restream.hpp | 3 +- UI/data/locale/en-US.ini | 1 + UI/forms/OBSRestreamActions.ui | 9 ++- UI/window-restream-actions.cpp | 37 ++++++++---- UI/window-restream-actions.hpp | 1 + 6 files changed, 74 insertions(+), 79 deletions(-) diff --git a/UI/auth-restream.cpp b/UI/auth-restream.cpp index a743b3dabc24bb..6a555b7a66e89a 100644 --- a/UI/auth-restream.cpp +++ b/UI/auth-restream.cpp @@ -45,63 +45,6 @@ RestreamAuth::~RestreamAuth() main->RemoveDockWidget(RESTREAM_CHANNELS_DOCK_NAME); } -bool RestreamAuth::SetMainChannelKey() -try { - std::string client_id = RESTREAM_CLIENTID; - deobfuscate_str(&client_id[0], RESTREAM_HASH); - - if (!GetToken(RESTREAM_TOKEN_URL, client_id, RESTREAM_SCOPE_VERSION)) - return false; - if (token.empty()) - return false; - if (!key_.empty()) - return true; - - std::string auth; - auth += "Authorization: Bearer "; - auth += token; - - std::vector headers; - headers.push_back(std::string("Client-ID: ") + client_id); - headers.push_back(std::move(auth)); - - std::string output; - std::string error; - Json json; - bool success; - - auto func = [&]() { - auto url = QString("%1/streamKey").arg(RESTREAM_API_URL); - success = GetRemoteFile(url.toUtf8(), output, error, nullptr, "application/json", "", nullptr, headers, - nullptr, 5); - }; - - ExecThreadedWithoutBlocking(func, QTStr("Auth.LoadingChannel.Title"), - QTStr("Auth.LoadingChannel.Text").arg(service())); - if (!success || output.empty()) - throw ErrorInfo("Failed to get stream key from remote", error); - - json = Json::parse(output, error); - if (!error.empty()) - throw ErrorInfo("Failed to parse json", error); - - error = json["error"].string_value(); - if (!error.empty()) - throw ErrorInfo(error, json["error_description"].string_value()); - - key_ = json["streamKey"].string_value(); - - return true; -} catch (ErrorInfo info) { - QString title = QTStr("Auth.ChannelFailure.Title"); - QString text = QTStr("Auth.ChannelFailure.Text").arg(service(), info.message.c_str(), info.error.c_str()); - - QMessageBox::warning(OBSBasic::Get(), title, text); - - blog(LOG_WARNING, "%s: %s: %s", __FUNCTION__, info.message.c_str(), info.error.c_str()); - return false; -} - bool RestreamAuth::GetBroadcastInfo(QVector &broadcast_out) try { std::string client_id = RESTREAM_CLIENTID; @@ -193,7 +136,9 @@ try { headers.push_back(std::string("Client-ID: ") + client_id); headers.push_back(std::move(auth)); - auto url = QString("%1/events/%2/streamKey").arg(RESTREAM_API_URL, id); + auto url = id.isEmpty() || id == "default" + ? QString("%1/streamKey").arg(RESTREAM_API_URL) + : QString("%1/events/%2/streamKey").arg(RESTREAM_API_URL, id); std::string output; std::string error; @@ -208,7 +153,7 @@ try { ExecThreadedWithoutBlocking(func, QTStr("Auth.LoadingChannel.Title"), QTStr("Auth.LoadingChannel.Text").arg(service())); if (!success || output.empty()) - throw ErrorInfo("Failed to get the event key from remote", error); + throw ErrorInfo("Failed to get the stream key from remote", error); json = Json::parse(output, error); if (!error.empty()) @@ -234,24 +179,42 @@ try { void RestreamAuth::UseBroadcastKey(QString key, QString show_id) { + if (QString::fromStdString(key_) == key && currentShowId == show_id) + return; + key_ = key.toUtf8(); + currentShowId = show_id; if (chatWidgetBrowser) { - auto url = QString("https://restream.io/chat-application?show-id=%1").arg(show_id); + auto url = QString("https://restream.io/chat-application"); + if (!show_id.isEmpty()) + url.append(QString("?show-id=%1").arg(show_id)); + chatWidgetBrowser->setURL(url.toStdString()); } if (titlesWidgetBrowser) { - auto url = QString("https://restream.io/titles/embed?show-id=%1").arg(show_id); + auto url = QString("https://restream.io/titles/embed"); + if (!show_id.isEmpty()) + url.append(QString("?show-id=%1").arg(show_id)); + titlesWidgetBrowser->setURL(url.toStdString()); } if (channelWidgetBrowser) { - auto url = QString("https://restream.io/channel/embed?show-id=%1").arg(show_id); + auto url = QString("https://restream.io/channel/embed"); + if (!show_id.isEmpty()) + url.append(QString("?show-id=%1").arg(show_id)); + channelWidgetBrowser->setURL(url.toStdString()); } } +QString RestreamAuth::GetCurrentShowId() +{ + return currentShowId; +} + void RestreamAuth::SaveInternal() { OBSBasic *main = OBSBasic::Get(); @@ -280,9 +243,13 @@ void RestreamAuth::LoadUI() if (!cef) return; - if (!SetMainChannelKey()) + + QString key; + if (!GetBroadcastKey("default", key)) return; + UseBroadcastKey(key, ""); + OBSBasic::InitBrowserPanelSafeBlock(); OBSBasic *main = OBSBasic::Get(); @@ -398,11 +365,12 @@ std::shared_ptr RestreamAuth::Login(QWidget *parent, const std::string &) if (!auth->GetToken(RESTREAM_TOKEN_URL, client_id, RESTREAM_SCOPE_VERSION, QT_TO_UTF8(login.GetCode()))) return nullptr; - std::string error; - if (auth->SetMainChannelKey()) - return auth; + QString key; + if (!auth->GetBroadcastKey("default", key)) + return nullptr; - return nullptr; + auth->UseBroadcastKey(key, ""); + return auth; } static std::shared_ptr CreateRestreamAuth() diff --git a/UI/auth-restream.hpp b/UI/auth-restream.hpp index 790db8538bd134..81614865a54b78 100644 --- a/UI/auth-restream.hpp +++ b/UI/auth-restream.hpp @@ -15,6 +15,7 @@ class RestreamAuth : public OAuthStreamKey { Q_OBJECT bool uiLoaded = false; + QString currentShowId = ""; QCefWidget *chatWidgetBrowser = NULL; QCefWidget *titlesWidgetBrowser = NULL; QCefWidget *channelWidgetBrowser = NULL; @@ -30,10 +31,10 @@ class RestreamAuth : public OAuthStreamKey { RestreamAuth(const Def &d); ~RestreamAuth(); - bool SetMainChannelKey(); bool GetBroadcastInfo(QVector &events); bool GetBroadcastKey(QString id, QString &key_out); void UseBroadcastKey(QString key, QString show_id); + QString GetCurrentShowId(); static std::shared_ptr Login(QWidget *parent, const std::string &service_name); }; diff --git a/UI/data/locale/en-US.ini b/UI/data/locale/en-US.ini index 1ad689795a17e0..361c2487dbda1f 100644 --- a/UI/data/locale/en-US.ini +++ b/UI/data/locale/en-US.ini @@ -1593,6 +1593,7 @@ MultitrackVideo.IncompatibleSettings.AudioChannelsMultiple="%1 requires multiple # Restream Actions Restream.Actions.WindowTitle="Restream Broadcast Setup" Restream.Actions.BroadcastSelectTitle="Select Existing Broadcast" +Restream.Actions.DashboardButton="Open Restream"; Restream.Actions.BroadcastSelectButton="Select broadcast" Restream.Actions.BroadcastSelectAndStartButton="Select broadcast and start streaming" Restream.Actions.BroadcastScheduled="Scheduled" diff --git a/UI/forms/OBSRestreamActions.ui b/UI/forms/OBSRestreamActions.ui index 52e6a6e2375f45..48ba2608108ae0 100644 --- a/UI/forms/OBSRestreamActions.ui +++ b/UI/forms/OBSRestreamActions.ui @@ -133,7 +133,7 @@ 0 - + 10 @@ -147,6 +147,13 @@ + + + + Restream.Actions.DashboardButton + + + diff --git a/UI/window-restream-actions.cpp b/UI/window-restream-actions.cpp index ca3cebd3189e01..419da4c4528232 100644 --- a/UI/window-restream-actions.cpp +++ b/UI/window-restream-actions.cpp @@ -11,10 +11,6 @@ #include #include -const QString SchedulDateAndTimeFormat = "yyyy-MM-dd'T'hh:mm:ss'Z'"; -const QString RepresentSchedulDateAndTimeFormat = "dddd, MMMM d, yyyy h:m"; -const QString IndexOfGamingCategory = "20"; - OBSRestreamActions::OBSRestreamActions(QWidget *parent, Auth *auth, bool broadcastReady) : QDialog(parent), ui(new Ui::OBSRestreamActions), @@ -28,6 +24,7 @@ OBSRestreamActions::OBSRestreamActions(QWidget *parent, Auth *auth, bool broadca connect(ui->okButton, &QPushButton::clicked, this, &OBSRestreamActions::BroadcastSelectAndStartAction); connect(ui->saveButton, &QPushButton::clicked, this, &OBSRestreamActions::BroadcastSelectAction); + connect(ui->dashboardButton, &QPushButton::clicked, this, &OBSRestreamActions::OpenRestreamDashboard); connect(ui->cancelButton, &QPushButton::clicked, this, [&]() { blog(LOG_DEBUG, "Restream live event creation cancelled."); reject(); @@ -37,10 +34,16 @@ OBSRestreamActions::OBSRestreamActions(QWidget *parent, Auth *auth, bool broadca QVector events; if (!restreamAuth->GetBroadcastInfo(events)) { - reject(); - return; + RestreamEventDescription event; + event.id = QString("default"); + event.title = QString("Live with Restream"); + event.scheduledFor = 0; + event.showId = QString(""); + events.push_back(event); } + auto currentShowId = restreamAuth->GetCurrentShowId(); + for (auto event : events) { ClickableLabel *label = new ClickableLabel(); label->setTextFormat(Qt::RichText); @@ -80,6 +83,17 @@ OBSRestreamActions::OBSRestreamActions(QWidget *parent, Auth *auth, bool broadca }); ui->scrollAreaWidgetContents->layout()->addWidget(label); + + if (broadcastReady && event.showId == currentShowId) { + label->setProperty("class", "row-selected"); + label->style()->unpolish(label); + label->style()->polish(label); + + selectedBroadcastId = event.id; + selectedShowId = event.showId; + + UpdateOkButtonStatus(); + } } } @@ -95,9 +109,8 @@ void OBSRestreamActions::UpdateOkButtonStatus() void OBSRestreamActions::BroadcastSelectAction() { QString streamKey; - if (!restreamAuth->GetBroadcastKey(selectedBroadcastId, streamKey)) { + if (!restreamAuth->GetBroadcastKey(selectedBroadcastId, streamKey)) return; - } emit ok(QT_TO_UTF8(selectedBroadcastId), QT_TO_UTF8(streamKey), QT_TO_UTF8(selectedShowId), false); accept(); @@ -106,10 +119,14 @@ void OBSRestreamActions::BroadcastSelectAction() void OBSRestreamActions::BroadcastSelectAndStartAction() { QString streamKey; - if (!restreamAuth->GetBroadcastKey(selectedBroadcastId, streamKey)) { + if (!restreamAuth->GetBroadcastKey(selectedBroadcastId, streamKey)) return; - } emit ok(QT_TO_UTF8(selectedBroadcastId), QT_TO_UTF8(streamKey), QT_TO_UTF8(selectedShowId), true); accept(); } + +void OBSRestreamActions::OpenRestreamDashboard() +{ + QDesktopServices::openUrl(QString("https://app.restream.io/")); +} diff --git a/UI/window-restream-actions.hpp b/UI/window-restream-actions.hpp index b1ea9f21b89d4a..a2707264e73721 100644 --- a/UI/window-restream-actions.hpp +++ b/UI/window-restream-actions.hpp @@ -28,6 +28,7 @@ class OBSRestreamActions : public QDialog { private: void BroadcastSelectAction(); void BroadcastSelectAndStartAction(); + void OpenRestreamDashboard(); QIcon GetPlaceholder() { return thumbPlaceholder; } void SetPlaceholder(const QIcon &icon) { thumbPlaceholder = icon; }