Skip to content

Commit 3a70f2b

Browse files
Release/1.0.0 rc8 (#22)
* Adds 'Explore Marketplace' button to no-products screen, fixes outgoing link to auto-login user. * Changes default/temporary file storage to AppData/Local/Elgato/MarketplaceConnect * Adds 'Signing in' screen.
1 parent 2e8cbfa commit 3a70f2b

12 files changed

+129
-29
lines changed

buildspec.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
"versionMinor": 0,
4343
"versionPatch": 0,
4444
"buildNumber": 0,
45-
"releaseType": "rc7",
45+
"releaseType": "rc8",
4646
"author": "Elgato",
4747
"website": "https://elgato.com",
4848
"email": "support@elgato.com",

data/locale/en-US.ini

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,14 @@ MarketplaceWindow.DownloadButton.Tooltip="Click to Download"
99
MarketplaceWindow.PurchasedTab="Products"
1010
MarketplaceWindow.Purchased.NoPurchasesTitle="You don't own any scene collection products yet"
1111
MarketplaceWindow.Purchased.NoPurchasesSubtitle="Your digital assets from Marketplace will appear here"
12+
MarketplaceWindow.Purchased.OpenMarketplaceButton="Explore Marketplace"
1213
MarketplaceWindow.LoginNeeded.Title="Sign in to get started"
1314
MarketplaceWindow.LoginNeeded.Subtitle="First off, let's connect your Marketplace account with OBS Studio"
1415
MarketplaceWindow.LoginError.Title="Login Error"
1516
MarketplaceWindow.LoginError.Subtitle="There was an error logging you in. Please click the Log In button above to try again."
17+
MarketplaceWindow.LoggingIn.Title="Signing you in"
18+
MarketplaceWindow.LoggingIn.Subtitle="Please sign in using the browser window that should have appeared. If no browser window appeared, or you accidentally closed it, click below to try again."
19+
MarketplaceWindow.LoggingIn.TryAgain="Try Again"
1620
MarketplaceWindow.ConnectionError.Title="Connection Error"
1721
MarketplaceWindow.ConnectionError.Subtitle="Could not connect to the server. (please check your network connection)"
1822
MarketplaceWindow.Loading.Title="Loading Your Purchased Products..."

src/api.cpp

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ with this program. If not, see <https://www.gnu.org/licenses/>
1818

1919
#include "api.hpp"
2020
#include "downloader.h"
21+
#include "util.h"
22+
#include "elgato-cloud-data.hpp"
2123
#include <plugin-support.h>
2224

2325
#include <fstream>
@@ -97,7 +99,7 @@ void MarketplaceApi::setUserDetails(nlohmann::json &data)
9799
_avatarUrl = it["asset_cdn"];
98100
_hasAvatar = true;
99101
std::string avatarPath = QDir::homePath().toStdString();
100-
avatarPath += "/AppData/Local/Elgato/DeepLinking/Thumbnails";
102+
avatarPath += "/AppData/Local/Elgato/MarketplaceConnect/Thumbnails";
101103
os_mkdirs(avatarPath.c_str());
102104

103105
auto found = _avatarUrl.find_last_of("/");
@@ -132,15 +134,14 @@ void MarketplaceApi::_downloadAvatar()
132134
_avatarDownloading = true;
133135
_avatarReady = false;
134136
std::string savePath = QDir::homePath().toStdString();
135-
savePath += "/AppData/Local/Elgato/DeepLinking/Thumbnails/";
137+
savePath += "/AppData/Local/Elgato/MarketplaceConnect/Thumbnails/";
136138
std::shared_ptr<Downloader> dl = Downloader::getInstance("");
137139
dl->Enqueue(_avatarUrl, savePath, MarketplaceApi::AvatarProgress, MarketplaceApi::AvatarDownloadComplete,
138140
this);
139141
}
140142

