From 00355586803eb40a01f37332ebb432d919d74113 Mon Sep 17 00:00:00 2001 From: Dmitry Vedenko Date: Mon, 29 May 2023 17:08:44 +0300 Subject: [PATCH] Fixes the audio.com upload flow 1. Anonymous uploads are allowed once again 2. After the upload is completed URL is opened in the browser immediately --- .../lib-cloud-audiocom/ServiceConfig.cpp | 8 ++- libraries/lib-cloud-audiocom/ServiceConfig.h | 2 + .../lib-cloud-audiocom/UploadService.cpp | 11 +++- libraries/lib-cloud-audiocom/UploadService.h | 4 ++ src/cloud/audiocom/ShareAudioDialog.cpp | 57 ++++--------------- src/cloud/audiocom/ShareAudioDialog.h | 7 +-- 6 files changed, 36 insertions(+), 53 deletions(-) diff --git a/libraries/lib-cloud-audiocom/ServiceConfig.cpp b/libraries/lib-cloud-audiocom/ServiceConfig.cpp index 71fec36c3880..9e5af8896f11 100644 --- a/libraries/lib-cloud-audiocom/ServiceConfig.cpp +++ b/libraries/lib-cloud-audiocom/ServiceConfig.cpp @@ -46,11 +46,17 @@ std::string ServiceConfig::GetAPIUrl(std::string_view apiURI) const std::string ServiceConfig::GetFinishUploadPage( std::string_view audioID, std::string_view token) const { - return "http://audio.com/audacity/upload?audioId=" + std::string(audioID) + + return "https://audio.com/audacity/upload?audioId=" + std::string(audioID) + "&token=" + std::string(token) + "&clientId=" + std::string(GetOAuthClientID()); } +std::string ServiceConfig::GetAudioURL( + std::string_view userSlug, std::string_view audioSlug) const +{ + return "https://audio.com/" + std::string(userSlug) + "/" + std::string(audioSlug) + "/edit"; +} + std::chrono::milliseconds ServiceConfig::GetProgressCallbackTimeout() const { return std::chrono::seconds(3); diff --git a/libraries/lib-cloud-audiocom/ServiceConfig.h b/libraries/lib-cloud-audiocom/ServiceConfig.h index 8eaeb81036ab..092fb4c5ef76 100644 --- a/libraries/lib-cloud-audiocom/ServiceConfig.h +++ b/libraries/lib-cloud-audiocom/ServiceConfig.h @@ -35,6 +35,8 @@ class CLOUD_AUDIOCOM_API ServiceConfig final std::string GetAPIUrl(std::string_view apiURI) const; //! Helper to construct the page URL for the anonymous upload last stage std::string GetFinishUploadPage(std::string_view audioID, std::string_view token) const; + //! Helper to construct the page URL for the authorised upload + std::string GetAudioURL(std::string_view userSlug, std::string_view audioSlug) const; //! Timeout between progress callbacks std::chrono::milliseconds GetProgressCallbackTimeout() const; //! Preferred audio format diff --git a/libraries/lib-cloud-audiocom/UploadService.cpp b/libraries/lib-cloud-audiocom/UploadService.cpp index 071dd19a5329..633ea8901871 100644 --- a/libraries/lib-cloud-audiocom/UploadService.cpp +++ b/libraries/lib-cloud-audiocom/UploadService.cpp @@ -206,6 +206,7 @@ struct AudiocomUploadOperation final : std::string mAudioID; std::string mUploadToken; + std::string mUserName; std::string mAudioSlug; @@ -264,10 +265,14 @@ struct AudiocomUploadOperation final : if (mCompletedCallback) { + const auto uploadURL = + mAuthToken.empty() ? + mServiceConfig.GetFinishUploadPage(mAudioID, mUploadToken) : + mServiceConfig.GetAudioURL(mUserName, mAudioSlug); mCompletedCallback( { UploadOperationCompleted::Result::Success, - UploadSuccessfulPayload { mAudioID, mAudioSlug } }); + UploadSuccessfulPayload { mAudioID, mAudioSlug, mUploadToken, uploadURL } }); } mProgressCallback = {}; @@ -395,6 +400,8 @@ struct AudiocomUploadOperation final : if (extra.HasMember("token")) mUploadToken = extra["token"].GetString(); + + mUserName = extra["audio"]["username"].GetString(); } const auto encType = document.HasMember("enctype") ? @@ -579,7 +586,7 @@ UploadOperationHandle UploadService::Upload( mServiceConfig, fileName, projectName, isPublic, std::move(completedCallback), std::move(progressCallback)); - mOAuthService.ValidateAuth([operation](std::string_view authToken) + mOAuthService.ValidateAuth([operation, this](std::string_view authToken) { operation->InitiateUpload(authToken); }); return UploadOperationHandle { operation }; diff --git a/libraries/lib-cloud-audiocom/UploadService.h b/libraries/lib-cloud-audiocom/UploadService.h index 23aa20080149..55f61e3427d7 100644 --- a/libraries/lib-cloud-audiocom/UploadService.h +++ b/libraries/lib-cloud-audiocom/UploadService.h @@ -43,6 +43,10 @@ struct CLOUD_AUDIOCOM_API UploadSuccessfulPayload final std::string audioId; //! "Slug" to be used for shareable URL construction std::string audioSlug; + //! Upload token, if any + std::string uploadToken; + //! URL to the uploaded audio + std::string audioUrl; }; //! Message that is sent when upload is finished. diff --git a/src/cloud/audiocom/ShareAudioDialog.cpp b/src/cloud/audiocom/ShareAudioDialog.cpp index df55f3a32ca4..7b4b68281a3e 100644 --- a/src/cloud/audiocom/ShareAudioDialog.cpp +++ b/src/cloud/audiocom/ShareAudioDialog.cpp @@ -169,7 +169,6 @@ ShareAudioDialog::ShareAudioDialog(AudacityProject& project, wxWindow* parent) parent, wxID_ANY, XO("Share Audio"), wxDefaultPosition, { 480, 250 }, wxDEFAULT_DIALOG_STYLE) , mProject(project) - , mInitialStatePanel(*this) , mServices(std::make_unique()) { GetAuthorizationHandler().PushSuppressDialogs(); @@ -240,7 +239,6 @@ void ShareAudioDialog::Populate(ShuttleGui& s) mContinueButton = s.AddButton(XXO("C&ontinue")); mContinueButton->Bind(wxEVT_BUTTON, [this](auto) { OnContinue(); }); - mContinueButton->Enable(mIsAuthorised); } s.EndHorizontalLay(); } @@ -436,28 +434,8 @@ void ShareAudioDialog::StartUploadProcess() void ShareAudioDialog::HandleUploadSucceeded( const UploadSuccessfulPayload& payload) { - mProgressPanel.timePanel->Hide(); - mProgressPanel.title->SetLabel(XO("Upload complete!").Translation()); - mProgressPanel.info->Show(); - - mProgressPanel.info->SetLabel( - "By pressing continue, you will be taken to audio.com and given a shareable link."); - mProgressPanel.info->Wrap(mProgressPanel.root->GetSize().GetWidth()); - - mContinueAction = [this, slug = std::string(payload.audioSlug)]() - { - EndModal(wxID_CLOSE); - auto url = wxString::Format( - "https://audio.com/%s/%s/edit", GetUserService().GetUserSlug(), - audacity::ToWXString(slug)); - - OpenInDefaultBrowser(url); - }; - - mContinueButton->Show(); - - Layout(); - Fit(); + EndModal(wxID_CLOSE); + OpenInDefaultBrowser(wxString { payload.audioUrl }); } void ShareAudioDialog::HandleUploadFailed(const UploadFailedPayload& payload) @@ -466,12 +444,7 @@ void ShareAudioDialog::HandleUploadFailed(const UploadFailedPayload& payload) TranslatableString message; - if (payload.status == 401) - { - message = XO( - "We are unable to upload this file. Please try again and make sure to link to your audio.com account before uploading."); - } - else + if (!payload.message.empty()) { auto details = payload.message; @@ -480,6 +453,11 @@ void ShareAudioDialog::HandleUploadFailed(const UploadFailedPayload& payload) message = XO("Error: %s").Format(details); } + else + { + message = XO( + "We are unable to upload this file. Please try again and make sure to link to your audio.com account before uploading."); + } BasicUI::ShowErrorDialog( {}, XO("Upload error"), @@ -574,9 +552,8 @@ void ShareAudioDialog::UpdateProgress(uint64_t current, uint64_t total) std::chrono::duration_cast(remains)); } -ShareAudioDialog::InitialStatePanel::InitialStatePanel(ShareAudioDialog& parent) - : parent { parent } - , mUserDataChangedSubscription( +ShareAudioDialog::InitialStatePanel::InitialStatePanel() + : mUserDataChangedSubscription( GetUserService().Subscribe([this](const auto&) { UpdateUserData(); })) { } @@ -709,14 +686,9 @@ void ShareAudioDialog::InitialStatePanel::UpdateUserData() avatar->SetBitmap(theTheme.Bitmap(bmpAnonymousUser)); oauthButton->SetLabel(XXO("&Unlink Account").Translation()); - - parent.mIsAuthorised = true; - + anonInfoPanel->Hide(); authorizedInfoPanel->Show(); - - if (parent.mContinueButton != nullptr) - parent.mContinueButton->Enable(); } void ShareAudioDialog::InitialStatePanel::OnLinkButtonPressed() @@ -741,18 +713,13 @@ void ShareAudioDialog::InitialStatePanel::OnLinkButtonPressed() } void ShareAudioDialog::InitialStatePanel::SetAnonymousState() -{ - parent.mIsAuthorised = false; - +{ name->SetLabel(XO("Anonymous").Translation()); avatar->SetBitmap(theTheme.Bitmap(bmpAnonymousUser)); oauthButton->SetLabel(XXO("&Link Account").Translation()); anonInfoPanel->Show(); authorizedInfoPanel->Hide(); - - if (parent.mContinueButton != nullptr) - parent.mContinueButton->Enable(false); } void ShareAudioDialog::ProgressPanel::PopulateProgressPanel(ShuttleGui& s) diff --git a/src/cloud/audiocom/ShareAudioDialog.h b/src/cloud/audiocom/ShareAudioDialog.h index a6ad83715370..1dc57742fab3 100644 --- a/src/cloud/audiocom/ShareAudioDialog.h +++ b/src/cloud/audiocom/ShareAudioDialog.h @@ -68,9 +68,7 @@ class ShareAudioDialog final : struct InitialStatePanel final { - explicit InitialStatePanel(ShareAudioDialog& parent); - - ShareAudioDialog& parent; + InitialStatePanel(); wxWindow* root { nullptr }; @@ -126,8 +124,7 @@ class ShareAudioDialog final : wxString mFilePath; std::function mContinueAction; - - bool mIsAuthorised { false }; + bool mInProgress { false }; }; } // namespace cloud::audiocom