diff --git a/CommunityToolkit.Authentication.Uwp/WindowsProvider.cs b/CommunityToolkit.Authentication.Uwp/WindowsProvider.cs index 1f603f5..b899803 100644 --- a/CommunityToolkit.Authentication.Uwp/WindowsProvider.cs +++ b/CommunityToolkit.Authentication.Uwp/WindowsProvider.cs @@ -12,6 +12,7 @@ using Windows.Security.Authentication.Web.Core; using Windows.Security.Credentials; using Windows.Storage; +using Windows.System; using Windows.UI.ApplicationSettings; namespace CommunityToolkit.Authentication @@ -197,7 +198,21 @@ public override async Task GetTokenAsync(bool silentOnly = false) } // Attempt to authenticate interactively. - authResult = await AuthenticateInteractiveAsync(_scopes); + var tcs = new TaskCompletionSource(); + var taskQueued = DispatcherQueue.GetForCurrentThread().TryEnqueue(async () => + { + var result = await AuthenticateInteractiveAsync(_scopes); + tcs.SetResult(result); + }); + + if (taskQueued) + { + authResult = await tcs.Task; + } + else + { + tcs.SetCanceled(); + } } if (authResult?.ResponseStatus == WebTokenRequestStatus.Success) @@ -241,74 +256,85 @@ public async Task ShowAccountManagementPaneAsync() throw new InvalidOperationException("A logged in account is required to display the account management pane."); } - // Build the AccountSettingsPane and configure it with available account commands. - void OnAccountCommandsRequested(AccountsSettingsPane sender, AccountsSettingsPaneCommandsRequestedEventArgs e) + var tcs = new TaskCompletionSource(); + _ = DispatcherQueue.GetForCurrentThread().TryEnqueue(async () => { - AccountsSettingsPaneEventDeferral deferral = e.GetDeferral(); - - // Apply the configured header. - var headerText = _accountsSettingsPaneConfig?.ManageAccountHeaderText; - if (!string.IsNullOrWhiteSpace(headerText)) - { - e.HeaderText = headerText; - } - - // Generate any account commands. - if (_accountsSettingsPaneConfig?.AccountCommandParameter != null) + AccountsSettingsPane pane = null; + try { - var commandParameter = _accountsSettingsPaneConfig.Value.AccountCommandParameter; - var webAccountCommand = new WebAccountCommand( - _webAccount, - async (command, args) => - { - // When the logout command is triggered, we also need to modify the state of the Provider. - if (args.Action == WebAccountAction.Remove) - { - await SignOutAsync(); - } + // GetForCurrentView may throw an exception if the current view isn't ready yet. + pane = AccountsSettingsPane.GetForCurrentView(); + pane.AccountCommandsRequested += OnAccountCommandsRequested; - commandParameter.Invoked?.Invoke(command, args); - }, - commandParameter.Actions); + // Show the AccountSettingsPane and wait for the result. + await AccountsSettingsPane.ShowManageAccountsAsync(); - e.WebAccountCommands.Add(webAccountCommand); + tcs.SetResult(true); } - - // Apply any configured setting commands. - var commands = _accountsSettingsPaneConfig?.Commands; - if (commands != null) + catch (Exception e) + { + tcs.SetException(e); + } + finally { - foreach (var command in commands) + if (pane != null) { - e.Commands.Add(command); + pane.AccountCommandsRequested -= OnAccountCommandsRequested; } } + }); - deferral.Complete(); - } + await tcs.Task; + } - AccountsSettingsPane pane = null; - try - { - // GetForCurrentView may throw an exception if the current view isn't ready yet. - pane = AccountsSettingsPane.GetForCurrentView(); - pane.AccountCommandsRequested += OnAccountCommandsRequested; + /// + /// Build the AccountSettingsPane and configure it with available account commands. + /// + /// The pane that fired the event. + /// Arguments for the AccountCommandsRequested event. + private void OnAccountCommandsRequested(AccountsSettingsPane sender, AccountsSettingsPaneCommandsRequestedEventArgs e) + { + AccountsSettingsPaneEventDeferral deferral = e.GetDeferral(); - // Show the AccountSettingsPane and wait for the result. - await AccountsSettingsPane.ShowManageAccountsAsync(); + // Apply the configured header. + var headerText = _accountsSettingsPaneConfig?.ManageAccountHeaderText; + if (!string.IsNullOrWhiteSpace(headerText)) + { + e.HeaderText = headerText; } - catch (Exception e) + + // Generate any account commands. + if (_accountsSettingsPaneConfig?.AccountCommandParameter != null) { - // TODO: Log exception - System.Diagnostics.Debug.WriteLine(e.Message); + var commandParameter = _accountsSettingsPaneConfig.Value.AccountCommandParameter; + var webAccountCommand = new WebAccountCommand( + _webAccount, + async (command, args) => + { + // When the logout command is triggered, we also need to modify the state of the Provider. + if (args.Action == WebAccountAction.Remove) + { + await SignOutAsync(); + } + + commandParameter.Invoked?.Invoke(command, args); + }, + commandParameter.Actions); + + e.WebAccountCommands.Add(webAccountCommand); } - finally + + // Apply any configured setting commands. + var commands = _accountsSettingsPaneConfig?.Commands; + if (commands != null) { - if (pane != null) + foreach (var command in commands) { - pane.AccountCommandsRequested -= OnAccountCommandsRequested; + e.Commands.Add(command); } } + + deferral.Complete(); } private async Task SetAccountAsync(WebAccount account)