From 67bb8d7028c6e36c49cf4af7c18580cfddde4c41 Mon Sep 17 00:00:00 2001 From: jp9000 Date: Wed, 6 Feb 2019 22:37:36 -0800 Subject: [PATCH] UI: Add auth. support to settings/autoconfig Adds the ability to connect/login to an account via the settings and auto-configuration dialogs. Checks registered Auth objects, and if the Auth object matches the currently selected service in the settings window or auto-configuration dialog, will display "connect account" buttons for the user to be able to click (which are optional, they can still use stream keys if they'd prefer). --- UI/data/locale/en-US.ini | 5 + UI/forms/AutoConfigStreamPage.ui | 125 +++++++++++++++++++++- UI/forms/OBSBasicSettings.ui | 154 +++++++++++++++++++++++++++- UI/window-basic-auto-config.cpp | 148 +++++++++++++++++++++++++- UI/window-basic-auto-config.hpp | 11 ++ UI/window-basic-main.hpp | 2 + UI/window-basic-settings-stream.cpp | 145 ++++++++++++++++++++++++++ UI/window-basic-settings.hpp | 9 ++ 8 files changed, 593 insertions(+), 6 deletions(-) diff --git a/UI/data/locale/en-US.ini b/UI/data/locale/en-US.ini index de07d7ddf..2c5bdeb34 100644 --- a/UI/data/locale/en-US.ini +++ b/UI/data/locale/en-US.ini @@ -141,6 +141,11 @@ Basic.AutoConfig.VideoPage.FPS.PreferHighRes="Either 60 or 30, but prefer high r Basic.AutoConfig.VideoPage.CanvasExplanation="Note: The canvas (base) resolution is not necessarily the same as the resolution you will stream or record with. Your actual stream/recording resolution may be scaled down from the canvas resolution to reduce resource usage or bitrate requirements." Basic.AutoConfig.StreamPage="Stream Information" Basic.AutoConfig.StreamPage.SubTitle="Please enter your stream information" +Basic.AutoConfig.StreamPage.ConnectAccount="Connect Account (optional)" +Basic.AutoConfig.StreamPage.DisconnectAccount="Disconnect Account" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title="Disconnect Account?" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text="This change will apply immediately. Are you sure you want to disconnect your account?" +Basic.AutoConfig.StreamPage.UseStreamKey="Use Stream Key" Basic.AutoConfig.StreamPage.Service="Service" Basic.AutoConfig.StreamPage.Service.ShowAll="Show All..." Basic.AutoConfig.StreamPage.Service.Custom="Custom..." diff --git a/UI/forms/AutoConfigStreamPage.ui b/UI/forms/AutoConfigStreamPage.ui index 7389adafe..c52e37979 100644 --- a/UI/forms/AutoConfigStreamPage.ui +++ b/UI/forms/AutoConfigStreamPage.ui @@ -79,8 +79,98 @@ - 0 + 1 + + + + QFormLayout::ExpandingFieldsGrow + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 87 + 17 + + + + + + + + + + Basic.AutoConfig.StreamPage.ConnectAccount + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 87 + 17 + + + + + + + + + + Basic.AutoConfig.StreamPage.UseStreamKey + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + @@ -294,6 +384,20 @@ + + + + Basic.AutoConfig.StreamPage.ConnectAccount + + + + + + + Basic.AutoConfig.StreamPage.DisconnectAccount + + + @@ -301,5 +405,22 @@ - + + + connectAccount2 + clicked() + connectAccount + click() + + + 382 + 279 + + + 114 + 82 + + + + diff --git a/UI/forms/OBSBasicSettings.ui b/UI/forms/OBSBasicSettings.ui index fee71e1da..fc8fed8a9 100644 --- a/UI/forms/OBSBasicSettings.ui +++ b/UI/forms/OBSBasicSettings.ui @@ -742,8 +742,92 @@ - 0 + 1 + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 170 + 19 + + + + + + + + + + Basic.AutoConfig.StreamPage.ConnectAccount + + + + + + + Qt::Horizontal + + + + 40 + 10 + + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 170 + 19 + + + + + + + + + + Basic.AutoConfig.StreamPage.UseStreamKey + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + @@ -868,6 +952,54 @@ + + + + + + Basic.AutoConfig.StreamPage.ConnectAccount + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + Basic.AutoConfig.StreamPage.DisconnectAccount + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + @@ -898,8 +1030,8 @@ 0 0 - 818 - 697 + 601 + 640 @@ -5428,5 +5560,21 @@ + + connectAccount2 + clicked() + connectAccount + click() + + + 484 + 142 + + + 454 + 87 + + + diff --git a/UI/window-basic-auto-config.cpp b/UI/window-basic-auto-config.cpp index e05c88d0c..f312b272a 100644 --- a/UI/window-basic-auto-config.cpp +++ b/UI/window-basic-auto-config.cpp @@ -12,6 +12,17 @@ #include "ui_AutoConfigVideoPage.h" #include "ui_AutoConfigStreamPage.h" +#ifdef BROWSER_AVAILABLE +#include +#include "auth-oauth.hpp" +#endif + +struct QCef; +struct QCefCookieManager; + +extern QCef *cef; +extern QCefCookieManager *panel_cookies; + #define wiz reinterpret_cast(wizard()) /* ------------------------------------------------------------------------- */ @@ -222,6 +233,8 @@ AutoConfigStreamPage::AutoConfigStreamPage(QWidget *parent) ui->setupUi(this); ui->bitrateLabel->setVisible(false); ui->bitrate->setVisible(false); + ui->connectAccount2->setVisible(false); + ui->disconnectAccount->setVisible(false); int vertSpacing = ui->topLayout->verticalSpacing(); @@ -229,6 +242,10 @@ AutoConfigStreamPage::AutoConfigStreamPage(QWidget *parent) m.setBottom(vertSpacing / 2); ui->topLayout->setContentsMargins(m); + m = ui->loginPageLayout->contentsMargins(); + m.setTop(vertSpacing / 2); + ui->loginPageLayout->setContentsMargins(m); + m = ui->streamkeyPageLayout->contentsMargins(); m.setTop(vertSpacing / 2); ui->streamkeyPageLayout->setContentsMargins(m); @@ -371,6 +388,94 @@ void AutoConfigStreamPage::on_show_clicked() } } +void AutoConfigStreamPage::OnOAuthStreamKeyConnected() +{ +#ifdef BROWSER_AVAILABLE + OAuthStreamKey *a = reinterpret_cast(auth.get()); + + if (a) { + bool validKey = !a->key().empty(); + + if (validKey) + ui->key->setText(QT_UTF8(a->key().c_str())); + + ui->streamKeyWidget->setVisible(!validKey); + ui->streamKeyLabel->setVisible(!validKey); + ui->connectAccount2->setVisible(!validKey); + ui->disconnectAccount->setVisible(validKey); + } + + ui->stackedWidget->setCurrentIndex((int)Section::StreamKey); + UpdateCompleted(); +#endif +} + +void AutoConfigStreamPage::OnAuthConnected() +{ + std::string service = QT_TO_UTF8(ui->service->currentText()); + Auth::Type type = Auth::AuthType(service); + + if (type == Auth::Type::OAuth_StreamKey) { + OnOAuthStreamKeyConnected(); + } +} + +void AutoConfigStreamPage::on_connectAccount_clicked() +{ +#ifdef BROWSER_AVAILABLE + std::string service = QT_TO_UTF8(ui->service->currentText()); + + auth = OAuthStreamKey::Login(this, service); + if (!!auth) + OnAuthConnected(); +#endif +} + +#define DISCONNECT_COMFIRM_TITLE \ + "Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title" +#define DISCONNECT_COMFIRM_TEXT \ + "Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text" + +void AutoConfigStreamPage::on_disconnectAccount_clicked() +{ + QMessageBox::StandardButton button; + + button = OBSMessageBox::question(this, + QTStr(DISCONNECT_COMFIRM_TITLE), + QTStr(DISCONNECT_COMFIRM_TEXT)); + + if (button == QMessageBox::No) { + return; + } + + OBSBasic *main = OBSBasic::Get(); + + main->auth.reset(); + auth.reset(); + + std::string service = QT_TO_UTF8(ui->service->currentText()); + +#ifdef BROWSER_AVAILABLE + OAuth::DeleteCookies(service); +#endif + + ui->streamKeyWidget->setVisible(true); + ui->streamKeyLabel->setVisible(true); + ui->connectAccount2->setVisible(true); + ui->disconnectAccount->setVisible(false); +} + +void AutoConfigStreamPage::on_useStreamKey_clicked() +{ + ui->stackedWidget->setCurrentIndex((int)Section::StreamKey); + UpdateCompleted(); +} + +static inline bool is_auth_service(const std::string &service) +{ + return Auth::AuthType(service) != Auth::Type::None; +} + void AutoConfigStreamPage::ServiceChanged() { bool showMore = @@ -384,6 +489,32 @@ void AutoConfigStreamPage::ServiceChanged() bool testBandwidth = ui->doBandwidthTest->isChecked(); bool custom = IsCustom(); + ui->disconnectAccount->setVisible(false); + +#ifdef BROWSER_AVAILABLE + if (cef) { + if (lastService != service.c_str()) { + bool can_auth = is_auth_service(service); + int page = can_auth + ? (int)Section::Connect + : (int)Section::StreamKey; + + ui->stackedWidget->setCurrentIndex(page); + ui->streamKeyWidget->setVisible(true); + ui->streamKeyLabel->setVisible(true); + ui->connectAccount2->setVisible(can_auth); + auth.reset(); + + if (lastService.isEmpty()) + lastService = service.c_str(); + } + } else { + ui->connectAccount2->setVisible(false); + } +#else + ui->connectAccount2->setVisible(false); +#endif + /* Test three closest servers if "Auto" is available for Twitch */ if (service == "Twitch" && wiz->twitchAuto) regionBased = false; @@ -415,6 +546,17 @@ void AutoConfigStreamPage::ServiceChanged() ui->bitrateLabel->setHidden(testBandwidth); ui->bitrate->setHidden(testBandwidth); +#ifdef BROWSER_AVAILABLE + OBSBasic *main = OBSBasic::Get(); + auth.reset(); + + if (!!main->auth && + service.find(main->auth->service()) != std::string::npos) { + auth = main->auth; + OnAuthConnected(); + } +#endif + UpdateCompleted(); } @@ -544,7 +686,8 @@ void AutoConfigStreamPage::UpdateServerList() void AutoConfigStreamPage::UpdateCompleted() { - if (ui->key->text().isEmpty()) { + if (ui->stackedWidget->currentIndex() == (int)Section::Connect || + (ui->key->text().isEmpty() && !auth)) { ready = false; } else { bool custom = IsCustom(); @@ -802,6 +945,9 @@ void AutoConfig::SaveStreamSettings() main->SetService(newService); main->SaveService(); + main->auth = streamPage->auth; + if (!!main->auth) + main->auth->LoadUI(); /* ---------------------------------- */ /* save stream settings */ diff --git a/UI/window-basic-auto-config.hpp b/UI/window-basic-auto-config.hpp index b51866b14..9426a7548 100644 --- a/UI/window-basic-auto-config.hpp +++ b/UI/window-basic-auto-config.hpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -18,6 +19,7 @@ class Ui_AutoConfigStreamPage; class Ui_AutoConfigTestPage; class AutoConfigStreamPage; +class Auth; class AutoConfig : public QWizard { Q_OBJECT @@ -160,9 +162,12 @@ class AutoConfigStreamPage : public QWizardPage { friend class AutoConfig; enum class Section : int { + Connect, StreamKey, }; + std::shared_ptr auth; + Ui_AutoConfigStreamPage *ui; QString lastService; bool ready = false; @@ -178,8 +183,14 @@ public: virtual int nextId() const override; virtual bool validatePage() override; + void OnAuthConnected(); + void OnOAuthStreamKeyConnected(); + public slots: void on_show_clicked(); + void on_connectAccount_clicked(); + void on_disconnectAccount_clicked(); + void on_useStreamKey_clicked(); void ServiceChanged(); void UpdateKeyLink(); void UpdateServerList(); diff --git a/UI/window-basic-main.hpp b/UI/window-basic-main.hpp index 109012579..50aac4feb 100644 --- a/UI/window-basic-main.hpp +++ b/UI/window-basic-main.hpp @@ -118,6 +118,8 @@ class OBSBasic : public OBSMainWindow { friend class OBSBasicSourceSelect; friend class OBSBasicSettings; friend class Auth; + friend class AutoConfig; + friend class AutoConfigStreamPage; friend struct OBSStudioAPI; enum class MoveDir { diff --git a/UI/window-basic-settings-stream.cpp b/UI/window-basic-settings-stream.cpp index ad1f67fbe..3a28aff40 100644 --- a/UI/window-basic-settings-stream.cpp +++ b/UI/window-basic-settings-stream.cpp @@ -5,12 +5,24 @@ #include "window-basic-main.hpp" #include "qt-wrappers.hpp" +#ifdef BROWSER_AVAILABLE +#include +#include "auth-oauth.hpp" +#endif + +struct QCef; +struct QCefCookieManager; + +extern QCef *cef; +extern QCefCookieManager *panel_cookies; + enum class ListOpt : int { ShowAll = 1, Custom, }; enum class Section : int { + Connect, StreamKey, }; @@ -21,12 +33,19 @@ inline bool OBSBasicSettings::IsCustomService() const void OBSBasicSettings::InitStreamPage() { + ui->connectAccount2->setVisible(false); + ui->disconnectAccount->setVisible(false); + int vertSpacing = ui->topStreamLayout->verticalSpacing(); QMargins m = ui->topStreamLayout->contentsMargins(); m.setBottom(vertSpacing / 2); ui->topStreamLayout->setContentsMargins(m); + m = ui->loginPageLayout->contentsMargins(); + m.setTop(vertSpacing / 2); + ui->loginPageLayout->setContentsMargins(m); + m = ui->streamkeyPageLayout->contentsMargins(); m.setTop(vertSpacing / 2); ui->streamkeyPageLayout->setContentsMargins(m); @@ -124,6 +143,9 @@ void OBSBasicSettings::SaveStream1Settings() main->SetService(newService); main->SaveService(); + main->auth = auth; + if (!!main->auth) + main->auth->LoadUI(); } void OBSBasicSettings::UpdateKeyLink() @@ -203,6 +225,11 @@ void OBSBasicSettings::LoadServices(bool showAll) ui->service->blockSignals(false); } +static inline bool is_auth_service(const std::string &service) +{ + return Auth::AuthType(service) != Auth::Type::None; +} + void OBSBasicSettings::on_service_currentIndexChanged(int) { bool showMore = @@ -213,6 +240,29 @@ void OBSBasicSettings::on_service_currentIndexChanged(int) std::string service = QT_TO_UTF8(ui->service->currentText()); bool custom = IsCustomService(); + ui->disconnectAccount->setVisible(false); + +#ifdef BROWSER_AVAILABLE + if (cef) { + if (lastService != service.c_str()) { + QString key = ui->key->text(); + bool can_auth = is_auth_service(service); + int page = can_auth && (!loading || key.isEmpty()) + ? (int)Section::Connect + : (int)Section::StreamKey; + + ui->streamStackWidget->setCurrentIndex(page); + ui->streamKeyWidget->setVisible(true); + ui->streamKeyLabel->setVisible(true); + ui->connectAccount2->setVisible(can_auth); + } + } else { + ui->connectAccount2->setVisible(false); + } +#else + ui->connectAccount2->setVisible(false); +#endif + if (custom) { ui->streamkeyPageLayout->insertRow(1, ui->serverLabel, ui->serverStackedWidget); @@ -223,6 +273,16 @@ void OBSBasicSettings::on_service_currentIndexChanged(int) } else { ui->serverStackedWidget->setCurrentIndex(0); } + +#ifdef BROWSER_AVAILABLE + auth.reset(); + + if (!!main->auth && + service.find(main->auth->service()) != std::string::npos) { + auth = main->auth; + OnAuthConnected(); + } +#endif } void OBSBasicSettings::UpdateServerList() @@ -298,3 +358,88 @@ OBSService OBSBasicSettings::SpawnTempService() return newService; } + +void OBSBasicSettings::OnOAuthStreamKeyConnected() +{ +#ifdef BROWSER_AVAILABLE + OAuthStreamKey *a = reinterpret_cast(auth.get()); + + if (a) { + bool validKey = !a->key().empty(); + + if (validKey) + ui->key->setText(QT_UTF8(a->key().c_str())); + + ui->streamKeyWidget->setVisible(!validKey); + ui->streamKeyLabel->setVisible(!validKey); + ui->connectAccount2->setVisible(!validKey); + ui->disconnectAccount->setVisible(validKey); + } + + ui->streamStackWidget->setCurrentIndex((int)Section::StreamKey); +#endif +} + +void OBSBasicSettings::OnAuthConnected() +{ + std::string service = QT_TO_UTF8(ui->service->currentText()); + Auth::Type type = Auth::AuthType(service); + + if (type == Auth::Type::OAuth_StreamKey) { + OnOAuthStreamKeyConnected(); + } + + if (!loading) { + stream1Changed = true; + EnableApplyButton(true); + } +} + +void OBSBasicSettings::on_connectAccount_clicked() +{ +#ifdef BROWSER_AVAILABLE + std::string service = QT_TO_UTF8(ui->service->currentText()); + + auth = OAuthStreamKey::Login(this, service); + if (!!auth) + OnAuthConnected(); +#endif +} + +#define DISCONNECT_COMFIRM_TITLE \ + "Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title" +#define DISCONNECT_COMFIRM_TEXT \ + "Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text" + +void OBSBasicSettings::on_disconnectAccount_clicked() +{ + QMessageBox::StandardButton button; + + button = OBSMessageBox::question(this, + QTStr(DISCONNECT_COMFIRM_TITLE), + QTStr(DISCONNECT_COMFIRM_TEXT)); + + if (button == QMessageBox::No) { + return; + } + + main->auth.reset(); + auth.reset(); + + std::string service = QT_TO_UTF8(ui->service->currentText()); + +#ifdef BROWSER_AVAILABLE + OAuth::DeleteCookies(service); +#endif + + ui->streamKeyWidget->setVisible(true); + ui->streamKeyLabel->setVisible(true); + ui->connectAccount2->setVisible(true); + ui->disconnectAccount->setVisible(false); + ui->key->setText(""); +} + +void OBSBasicSettings::on_useStreamKey_clicked() +{ + ui->streamStackWidget->setCurrentIndex((int)Section::StreamKey); +} diff --git a/UI/window-basic-settings.hpp b/UI/window-basic-settings.hpp index 3f913d669..e3c7ccd56 100644 --- a/UI/window-basic-settings.hpp +++ b/UI/window-basic-settings.hpp @@ -28,6 +28,8 @@ #include +#include "auth-base.hpp" + class OBSBasic; class QAbstractButton; class QComboBox; @@ -91,6 +93,8 @@ private: std::unique_ptr ui; + std::shared_ptr auth; + bool generalChanged = false; bool stream1Changed = false; bool outputsChanged = false; @@ -211,11 +215,16 @@ private: void InitStreamPage(); inline bool IsCustomService() const; void LoadServices(bool showAll); + void OnOAuthStreamKeyConnected(); + void OnAuthConnected(); QString lastService; private slots: void UpdateServerList(); void UpdateKeyLink(); void on_show_clicked(); + void on_connectAccount_clicked(); + void on_disconnectAccount_clicked(); + void on_useStreamKey_clicked(); private: /* output */ -- GitLab