Browse Source

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).
jp9000 6 years ago
parent
commit
67bb8d7028

+ 5 - 0
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..."

+ 123 - 2
UI/forms/AutoConfigStreamPage.ui

@@ -79,8 +79,98 @@
    <item>
     <widget class="QStackedWidget" name="stackedWidget">
      <property name="currentIndex">
-      <number>0</number>
+      <number>1</number>
      </property>
+     <widget class="QWidget" name="loginPage">
+      <layout class="QFormLayout" name="loginPageLayout">
+       <property name="fieldGrowthPolicy">
+        <enum>QFormLayout::ExpandingFieldsGrow</enum>
+       </property>
+       <property name="labelAlignment">
+        <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+       </property>
+       <item row="0" column="0">
+        <spacer name="horizontalSpacer_3">
+         <property name="orientation">
+          <enum>Qt::Horizontal</enum>
+         </property>
+         <property name="sizeType">
+          <enum>QSizePolicy::Fixed</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>87</width>
+           <height>17</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+       <item row="0" column="1">
+        <layout class="QHBoxLayout" name="horizontalLayout">
+         <item>
+          <widget class="QPushButton" name="connectAccount">
+           <property name="text">
+            <string>Basic.AutoConfig.StreamPage.ConnectAccount</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <spacer name="horizontalSpacer_4">
+           <property name="orientation">
+            <enum>Qt::Horizontal</enum>
+           </property>
+           <property name="sizeHint" stdset="0">
+            <size>
+             <width>40</width>
+             <height>20</height>
+            </size>
+           </property>
+          </spacer>
+         </item>
+        </layout>
+       </item>
+       <item row="1" column="0">
+        <spacer name="horizontalSpacer_7">
+         <property name="orientation">
+          <enum>Qt::Horizontal</enum>
+         </property>
+         <property name="sizeType">
+          <enum>QSizePolicy::Fixed</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>87</width>
+           <height>17</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+       <item row="1" column="1">
+        <layout class="QHBoxLayout" name="horizontalLayout_5">
+         <item>
+          <widget class="QPushButton" name="useStreamKey">
+           <property name="text">
+            <string>Basic.AutoConfig.StreamPage.UseStreamKey</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <spacer name="horizontalSpacer_8">
+           <property name="orientation">
+            <enum>Qt::Horizontal</enum>
+           </property>
+           <property name="sizeHint" stdset="0">
+            <size>
+             <width>40</width>
+             <height>20</height>
+            </size>
+           </property>
+          </spacer>
+         </item>
+        </layout>
+       </item>
+      </layout>
+     </widget>
      <widget class="QWidget" name="streamkeyPage">
       <layout class="QFormLayout" name="streamkeyPageLayout">
        <property name="fieldGrowthPolicy">
@@ -294,6 +384,20 @@
          </layout>
         </widget>
        </item>
+       <item row="6" column="1">
+        <widget class="QPushButton" name="connectAccount2">
+         <property name="text">
+          <string>Basic.AutoConfig.StreamPage.ConnectAccount</string>
+         </property>
+        </widget>
+       </item>
+       <item row="7" column="1">
+        <widget class="QPushButton" name="disconnectAccount">
+         <property name="text">
+          <string>Basic.AutoConfig.StreamPage.DisconnectAccount</string>
+         </property>
+        </widget>
+       </item>
       </layout>
      </widget>
     </widget>
@@ -301,5 +405,22 @@
   </layout>
  </widget>
  <resources/>
- <connections/>
+ <connections>
+  <connection>
+   <sender>connectAccount2</sender>
+   <signal>clicked()</signal>
+   <receiver>connectAccount</receiver>
+   <slot>click()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>382</x>
+     <y>279</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>114</x>
+     <y>82</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
 </ui>

+ 151 - 3
UI/forms/OBSBasicSettings.ui

@@ -742,8 +742,92 @@
             </sizepolicy>
            </property>
            <property name="currentIndex">
-            <number>0</number>
+            <number>1</number>
            </property>
+           <widget class="QWidget" name="loginPage">
+            <layout class="QFormLayout" name="loginPageLayout">
+             <item row="0" column="0">
+              <spacer name="horizontalSpacer_20">
+               <property name="orientation">
+                <enum>Qt::Horizontal</enum>
+               </property>
+               <property name="sizeType">
+                <enum>QSizePolicy::Fixed</enum>
+               </property>
+               <property name="sizeHint" stdset="0">
+                <size>
+                 <width>170</width>
+                 <height>19</height>
+                </size>
+               </property>
+              </spacer>
+             </item>
+             <item row="0" column="1">
+              <layout class="QHBoxLayout" name="horizontalLayout_16">
+               <item>
+                <widget class="QPushButton" name="connectAccount">
+                 <property name="text">
+                  <string>Basic.AutoConfig.StreamPage.ConnectAccount</string>
+                 </property>
+                </widget>
+               </item>
+               <item>
+                <spacer name="horizontalSpacer_21">
+                 <property name="orientation">
+                  <enum>Qt::Horizontal</enum>
+                 </property>
+                 <property name="sizeHint" stdset="0">
+                  <size>
+                   <width>40</width>
+                   <height>10</height>
+                  </size>
+                 </property>
+                </spacer>
+               </item>
+              </layout>
+             </item>
+             <item row="1" column="0">
+              <spacer name="horizontalSpacer_22">
+               <property name="orientation">
+                <enum>Qt::Horizontal</enum>
+               </property>
+               <property name="sizeType">
+                <enum>QSizePolicy::Fixed</enum>
+               </property>
+               <property name="sizeHint" stdset="0">
+                <size>
+                 <width>170</width>
+                 <height>19</height>
+                </size>
+               </property>
+              </spacer>
+             </item>
+             <item row="1" column="1">
+              <layout class="QHBoxLayout" name="horizontalLayout_17">
+               <item>
+                <widget class="QPushButton" name="useStreamKey">
+                 <property name="text">
+                  <string>Basic.AutoConfig.StreamPage.UseStreamKey</string>
+                 </property>
+                </widget>
+               </item>
+               <item>
+                <spacer name="horizontalSpacer_23">
+                 <property name="orientation">
+                  <enum>Qt::Horizontal</enum>
+                 </property>
+                 <property name="sizeHint" stdset="0">
+                  <size>
+                   <width>40</width>
+                   <height>20</height>
+                  </size>
+                 </property>
+                </spacer>
+               </item>
+              </layout>
+             </item>
+            </layout>
+           </widget>
            <widget class="QWidget" name="streamKeyPage">
             <layout class="QFormLayout" name="streamkeyPageLayout">
              <property name="fieldGrowthPolicy">
