Audacity 3.2.0
UserPanel.cpp
Go to the documentation of this file.
1/* SPDX-License-Identifier: GPL-2.0-or-later */
2/*!********************************************************************
3
4 Audacity: A Digital Audio Editor
5
6 UserPanel.cpp
7
8 Dmitry Vedenko
9
10**********************************************************************/
11
12#include "UserPanel.h"
13
14#include <cassert>
15
16#include <wx/button.h>
17#include <wx/sizer.h>
18#include <wx/stattext.h>
19
20#ifdef HAS_CUSTOM_URL_HANDLING
21# include "URLSchemesRegistry.h"
22#endif
23
25
26#include "OAuthService.h"
27#include "ServiceConfig.h"
28#include "UserService.h"
29
30#include "CodeConversions.h"
31#include "ExportUtils.h"
32
33#include "AllThemeResources.h"
34#include "Theme.h"
35
36#include "UserImage.h"
37
38#include "MemoryX.h"
39
40#include "HelpSystem.h"
41
43{
44
45namespace
46{
47const wxSize avatarSize = { 32, 32 };
48const auto anonymousText = XO("Account not linked");
49} // namespace
50
52 const ServiceConfig& serviceConfig, OAuthService& authService,
53 UserService& userService, bool hasLinkButton, AudiocomTrace trace,
54 wxWindow* parent, const wxPoint& pos, const wxSize& size)
55 : wxPanelWrapper { parent, wxID_ANY, pos, size }
56 , mServiceConfig { serviceConfig }
57 , mAuthService { authService }
58 , mUserService { userService }
59 , mAudiocomTrace { trace }
60 , mUserDataChangedSubscription { userService.Subscribe(
61 [this](const auto&) { UpdateUserData(); }) }
62{
63 mUserImage = safenew UserImage(this, avatarSize);
64 mUserImage->SetLabel(anonymousText); // for screen readers
65 mUserName =
66 safenew wxStaticText(this, wxID_ANY, anonymousText.Translation());
67 mLinkButton =
68 safenew wxButton(this, wxID_ANY, XXO("&Link Account").Translation());
69 mLinkButton->Bind(wxEVT_BUTTON, [this](auto) { OnLinkButtonPressed(); });
70 mLinkButton->Show(hasLinkButton);
71
72 auto sizer = safenew wxBoxSizer { wxHORIZONTAL };
73
74 sizer->Add(mUserImage, 0, wxALIGN_CENTER_VERTICAL);
75 sizer->AddSpacer(8);
76 sizer->Add(mUserName, 0, wxALIGN_CENTER_VERTICAL);
77 sizer->AddStretchSpacer();
78 sizer->Add(mLinkButton, 0, wxALIGN_CENTER_VERTICAL);
79
80 SetSizerAndFit(sizer);
81 UpdateUserData();
82}
83
84UserPanel::~UserPanel() = default;
85
86bool UserPanel::IsAuthorized() const
87{
88 return mIsAuthorized;
89}
90
91void UserPanel::OnStateChaged(bool isAuthorized)
92{
93 if (mIsAuthorized == isAuthorized)
94 return;
95
96 mIsAuthorized = isAuthorized;
97 Publish(UserPanelStateChangedMessage { isAuthorized });
98}
99
100void UserPanel::UpdateUserData()
101{
102 Freeze();
103
104 auto layoutUpdater = finally(
105 [this]()
106 {
107 mLinkButton->Fit();
108
109 Layout();
110 Thaw();
111
112 auto parent = GetParent();
113
114 if (parent != nullptr)
115 parent->Refresh();
116 else
117 Refresh();
118 });
119
120 auto& oauthService = GetOAuthService();
121
122 if (!oauthService.HasRefreshToken())
123 {
124 SetAnonymousState();
125 return;
126 }
127
128 if (!oauthService.HasAccessToken())
129 oauthService.ValidateAuth({}, mAudiocomTrace, true);
130
131 auto& userService = GetUserService();
132
133 if (userService.GetUserSlug().empty())
134 {
135 SetAnonymousState();
136 return;
137 }
138
139 const auto displayName = userService.GetDisplayName();
140
141 if (!displayName.empty()) {
142 mUserName->SetLabel(displayName);
143 mUserImage->wxPanel::SetLabel(displayName); // for screen readers
144 }
145
146 const auto avatarPath = userService.GetAvatarPath();
147
148 if (!avatarPath.empty())
149 mUserImage->SetBitmap(avatarPath);
150 else
151 mUserImage->SetBitmap(theTheme.Bitmap(bmpAnonymousUser));
152
153 mLinkButton->SetLabel(XXO("&Unlink Account").Translation());
154
155 OnStateChaged(true);
156}
157
158void UserPanel::OnLinkButtonPressed()
159{
160 auto& oauthService = GetOAuthService();
161
162 if (oauthService.HasAccessToken())
163 oauthService.UnlinkAccount(mAudiocomTrace);
164 else
165 {
167 mServiceConfig.GetOAuthLoginPage(mAudiocomTrace)) });
168
169#ifdef HAS_CUSTOM_URL_HANDLING
171#endif
172 {
173 LinkWithTokenDialog dlg(mAudiocomTrace, this);
174 dlg.ShowModal();
175 }
176 }
177}
178
179void UserPanel::SetAnonymousState()
180{
181 mUserName->SetLabel(anonymousText.Translation());
182 mUserImage->SetBitmap(theTheme.Bitmap(bmpAnonymousUser));
183 mUserImage->SetLabel(anonymousText); // for screen readers
184 mLinkButton->SetLabel(XXO("&Link Account").Translation());
185
186 OnStateChaged(false);
187}
188
189} // namespace audacity::cloud::audiocom
Declare functions to perform UTF-8 to std::wstring conversions.
AudiocomTrace
Definition: ExportUtils.h:27
XO("Cut/Copy/Paste")
XXO("&Cut/Copy/Paste Toolbar")
#define safenew
Definition: MemoryX.h:10
THEME_API Theme theTheme
Definition: Theme.cpp:82
wxBitmap & Bitmap(int iIndex)
bool IsURLHandlingSupported() const noexcept
Returns true, if Audacity can handle custom URLs.
static URLSchemesRegistry & Get()
Retrieves the registry instance.
Service responsible for OAuth authentication against the audio.com service.
Definition: OAuthService.h:43
Configuration for the audio.com.
Definition: ServiceConfig.h:25
UserPanel(const ServiceConfig &serviceConfig, OAuthService &authService, UserService &userService, bool hasLinkButton, AudiocomTrace, wxWindow *parent=nullptr, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize)
Definition: UserPanel.cpp:51
Service for providing information about the user profile.
Definition: UserService.h:28
void SetLabel(const TranslatableString &title)
bool OpenInDefaultBrowser(const wxString &url)
Open an URL in default browser.
Definition: BasicUI.cpp:246
UserService & GetUserService()
OAuthService & GetOAuthService()
Returns the instance of the OAuthService.
wxString ToWXString(const std::string &str)