Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 23 additions & 5 deletions CommunityToolkit.Authentication.Uwp/AccountsSettingsPaneConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,24 +13,42 @@ namespace CommunityToolkit.Authentication
public struct AccountsSettingsPaneConfig
{
/// <summary>
/// Gets or sets the header text for the accounts settings pane.
/// Gets or sets the header text for the add accounts settings pane.
/// </summary>
public string HeaderText { get; set; }
public string AddAccountHeaderText { get; set; }

/// <summary>
/// Gets or sets the header text for the manage accounts settings pane.
/// </summary>
public string ManageAccountHeaderText { get; set; }

/// <summary>
/// Gets or sets the SettingsCommand collection for the account settings pane.
/// </summary>
public IList<SettingsCommand> Commands { get; set; }

/// <summary>
/// Gets or sets the WebAccountCommandParameter collection for the account settings pane.
/// </summary>
public WebAccountCommandParameter AccountCommandParameter { get; set; }

/// <summary>
/// Initializes a new instance of the <see cref="AccountsSettingsPaneConfig"/> struct.
/// </summary>
/// <param name="headerText">The header text for the accounts settings pane.</param>
/// <param name="addAccountHeaderText">The header text for the add accounts settings pane.</param>
/// <param name="manageAccountHeaderText">The header text for the manage accounts settings pane.</param>
/// <param name="commands">The SettingsCommand collection for the account settings pane.</param>
public AccountsSettingsPaneConfig(string headerText = null, IList<SettingsCommand> commands = null)
/// <param name="accountCommandParameter">The WebAccountCommandParameter for the account settings pane.</param>
public AccountsSettingsPaneConfig(
string addAccountHeaderText = null,
string manageAccountHeaderText = null,
IList<SettingsCommand> commands = null,
WebAccountCommandParameter accountCommandParameter = null)
{
HeaderText = headerText;
AddAccountHeaderText = addAccountHeaderText;
ManageAccountHeaderText = manageAccountHeaderText;
Commands = commands;
AccountCommandParameter = accountCommandParameter;
}
}
}
37 changes: 37 additions & 0 deletions CommunityToolkit.Authentication.Uwp/WebAccountCommandParameter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using Windows.UI.ApplicationSettings;

namespace CommunityToolkit.Authentication
{
/// <summary>
/// <see cref="WebAccountCommand"/> can be produced through this parameter.
/// </summary>
public class WebAccountCommandParameter
{
/// <summary>
/// Gets the delegate that's invoked when the user selects an account and a specific
/// action in the account settings pane.
/// </summary>
public WebAccountCommandInvokedHandler Invoked { get; }

/// <summary>
/// Gets the actions that the command performs on the web account in the accounts pane.
/// </summary>
public SupportedWebAccountActions Actions { get; }

/// <summary>
/// Initializes a new instance of the <see cref="WebAccountCommandParameter"/> class.
/// </summary>
/// <param name="invoked">The delegate that's invoked when the user selects an account and a specific
/// action in the account settings pane.</param>
/// <param name="actions">The actions that the command performs on the web account in the accounts pane.</param>
public WebAccountCommandParameter(WebAccountCommandInvokedHandler invoked, SupportedWebAccountActions actions)
{
Invoked = invoked;
Actions = actions;
}
}
}
87 changes: 84 additions & 3 deletions CommunityToolkit.Authentication.Uwp/WindowsProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -224,13 +224,94 @@ public override async Task<string> GetTokenAsync(bool silentOnly = false)
return null;
}