@@ -868,6 +952,54 @@
                </property>
               </spacer>
              </item>
+             <item row="2" column="1">
+              <layout class="QHBoxLayout" name="horizontalLayout_15">
+               <item>
+                <widget class="QPushButton" name="connectAccount2">
+                 <property name="text">
+                  <string>Basic.AutoConfig.StreamPage.ConnectAccount</string>
+                 </property>
+                </widget>
+               </item>
+               <item>
+                <spacer name="horizontalSpacer_19">
+                 <property name="orientation">
+                  <enum>Qt::Horizontal</enum>
+                 </property>
+                 <property name="sizeHint" stdset="0">
+                  <size>
+                   <width>40</width>
+                   <height>20</height>
+                  </size>
+                 </property>
+                </spacer>
+               </item>
+              </layout>
+             </item>
+             <item row="3" column="1">
+              <layout class="QHBoxLayout" name="horizontalLayout_23">
+               <item>
+                <widget class="QPushButton" name="disconnectAccount">
+                 <property name="text">
+                  <string>Basic.AutoConfig.StreamPage.DisconnectAccount</string>
+                 </property>
+                </widget>
+               </item>
+               <item>
+                <spacer name="horizontalSpacer_24">
+                 <property name="orientation">
+                  <enum>Qt::Horizontal</enum>
+                 </property>
+                 <property name="sizeHint" stdset="0">
+                  <size>
+                   <width>40</width>
+                   <height>20</height>
+                  </size>
+                 </property>
+                </spacer>
+               </item>
+              </layout>
+             </item>
             </layout>
            </widget>
           </widget>
@@ -898,8 +1030,8 @@
              <rect>
               <x>0</x>
               <y>0</y>
-              <width>818</width>
-              <height>697</height>
+              <width>601</width>
+              <height>640</height>
              </rect>
             </property>
             <layout class="QVBoxLayout" name="verticalLayout_21">
@@ -5428,5 +5560,21 @@
     </hint>
    </hints>
   </connection>
+  <connection>
+   <sender>connectAccount2</sender>
+   <signal>clicked()</signal>
+   <receiver>connectAccount</receiver>
+   <slot>click()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>484</x>
+     <y>142</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>454</x>
+     <y>87</y>
+    </hint>
+   </hints>
+  </connection>
  </connections>
 </ui>

+ 147 - 1
UI/window-basic-auto-config.cpp

@@ -12,6 +12,17 @@
 #include "ui_AutoConfigVideoPage.h"
 #include "ui_AutoConfigStreamPage.h"
 
+#ifdef BROWSER_AVAILABLE
+#include <browser-panel.hpp>
+#include "auth-oauth.hpp"
+#endif
+
+struct QCef;
+struct QCefCookieManager;
+
+extern QCef              *cef;
+extern QCefCookieManager *panel_cookies;
+
 #define wiz reinterpret_cast<AutoConfig*>(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<OAuthStreamKey*>(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               */

+ 11 - 0
UI/window-basic-auto-config.hpp

@@ -8,6 +8,7 @@
 #include <condition_variable>
 #include <utility>
 #include <thread>
+#include <memory>
 #include <vector>
 #include <string>
 #include <mutex>
@@ -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> 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();

+ 2 - 0
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 {

+ 145 - 0
UI/window-basic-settings-stream.cpp

@@ -5,12 +5,24 @@
 #include "window-basic-main.hpp"
 #include "qt-wrappers.hpp"
 
+#ifdef BROWSER_AVAILABLE
+#include <browser-panel.hpp>
+#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<OAuthStreamKey*>(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);
+}

+ 9 - 0
UI/window-basic-settings.hpp

@@ -28,6 +28,8 @@
 
 #include <obs.hpp>
 
+#include "auth-base.hpp"
+
 class OBSBasic;
 class QAbstractButton;
 class QComboBox;
@@ -91,6 +93,8 @@ private:
 
 	std::unique_ptr<Ui::OBSBasicSettings> ui;
 
+	std::shared_ptr<Auth> 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 */