141143
void MarketplaceApi::AvatarDownloadComplete(std::string filename, void* data)
142144
{
143-
obs_log(LOG_INFO, "Avatar Downloaded! %s", filename.c_str());
144145
auto api = static_cast<MarketplaceApi*>(data);
145146
api->_avatarReady = true;
146147
api->_avatarPath = filename;
@@ -163,4 +164,22 @@ void MarketplaceApi::AvatarProgress(void* ptr, bool finished,
163164
}
164165
}
165166

167+
void MarketplaceApi::OpenStoreInBrowser() const
168+
{
169+
auto ec = GetElgatoCloud();
170+
auto accessToken = ec->GetAccessToken();
171+
std::string storeUrl =
172+
_storeUrl +
173+
"/obs/scene-collections?utm_source=mp_connect&utm_medium=direct_software&utm_campaign=v_1.0";
174+
std::string url;
175+
if (accessToken != "") {
176+
std::string storeUrlEnc = url_encode(storeUrl);
177+
url = _storeUrl + "/api/auth/login?token=" + accessToken + "&redirect=" + storeUrlEnc;
178+
}
179+
else {
180+
url = storeUrl;
181+
}
182+
ShellExecuteA(NULL, NULL, url.c_str(), NULL, NULL, SW_SHOW);
183+
}
184+
166185
} // namespace elgatocloud

src/api.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ class MarketplaceApi : public QObject {
5454
static void AvatarDownloadComplete(std::string filename, void* data);
5555
void setUserDetails(nlohmann::json &data);
5656
void logOut();
57+
void OpenStoreInBrowser() const;
5758

5859
signals:
5960
void AvatarDownloaded();

src/elgato-cloud-data.cpp

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -92,14 +92,25 @@ void ElgatoCloud::Thread()
9292
// Here is our Elgato Cloud loop
9393
}
9494