/// <summary>
/// Display AccountSettingsPane for the management of logged-in users.
/// </summary>
/// <returns><see cref="Task"/>.</returns>
public async Task ShowAccountManagementPaneAsync()
{
if (_webAccount == null)
{
throw new InvalidOperationException("Display account management pane requires at least one logged in account.");
}

if (_accountsSettingsPaneConfig?.AccountCommandParameter == null)
{
throw new ArgumentNullException("At least one account command is required to display the account management pane.");
}

// Build the AccountSettingsPane and configure it with available account commands.
void OnAccountCommandsRequested(AccountsSettingsPane sender, AccountsSettingsPaneCommandsRequestedEventArgs e)
{
AccountsSettingsPaneEventDeferral deferral = e.GetDeferral();

// Apply the configured header.
var headerText = _accountsSettingsPaneConfig?.ManageAccountHeaderText;
if (!string.IsNullOrWhiteSpace(headerText))
{
e.HeaderText = headerText;
}

// Generate account command.
var commandParameter = _accountsSettingsPaneConfig?.AccountCommandParameter;
var webAccountCommand = new WebAccountCommand(
_webAccount,
async (command, args) =>
{
commandParameter.Invoked?.Invoke(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.Actions);

e.WebAccountCommands.Add(webAccountCommand);

// Apply any configured setting commands.
var commands = _accountsSettingsPaneConfig?.Commands;
if (commands != null)
{
foreach (var command in commands)
{
e.Commands.Add(command);
}
}

deferral.Complete();
}

AccountsSettingsPane pane = null;
try
{
// GetForCurrentView may throw an exception if the current view isn't ready yet.
pane = AccountsSettingsPane.GetForCurrentView();
pane.AccountCommandsRequested += OnAccountCommandsRequested;

// Show the AccountSettingsPane and wait for the result.
await AccountsSettingsPane.ShowManageAccountsAsync();
}
catch (Exception)
{
}
finally
{
if (pane != null)
{
pane.AccountCommandsRequested -= OnAccountCommandsRequested;
}
}
}

private async Task SetAccountAsync(WebAccount account)
{
if (account == null)
{
// Clear account
await SignOutAsync();
return;
await SignOutAsync();
return;
}
else if (account.Id == _webAccount?.Id)
{
Expand Down Expand Up @@ -353,7 +434,7 @@ async void OnAccountCommandsRequested(AccountsSettingsPane sender, AccountsSetti
}

// Apply the configured header.
var headerText = _accountsSettingsPaneConfig?.HeaderText;
var headerText = _accountsSettingsPaneConfig?.AddAccountHeaderText;
if (!string.IsNullOrWhiteSpace(headerText))
{
e.HeaderText = headerText;
Expand Down
17 changes: 17 additions & 0 deletions Samples/UwpWindowsProviderSample/AccountManagerButton.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<UserControl x:Class="UwpWindowsProviderSample.AccountManagerButton"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:UwpWindowsProviderSample"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
d:DesignHeight="300"
d:DesignWidth="400"
mc:Ignorable="d">

<Grid>
<Button x:Name="ManagerButton"
Click="ManagerButton_Click"
Content="Account management"
IsEnabled="{Binding IsEnabled}" />
</Grid>
</UserControl>
29 changes: 29 additions & 0 deletions Samples/UwpWindowsProviderSample/AccountManagerButton.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using CommunityToolkit.Authentication;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;

namespace UwpWindowsProviderSample
{
/// <summary>
/// A simple button for triggering the globally configured WindowsProvider to manage account.
/// </summary>
public sealed partial class AccountManagerButton : UserControl
{
public AccountManagerButton()
{
this.InitializeComponent();
}

private async void ManagerButton_Click(object sender, RoutedEventArgs e)
{
if(ProviderManager.Instance.GlobalProvider is WindowsProvider provider)
{
await provider.ShowAccountManagementPaneAsync();
}
}
}
}
26 changes: 25 additions & 1 deletion Samples/UwpWindowsProviderSample/App.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,12 @@
// See the LICENSE file in the project root for more information.

using CommunityToolkit.Authentication;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using Windows.ApplicationModel.Activation;
using Windows.System;
using Windows.UI.ApplicationSettings;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;

Expand Down Expand Up @@ -32,11 +36,31 @@ void ConfigureGlobalProvider()
if (ProviderManager.Instance.GlobalProvider == null)
{
string[] scopes = new string[] { "User.Read" };
ProviderManager.Instance.GlobalProvider = new WindowsProvider(scopes);
var paneConfig = GetAccountsSettingsPaneConfig();
ProviderManager.Instance.GlobalProvider = new WindowsProvider(scopes, accountsSettingsPaneConfig: paneConfig);
}
});
}

AccountsSettingsPaneConfig GetAccountsSettingsPaneConfig()
{
void OnAccountCommandInvoked(WebAccountCommand command, WebAccountInvokedArgs args)
{
Debug.WriteLine($"Action: {args.Action}");
}

var accountCommandParameter = new WebAccountCommandParameter(
OnAccountCommandInvoked,
SupportedWebAccountActions.Remove | SupportedWebAccountActions.Manage);

var addAccountHeaderText = "Login account";
var manageAccountHeaderText = "Account management";

return new AccountsSettingsPaneConfig(addAccountHeaderText, manageAccountHeaderText, accountCommandParameter: accountCommandParameter);
}



protected override void OnLaunched(LaunchActivatedEventArgs e)
{
Frame rootFrame = Window.Current.Content as Frame;
Expand Down
20 changes: 11 additions & 9 deletions Samples/UwpWindowsProviderSample/MainPage.xaml
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
<Page
x:Class="UwpWindowsProviderSample.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:UwpWindowsProviderSample"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Page x:Class="UwpWindowsProviderSample.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:UwpWindowsProviderSample"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
mc:Ignorable="d">

<StackPanel>
<local:LoginButton />
<local:AccountManagerButton x:Name="ManagerButton"
Margin="0,8,0,0"
IsEnabled="False" />
<TextBlock x:Name="SignedInUserTextBlock" />
</StackPanel>
</Page>
2 changes: 2 additions & 0 deletions Samples/UwpWindowsProviderSample/MainPage.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,11 @@ private async void OnProviderUpdated(object sender, ProviderUpdatedEventArgs e)
if (provider == null || provider.State != ProviderState.SignedIn)
{
SignedInUserTextBlock.Text = "Please sign in.";
ManagerButton.IsEnabled = false;
}
else
{
ManagerButton.IsEnabled = true;
SignedInUserTextBlock.Text = "Signed in as...";

var graphClient = provider.GetClient();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,9 @@
<RestoreProjectStyle>PackageReference</RestoreProjectStyle>
</PropertyGroup>
<ItemGroup>
<Compile Include="AccountManagerButton.xaml.cs">
<DependentUpon>AccountManagerButton.xaml</DependentUpon>
</Compile>
<Compile Include="App.xaml.cs">
<DependentUpon>App.xaml</DependentUpon>
</Compile>
Expand Down Expand Up @@ -147,6 +150,10 @@
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</ApplicationDefinition>
<Page Include="AccountManagerButton.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="LoginButton.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
Expand Down