95+
std::string ElgatoCloud::GetAccessToken()
96+
{
97+
if (!loggedIn) {
98+
return "";
99+
}
100+
_TokenRefresh(false, false);
101+
if (loggedIn) {
102+
return _accessToken;
103+
} else { // Our refresh token has expired, we're not really logged in.
104+
return "";
105+
}
106+
}
107+
95108
void ElgatoCloud::_TokenRefresh(bool loadData, bool loadUserDetails)
96109
{
97110
const auto now = std::chrono::system_clock::now();
98111
const auto epoch = now.time_since_epoch();
99112
const auto seconds =
100113
std::chrono::duration_cast<std::chrono::seconds>(epoch);
101-
obs_log(LOG_INFO, "Token Refresh? %i < %i", seconds.count(),
102-
_accessTokenExpiration);
103114
if (seconds.count() < _accessTokenExpiration) {
104115
loggedIn = true;
105116
loading = loadData;
@@ -119,7 +130,6 @@ void ElgatoCloud::_TokenRefresh(bool loadData, bool loadUserDetails)
119130
std::string url = api->authUrl();
120131
url += "/auth/realms/mp/protocol/openid-connect/token?";
121132
url += encodeddata;
122-
obs_log(LOG_INFO, "Token Refresh Called");
123133
auto response = fetch_string_from_post(url, encodeddata);
124134
try {
125135
auto responseJson = nlohmann::json::parse(response);
@@ -141,7 +151,6 @@ void ElgatoCloud::_Listen()
141151
{
142152
_listenThread = std::thread([this]() {
143153
listen_on_pipe("elgato_cloud", [this](std::string d) {
144-
obs_log(LOG_INFO, "Got Deeplink %s", d.c_str());
145154
if (d.find("elgatolink://auth") == 0) {
146155
if (mainWindowOpen && window) {
147156
QMetaObject::invokeMethod(
@@ -155,7 +164,6 @@ void ElgatoCloud::_Listen()
155164
});
156165
}
157166

158-
obs_log(LOG_INFO, "auth detected");
159167
std::unique_lock lock(m);
160168
if (!authorizing) {
161169
return;
@@ -207,11 +215,13 @@ void ElgatoCloud::_Listen()
207215
[this]() {
208216
loginError =
209217
true;
218+
loggingIn = false;
210219
window->setLoggedIn();
211220
});
212221
}
213222
} else {
214223
loginError = false;
224+
loggingIn = false;
215225
_ProcessLogin(responseJson);
216226
}
217227
authorizing = false;
@@ -245,6 +255,10 @@ void ElgatoCloud::_Initialize()
245255

246256
void ElgatoCloud::StartLogin()
247257
{
258+
loggingIn = true;
259+
if (mainWindowOpen && window) {
260+
window->setLoggedIn();
261+
}
248262
std::unique_lock lock(m);
249263
union {
250264
uint32_t uint[8];
@@ -349,8 +363,6 @@ void ElgatoCloud::LoadPurchasedProducts()
349363
api_url +=
350364
"/my-products?extension=scene-collections&offset=0&limit=100";
351365
auto productsResponse = fetch_string_from_get(api_url, _accessToken);
352-
obs_log(LOG_INFO, "url: %s", api_url.c_str());
353-
obs_log(LOG_INFO, "Products: %s", productsResponse.c_str());
354366
products.clear();
355367
try {
356368
auto productsJson = nlohmann::json::parse(productsResponse);
@@ -428,9 +440,6 @@ void ElgatoCloud::_ProcessLogin(nlohmann::json &loginData, bool loadData)
428440

429441
_SaveState();
430442

431-
obs_log(LOG_INFO, "Access and refresh token stored.");
432-
obs_log(LOG_INFO, "%s", _accessToken.c_str());
433-
434443
loggedIn = true;
435444
loading = true;
436445
} catch (const nlohmann::json::out_of_range &e) {
@@ -453,7 +462,6 @@ void ElgatoCloud::_LoadUserData(bool loadData)
453462
api_url += "/user";
454463
auto userResponse =
455464
fetch_string_from_get(api_url, _accessToken);
456-
obs_log(LOG_INFO, "User Response: %s", userResponse.c_str());
457465
auto userData = nlohmann::json::parse(userResponse);
458466
api->setUserDetails(userData);
459467
if (mainWindowOpen && window) {

src/elgato-cloud-data.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ class ElgatoCloud {
5656
obs_data_t *GetConfig();
5757
void SetSkipVersion(std::string version);
5858
void SaveConfig();
59+
std::string GetAccessToken();
5960
nlohmann::json GetPurchaseDownloadLink(std::string variantId);
6061

6162
obs_module_t *GetModule();
@@ -64,6 +65,7 @@ class ElgatoCloud {
6465
bool authorizing = false;
6566
bool connectionError = false;
6667
bool loginError = false;
68+
bool loggingIn = false;
6769

6870
void Thread();
6971
bool mainWindowOpen = false;

src/elgato-cloud-window.cpp

Lines changed: 59 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -297,9 +297,6 @@ WindowToolBar::WindowToolBar(QWidget *parent) : QWidget(parent)
297297
imageBaseDir += "/images/";
298298

299299
auto api = MarketplaceApi::getInstance();
300-
std::string storeUrl =
301-
api->storeUrl() +
302-
"/obs/scene-collections?utm_source=mp_connect&utm_medium=direct_software&utm_campaign=v_1.0";
303300

304301
QPalette pal = QPalette();
305302
pal.setColor(QPalette::Window, "#151515");
@@ -349,9 +346,8 @@ WindowToolBar::WindowToolBar(QWidget *parent) : QWidget(parent)
349346
_storeButton->setStyleSheet(buttonStyle);
350347
_storeButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
351348

352-
connect(_storeButton, &QPushButton::pressed, this, [this, storeUrl]() {
353-
ShellExecuteA(NULL, NULL, storeUrl.c_str(), NULL, NULL,
354-
SW_SHOW);
349+
connect(_storeButton, &QPushButton::pressed, this, [this, api]() {
350+
api->OpenStoreInBrowser();
355351
});
356352
_layout->addWidget(_storeButton);
357353

@@ -470,6 +466,7 @@ void ProductGrid::enableDownload()
470466

471467
OwnedProducts::OwnedProducts(QWidget *parent) : QWidget(parent)
472468
{
469+
auto api = MarketplaceApi::getInstance();
473470
_layout = new QHBoxLayout(this);
474471
_sideMenu = new QListWidget(this);
475472
_sideMenu->addItem(obs_module_text("MarketplaceWindow.PurchasedTab"));
@@ -521,6 +518,22 @@ OwnedProducts::OwnedProducts(QWidget *parent) : QWidget(parent)
521518
npSubTitle->setStyleSheet("QLabel {font-size: 13pt;}");
522519
npSubTitle->setAlignment(Qt::AlignCenter);
523520
npLayout->addWidget(npSubTitle);
521+
522+
auto hLayout = new QHBoxLayout();
523+
auto mpButton = new QPushButton(this);
524+
mpButton->setText(
525+
obs_module_text("MarketplaceWindow.Purchased.OpenMarketplaceButton"));
526+
mpButton->setStyleSheet(
527+
"QPushButton {font-size: 12pt; border-radius: 8px; padding: 8px; background-color: #232323; border: none; } "
528+
"QPushButton:hover {background-color: #444444; }");
529+
connect(mpButton, &QPushButton::clicked, this, [this, api]() {
530+
api->OpenStoreInBrowser();
531+
});
532+
hLayout->addStretch();
533+
hLayout->addWidget(mpButton);
534+
hLayout->addStretch();
535+
536+
npLayout->addLayout(hLayout);
524537
npLayout->addStretch();
525538
scroll->setWidget(_purchased);
526539
_content->addWidget(scroll);
@@ -556,6 +569,7 @@ ElgatoCloudWindow::ElgatoCloudWindow(QWidget *parent) : QDialog(parent)
556569
ElgatoCloudWindow::~ElgatoCloudWindow()
557570
{
558571
if (elgatoCloud) {
572+
elgatoCloud->loggingIn = false;
559573
elgatoCloud->mainWindowOpen = false;
560574
elgatoCloud->window = nullptr;
561575
}
@@ -608,6 +622,9 @@ void ElgatoCloudWindow::initialize()
608622
new LoginError(this); // Login error widget, id: 4
609623
_stackedContent->addWidget(loginErrorWidget);
610624

625+
auto loggingInWidget = new LoggingIn(this); // logging in widget, id: 5
626+
_stackedContent->addWidget(loggingInWidget);
627+
611628
mainLayout->addWidget(_stackedContent);
612629
_mainWidget->setLayout(mainLayout);
613630

@@ -637,6 +654,8 @@ void ElgatoCloudWindow::setLoggedIn()
637654
_toolbar->disableLogout(false);
638655
if (elgatoCloud->connectionError) {
639656
_stackedContent->setCurrentIndex(2);
657+
} else if (elgatoCloud->loggingIn) {
658+
_stackedContent->setCurrentIndex(5);
640659
} else if (elgatoCloud->loginError) {
641660
_stackedContent->setCurrentIndex(4);
642661
} else if (!elgatoCloud->loggedIn) {
@@ -808,7 +827,40 @@ LoginNeeded::LoginNeeded(QWidget *parent) : QWidget(parent)
808827
auto loginButton = new QPushButton(this);
809828
loginButton->setText(
810829
obs_module_text("MarketplaceWindow.LoginButton.LogIn"));
811-
loginButton->setHidden(elgatoCloud->loggedIn);
830+
loginButton->setStyleSheet(
831+
"QPushButton {font-size: 12pt; border-radius: 8px; padding: 8px; background-color: #232323; border: none; } "
832+
"QPushButton:hover {background-color: #444444; }");
833+
connect(loginButton, &QPushButton::clicked, this,
834+
[this]() { elgatoCloud->StartLogin(); });
835+
hLayout->addStretch();
836+
hLayout->addWidget(loginButton);
837+
hLayout->addStretch();
838+
layout->addStretch();
839+
layout->addWidget(login);
840+
layout->addWidget(loginSub);
841+
layout->addLayout(hLayout);
842+
layout->addStretch();
843+
}
844+
845+
LoggingIn::LoggingIn(QWidget* parent) : QWidget(parent)
846+
{
847+
auto layout = new QVBoxLayout(this);
848+
849+
auto login = new QLabel(this);
850+
login->setText(obs_module_text("MarketplaceWindow.LoggingIn.Title"));
851+
login->setStyleSheet("QLabel {font-size: 18pt;}");
852+
login->setAlignment(Qt::AlignCenter);
853+
854+
auto loginSub = new QLabel(this);
855+
loginSub->setText(
856+
obs_module_text("MarketplaceWindow.LoggingIn.Subtitle"));
857+
loginSub->setWordWrap(true);
858+
loginSub->setAlignment(Qt::AlignCenter);
859+
860+
auto hLayout = new QHBoxLayout();
861+
auto loginButton = new QPushButton(this);
862+
loginButton->setText(
863+
obs_module_text("MarketplaceWindow.LoggingIn.TryAgain"));
812864
loginButton->setStyleSheet(
813865
"QPushButton {font-size: 12pt; border-radius: 8px; padding: 8px; background-color: #232323; border: none; } "
814866
"QPushButton:hover {background-color: #444444; }");

src/elgato-cloud-window.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,12 @@ class LoginError : public QWidget {
196196
LoginError(QWidget* parent);
197197
};
198198

199+
class LoggingIn : public QWidget {
200+
Q_OBJECT
201+
public:
202+
LoggingIn(QWidget* parent);
203+
};
204+
199205
class ConnectionError : public QWidget {
200206
Q_OBJECT
201207
public:

src/elgato-product.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,11 @@ namespace elgatocloud {
4646
ElgatoProduct::ElgatoProduct(nlohmann::json &productData) : _fileSize(0)
4747
{
4848
thumbnailPath = QDir::homePath().toStdString();
49-
thumbnailPath += "/AppData/Local/Elgato/DeepLinking/Thumbnails";
49+
thumbnailPath += "/AppData/Local/Elgato/MarketplaceConnect/Thumbnails";
5050
os_mkdirs(thumbnailPath.c_str());
5151

5252
std::string savePath = QDir::homePath().toStdString();
53-
savePath += "/AppData/Local/Elgato/DeepLinking/Downloads";
53+
savePath += "/AppData/Local/Elgato/MarketplaceConnect/Downloads";
5454
os_mkdirs(savePath.c_str());
5555

5656
_thumbnailReady = false;
@@ -119,7 +119,7 @@ bool ElgatoProduct::DownloadProduct()
119119
}
120120

121121
std::string savePath = QDir::homePath().toStdString();
122-
savePath += "/AppData/Local/Elgato/DeepLinking/Downloads/";
122+
savePath += "/AppData/Local/Elgato/MarketplaceConnect/Downloads/";
123123
os_mkdirs(savePath.c_str());
124124

125125
std::shared_ptr<Downloader> dl = Downloader::getInstance("");
@@ -130,7 +130,7 @@ bool ElgatoProduct::DownloadProduct()
130130
void ElgatoProduct::_downloadThumbnail()
131131
{
132132
std::string savePath = QDir::homePath().toStdString();
133-
savePath += "/AppData/Local/Elgato/DeepLinking/Thumbnails/";
133+
savePath += "/AppData/Local/Elgato/MarketplaceConnect/Thumbnails/";
134134
std::shared_ptr<Downloader> dl = Downloader::getInstance("");
135135
dl->Enqueue(thumbnailUrl, savePath, ElgatoProduct::ThumbnailProgress, ElgatoProduct::SetThumbnail,
136136
this);

src/scene-bundle.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ void SceneBundle::ToCollection(std::string collection_name,
170170
bfree(ccpath);
171171

172172
std::string savePath = QDir::homePath().toStdString();
173-
savePath += "/AppData/Local/Elgato/DeepLinking/SCBackups/";
173+
savePath += "/AppData/Local/Elgato/MarketplaceConnect/SCBackups/";
174174
os_mkdirs(savePath.c_str());
175175

176176
std::string backupFilename = get_current_scene_collection_filename();

0 commit comments

Comments
 (0)