diff --git a/CommunityToolkit.Authentication.Msal/CommunityToolkit.Authentication.Msal.csproj b/CommunityToolkit.Authentication.Msal/CommunityToolkit.Authentication.Msal.csproj
index 3024215..6b1ff0b 100644
--- a/CommunityToolkit.Authentication.Msal/CommunityToolkit.Authentication.Msal.csproj
+++ b/CommunityToolkit.Authentication.Msal/CommunityToolkit.Authentication.Msal.csproj
@@ -5,6 +5,7 @@
Windows Community Toolkit .NET Standard Auth Services
This package includes .NET Standard authentication helpers such as:
+
- MsalProvider:
Community Toolkit Provider Authentication Auth Msal
diff --git a/CommunityToolkit.Authentication.Uwp/CommunityToolkit.Authentication.Uwp.csproj b/CommunityToolkit.Authentication.Uwp/CommunityToolkit.Authentication.Uwp.csproj
index d6d0735..40c0024 100644
--- a/CommunityToolkit.Authentication.Uwp/CommunityToolkit.Authentication.Uwp.csproj
+++ b/CommunityToolkit.Authentication.Uwp/CommunityToolkit.Authentication.Uwp.csproj
@@ -8,7 +8,7 @@
This library provides an authentication provider based on the native Windows dialogues. It is part of the Windows Community Toolkit.
Classes:
- - WindowsProvider:
+ - WindowsProvider: Lightweight authentication provider built around the native Windows Account Manager (WAM) APIs.
UWP Toolkit Windows Microsoft Graph AadLogin Authentication Login
false
diff --git a/CommunityToolkit.Graph.Uwp/Assets/person.png b/CommunityToolkit.Graph.Uwp/Assets/person.png
deleted file mode 100644
index 3566862..0000000
Binary files a/CommunityToolkit.Graph.Uwp/Assets/person.png and /dev/null differ
diff --git a/CommunityToolkit.Graph.Uwp/CommunityToolkit.Graph.Uwp.csproj b/CommunityToolkit.Graph.Uwp/CommunityToolkit.Graph.Uwp.csproj
deleted file mode 100644
index 46262c7..0000000
--- a/CommunityToolkit.Graph.Uwp/CommunityToolkit.Graph.Uwp.csproj
+++ /dev/null
@@ -1,66 +0,0 @@
-
-
-
- uap10.0.17763
- Windows Community Toolkit Graph Uwp Controls and Helpers
- CommunityToolkit.Uwp.Graph.Controls
-
- This library provides Microsoft Graph UWP XAML controls. It is part of the Windows Community Toolkit.
-
- Classes:
- - GraphPresenter:
- - LoginButton: The Login Control leverages MSAL libraries to support the sign-in processes for Microsoft Graph and beyond.
- - PersonView: The PersonView control displays a user photo and can display their name and e-mail.
- - PeoplePicker: The PeoplePicker Control is a simple control that allows for selection of one or more users.
-
- UWP Toolkit Windows Controls MSAL Microsoft Graph AadLogin ProfileCard Person PeoplePicker Login
- false
- true
- 9.0
- Debug;Release;CI
- AnyCPU;ARM;ARM64;x64;x86
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- MSBuild:Compile
-
-
-
-
- $(DefineConstants);WINRT
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/CommunityToolkit.Graph.Uwp/Controls/GraphPresenter/GraphPresenter.cs b/CommunityToolkit.Graph.Uwp/Controls/GraphPresenter/GraphPresenter.cs
deleted file mode 100644
index 484d24f..0000000
--- a/CommunityToolkit.Graph.Uwp/Controls/GraphPresenter/GraphPresenter.cs
+++ /dev/null
@@ -1,117 +0,0 @@
-// 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 System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading;
-using Microsoft.Graph;
-using Microsoft.Toolkit.Uwp;
-using Newtonsoft.Json.Linq;
-using Windows.System;
-using Windows.UI.Xaml;
-using Windows.UI.Xaml.Controls;
-
-namespace CommunityToolkit.Graph.Uwp.Controls
-{
- ///
- /// Specialized to fetch and display data from the Microsoft Graph.
- ///
- public class GraphPresenter : ContentPresenter
- {
- ///
- /// Gets or sets a to be used to make a request to the graph. The results will be automatically populated to the property. Use a to change the presentation of the data.
- ///
- public IBaseRequestBuilder RequestBuilder
- {
- get { return (IBaseRequestBuilder)GetValue(RequestBuilderProperty); }
- set { SetValue(RequestBuilderProperty, value); }
- }
-
- ///
- /// Identifies the dependency property.
- ///
- ///
- /// The identifier for the dependency property.
- ///
- public static readonly DependencyProperty RequestBuilderProperty =
- DependencyProperty.Register(nameof(RequestBuilder), typeof(IBaseRequestBuilder), typeof(GraphPresenter), new PropertyMetadata(null));
-
- ///
- /// Gets or sets the of item returned by the .
- /// Set to the base item type and use the property to indicate if a collection is expected back.
- ///
- public Type ResponseType { get; set; }
-
- ///
- /// Gets or sets a value indicating whether the returned data from the is a collection.
- ///
- public bool IsCollection { get; set; }
-
- ///
- /// Gets or sets list of representing values to pass into the request built by .
- ///
- public List QueryOptions { get; set; } = new List();
-
- ///
- /// Gets or sets a string to indicate a sorting order for the . This is a helper to add this specific request option to the .
- ///
- public string OrderBy { get; set; }
-
- ///
- /// Initializes a new instance of the class.
- ///
- public GraphPresenter()
- {
- Loaded += GraphPresenter_Loaded;
- }
-
- private async void GraphPresenter_Loaded(object sender, RoutedEventArgs e)
- {
- var dispatcherQueue = DispatcherQueue.GetForCurrentThread();
-
- // Note: some interfaces from the Graph SDK don't implement IBaseRequestBuilder properly, see https://github.com/microsoftgraph/msgraph-sdk-dotnet/issues/722
- if (RequestBuilder != null)
- {
- var request = new BaseRequest(
- RequestBuilder.RequestUrl,
- RequestBuilder.Client); // TODO: Do we need separate Options here?
- ////request.Method = HttpMethods.GET;
- request.Method = "GET";
- request.QueryOptions = QueryOptions?.Select(option => (Microsoft.Graph.QueryOption)option)?.ToList() ?? new List();
-
- // Handle Special QueryOptions
- if (!string.IsNullOrWhiteSpace(OrderBy))
- {
- request.QueryOptions.Add(new Microsoft.Graph.QueryOption("$orderby", OrderBy));
- }
-
- try
- {
- var response = await request.SendAsync(null, CancellationToken.None).ConfigureAwait(false) as JObject;
-
- //// TODO: Deal with paging?
-
- var values = response["value"];
- object data = null;
-
- if (IsCollection)
- {
- data = values.ToObject(Array.CreateInstance(ResponseType, 0).GetType());
- }
- else
- {
- data = values.ToObject(ResponseType);
- }
-
- _ = dispatcherQueue.EnqueueAsync(() => Content = data);
- }
- catch
- {
- // TODO: We should figure out what we want to do for Loading/Error states here.
- }
- }
- }
- }
-}
\ No newline at end of file
diff --git a/CommunityToolkit.Graph.Uwp/Controls/GraphPresenter/QueryOption.cs b/CommunityToolkit.Graph.Uwp/Controls/GraphPresenter/QueryOption.cs
deleted file mode 100644
index 9486c28..0000000
--- a/CommunityToolkit.Graph.Uwp/Controls/GraphPresenter/QueryOption.cs
+++ /dev/null
@@ -1,34 +0,0 @@
-// 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 System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Windows.UI.Xaml;
-
-namespace CommunityToolkit.Graph.Uwp.Controls
-{
- ///
- /// XAML Proxy for .
- ///
- public sealed class QueryOption
- {
- ///
- public string Name { get; set; }
-
- ///
- public string Value { get; set; }
-
- ///
- /// Implicit conversion for to .
- ///
- /// query option to convert.
- public static implicit operator Microsoft.Graph.QueryOption(QueryOption option)
- {
- return new Microsoft.Graph.QueryOption(option.Name, option.Value);
- }
- }
-}
diff --git a/CommunityToolkit.Graph.Uwp/Controls/LoginButton/LoginButton.Events.cs b/CommunityToolkit.Graph.Uwp/Controls/LoginButton/LoginButton.Events.cs
deleted file mode 100644
index a5ba998..0000000
--- a/CommunityToolkit.Graph.Uwp/Controls/LoginButton/LoginButton.Events.cs
+++ /dev/null
@@ -1,40 +0,0 @@
-// 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 System;
-using System.ComponentModel;
-
-namespace CommunityToolkit.Graph.Uwp.Controls
-{
- ///
- /// The control is a button which can be used to sign the user in or show them profile details.
- ///
- public partial class LoginButton
- {
- ///
- /// The user clicked the sign in button to start the login process - cancelable.
- ///
- public event CancelEventHandler LoginInitiated;
-
- ///
- /// The login process was successful and the user is now signed in.
- ///
- public event EventHandler LoginCompleted;
-
- ///
- /// The user canceled the login process or was unable to sign in.
- ///
- public event EventHandler LoginFailed;
-
- ///
- /// The user started to logout - cancelable.
- ///
- public event CancelEventHandler LogoutInitiated;
-
- ///
- /// The user signed out.
- ///
- public event EventHandler LogoutCompleted;
- }
-}
diff --git a/CommunityToolkit.Graph.Uwp/Controls/LoginButton/LoginButton.Properties.cs b/CommunityToolkit.Graph.Uwp/Controls/LoginButton/LoginButton.Properties.cs
deleted file mode 100644
index addd2f8..0000000
--- a/CommunityToolkit.Graph.Uwp/Controls/LoginButton/LoginButton.Properties.cs
+++ /dev/null
@@ -1,51 +0,0 @@
-// 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 Microsoft.Graph;
-using Windows.UI.Xaml;
-
-namespace CommunityToolkit.Graph.Uwp.Controls
-{
- ///
- /// The control is a button which can be used to sign the user in or show them profile details.
- ///
- public partial class LoginButton
- {
- ///
- /// Gets or sets details about this person retrieved from the graph or provided by the developer.
- ///
- public User UserDetails
- {
- get { return (User)GetValue(UserDetailsProperty); }
- set { SetValue(UserDetailsProperty, value); }
- }
-
- ///
- /// Identifies the dependency property.
- ///
- ///
- /// The identifier for the dependency property.
- ///
- public static readonly DependencyProperty UserDetailsProperty =
- DependencyProperty.Register(nameof(UserDetails), typeof(User), typeof(LoginButton), new PropertyMetadata(null));
-
- ///
- /// Gets or sets a value indicating whether the control is loading and has not established a sign-in state.
- ///
- public bool IsLoading
- {
- get { return (bool)GetValue(IsLoadingProperty); }
- protected set { SetValue(IsLoadingProperty, value); }
- }
-
- ///
- /// Identifies the dependency property.
- ///
- ///
- /// The identifier for the dependency property.
- ///
- public static readonly DependencyProperty IsLoadingProperty =
- DependencyProperty.Register(nameof(IsLoading), typeof(bool), typeof(LoginButton), new PropertyMetadata(true));
- }
-}
diff --git a/CommunityToolkit.Graph.Uwp/Controls/LoginButton/LoginButton.cs b/CommunityToolkit.Graph.Uwp/Controls/LoginButton/LoginButton.cs
deleted file mode 100644
index f9acd1b..0000000
--- a/CommunityToolkit.Graph.Uwp/Controls/LoginButton/LoginButton.cs
+++ /dev/null
@@ -1,229 +0,0 @@
-// 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 System;
-using System.ComponentModel;
-using System.Diagnostics;
-using System.Threading.Tasks;
-using CommunityToolkit.Authentication;
-using CommunityToolkit.Graph.Extensions;
-using Windows.UI.Xaml;
-using Windows.UI.Xaml.Controls;
-using Windows.UI.Xaml.Controls.Primitives;
-
-namespace CommunityToolkit.Graph.Uwp.Controls
-{
- ///
- /// The control is a button which can be used to sign the user in or show them profile details.
- ///
- [TemplatePart(Name = LoginButtonPart, Type = typeof(Button))]
- [TemplatePart(Name = SignOutButtonPart, Type = typeof(ButtonBase))]
- public partial class LoginButton : Control
- {
- private const string LoginButtonPart = "PART_LoginButton";
- private const string SignOutButtonPart = "PART_SignOutButton";
-
- private Button _loginButton;
- private ButtonBase _signOutButton;
-
- ///
- /// Initializes a new instance of the class.
- ///
- public LoginButton()
- {
- this.DefaultStyleKey = typeof(LoginButton);
-
- ProviderManager.Instance.ProviderUpdated += (sender, args) => LoadData();
- }
-
- ///
- protected override void OnApplyTemplate()
- {
- base.OnApplyTemplate();
-
- IsLoading = true;
- LoadData();
-
- if (_loginButton != null)
- {
- _loginButton.Click -= LoginButton_Click;
- }
-
- _loginButton = GetTemplateChild(LoginButtonPart) as Button;
-
- if (_loginButton != null)
- {
- _loginButton.Click += LoginButton_Click;
- }
-
- if (_signOutButton != null)
- {
- _signOutButton.Click -= LoginButton_Click;
- }
-
- _signOutButton = GetTemplateChild(SignOutButtonPart) as ButtonBase;
-
- if (_signOutButton != null)
- {
- _signOutButton.Click += SignOutButton_Click;
- }
- }
-
- private async void LoginButton_Click(object sender, RoutedEventArgs e)
- {
- if (this.UserDetails != null)
- {
- if (FlyoutBase.GetAttachedFlyout(_loginButton) is FlyoutBase flyout)
- {
- flyout.ShowAt(_loginButton);
- }
- }
- else
- {
- var cargs = new CancelEventArgs();
- LoginInitiated?.Invoke(this, cargs);
-
- if (!cargs.Cancel)
- {
- await SignInAsync();
- }
- }
- }
-
- private async void SignOutButton_Click(object sender, RoutedEventArgs e)
- {
- await SignOutAsync();
- }
-
- private async void LoadData()
- {
- var provider = ProviderManager.Instance.GlobalProvider;
-
- if (provider == null)
- {
- return;
- }
-
- if (provider.State == ProviderState.Loading)
- {
- IsLoading = true;
- }
- else if (provider.State == ProviderState.SignedIn)
- {
- try
- {
- // https://github.com/microsoftgraph/microsoft-graph-toolkit/blob/master/src/components/mgt-login/mgt-login.ts#L139
- // TODO: Batch with photo request later? https://github.com/microsoftgraph/msgraph-sdk-dotnet-core/issues/29
- UserDetails = await provider.GetClient().GetMeAsync();
- }
- catch (Exception e)
- {
- LoginFailed?.Invoke(this, new LoginFailedEventArgs(e));
- }
-
- IsLoading = false;
- }
- else if (provider.State == ProviderState.SignedOut)
- {
- UserDetails = null; // What if this was user provided? Should we not hook into these events then?
-
- IsLoading = false;
- }
- else
- {
- // Provider in Loading state
- Debug.Fail("unsupported state");
- }
- }
-
- ///
- /// Initiates logging in with the current registered in the .
- ///
- /// A representing the asynchronous operation.
- public async Task SignInAsync()
- {
- if (UserDetails != null || IsLoading)
- {
- return;
- }
-
- var provider = ProviderManager.Instance.GlobalProvider;
-
- if (provider != null)
- {
- try
- {
- IsLoading = true;
- await provider.SignInAsync();
-
- if (provider.State == ProviderState.SignedIn)
- {
- // TODO: include user details?
- LoginCompleted?.Invoke(this, new EventArgs());
-
- LoadData();
- }
- else
- {
- LoginFailed?.Invoke(this, new LoginFailedEventArgs(new TimeoutException("Login did not complete.")));
- }
- }
- catch (Exception e)
- {
- LoginFailed?.Invoke(this, new LoginFailedEventArgs(e));
- }
- finally
- {
- IsLoading = false;
- }
- }
- }
-
- ///
- /// Log a signed-in user out.
- ///
- /// A representing the asynchronous operation.
- public async Task SignOutAsync()
- {
- // Close Menu
- if (FlyoutBase.GetAttachedFlyout(_loginButton) is FlyoutBase flyout)
- {
- flyout.Hide();
- }
-
- if (IsLoading)
- {
- return;
- }
-
- var cargs = new CancelEventArgs();
- LogoutInitiated?.Invoke(this, cargs);
-
- if (cargs.Cancel)
- {
- return;
- }
-
- if (UserDetails != null)
- {
- UserDetails = null;
- }
- else
- {
- return; // No-op
- }
-
- var provider = ProviderManager.Instance.GlobalProvider;
-
- if (provider != null)
- {
- IsLoading = true;
- await provider.SignOutAsync();
- IsLoading = false;
-
- LogoutCompleted?.Invoke(this, new EventArgs());
- }
- }
- }
-}
diff --git a/CommunityToolkit.Graph.Uwp/Controls/LoginButton/LoginButton.xaml b/CommunityToolkit.Graph.Uwp/Controls/LoginButton/LoginButton.xaml
deleted file mode 100644
index c15d51a..0000000
--- a/CommunityToolkit.Graph.Uwp/Controls/LoginButton/LoginButton.xaml
+++ /dev/null
@@ -1,60 +0,0 @@
-
-
-
-
-
-
-
-
diff --git a/CommunityToolkit.Graph.Uwp/Controls/LoginButton/LoginFailedEventArgs.cs b/CommunityToolkit.Graph.Uwp/Controls/LoginButton/LoginFailedEventArgs.cs
deleted file mode 100644
index bb2c0dd..0000000
--- a/CommunityToolkit.Graph.Uwp/Controls/LoginButton/LoginFailedEventArgs.cs
+++ /dev/null
@@ -1,50 +0,0 @@
-// 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 System;
-
-namespace CommunityToolkit.Graph.Uwp.Controls
-{
- ///
- /// for event.
- ///
- public class LoginFailedEventArgs : EventArgs
- {
- ///
- /// Gets the exception which occured during login.
- ///
- public Exception Exception { get; private set; }
-
- ///
- /// Gets the inner exception which occured during login.
- ///
- public Exception InnerException
- {
- get
- {
- return Exception?.InnerException;
- }
- }
-
- ///
- /// Gets the error message of the inner error or error.
- ///
- public string Message
- {
- get
- {
- return Exception?.InnerException?.Message ?? Exception?.Message;
- }
- }
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// Exception encountered during login.
- public LoginFailedEventArgs(Exception exception)
- {
- Exception = exception;
- }
- }
-}
\ No newline at end of file
diff --git a/CommunityToolkit.Graph.Uwp/Controls/PeoplePicker/PeoplePicker.cs b/CommunityToolkit.Graph.Uwp/Controls/PeoplePicker/PeoplePicker.cs
deleted file mode 100644
index 3203c87..0000000
--- a/CommunityToolkit.Graph.Uwp/Controls/PeoplePicker/PeoplePicker.cs
+++ /dev/null
@@ -1,118 +0,0 @@
-// 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 System;
-using System.Collections;
-using System.Collections.ObjectModel;
-using System.Linq;
-using CommunityToolkit.Authentication;
-using CommunityToolkit.Graph.Extensions;
-using Microsoft.Graph;
-using Microsoft.Toolkit.Uwp.UI;
-using Microsoft.Toolkit.Uwp.UI.Controls;
-using Windows.System;
-using Windows.UI.Xaml.Controls;
-
-namespace CommunityToolkit.Graph.Uwp.Controls
-{
- ///
- /// Control which allows user to search for a person or contact within Microsoft Graph. Built on top of .
- ///
- public partial class PeoplePicker : TokenizingTextBox
- {
- private DispatcherQueueTimer _typeTimer = null;
-
- ///
- /// Initializes a new instance of the class.
- ///
- public PeoplePicker()
- {
- this.DefaultStyleKey = typeof(PeoplePicker);
-
- SuggestedItemsSource = new ObservableCollection();
-
- TextChanged += TokenBox_TextChanged;
- TokenItemAdding += TokenBox_TokenItemTokenItemAdding;
-
- _typeTimer = DispatcherQueue.GetForCurrentThread().CreateTimer();
- }
-
- private async void TokenBox_TokenItemTokenItemAdding(TokenizingTextBox sender, TokenItemAddingEventArgs args)
- {
- using (args.GetDeferral())
- {
- // Try and convert typed text to people
- var graph = ProviderManager.Instance.GlobalProvider.GetClient();
- if (graph != null)
- {
- args.Item = (await graph.FindPersonAsync(args.TokenText)).CurrentPage.FirstOrDefault();
- }
-
- // If we didn't find anyone, then don't add anyone.
- if (args.Item == null)
- {
- args.Cancel = true;
-
- // TODO: We should raise a 'person not found' type event or automatically display some feedback?
- }
- }
- }
-
- private void TokenBox_TextChanged(AutoSuggestBox sender, AutoSuggestBoxTextChangedEventArgs args)
- {
- if (!args.CheckCurrent())
- {
- return;
- }
-
- if (args.Reason == AutoSuggestionBoxTextChangeReason.UserInput)
- {
- var text = sender.Text;
- var list = SuggestedItemsSource as IList;
-
- if (list != null)
- {
- _typeTimer.Debounce(
- async () =>
- {
- var graph = ProviderManager.Instance.GlobalProvider.GetClient();
- if (graph != null)
- {
- // If empty, will clear out
- list.Clear();
-
- if (!string.IsNullOrWhiteSpace(text))
- {
- foreach (var user in (await graph.FindUserAsync(text)).CurrentPage)
- {
- // Exclude people in suggested list that we already have picked
- if (!Items.Any(person => (person as Person)?.Id == user.Id))
- {
- list.Add(user.ToPerson());
- }
- }
-
- // Grab ids of current suggestions
- var ids = list.Cast().Select(person => (person as Person).Id);
-
- foreach (var contact in (await graph.FindPersonAsync(text)).CurrentPage)
- {
- // Exclude people in suggested list that we already have picked
- // Or already suggested
- if (!Items.Any(person => (person as Person)?.Id == contact.Id) &&
- !ids.Any(id => id == contact.Id))
- {
- list.Add(contact);
- }
- }
- }
- }
-
- // TODO: If we don't have Graph connection and just list of Person should we auto-filter here?
- }, TimeSpan.FromSeconds(0.3));
- }
- }
- }
- }
-}
diff --git a/CommunityToolkit.Graph.Uwp/Controls/PeoplePicker/PeoplePicker.xaml b/CommunityToolkit.Graph.Uwp/Controls/PeoplePicker/PeoplePicker.xaml
deleted file mode 100644
index 4ad12dc..0000000
--- a/CommunityToolkit.Graph.Uwp/Controls/PeoplePicker/PeoplePicker.xaml
+++ /dev/null
@@ -1,39 +0,0 @@
-
-
-
-
-
-
-
-
-
diff --git a/CommunityToolkit.Graph.Uwp/Controls/PersonView/PersonView.Properties.cs b/CommunityToolkit.Graph.Uwp/Controls/PersonView/PersonView.Properties.cs
deleted file mode 100644
index 1b47d42..0000000
--- a/CommunityToolkit.Graph.Uwp/Controls/PersonView/PersonView.Properties.cs
+++ /dev/null
@@ -1,139 +0,0 @@
-// 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 Microsoft.Graph;
-using Windows.UI.Xaml;
-using Windows.UI.Xaml.Media.Imaging;
-
-namespace CommunityToolkit.Graph.Uwp.Controls
-{
- ///
- /// The control displays a user photo and can display their name and e-mail.
- ///
- public partial class PersonView
- {
- ///
- /// Gets or sets details about this person retrieved from the graph or provided by the developer.
- ///
- public Person PersonDetails
- {
- get { return (Person)GetValue(PersonDetailsProperty); }
- set { SetValue(PersonDetailsProperty, value); }
- }
-
- ///
- /// Identifies the dependency property.
- ///
- ///
- /// The identifier for the dependency property.
- ///
- public static readonly DependencyProperty PersonDetailsProperty =
- DependencyProperty.Register(nameof(PersonDetails), typeof(Person), typeof(PersonView), new PropertyMetadata(null, PersonDetailsPropertyChanged));
-
- ///
- /// Gets or sets a string to automatically retrieve data on the specified query from the graph. Use to retrieve info about the current user. Otherwise, it's best to use an e-mail address as a query.
- ///
- public string PersonQuery
- {
- get { return (string)GetValue(PersonQueryProperty); }
- set { SetValue(PersonQueryProperty, value); }
- }
-
- ///
- /// Identifies the dependency property.
- ///
- ///
- /// The identifier for the dependency property.
- ///
- public static readonly DependencyProperty PersonQueryProperty =
- DependencyProperty.Register(nameof(PersonQuery), typeof(string), typeof(PersonView), new PropertyMetadata(null, QueryPropertyChanged));
-
- ///
- /// Gets or sets the UserId.
- ///
- public string UserId
- {
- get { return (string)GetValue(UserIdProperty); }
- set { SetValue(UserIdProperty, value); }
- }
-
- ///
- /// Identifies the dependency property.
- ///
- ///
- /// The identifier for the dependency property.
- ///
- public static readonly DependencyProperty UserIdProperty =
- DependencyProperty.Register(nameof(UserId), typeof(string), typeof(PersonView), new PropertyMetadata(null, QueryPropertyChanged));
-
- ///
- /// Gets or sets the photo of the user to be displayed.
- ///
- public BitmapImage UserPhoto
- {
- get { return (BitmapImage)GetValue(UserPhotoProperty); }
- set { SetValue(UserPhotoProperty, value); }
- }
-
- ///
- /// Identifies the dependency property.
- ///
- ///
- /// The identifier for the dependency property.
- ///
- public static readonly DependencyProperty UserPhotoProperty =
- DependencyProperty.Register(nameof(UserPhoto), typeof(BitmapImage), typeof(PersonView), new PropertyMetadata(null));
-
- ///
- /// Gets the initials of the person from the .
- ///
- public string Initials
- {
- get { return (string)GetValue(InitialsProperty); }
- internal set { SetValue(InitialsProperty, value); }
- }
-
- ///
- /// Identifies the dependency property.
- ///
- ///
- /// The identifier for the dependency property.
- ///
- public static readonly DependencyProperty InitialsProperty =
- DependencyProperty.Register(nameof(Initials), typeof(string), typeof(PersonView), new PropertyMetadata(string.Empty));
-
- ///
- /// Gets a value indicating whether the image has expanded based on the PersonViewType.
- ///
- public bool IsLargeImage
- {
- get { return (bool)GetValue(IsLargeImageProperty); }
- internal set { SetValue(IsLargeImageProperty, value); }
- }
-
- ///
- /// Identifies the dependency property.
- ///
- ///
- /// The identifier for the dependency property.
- ///
- public static readonly DependencyProperty IsLargeImageProperty =
- DependencyProperty.Register(nameof(IsLargeImage), typeof(bool), typeof(PersonView), new PropertyMetadata(false));
-
- ///
- /// Gets or sets the type of details to display in the PersonView part of the template.
- ///
- public PersonViewType PersonViewType
- {
- get => (PersonViewType)GetValue(PersonViewTypeProperty);
- set => SetValue(PersonViewTypeProperty, value);
- }
-
- ///
- /// Identifies the dependency property.
- ///
- public static readonly DependencyProperty PersonViewTypeProperty =
- DependencyProperty.Register(nameof(PersonViewType), typeof(PersonViewType), typeof(PersonView), new PropertyMetadata(PersonViewType.TwoLines, PersonViewTypePropertiesChanged));
- }
-}
diff --git a/CommunityToolkit.Graph.Uwp/Controls/PersonView/PersonView.cs b/CommunityToolkit.Graph.Uwp/Controls/PersonView/PersonView.cs
deleted file mode 100644
index 5ef9e4a..0000000
--- a/CommunityToolkit.Graph.Uwp/Controls/PersonView/PersonView.cs
+++ /dev/null
@@ -1,228 +0,0 @@
-// 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 System;
-using System.IO;
-using System.Linq;
-using System.Threading.Tasks;
-using CommunityToolkit.Authentication;
-using CommunityToolkit.Graph.Extensions;
-using Microsoft.Graph;
-using Windows.UI.Xaml;
-using Windows.UI.Xaml.Controls;
-using Windows.UI.Xaml.Media.Imaging;
-
-namespace CommunityToolkit.Graph.Uwp.Controls
-{
- ///
- /// The control displays a user photo and can display their name and e-mail.
- ///
- public partial class PersonView : Control
- {
- private const string PersonViewDefaultImageSourceResourceName = "PersonViewDefaultImageSource";
-
- ///
- /// value used to retrieve the signed-in user's info.
- ///
- public const string PersonQueryMe = "me";
-
- private string _photoId = null;
-
- private string _defaultImageSource = "ms-appx:///Microsoft.Toolkit.Graph.Controls/Assets/person.png";
-
- private BitmapImage _defaultImage;
-
- private static async void PersonDetailsPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
- {
- if (d is PersonView pv)
- {
- if (pv.PersonDetails != null)
- {
- if (pv?.PersonDetails?.GivenName?.Length > 0 && pv?.PersonDetails?.Surname?.Length > 0)
- {
- pv.Initials = string.Empty + pv.PersonDetails.GivenName[0] + pv.PersonDetails.Surname[0];
- }
- else if (pv?.PersonDetails?.DisplayName?.Length > 0)
- {
- // Grab first two initials in name
- var initials = pv.PersonDetails.DisplayName.ToUpper().Split(' ').Select(i => i.First());
- pv.Initials = string.Join(string.Empty, initials.Where(i => char.IsLetter(i)).Take(2));
- }
-
- if (pv?.UserPhoto?.UriSource?.AbsoluteUri == pv._defaultImageSource || pv?.PersonDetails?.Id != pv._photoId)
- {
- // Reload Image
- pv.UserPhoto = pv._defaultImage;
- await pv.LoadImageAsync(pv.PersonDetails);
- }
- else if (pv?.PersonDetails?.Id != pv._photoId)
- {
- pv.UserPhoto = pv._defaultImage;
- pv._photoId = null;
- }
- }
- }
- }
-
- private static void QueryPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
- {
- if (d is PersonView view)
- {
- view.PersonDetails = null;
- view.LoadData();
- }
- }
-
- private static void PersonViewTypePropertiesChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
- {
- if (d is PersonView pv)
- {
- pv.IsLargeImage = pv.PersonViewType == PersonViewType.Avatar;
- }
- }
-
- ///
- /// Initializes a new instance of the class.
- ///
- public PersonView()
- {
- this.DefaultStyleKey = typeof(PersonView);
-
- _defaultImage = new BitmapImage(new Uri(_defaultImageSource));
-
- ProviderManager.Instance.ProviderUpdated += (sender, args) => LoadData();
- }
-
- ///
- protected override void OnApplyTemplate()
- {
- base.OnApplyTemplate();
-
- if (Resources.TryGetValue(PersonViewDefaultImageSourceResourceName, out object value) && value is string uri)
- {
- _defaultImageSource = uri;
- _defaultImage = new BitmapImage(new Uri(_defaultImageSource)); // TODO: Couldn't load image from app package, only remote or in our assembly?
- UserPhoto = _defaultImage;
- }
-
- LoadData();
- }
-
- private async void LoadData()
- {
- var provider = ProviderManager.Instance.GlobalProvider;
-
- if (provider == null || provider.State != ProviderState.SignedIn)
- {
- // Set back to Default if not signed-in
- if (provider != null)
- {
- UserPhoto = _defaultImage;
- }
-
- return;
- }
-
- if (PersonDetails != null && UserPhoto == null)
- {
- await LoadImageAsync(PersonDetails);
- }
- else if (!string.IsNullOrWhiteSpace(UserId) || PersonQuery?.ToLowerInvariant() == PersonQueryMe)
- {
- User user = null;
- if (!string.IsNullOrWhiteSpace(UserId))
- {
- // TODO: Batch when API easier https://github.com/microsoftgraph/msgraph-sdk-dotnet-core/issues/29
- try
- {
- user = await provider.GetClient().GetUserAsync(UserId);
- }
- catch
- {
- }
-
- try
- {
- // TODO: Move to LoadImage based on previous call?
- await DecodeStreamAsync(await provider.GetBetaClient().GetUserPhoto(UserId));
- _photoId = UserId;
- }
- catch
- {
- }
- }
- else
- {
- try
- {
- user = await provider.GetClient().GetMeAsync();
- }
- catch
- {
- }
-
- try
- {
- await DecodeStreamAsync(await provider.GetBetaClient().GetMyPhotoAsync());
- _photoId = user.Id;
- }
- catch
- {
- }
- }
-
- if (user != null)
- {
- PersonDetails = user.ToPerson();
- }
- }
- else if (PersonDetails == null && !string.IsNullOrWhiteSpace(PersonQuery))
- {
- var people = await provider.GetClient().FindPersonAsync(PersonQuery);
- if (people != null && people.Count > 0)
- {
- var person = people.FirstOrDefault();
- PersonDetails = person;
- await LoadImageAsync(person);
- }
- }
- }
-
- private async Task LoadImageAsync(Person person)
- {
- try
- {
- // TODO: Better guarding
- var graph = ProviderManager.Instance.GlobalProvider.GetBetaClient();
-
- if (!string.IsNullOrWhiteSpace(person.UserPrincipalName))
- {
- await DecodeStreamAsync(await graph.GetUserPhoto(person.UserPrincipalName));
- _photoId = person.Id; // TODO: Only set on success for photo?
- }
- else if (!string.IsNullOrWhiteSpace(person.ScoredEmailAddresses.First().Address))
- {
- // TODO https://github.com/microsoftgraph/microsoft-graph-toolkit/blob/master/src/components/mgt-person/mgt-person.ts#L174
- }
- }
- catch
- {
- // If we can't load a photo, that's ok.
- }
- }
-
- private async Task DecodeStreamAsync(Stream photoStream)
- {
- if (photoStream != null)
- {
- using (var ras = photoStream.AsRandomAccessStream())
- {
- var bitmap = new BitmapImage();
- await bitmap.SetSourceAsync(ras);
- UserPhoto = bitmap;
- }
- }
- }
- }
-}
diff --git a/CommunityToolkit.Graph.Uwp/Controls/PersonView/PersonView.xaml b/CommunityToolkit.Graph.Uwp/Controls/PersonView/PersonView.xaml
deleted file mode 100644
index b9988f3..0000000
--- a/CommunityToolkit.Graph.Uwp/Controls/PersonView/PersonView.xaml
+++ /dev/null
@@ -1,96 +0,0 @@
-
-
-
-
-
-
-
-
- ms-appx:///Microsoft.Toolkit.Graph.Controls/Assets/person.png
-
-
-
diff --git a/CommunityToolkit.Graph.Uwp/Controls/PersonView/PersonViewType.cs b/CommunityToolkit.Graph.Uwp/Controls/PersonView/PersonViewType.cs
deleted file mode 100644
index d80c36b..0000000
--- a/CommunityToolkit.Graph.Uwp/Controls/PersonView/PersonViewType.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-// 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.
-
-namespace CommunityToolkit.Graph.Uwp.Controls
-{
- ///
- /// Enumeration of what details should be displayed in a PersonView.
- ///
- public enum PersonViewType
- {
- /**
- * Render only the avatar
- */
- Avatar = 0,
-
- /**
- * Render the avatar and one line of text
- */
- OneLine = 1,
-
- /**
- * Render the avatar and two lines of text
- */
- TwoLines = 2,
- }
-}
diff --git a/CommunityToolkit.Graph.Uwp/Converters/ObjectToStringConverter.cs b/CommunityToolkit.Graph.Uwp/Converters/ObjectToStringConverter.cs
deleted file mode 100644
index b6d8707..0000000
--- a/CommunityToolkit.Graph.Uwp/Converters/ObjectToStringConverter.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-// 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 System;
-using Windows.UI.Xaml.Data;
-
-namespace CommunityToolkit.Graph.Uwp.Converters
-{
- ///
- /// Converts any object to a string representation.
- ///
- public class ObjectToStringConverter : IValueConverter
- {
- ///
- public object Convert(object value, Type targetType, object parameter, string language)
- {
- return value.ToString();
- }
-
- ///
- public object ConvertBack(object value, Type targetType, object parameter, string language)
- {
- throw new NotImplementedException();
- }
- }
-}
diff --git a/CommunityToolkit.Graph.Uwp/Converters/UserToPersonConverter.cs b/CommunityToolkit.Graph.Uwp/Converters/UserToPersonConverter.cs
deleted file mode 100644
index bdb88fb..0000000
--- a/CommunityToolkit.Graph.Uwp/Converters/UserToPersonConverter.cs
+++ /dev/null
@@ -1,34 +0,0 @@
-// 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 System;
-using CommunityToolkit.Graph.Extensions;
-using Microsoft.Graph;
-using Windows.UI.Xaml.Data;
-
-namespace CommunityToolkit.Graph.Uwp.Converters
-{
- ///
- /// Converts a to a .
- ///
- public class UserToPersonConverter : IValueConverter
- {
- ///
- public object Convert(object value, Type targetType, object parameter, string language)
- {
- if (value is User user)
- {
- return user.ToPerson();
- }
-
- return null;
- }
-
- ///
- public object ConvertBack(object value, Type targetType, object parameter, string language)
- {
- throw new NotImplementedException();
- }
- }
-}
diff --git a/CommunityToolkit.Graph.Uwp/Helpers/RoamingSettings/BaseRoamingSettingsDataStore.cs b/CommunityToolkit.Graph.Uwp/Helpers/RoamingSettings/BaseRoamingSettingsDataStore.cs
deleted file mode 100644
index b3109d1..0000000
--- a/CommunityToolkit.Graph.Uwp/Helpers/RoamingSettings/BaseRoamingSettingsDataStore.cs
+++ /dev/null
@@ -1,303 +0,0 @@
-// 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 System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Reflection;
-using System.Threading.Tasks;
-using Microsoft.Toolkit.Uwp.Helpers;
-using Windows.Storage;
-
-namespace CommunityToolkit.Uwp.Graph.Helpers.RoamingSettings
-{
- ///
- /// A base class for easily building roaming settings helper implementations.
- ///
- public abstract class BaseRoamingSettingsDataStore : IRoamingSettingsDataStore
- {
- ///
- public EventHandler SyncCompleted { get; set; }
-
- ///
- public EventHandler SyncFailed { get; set; }
-
- ///
- public bool AutoSync { get; }
-
- ///
- public string Id { get; }
-
- ///
- public string UserId { get; }
-
- ///
- public IDictionary Cache { get; private set; } = new Dictionary();
-
- ///
- /// Gets an object serializer for converting objects in the data store.
- ///
- protected IObjectSerializer Serializer { get; }
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The id of the target Graph user.
- /// A unique id for the data store.
- /// An IObjectSerializer used for serializing objects.
- /// Determines if the data store should sync for every interaction.
- public BaseRoamingSettingsDataStore(string userId, string dataStoreId, IObjectSerializer objectSerializer, bool autoSync = true)
- {
- AutoSync = autoSync;
- Id = dataStoreId;
- UserId = userId;
- Serializer = objectSerializer;
- }
-
- ///
- /// Create a new instance of the data storage container.
- ///
- /// A task.
- public abstract Task Create();
-
- ///
- /// Delete the instance of the data storage container.
- ///
- /// A task.
- public abstract Task Delete();
-
- ///
- /// Determines whether a setting already exists.
- ///
- /// Key of the setting (that contains object).
- /// True if a value exists.
- public bool KeyExists(string key)
- {
- return Cache?.ContainsKey(key) ?? false;
- }
-
- ///
- /// Determines whether a setting already exists in composite.
- ///
- /// Key of the composite (that contains settings).
- /// Key of the setting (that contains object).
- /// True if a value exists.
- public bool KeyExists(string compositeKey, string key)
- {
- if (KeyExists(compositeKey))
- {
- ApplicationDataCompositeValue composite = (ApplicationDataCompositeValue)Cache[compositeKey];
- if (composite != null)
- {
- return composite.ContainsKey(key);
- }
- }
-
- return false;
- }
-
- ///
- /// Retrieves a single item by its key.
- ///
- /// Key of the object.
- /// Default value of the object.
- /// Type of object retrieved.
- /// The T object.
- public T Read(string key, T @default = default)
- {
- if (Cache != null && Cache.TryGetValue(key, out object value))
- {
- return DeserializeValue(value);
- }
-
- return @default;
- }
-
- ///
- /// Retrieves a single item by its key in composite.
- ///
- /// Key of the composite (that contains settings).
- /// Key of the object.
- /// Default value of the object.
- /// Type of object retrieved.
- /// The T object.
- public T Read(string compositeKey, string key, T @default = default)
- {
- if (Cache != null)
- {
- ApplicationDataCompositeValue composite = (ApplicationDataCompositeValue)Cache[compositeKey];
- if (composite != null)
- {
- object value = composite[key];
- if (value != null)
- {
- return DeserializeValue(value);
- }
- }
- }
-
- return @default;
- }
-
- ///
- /// Saves a single item by its key.
- ///
- /// Key of the value saved.
- /// Object to save.
- /// Type of object saved.
- public void Save(string key, T value)
- {
- // Update the cache
- Cache[key] = SerializeValue(value);
-
- if (AutoSync)
- {
- // Update the remote
- Task.Run(() => Sync());
- }
- }
-
- ///
- /// Saves a group of items by its key in a composite. This method should be considered
- /// for objects that do not exceed 8k bytes during the lifetime of the application
- /// (refers to Microsoft.Toolkit.Uwp.Helpers.IObjectStorageHelper.SaveFileAsync``1(System.String,``0)
- /// for complex/large objects) and for groups of settings which need to be treated
- /// in an atomic way.
- ///
- /// Key of the composite (that contains settings).
- /// Objects to save.
- /// Type of object saved.
- public void Save(string compositeKey, IDictionary values)
- {
- var type = typeof(T);
- var typeInfo = type.GetTypeInfo();
-
- if (KeyExists(compositeKey))
- {
- ApplicationDataCompositeValue composite = (ApplicationDataCompositeValue)Cache[compositeKey];
-
- foreach (KeyValuePair setting in values.ToList())
- {
- string key = setting.Key;
- object value = SerializeValue(setting.Value);
- if (composite.ContainsKey(setting.Key))
- {
- composite[key] = value;
- }
- else
- {
- composite.Add(key, value);
- }
- }
-
- // Update the cache
- Cache[compositeKey] = composite;
-
- if (AutoSync)
- {
- // Update the remote
- Task.Run(() => Sync());
- }
- }
- else
- {
- ApplicationDataCompositeValue composite = new ApplicationDataCompositeValue();
- foreach (KeyValuePair setting in values.ToList())
- {
- string key = setting.Key;
- object value = SerializeValue(setting.Value);
- composite.Add(key, value);
- }
-
- // Update the cache
- Cache[compositeKey] = composite;
-
- if (AutoSync)
- {
- // Update the remote
- Task.Run(() => Sync());
- }
- }
- }
-
- ///
- /// Determines whether a file already exists.
- ///
- /// Key of the file (that contains object).
- /// True if a value exists.
- public abstract Task FileExistsAsync(string filePath);
-
- ///
- /// Retrieves an object from a file.
- ///
- /// Path to the file that contains the object.
- /// Default value of the object.
- /// Type of object retrieved.
- /// Waiting task until completion with the object in the file.
- public abstract Task ReadFileAsync(string filePath, T @default = default);
-
- ///
- /// Saves an object inside a file.
- ///
- /// Path to the file that will contain the object.
- /// Object to save.
- /// Type of object saved.
- /// Waiting task until completion.
- public abstract Task SaveFileAsync(string filePath, T value);
-
- ///
- public abstract Task Sync();
-
- ///
- /// Delete the internal cache.
- ///
- protected void DeleteCache()
- {
- Cache.Clear();
- }
-
- ///
- /// Use the serializer to deserialize a value appropriately for the type.
- ///
- /// The type of object expected.
- /// The value to deserialize.
- /// An object of type T.
- protected T DeserializeValue(object value)
- {
- try
- {
- return Serializer.Deserialize((string)value);
- }
- catch
- {
- // Primitive types can't be deserialized.
- return (T)Convert.ChangeType(value, typeof(T));
- }
- }
-
- ///
- /// Use the serializer to serialize a value appropriately for the type.
- ///
- /// The type of object being serialized.
- /// The object to serialize.
- /// The serialized object.
- protected object SerializeValue(T value)
- {
- var type = typeof(T);
- var typeInfo = type.GetTypeInfo();
-
- // Skip serialization for primitives.
- if (typeInfo.IsPrimitive || type == typeof(string))
- {
- // Update the cache
- return value;
- }
- else
- {
- // Update the cache
- return Serializer.Serialize(value);
- }
- }
- }
-}
diff --git a/CommunityToolkit.Graph.Uwp/Helpers/RoamingSettings/IRoamingSettingsDataStore.cs b/CommunityToolkit.Graph.Uwp/Helpers/RoamingSettings/IRoamingSettingsDataStore.cs
deleted file mode 100644
index d5b8a67..0000000
--- a/CommunityToolkit.Graph.Uwp/Helpers/RoamingSettings/IRoamingSettingsDataStore.cs
+++ /dev/null
@@ -1,65 +0,0 @@
-// 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 System;
-using System.Collections.Generic;
-using System.Threading.Tasks;
-using Microsoft.Toolkit.Uwp.Helpers;
-
-namespace CommunityToolkit.Uwp.Graph.Helpers.RoamingSettings
-{
- ///
- /// Defines the contract for creating storage containers used for roaming data.
- ///
- public interface IRoamingSettingsDataStore : IObjectStorageHelper
- {
- ///
- /// Gets a value indicating whether the values should immediately sync or not.
- ///
- bool AutoSync { get; }
-
- ///
- /// Gets access to the key/value pairs cache directly.
- ///
- IDictionary Cache { get; }
-
- ///
- /// Gets the id of the data store.
- ///
- string Id { get; }
-
- ///
- /// Gets the id of the target user.
- ///
- string UserId { get; }
-
- ///
- /// Gets or sets an event handler for when a remote data sync completes successfully.
- ///
- EventHandler SyncCompleted { get; set; }
-
- ///
- /// Gets or sets an event handler for when a remote data sync fails.
- ///
- EventHandler SyncFailed { get; set; }
-
- ///
- /// Create a new storage container.
- ///
- /// A Task.
- Task Create();
-
- ///
- /// Delete the existing storage container.
- ///
- /// A Task.
- Task Delete();
-
- ///
- /// Syncronize the internal cache with the remote storage endpoint.
- ///
- /// A Task.
- Task Sync();
- }
-}
\ No newline at end of file
diff --git a/CommunityToolkit.Graph.Uwp/Helpers/RoamingSettings/OneDriveDataSource.cs b/CommunityToolkit.Graph.Uwp/Helpers/RoamingSettings/OneDriveDataSource.cs
deleted file mode 100644
index f5a0c66..0000000
--- a/CommunityToolkit.Graph.Uwp/Helpers/RoamingSettings/OneDriveDataSource.cs
+++ /dev/null
@@ -1,69 +0,0 @@
-// 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 System.IO;
-using System.Text;
-using System.Threading.Tasks;
-using CommunityToolkit.Authentication;
-using CommunityToolkit.Graph.Extensions;
-using Microsoft.Graph;
-using Microsoft.Toolkit.Uwp.Helpers;
-
-namespace CommunityToolkit.Uwp.Graph.Helpers.RoamingSettings
-{
- ///
- /// Helpers for interacting with files in the special OneDrive AppRoot folder.
- ///
- internal static class OneDriveDataSource
- {
- private static GraphServiceClient Graph => ProviderManager.Instance.GlobalProvider?.GetClient();
-
- // Create a new file.
- // This fails, because OneDrive doesn't like empty files. Use Update instead.
- // public static async Task Create(string fileWithExt)
- // {
- // var driveItem = new DriveItem()
- // {
- // Name = fileWithExt,
- // };
- // await Graph.Users[userId].Drive.Special.AppRoot.ItemWithPath(fileWithExt).Request().CreateAsync(driveItem);
- // }
-
- ///
- /// Updates or create a new file on the remote with the provided content.
- ///
- /// The type of object to save.
- /// A representing the asynchronous operation.
- public static async Task Update(string userId, string fileWithExt, T fileContents, IObjectSerializer serializer)
- {
- var json = serializer.Serialize(fileContents) as string;
- using var stream = new MemoryStream(Encoding.UTF8.GetBytes(json));
-
- return await Graph.Users[userId].Drive.Special.AppRoot.ItemWithPath(fileWithExt).Content.Request().PutAsync(stream);
- }
-
- ///
- /// Get a file from the remote.
- ///
- /// The type of object to return.
- /// A representing the asynchronous operation.
- public static async Task Retrieve(string userId, string fileWithExt, IObjectSerializer serializer)
- {
- Stream stream = await Graph.Users[userId].Drive.Special.AppRoot.ItemWithPath(fileWithExt).Content.Request().GetAsync();
-
- string streamContents = new StreamReader(stream).ReadToEnd();
-
- return serializer.Deserialize(streamContents);
- }
-
- ///
- /// Delete the file from the remote.
- ///
- /// A representing the asynchronous operation.
- public static async Task Delete(string userId, string fileWithExt)
- {
- await Graph.Users[userId].Drive.Special.AppRoot.ItemWithPath(fileWithExt).Request().DeleteAsync();
- }
- }
-}
diff --git a/CommunityToolkit.Graph.Uwp/Helpers/RoamingSettings/OneDriveDataStore.cs b/CommunityToolkit.Graph.Uwp/Helpers/RoamingSettings/OneDriveDataStore.cs
deleted file mode 100644
index c3b7063..0000000
--- a/CommunityToolkit.Graph.Uwp/Helpers/RoamingSettings/OneDriveDataStore.cs
+++ /dev/null
@@ -1,154 +0,0 @@
-// 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 System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
-using Microsoft.Toolkit.Uwp.Helpers;
-using Windows.Storage;
-
-namespace CommunityToolkit.Uwp.Graph.Helpers.RoamingSettings
-{
- ///
- /// A DataStore for managing roaming settings in OneDrive.
- ///
- public class OneDriveDataStore : BaseRoamingSettingsDataStore
- {
- ///
- /// Retrieve an object stored in a OneDrive file.
- ///
- /// The type of object to retrieve.
- /// The id of the target Graph user.
- /// The name of the file.
- /// An object serializer for handling deserialization.
- /// The deserialized file contents.
- public static async Task Get(string userId, string fileName, IObjectSerializer serializer)
- {
- return await OneDriveDataSource.Retrieve(userId, fileName, serializer);
- }
-
- ///
- /// Update the contents of a OneDrive file.
- ///
- /// The type of object being stored.
- /// The id of the target Graph user.
- /// The name of the file.
- /// The object to store.
- /// An object serializer for handling serialization.
- /// A task.
- public static async Task Set(string userId, string fileName, T fileContents, IObjectSerializer serializer)
- {
- await OneDriveDataSource.Update(userId, fileName, fileContents, serializer);
- }
-
- ///
- /// Delete a file from OneDrive by name.
- ///
- /// The id of the target Graph user.
- /// The name of the file.
- /// A task.
- public static async Task Delete(string userId, string fileName)
- {
- await OneDriveDataSource.Delete(userId, fileName);
- }
-
- ///
- /// Initializes a new instance of the class.
- ///
- public OneDriveDataStore(string userId, string syncDataFileName, IObjectSerializer objectSerializer, bool autoSync = true)
- : base(userId, syncDataFileName, objectSerializer, autoSync)
- {
- }
-
- ///
- public override Task Create()
- {
- return Task.CompletedTask;
- }
-
- ///
- public override async Task Delete()
- {
- // Clear the cache
- Cache.Clear();
-
- // Delete the remote.
- await Delete(UserId, Id);
- }
-
- ///
- public override async Task FileExistsAsync(string filePath)
- {
- var roamingSettings = await Get(UserId, Id, Serializer);
- return roamingSettings != null;
- }
-
- ///
- public override async Task ReadFileAsync(string filePath, T @default = default)
- {
- return await Get(UserId, filePath, Serializer) ?? @default;
- }
-
- ///
- public override async Task SaveFileAsync(string filePath, T value)
- {
- await Set(UserId, filePath, value, Serializer);
-
- // Can't convert DriveItem to StorageFile, so we return null instead.
- return null;
- }
-
- ///
- public override async Task Sync()
- {
- try
- {
- // Get the remote
- string fileName = Id;
- IDictionary remoteData = null;
- try
- {
- remoteData = await Get>(UserId, fileName, Serializer);
- }
- catch
- {
- // If get fails, we know the remote store does not exist.
- }
-
- bool needsUpdate = false;
- if (remoteData != null)
- {
- // Update local cache with additions from remote
- foreach (string key in remoteData.Keys.ToList())
- {
- // Only insert new values. Existing keys should be overwritten on the remote.
- if (!Cache.ContainsKey(key))
- {
- Cache.Add(key, remoteData[key]);
- needsUpdate = true;
- }
- }
- }
- else if (Cache.Count > 0)
- {
- // The remote does not yet exist, and we have data to save.
- needsUpdate = true;
- }
-
- if (needsUpdate)
- {
- // Send updates for local values, overwriting the remote.
- await Set(UserId, fileName, Cache, Serializer);
- }
-
- SyncCompleted?.Invoke(this, new EventArgs());
- }
- catch
- {
- SyncFailed?.Invoke(this, new EventArgs());
- }
- }
- }
-}
diff --git a/CommunityToolkit.Graph.Uwp/Helpers/RoamingSettings/RoamingSettingsHelper.cs b/CommunityToolkit.Graph.Uwp/Helpers/RoamingSettings/RoamingSettingsHelper.cs
deleted file mode 100644
index c160e0d..0000000
--- a/CommunityToolkit.Graph.Uwp/Helpers/RoamingSettings/RoamingSettingsHelper.cs
+++ /dev/null
@@ -1,188 +0,0 @@
-// 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 System;
-using System.Collections.Generic;
-using System.Threading.Tasks;
-using CommunityToolkit.Authentication;
-using CommunityToolkit.Graph.Extensions;
-using Microsoft.Toolkit.Uwp.Helpers;
-using Windows.Storage;
-
-namespace CommunityToolkit.Uwp.Graph.Helpers.RoamingSettings
-{
- ///
- /// An enumeration of the available data storage methods for roaming data.
- ///
- public enum RoamingDataStore
- {
- ///
- /// Store data using open extensions on the Graph User.
- ///
- UserExtensions,
-
- ///
- /// Store data in a Graph User's OneDrive.
- ///
- OneDrive,
- }
-
- ///
- /// A helper class for syncing data to roaming data store.
- ///
- public class RoamingSettingsHelper : IRoamingSettingsDataStore
- {
- ///
- /// Gets the internal data store instance.
- ///
- public IRoamingSettingsDataStore DataStore { get; private set; }
-
- ///
- public EventHandler SyncCompleted { get; set; }
-
- ///
- public EventHandler SyncFailed { get; set; }
-
- ///
- public bool AutoSync => DataStore.AutoSync;
-
- ///
- public IDictionary Cache => DataStore.Cache;
-
- ///
- public string Id => DataStore.Id;
-
- ///
- public string UserId => DataStore.UserId;
-
- ///
- /// Creates a new RoamingSettingsHelper instance for the currently signed in user.
- ///
- /// Which specific data store is being used.
- /// Whether the values should immediately sync or not.
- /// Whether the values should immediately sync on change or wait until Sync is called explicitly.
- /// An object serializer for serialization of objects in the data store.
- /// A new instance of the RoamingSettingsHelper configured for the current user.
- public static async Task CreateForCurrentUser(RoamingDataStore dataStore = RoamingDataStore.UserExtensions, bool syncOnInit = true, bool autoSync = true, IObjectSerializer serializer = null)
- {
- var provider = ProviderManager.Instance.GlobalProvider;
- if (provider == null || provider.State != ProviderState.SignedIn)
- {
- throw new InvalidOperationException("The GlobalProvider must be set and signed in to create a new RoamingSettingsHelper for the current user.");
- }
-
- var me = await provider.GetClient().Me.Request().GetAsync();
- return new RoamingSettingsHelper(me.Id, dataStore, syncOnInit, autoSync, serializer);
- }
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The id of the target Graph User.
- /// Which specific data store is being used.
- /// Whether the values should immediately sync or not.
- /// Whether the values should immediately sync on change or wait until Sync is called explicitly.
- /// An object serializer for serialization of objects in the data store.
- public RoamingSettingsHelper(string userId, RoamingDataStore dataStore = RoamingDataStore.UserExtensions, bool syncOnInit = true, bool autoSync = true, IObjectSerializer serializer = null)
- {
- // TODO: Infuse unique identifier from Graph registration into the storage name.
- string dataStoreName = "communityToolkit.roamingSettings";
-
- if (serializer == null)
- {
- serializer = new SystemSerializer();
- }
-
- switch (dataStore)
- {
- case RoamingDataStore.UserExtensions:
- DataStore = new UserExtensionDataStore(userId, dataStoreName, serializer, autoSync);
- break;
-
- case RoamingDataStore.OneDrive:
- DataStore = new OneDriveDataStore(userId, dataStoreName, serializer, autoSync);
- break;
-
- default:
- throw new ArgumentOutOfRangeException(nameof(dataStore));
- }
-
- DataStore.SyncCompleted += (s, e) => SyncCompleted?.Invoke(this, e);
- DataStore.SyncFailed += (s, e) => SyncFailed?.Invoke(this, e);
-
- if (syncOnInit)
- {
- _ = Sync();
- }
- }
-
- ///
- /// An indexer for easily accessing key values.
- ///
- /// The key for the desired value.
- /// The value found for the provided key.
- public object this[string key]
- {
- get => DataStore.Read(key);
- set => DataStore.Save(key, value);
- }
-
- ///
- public Task FileExistsAsync(string filePath) => DataStore.FileExistsAsync(filePath);
-
- ///
- public bool KeyExists(string key) => DataStore.KeyExists(key);
-
- ///
- public bool KeyExists(string compositeKey, string key) => DataStore.KeyExists(compositeKey, key);
-
- ///
- public T Read(string key, T @default = default) => DataStore.Read(key, @default);
-
- ///
- public T Read(string compositeKey, string key, T @default = default) => DataStore.Read(compositeKey, key, @default);
-
- ///
- public Task ReadFileAsync(string filePath, T @default = default) => DataStore.ReadFileAsync(filePath, @default);
-
- ///
- public void Save(string key, T value) => DataStore.Save(key, value);
-
- ///
- public void Save(string compositeKey, IDictionary values) => DataStore.Save(compositeKey, values);
-
- ///
- public Task SaveFileAsync(string filePath, T value) => DataStore.SaveFileAsync(filePath, value);
-
- ///
- /// Create a new storage container.
- ///
- /// A Task.
- public Task Create() => DataStore.Create();
-
- ///
- /// Delete the existing storage container.
- ///
- /// A Task.
- public Task Delete() => DataStore.Delete();
-
- ///
- /// Syncronize the internal cache with the remote storage endpoint.
- ///
- /// A Task.
- public async Task Sync()
- {
- try
- {
- await DataStore.Sync();
- }
- catch
- {
- // Sync may fail if the storage container does not yet exist.
- await DataStore.Create();
- await DataStore.Sync();
- }
- }
- }
-}
\ No newline at end of file
diff --git a/CommunityToolkit.Graph.Uwp/Helpers/RoamingSettings/UserExtensionDataStore.cs b/CommunityToolkit.Graph.Uwp/Helpers/RoamingSettings/UserExtensionDataStore.cs
deleted file mode 100644
index ff4d884..0000000
--- a/CommunityToolkit.Graph.Uwp/Helpers/RoamingSettings/UserExtensionDataStore.cs
+++ /dev/null
@@ -1,201 +0,0 @@
-// 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 System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
-using Microsoft.Graph;
-using Microsoft.Toolkit.Uwp.Helpers;
-using Windows.Storage;
-
-namespace CommunityToolkit.Uwp.Graph.Helpers.RoamingSettings
-{
- ///
- /// An IObjectStorageHelper implementation using open extensions on the Graph User for storing key/value pairs.
- ///
- public class UserExtensionDataStore : BaseRoamingSettingsDataStore
- {
- ///
- /// Retrieve the value from Graph User extensions and cast the response to the provided type.
- ///
- /// The type to cast the return result to.
- /// The id of the user.
- /// The id of the user extension.
- /// The key for the desired value.
- /// The value from the data store.
- public static async Task Get(string userId, string extensionId, string key)
- {
- return (T)await Get(userId, extensionId, key);
- }
-
- ///
- /// Retrieve the value from Graph User extensions by extensionId, userId, and key.
- ///
- /// The id of the user.
- /// The id of the user extension.
- /// The key for the desired value.
- /// The value from the data store.
- public static async Task Get(string userId, string extensionId, string key)
- {
- var userExtension = await GetExtensionForUser(userId, extensionId);
- return userExtension.AdditionalData[key];
- }
-
- ///
- /// Set a value by key in a Graph User's extension.
- ///
- /// The id of the user.
- /// The id of the user extension.
- /// The key for the target value.
- /// The value to set.
- /// A task upon completion.
- public static async Task Set(string userId, string extensionId, string key, object value)
- {
- await UserExtensionsDataSource.SetValue(userId, extensionId, key, value);
- }
-
- ///
- /// Creates a new roaming settings extension on a Graph User.
- ///
- /// The id of the user.
- /// The id of the user extension.
- /// The newly created user extension.
- public static async Task Create(string userId, string extensionId)
- {
- var userExtension = await UserExtensionsDataSource.CreateExtension(userId, extensionId);
- return userExtension;
- }
-
- ///
- /// Deletes an extension by id on a Graph User.
- ///
- /// The id of the user.
- /// The id of the user extension.
- /// A task upon completion.
- public static async Task Delete(string userId, string extensionId)
- {
- await UserExtensionsDataSource.DeleteExtension(userId, extensionId);
- }
-
- ///
- /// Retrieves a user extension.
- ///
- /// The id of the user.
- /// The id of the user extension.
- /// The target extension.
- public static async Task GetExtensionForUser(string userId, string extensionId)
- {
- var userExtension = await UserExtensionsDataSource.GetExtension(userId, extensionId);
- return userExtension;
- }
-
- private static readonly IList ReservedKeys = new List { "responseHeaders", "statusCode", "@odata.context" };
-
- ///
- /// Initializes a new instance of the class.
- ///
- public UserExtensionDataStore(string userId, string extensionId, IObjectSerializer objectSerializer, bool autoSync = true)
- : base(userId, extensionId, objectSerializer, autoSync)
- {
- }
-
- ///
- /// Creates a new roaming settings extension on the Graph User.
- ///
- /// The newly created Extension object.
- public override async Task Create()
- {
- await Create(UserId, Id);
- }
-
- ///
- /// Deletes the roamingSettings extension from the Graph User.
- ///
- /// A void task.
- public override async Task Delete()
- {
- // Delete the cache
- Cache.Clear();
-
- // Delete the remote.
- await Delete(UserId, Id);
- }
-
- ///
- /// Update the remote extension to match the local cache and retrieve any new keys. Any existing remote values are replaced.
- ///
- /// The freshly synced user extension.
- public override async Task Sync()
- {
- try
- {
- IDictionary remoteData = null;
-
- try
- {
- // Get the remote
- Extension extension = await GetExtensionForUser(UserId, Id);
- remoteData = extension.AdditionalData;
- }
- catch
- {
- }
-
- if (Cache != null)
- {
- // Send updates for all local values, overwriting the remote.
- foreach (string key in Cache.Keys.ToList())
- {
- if (ReservedKeys.Contains(key))
- {
- continue;
- }
-
- if (remoteData == null || !remoteData.ContainsKey(key) || !EqualityComparer.Default.Equals(remoteData[key], Cache[key]))
- {
- Save(key, Cache[key]);
- }
- }
- }
-
- if (remoteData != null)
- {
- // Update local cache with additions from remote
- foreach (string key in remoteData.Keys.ToList())
- {
- if (!Cache.ContainsKey(key))
- {
- Cache.Add(key, remoteData[key]);
- }
- }
- }
-
- SyncCompleted?.Invoke(this, new EventArgs());
- }
- catch
- {
- SyncFailed?.Invoke(this, new EventArgs());
- }
- }
-
- ///
- public override Task FileExistsAsync(string filePath)
- {
- throw new NotImplementedException();
- }
-
- ///
- public override Task ReadFileAsync(string filePath, T @default = default)
- {
- throw new NotImplementedException();
- }
-
- ///
- public override Task SaveFileAsync(string filePath, T value)
- {
- throw new NotImplementedException();
- }
- }
-}
\ No newline at end of file
diff --git a/CommunityToolkit.Graph.Uwp/Helpers/RoamingSettings/UserExtensionsDataSource.cs b/CommunityToolkit.Graph.Uwp/Helpers/RoamingSettings/UserExtensionsDataSource.cs
deleted file mode 100644
index 32b5d38..0000000
--- a/CommunityToolkit.Graph.Uwp/Helpers/RoamingSettings/UserExtensionsDataSource.cs
+++ /dev/null
@@ -1,204 +0,0 @@
-// 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 System;
-using System.Collections.Generic;
-using System.Net.Http;
-using System.Threading.Tasks;
-using CommunityToolkit.Authentication;
-using CommunityToolkit.Graph.Extensions;
-using Microsoft.Graph;
-
-namespace CommunityToolkit.Uwp.Graph.Helpers.RoamingSettings
-{
- ///
- /// Manages Graph interaction with open extensions on the user.
- ///
- internal static class UserExtensionsDataSource
- {
- private static GraphServiceClient Graph => ProviderManager.Instance.GlobalProvider?.GetClient();
-
- ///
- /// Retrieve an extension object for a user.
- ///
- /// The user to access.
- /// The extension to retrieve.
- /// The extension result.
- public static async Task GetExtension(string userId, string extensionId)
- {
- if (string.IsNullOrWhiteSpace(extensionId))
- {
- throw new ArgumentNullException(nameof(extensionId));
- }
-
- if (string.IsNullOrWhiteSpace(userId))
- {
- throw new ArgumentNullException(nameof(userId));
- }
-
- var extension = await Graph.Users[userId].Extensions[extensionId].Request().GetAsync();
- return extension;
- }
-
- ///
- /// Get all extension objects for a user.
- ///
- /// The user to access.
- /// All extension results.
- public static async Task> GetAllExtensions(string userId)
- {
- if (string.IsNullOrWhiteSpace(userId))
- {
- throw new ArgumentNullException(nameof(userId));
- }
-
- var extensions = await Graph.Users[userId].Extensions.Request().GetAsync();
- return extensions;
- }
-
- ///
- /// Create a new extension object on a user.
- ///
- /// The user to access.
- /// The id of the new extension.
- /// The newly created extension.
- public static async Task CreateExtension(string userId, string extensionId)
- {
- if (string.IsNullOrWhiteSpace(extensionId))
- {
- throw new ArgumentNullException(nameof(extensionId));
- }
-
- if (string.IsNullOrWhiteSpace(userId))
- {
- throw new ArgumentNullException(nameof(userId));
- }
-
- try
- {
- // Try to see if the extension already exists.
- return await GetExtension(userId, extensionId);
- }
- catch
- {
- }
-
- string requestUrl = Graph.Users[userId].Extensions.Request().RequestUrl;
-
- string json = "{" +
- "\"@odata.type\": \"microsoft.graph.openTypeExtension\"," +
- "\"extensionName\": \"" + extensionId + "\"," +
- "}";
-
- HttpRequestMessage hrm = new HttpRequestMessage(HttpMethod.Post, requestUrl);
- hrm.Content = new StringContent(json, System.Text.Encoding.UTF8, "application/json");
- await Graph.AuthenticationProvider.AuthenticateRequestAsync(hrm);
- HttpResponseMessage response = await Graph.HttpProvider.SendAsync(hrm);
- if (response.IsSuccessStatusCode)
- {
- // Deserialize into Extension object.
- var content = await response.Content.ReadAsStringAsync();
- var extension = Graph.HttpProvider.Serializer.DeserializeObject(content);
- return extension;
- }
-
- return null;
- }
-
- ///
- /// Delete a user extension by id.
- ///
- /// The user to access.
- /// The id of the extension to delete.
- /// A task.
- public static async Task DeleteExtension(string userId, string extensionId)
- {
- if (string.IsNullOrWhiteSpace(extensionId))
- {
- throw new ArgumentNullException(nameof(extensionId));
- }
-
- if (string.IsNullOrWhiteSpace(userId))
- {
- throw new ArgumentNullException(nameof(userId));
- }
-
- try
- {
- await GetExtension(userId, extensionId);
- }
- catch
- {
- // If we can't retrieve the extension, it must not exist.
- return;
- }
-
- await Graph.Users[userId].Extensions[extensionId].Request().DeleteAsync();
- }
-
- ///
- /// Get a value from an extension by key.
- ///
- /// The type of object to return.
- /// The target extension.
- /// The key for the desired value.
- /// The value for the provided key.
- public static T GetValue(this Extension extension, string key)
- {
- return (T)GetValue(extension, key);
- }
-
- ///
- /// Get a value from a user extension by key.
- ///
- /// The target extension.
- /// The key for the desired value.
- /// The value for the provided key.
- public static object GetValue(this Extension extension, string key)
- {
- if (string.IsNullOrWhiteSpace(key))
- {
- throw new ArgumentNullException(nameof(key));
- }
-
- if (extension.AdditionalData.ContainsKey(key))
- {
- return extension.AdditionalData[key];
- }
-
- return null;
- }
-
- ///
- /// Sets a user extension value at the specified key.
- ///
- /// The user to access.
- /// The id of the target extension.
- /// The key.
- /// The value to set.
- /// A task.
- public static async Task SetValue(string userId, string extensionId, string key, object value)
- {
- if (string.IsNullOrWhiteSpace(userId))
- {
- throw new ArgumentNullException(nameof(userId));
- }
-
- if (string.IsNullOrWhiteSpace(extensionId))
- {
- throw new ArgumentNullException(nameof(extensionId));
- }
-
- if (string.IsNullOrWhiteSpace(key))
- {
- throw new ArgumentNullException(nameof(key));
- }
-
- var extensionToUpdate = (Extension)Activator.CreateInstance(typeof(Extension), true);
- extensionToUpdate.AdditionalData = new Dictionary() { { key, value } };
-
- await Graph.Users[userId].Extensions[extensionId].Request().UpdateAsync(extensionToUpdate);
- }
- }
-}
\ No newline at end of file
diff --git a/CommunityToolkit.Graph.Uwp/Properties/AssemblyInfo.cs b/CommunityToolkit.Graph.Uwp/Properties/AssemblyInfo.cs
deleted file mode 100644
index c244792..0000000
--- a/CommunityToolkit.Graph.Uwp/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-// 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 System.Resources;
-using System.Runtime.CompilerServices;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: NeutralResourcesLanguage("en-US")]
\ No newline at end of file
diff --git a/CommunityToolkit.Graph.Uwp/Properties/CommunityToolkit.Uwp.Graph.Controls.rd.xml b/CommunityToolkit.Graph.Uwp/Properties/CommunityToolkit.Uwp.Graph.Controls.rd.xml
deleted file mode 100644
index 419fe19..0000000
--- a/CommunityToolkit.Graph.Uwp/Properties/CommunityToolkit.Uwp.Graph.Controls.rd.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
-
diff --git a/CommunityToolkit.Graph.Uwp/Themes/Generic.xaml b/CommunityToolkit.Graph.Uwp/Themes/Generic.xaml
deleted file mode 100644
index 93e8a92..0000000
--- a/CommunityToolkit.Graph.Uwp/Themes/Generic.xaml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/CommunityToolkit.Graph.Uwp/VisualStudioToolsManifest.xml b/CommunityToolkit.Graph.Uwp/VisualStudioToolsManifest.xml
deleted file mode 100644
index 1232610..0000000
--- a/CommunityToolkit.Graph.Uwp/VisualStudioToolsManifest.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/CommunityToolkit.Graph/CommunityToolkit.Graph.csproj b/CommunityToolkit.Graph/CommunityToolkit.Graph.csproj
index 8d501e3..7d3ef51 100644
--- a/CommunityToolkit.Graph/CommunityToolkit.Graph.csproj
+++ b/CommunityToolkit.Graph/CommunityToolkit.Graph.csproj
@@ -6,7 +6,6 @@
Windows Community Toolkit .NET Standard Graph Services
This package includes .NET Standard code helpers such as:
- - GraphExtensions: Helpers for common tasks related to the Microsoft Graph used by the Microsoft.Toolkit.Graph.Controls.
- ProviderExtensions: Extension on IProvider for accessing a pre-configured GraphServiceClient instance.
Windows Community Toolkit Graph Provider Extensions
diff --git a/CommunityToolkit.Graph/Extensions/GraphExtensions.People.cs b/CommunityToolkit.Graph/Extensions/GraphExtensions.People.cs
deleted file mode 100644
index dccc79f..0000000
--- a/CommunityToolkit.Graph/Extensions/GraphExtensions.People.cs
+++ /dev/null
@@ -1,40 +0,0 @@
-// 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 System.Threading.Tasks;
-using Microsoft.Graph;
-
-namespace CommunityToolkit.Graph.Extensions
-{
- ///
- /// People focused extension methods to the Graph SDK used by the controls and helpers.
- ///
- public static partial class GraphExtensions
- {
- ///
- /// Shortcut to perform a person query.
- ///
- /// Instance of the .
- /// User to search for.
- /// collection of .
- public static async Task FindPersonAsync(this GraphServiceClient graph, string query)
- {
- try
- {
- return await graph
- .Me
- .People
- .Request()
- .Search(query)
- ////.WithScopes(new string[] { "people.read" })
- .GetAsync();
- }
- catch
- {
- }
-
- return new UserPeopleCollectionPage();
- }
- }
-}
diff --git a/CommunityToolkit.Graph/Extensions/GraphExtensions.Users.cs b/CommunityToolkit.Graph/Extensions/GraphExtensions.Users.cs
deleted file mode 100644
index 7f0d381..0000000
--- a/CommunityToolkit.Graph/Extensions/GraphExtensions.Users.cs
+++ /dev/null
@@ -1,126 +0,0 @@
-// 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 System.IO;
-using System.Threading.Tasks;
-using Microsoft.Graph;
-
-namespace CommunityToolkit.Graph.Extensions
-{
- ///
- /// User focused extension methods to the Graph SDK used by the controls and helpers.
- ///
- public static partial class GraphExtensions
- {
- ///
- /// Retrieve the curernt user.
- ///
- /// Instance of the .
- /// A representing the asynchronous operation.
- public static async Task GetMeAsync(this GraphServiceClient graph)
- {
- try
- {
- return await graph.Me.Request().GetAsync();
- }
- catch
- {
- }
-
- return null;
- }
-
- ///
- /// Retrieve a user by id.
- ///
- /// Instance of the .
- /// The is of the user to retrieve.
- /// A representing the asynchronous operation.
- public static async Task GetUserAsync(this GraphServiceClient graph, string userId)
- {
- try
- {
- return await graph.Users[userId].Request().GetAsync();
- }
- catch
- {
- }
-
- return null;
- }
-
- ///
- /// Shortcut to perform a user query.
- ///
- /// Instance of the .
- /// User to search for.
- /// collection of .
- public static async Task FindUserAsync(this GraphServiceClient graph, string query)
- {
- try
- {
- return await graph
- .Users
- .Request()
- .Filter($"startswith(displayName, '{query}') or startswith(givenName, '{query}') or startswith(surname, '{query}') or startswith(mail, '{query}') or startswith(userPrincipalName, '{query}')")
- ////.WithScopes(new string[] { "user.readbasic.all" })
- .GetAsync();
- }
- catch
- {
- }
-
- return new GraphServiceUsersCollectionPage();
- }
-
- ///
- /// Helper to get the photo of a particular user.
- ///
- /// Instance of the .
- /// UserID.
- /// Stream with user photo or null.
- public static async Task GetUserPhoto(this GraphServiceClient graph, string userId)
- {
- try
- {
- return await graph
- .Users[userId]
- .Photo
- .Content
- .Request()
- ////.WithScopes(new string[] { "user.readbasic.all" })
- .GetAsync();
- }
- catch
- {
- }
-
- return null;
- }
-
- ///
- /// Get the photo of the current user.
- ///
- /// Instance of the .
- /// Stream with user photo or null.
- public static async Task GetMyPhotoAsync(this GraphServiceClient graph)
- {
- try
- {
- return await graph
- .Me
- .Photo
- .Content
- .Request()
- ////.WithScopes(new string[] { "user.read" })
- .GetAsync();
- }
- catch
- {
- }
-
- return null;
- }
- }
-}
diff --git a/CommunityToolkit.Graph/Extensions/GraphExtensions.cs b/CommunityToolkit.Graph/Extensions/GraphExtensions.cs
deleted file mode 100644
index 118dba6..0000000
--- a/CommunityToolkit.Graph/Extensions/GraphExtensions.cs
+++ /dev/null
@@ -1,63 +0,0 @@
-// 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 Microsoft.Graph;
-
-namespace CommunityToolkit.Graph.Extensions
-{
- ///
- /// Extension methods to the Graph SDK used by the controls and helpers.
- ///
- public static partial class GraphExtensions
- {
- ///
- /// Simple method to convert a to a with basic common properties like , , , , and intact.
- ///
- /// instance to convert.
- /// A new basic representation of that user.
- public static Person ToPerson(this User user)
- {
- return new Person()
- {
- // Primary Id
- Id = user.Id,
- UserPrincipalName = user.UserPrincipalName,
-
- // Standard User Info
- DisplayName = user.DisplayName,
- ScoredEmailAddresses = new ScoredEmailAddress[]
- {
- new ScoredEmailAddress()
- {
- Address = user.Mail ?? user.UserPrincipalName,
- },
- },
- GivenName = user.GivenName,
- Surname = user.Surname,
-
- // Company Information
- CompanyName = user.CompanyName,
- Department = user.Department,
- JobTitle = user.JobTitle,
- OfficeLocation = user.OfficeLocation,
- };
- }
-
- ///
- /// Extension to provider Searching on OData Requests.
- ///
- /// type.
- /// Request chain.
- /// Query to add for searching in QueryOptions.
- /// Same type.
- public static T Search(this T request, string query)
- where T : IBaseRequest
- {
- // Need quotes around query for e-mail searches: https://docs.microsoft.com/en-us/graph/people-example#perform-a-fuzzy-search
- request.QueryOptions?.Add(new QueryOption("$search", '"' + query + '"'));
-
- return request;
- }
- }
-}
diff --git a/SampleTest/App.xaml b/SampleTest/App.xaml
deleted file mode 100644
index 13f775b..0000000
--- a/SampleTest/App.xaml
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
diff --git a/SampleTest/App.xaml.cs b/SampleTest/App.xaml.cs
deleted file mode 100644
index b12e662..0000000
--- a/SampleTest/App.xaml.cs
+++ /dev/null
@@ -1,146 +0,0 @@
-// 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 System;
-using Windows.ApplicationModel;
-using Windows.ApplicationModel.Activation;
-using Windows.UI.Xaml;
-using Windows.UI.Xaml.Controls;
-using Windows.UI.Xaml.Navigation;
-
-namespace SampleTest
-{
- ///
- /// Provides application-specific behavior to supplement the default Application class.
- ///
- sealed partial class App : Application
- {
- ///
- /// Initializes the singleton application object. This is the first line of authored code
- /// executed, and as such is the logical equivalent of main() or WinMain().
- ///
- public App()
- {
- this.InitializeComponent();
- this.Suspending += OnSuspending;
- }
-
- // Which provider should be used for authentication?
- private readonly ProviderType _providerType = ProviderType.Mock;
-
- // List of available authentication providers.
- private enum ProviderType
- {
- Mock,
- Msal,
- Windows
- }
-
- ///
- /// Initialize the global authentication provider.
- ///
- private async void InitializeGlobalProvider()
- {
- if (ProviderManager.Instance.GlobalProvider != null)
- {
- return;
- }
-
- await Window.Current.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
- {
- // Provider config
- string clientId = "YOUR_CLIENT_ID_HERE";
- string[] scopes = { "User.Read", "User.ReadBasic.All", "People.Read", "Calendars.Read", "Mail.Read", "Group.Read.All", "ChannelMessage.Read.All" };
- bool autoSignIn = true;
-
- switch (_providerType)
- {
- // Mock provider
- case ProviderType.Mock:
- ProviderManager.Instance.GlobalProvider = new MockProvider(signedIn: autoSignIn);
- break;
-
- // Msal provider
- case ProviderType.Msal:
- ProviderManager.Instance.GlobalProvider = new MsalProvider(clientId: clientId, scopes: scopes, autoSignIn: autoSignIn);
- break;
-
- // Windows provider
- case ProviderType.Windows:
- var webAccountProviderConfig = new WebAccountProviderConfig(WebAccountProviderType.Msa, clientId);
- ProviderManager.Instance.GlobalProvider = new WindowsProvider(scopes, webAccountProviderConfig: webAccountProviderConfig, autoSignIn: autoSignIn);
- break;
- }
- });
- }
-
- ///
- /// Invoked when the application is launched normally by the end user. Other entry points
- /// will be used such as when the application is launched to open a specific file.
- ///
- /// Details about the launch request and process.
- protected override void OnLaunched(LaunchActivatedEventArgs e)
- {
- Frame rootFrame = Window.Current.Content as Frame;
-
- // Do not repeat app initialization when the Window already has content,
- // just ensure that the window is active
- if (rootFrame == null)
- {
- // Create a Frame to act as the navigation context and navigate to the first page
- rootFrame = new Frame();
-
- rootFrame.NavigationFailed += OnNavigationFailed;
-
- if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
- {
- //TODO: Load state from previously suspended application
- }
-
- // Place the frame in the current Window
- Window.Current.Content = rootFrame;
- }
-
- if (e.PrelaunchActivated == false)
- {
- if (rootFrame.Content == null)
- {
- // When the navigation stack isn't restored navigate to the first page,
- // configuring the new page by passing required information as a navigation
- // parameter
- rootFrame.Navigate(typeof(MainPage), e.Arguments);
- }
- // Ensure the current window is active
- Window.Current.Activate();
-
- InitializeGlobalProvider();
- }
- }
-
- ///
- /// Invoked when Navigation to a certain page fails
- ///
- /// The Frame which failed navigation
- /// Details about the navigation failure
- void OnNavigationFailed(object sender, NavigationFailedEventArgs e)
- {
- throw new Exception("Failed to load Page " + e.SourcePageType.FullName);
- }
-
- ///
- /// Invoked when application execution is being suspended. Application state is saved
- /// without knowing whether the application will be terminated or resumed with the contents
- /// of memory still intact.
- ///
- /// The source of the suspend request.
- /// Details about the suspend request.
- private void OnSuspending(object sender, SuspendingEventArgs e)
- {
- var deferral = e.SuspendingOperation.GetDeferral();
- //TODO: Save application state and stop any background activity
- deferral.Complete();
- }
- }
-}
diff --git a/SampleTest/Assets/FileIcon.png b/SampleTest/Assets/FileIcon.png
deleted file mode 100644
index 0435822..0000000
Binary files a/SampleTest/Assets/FileIcon.png and /dev/null differ
diff --git a/SampleTest/Assets/LockScreenLogo.scale-200.png b/SampleTest/Assets/LockScreenLogo.scale-200.png
deleted file mode 100644
index 735f57a..0000000
Binary files a/SampleTest/Assets/LockScreenLogo.scale-200.png and /dev/null differ
diff --git a/SampleTest/Assets/SplashScreen.scale-200.png b/SampleTest/Assets/SplashScreen.scale-200.png
deleted file mode 100644
index 023e7f1..0000000
Binary files a/SampleTest/Assets/SplashScreen.scale-200.png and /dev/null differ
diff --git a/SampleTest/Assets/Square150x150Logo.scale-200.png b/SampleTest/Assets/Square150x150Logo.scale-200.png
deleted file mode 100644
index af49fec..0000000
Binary files a/SampleTest/Assets/Square150x150Logo.scale-200.png and /dev/null differ
diff --git a/SampleTest/Assets/Square44x44Logo.scale-200.png b/SampleTest/Assets/Square44x44Logo.scale-200.png
deleted file mode 100644
index ce342a2..0000000
Binary files a/SampleTest/Assets/Square44x44Logo.scale-200.png and /dev/null differ
diff --git a/SampleTest/Assets/Square44x44Logo.targetsize-24_altform-unplated.png b/SampleTest/Assets/Square44x44Logo.targetsize-24_altform-unplated.png
deleted file mode 100644
index f6c02ce..0000000
Binary files a/SampleTest/Assets/Square44x44Logo.targetsize-24_altform-unplated.png and /dev/null differ
diff --git a/SampleTest/Assets/StoreLogo.png b/SampleTest/Assets/StoreLogo.png
deleted file mode 100644
index 7385b56..0000000
Binary files a/SampleTest/Assets/StoreLogo.png and /dev/null differ
diff --git a/SampleTest/Assets/Wide310x150Logo.scale-200.png b/SampleTest/Assets/Wide310x150Logo.scale-200.png
deleted file mode 100644
index 288995b..0000000
Binary files a/SampleTest/Assets/Wide310x150Logo.scale-200.png and /dev/null differ
diff --git a/SampleTest/MainPage.xaml b/SampleTest/MainPage.xaml
deleted file mode 100644
index 76dcd4a..0000000
--- a/SampleTest/MainPage.xaml
+++ /dev/null
@@ -1,309 +0,0 @@
-
-
-
-
-
-
-
-
-
-
- The `LoginButton` above allows your user and application to easily connect to the Microsoft Graph. They can then also easily logout from the drop-down menu.
-
-
-
-
-
-
-
-
-
- The `PeoplePicker` lets a logged in user easily search for familiar people they interact with or contacts. Great for emails or messages.
-
-
-
- Picked People:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- The `GraphPresenter` is a unique control in the library which makes it easier for a developer to make any graph call and configure a nice display template in XAML. This opens up a world of possibilities for many uses outside of any other control available within this library. You can see a few examples of what's possible below.
-
-
-
-
-
-
-
-
-
-
-
-
- The following example shows the `Me.CalendarView` API.
-
- My Upcoming Calendar Events:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- The following example shows the `Me.Messages` API for getting a user's inbox mail messages.
-
- My Messages:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- The following example shows the `Me.Planner.Tasks` API for getting a user's tasks.
-
- My Tasks:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Due
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- The following example shows the beta `Teams/id/Channels/id/messages` API for getting a list of messages (without replies) from a Channel in Teams.
-
- My Chat Messages:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/SampleTest/MainPage.xaml.cs b/SampleTest/MainPage.xaml.cs
deleted file mode 100644
index 248db96..0000000
--- a/SampleTest/MainPage.xaml.cs
+++ /dev/null
@@ -1,83 +0,0 @@
-// 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 CommunityToolkit.Graph.Extensions;
-using Microsoft.Graph;
-using Microsoft.Graph.Extensions;
-using System;
-using System.Text.RegularExpressions;
-using Windows.UI.Xaml.Controls;
-
-namespace SampleTest
-{
- ///
- /// An empty page that can be used on its own or navigated to within a Frame.
- ///
- public sealed partial class MainPage : Page
- {
- // Workaround for https://github.com/microsoft/microsoft-ui-xaml/issues/2407
- public DateTime Today => DateTimeOffset.Now.Date.ToUniversalTime();
-
- // Workaround for https://github.com/microsoft/microsoft-ui-xaml/issues/2407
- public DateTime ThreeDaysFromNow => Today.AddDays(3);
-
- public IBaseRequestBuilder CalendarViewBuilder;
- public IBaseRequestBuilder MessagesBuilder;
- public IBaseRequestBuilder PlannerTasksBuilder;
- public IBaseRequestBuilder TeamsChannelMessagesBuilder;
-
- public MainPage()
- {
- this.InitializeComponent();
-
- ProviderManager.Instance.ProviderUpdated += this.OnProviderUpdated;
- }
-
- private void OnProviderUpdated(object sender, ProviderUpdatedEventArgs e)
- {
- if (e.Reason == ProviderManagerChangedState.ProviderStateChanged
- && sender is ProviderManager pm
- && pm.GlobalProvider.State == ProviderState.SignedIn)
- {
- var graphClient = ProviderManager.Instance.GlobalProvider.GetClient();
-
- CalendarViewBuilder = graphClient.Me.CalendarView;
- MessagesBuilder = graphClient.Me.Messages;
- PlannerTasksBuilder = graphClient.Me.Planner.Tasks;
- TeamsChannelMessagesBuilder = graphClient.Teams["02bd9fd6-8f93-4758-87c3-1fb73740a315"].Channels["19:d0bba23c2fc8413991125a43a54cc30e@thread.skype"].Messages;
- }
- else
- {
- CalendarViewBuilder = null;
- MessagesBuilder = null;
- PlannerTasksBuilder = null;
- TeamsChannelMessagesBuilder = null;
- }
- }
-
- public static string ToLocalTime(DateTimeTimeZone value)
- {
- // Workaround for https://github.com/microsoft/microsoft-ui-xaml/issues/2407
- return value.ToDateTimeOffset().LocalDateTime.ToString("g");
- }
-
- public static string ToLocalTime(DateTimeOffset? value)
- {
- // Workaround for https://github.com/microsoft/microsoft-ui-xaml/issues/2654
- return value?.LocalDateTime.ToString("g");
- }
-
- public static string RemoveWhitespace(string value)
- {
- // Workaround for https://github.com/microsoft/microsoft-ui-xaml/issues/2654
- return Regex.Replace(value, @"\t|\r|\n", " ");
- }
-
- public static bool IsTaskCompleted(int? percentCompleted)
- {
- return percentCompleted == 100;
- }
- }
-}
diff --git a/SampleTest/Package.appxmanifest b/SampleTest/Package.appxmanifest
deleted file mode 100644
index 2b919ae..0000000
--- a/SampleTest/Package.appxmanifest
+++ /dev/null
@@ -1,49 +0,0 @@
-
-
-
-
-
-
-
-
-
- SampleTest
- Microsoft
- Assets\StoreLogo.png
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/SampleTest/Properties/AssemblyInfo.cs b/SampleTest/Properties/AssemblyInfo.cs
deleted file mode 100644
index 67a172e..0000000
--- a/SampleTest/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,31 +0,0 @@
-// 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 System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("SampleTest")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("SampleTest")]
-[assembly: AssemblyCopyright("Copyright © 2019")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: ComVisible(false)]
\ No newline at end of file
diff --git a/SampleTest/Properties/Default.rd.xml b/SampleTest/Properties/Default.rd.xml
deleted file mode 100644
index af00722..0000000
--- a/SampleTest/Properties/Default.rd.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/SampleTest/SampleTest.csproj b/SampleTest/SampleTest.csproj
deleted file mode 100644
index eb8508b..0000000
--- a/SampleTest/SampleTest.csproj
+++ /dev/null
@@ -1,258 +0,0 @@
-
-
-
-
- Debug
- x86
- {26F5807A-25B5-4E09-8C72-1749C4C59591}
- AppContainerExe
- Properties
- SampleTest
- SampleTest
- en-US
- UAP
- 10.0.19041.0
- 10.0.17763.0
- 14
- 512
- {A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
- true
- false
-
-
- true
- bin\x86\Debug\
- DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP
- ;2008
- full
- x86
- false
- prompt
- true
-
-
- bin\x86\Release\
- TRACE;NETFX_CORE;WINDOWS_UWP
- true
- ;2008
- pdbonly
- x86
- false
- prompt
- true
- true
-
-
- true
- bin\ARM\Debug\
- DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP
- ;2008
- full
- ARM
- false
- prompt
- true
-
-
- bin\ARM\Release\
- TRACE;NETFX_CORE;WINDOWS_UWP
- true
- ;2008
- pdbonly
- ARM
- false
- prompt
- true
- true
-
-
- true
- bin\ARM64\Debug\
- DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP
- ;2008
- full
- ARM64
- false
- prompt
- true
- true
-
-
- bin\ARM64\Release\
- TRACE;NETFX_CORE;WINDOWS_UWP
- true
- ;2008
- pdbonly
- ARM64
- false
- prompt
- true
- true
-
-
- true
- bin\x64\Debug\
- DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP
- ;2008
- full
- x64
- false
- prompt
- true
-
-
- bin\x64\Release\
- TRACE;NETFX_CORE;WINDOWS_UWP
- true
- ;2008
- pdbonly
- x64
- false
- prompt
- true
- true
-
-
- PackageReference
-
-
-
- App.xaml
-
-
- MainPage.xaml
-
-
-
- RoamingSettingsView.xaml
-
-
-
-
-
- Designer
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- MSBuild:Compile
- Designer
-
-
- MSBuild:Compile
- Designer
-
-
- MSBuild:Compile
- Designer
-
-
-
-
- 3.31.0
-
-
- 6.2.12
-
-
-
-
- {ca4042d2-33a2-450b-8b9d-c286b9f3f3f4}
- CommunityToolkit.Authentication.Msal
-
-
- {b323a2e1-66ef-4037-95b7-2defa051b4b1}
- CommunityToolkit.Authentication
-
-
- {b2246169-0cd8-473c-aff6-172310e2c3f6}
- CommunityToolkit.Graph
-
-
- {2E4A708A-DF53-4863-B797-E14CDC6B90FA}
- CommunityToolkit.Authentication.Uwp
-
-
- {42252ee8-7e68-428f-972b-6d2dd3aa12cc}
- CommunityToolkit.Graph.Uwp
-
-
-
- 14.0
-
-
- bin\x86\CI\
- TRACE;NETFX_CORE;WINDOWS_UWP;CODE_ANALYSIS
- true
- ;2008
- true
- pdbonly
- x86
- false
- 7.3
- prompt
- C:\code\Graph-Controls\Toolkit.ruleset
- true
-
-
- bin\ARM\CI\
- TRACE;NETFX_CORE;WINDOWS_UWP;CODE_ANALYSIS
- true
- ;2008
- true
- pdbonly
- ARM
- false
- 7.3
- prompt
- C:\code\Graph-Controls\Toolkit.ruleset
- true
-
-
- bin\ARM64\CI\
- TRACE;NETFX_CORE;WINDOWS_UWP;CODE_ANALYSIS
- true
- ;2008
- true
- pdbonly
- ARM64
- false
- 7.3
- prompt
- C:\code\Graph-Controls\Toolkit.ruleset
- true
-
-
- bin\x64\CI\
- TRACE;NETFX_CORE;WINDOWS_UWP;CODE_ANALYSIS
- true
- ;2008
- true
- pdbonly
- x64
- false
- 7.3
- prompt
- C:\code\Graph-Controls\Toolkit.ruleset
- true
-
-
-
-
\ No newline at end of file
diff --git a/SampleTest/Samples/RoamingSettings/RoamingSettingsView.xaml b/SampleTest/Samples/RoamingSettings/RoamingSettingsView.xaml
deleted file mode 100644
index 398282c..0000000
--- a/SampleTest/Samples/RoamingSettings/RoamingSettingsView.xaml
+++ /dev/null
@@ -1,79 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/SampleTest/Samples/RoamingSettings/RoamingSettingsView.xaml.cs b/SampleTest/Samples/RoamingSettings/RoamingSettingsView.xaml.cs
deleted file mode 100644
index 66f2b4b..0000000
--- a/SampleTest/Samples/RoamingSettings/RoamingSettingsView.xaml.cs
+++ /dev/null
@@ -1,57 +0,0 @@
-// 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 System.Collections.Generic;
-using Windows.UI.Xaml.Controls;
-
-namespace SampleTest.Samples
-{
- ///
- /// A sample for demonstrating features in the RoamingSettings namespace.
- ///
- public sealed partial class RoamingSettingsView : Page
- {
- private RoamingSettingsViewModel _vm => DataContext as RoamingSettingsViewModel;
-
- public RoamingSettingsView()
- {
- InitializeComponent();
- DataContext = new RoamingSettingsViewModel();
- }
-
- private void CreateButton_Click(object sender, Windows.UI.Xaml.RoutedEventArgs e)
- {
- _vm.CreateCustomRoamingSettings();
- }
-
- private void DeleteButton_Click(object sender, Windows.UI.Xaml.RoutedEventArgs e)
- {
- _vm.DeleteCustomRoamingSettings();
- }
-
- private void SetButton_Click(object sender, Windows.UI.Xaml.RoutedEventArgs e)
- {
- _vm.SetValue();
- }
-
- private void GetButton_Click(object sender, Windows.UI.Xaml.RoutedEventArgs e)
- {
- _vm.GetValue();
- }
-
- private void ViewButton_Click(object sender, Windows.UI.Xaml.RoutedEventArgs e)
- {
- _vm.SyncRoamingSettings();
- }
-
- private void AdditionalData_ItemClick(object sender, ItemClickEventArgs e)
- {
- if (e.ClickedItem is KeyValuePair kvp)
- {
- _vm.KeyInputText = kvp.Key;
- _vm.ValueInputText = kvp.Value.ToString();
- }
- }
- }
-}
diff --git a/SampleTest/Samples/RoamingSettings/RoamingSettingsViewModel.cs b/SampleTest/Samples/RoamingSettings/RoamingSettingsViewModel.cs
deleted file mode 100644
index a642d5a..0000000
--- a/SampleTest/Samples/RoamingSettings/RoamingSettingsViewModel.cs
+++ /dev/null
@@ -1,195 +0,0 @@
-// 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 CommunityToolkit.Uwp.Graph.Helpers.RoamingSettings;
-using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.ComponentModel;
-using System.Runtime.CompilerServices;
-using System.Threading.Tasks;
-
-namespace SampleTest.Samples
-{
- public class RoamingSettingsViewModel : INotifyPropertyChanged
- {
- private IProvider GlobalProvider => ProviderManager.Instance.GlobalProvider;
-
- public event PropertyChangedEventHandler PropertyChanged;
-
- private string _errorText;
- public string ErrorText
- {
- get => _errorText;
- set => Set(ref _errorText, value);
- }
-
- private RoamingSettingsHelper _roamingSettings;
-
- private ObservableCollection> _additionalData;
- public ObservableCollection> AdditionalData
- {
- get => _additionalData;
- set => Set(ref _additionalData, value);
- }
-
- private string _keyInputText;
- public string KeyInputText
- {
- get => _keyInputText;
- set => Set(ref _keyInputText, value);
- }
-
- private string _valueInputText;
- public string ValueInputText
- {
- get => _valueInputText;
- set => Set(ref _valueInputText, value);
- }
-
- public RoamingSettingsViewModel()
- {
- _roamingSettings = null;
- _keyInputText = string.Empty;
- _valueInputText = string.Empty;
-
- ProviderManager.Instance.ProviderUpdated += (s, e) => CheckState();
- CheckState();
- }
-
- public void GetValue()
- {
- try
- {
- ErrorText = string.Empty;
- ValueInputText = string.Empty;
-
- string key = KeyInputText;
- string value = _roamingSettings.Read(key);
-
- ValueInputText = value;
- }
- catch (Exception e)
- {
- ErrorText = e.Message;
- }
- }
-
- public void SetValue()
- {
- try
- {
- ErrorText = string.Empty;
-
- _roamingSettings.Save(KeyInputText, ValueInputText);
-
- SyncRoamingSettings();
- }
- catch (Exception e)
- {
- ErrorText = e.Message;
- }
- }
-
- public async void CreateCustomRoamingSettings()
- {
- try
- {
- ErrorText = string.Empty;
-
- await _roamingSettings.Create();
-
- AdditionalData = new ObservableCollection>(_roamingSettings.Cache);
-
- KeyInputText = string.Empty;
- ValueInputText = string.Empty;
- }
- catch (Exception e)
- {
- ErrorText = e.Message;
- }
- }
-
- public async void DeleteCustomRoamingSettings()
- {
- try
- {
- ErrorText = string.Empty;
-
- await _roamingSettings.Delete();
-
- AdditionalData?.Clear();
- KeyInputText = string.Empty;
- ValueInputText = string.Empty;
- }
- catch (Exception e)
- {
- ErrorText = e.Message;
- }
- }
-
- public async void SyncRoamingSettings()
- {
- try
- {
- ErrorText = string.Empty;
- AdditionalData?.Clear();
-
- await _roamingSettings.Sync();
- if (_roamingSettings.Cache != null)
- {
- AdditionalData = new ObservableCollection>(_roamingSettings.Cache);
- }
- }
- catch (Exception e)
- {
- ErrorText = e.Message;
- }
- }
-
- private async void CheckState()
- {
- if (GlobalProvider != null && GlobalProvider.State == ProviderState.SignedIn)
- {
- await LoadState();
- }
- else
- {
- ClearState();
- }
- }
-
- private async Task LoadState()
- {
- try
- {
- ClearState();
-
- _roamingSettings = await RoamingSettingsHelper.CreateForCurrentUser();
- }
- catch (Exception e)
- {
- ErrorText = e.Message;
- }
- }
-
- private void ClearState()
- {
- _roamingSettings = null;
-
- KeyInputText = string.Empty;
- ValueInputText = string.Empty;
- }
-
- private void Set(ref T field, T value, [CallerMemberName] string propertyName = null)
- {
- if (!EqualityComparer.Default.Equals(field, value))
- {
- field = value;
- PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
- }
- }
- }
-}
diff --git a/Samples/UwpMsalProviderSample/LoginButton.xaml b/Samples/UwpMsalProviderSample/LoginButton.xaml
new file mode 100644
index 0000000..92b2f0b
--- /dev/null
+++ b/Samples/UwpMsalProviderSample/LoginButton.xaml
@@ -0,0 +1,14 @@
+
+
+
+
+
diff --git a/Samples/UwpMsalProviderSample/LoginButton.xaml.cs b/Samples/UwpMsalProviderSample/LoginButton.xaml.cs
new file mode 100644
index 0000000..844a41f
--- /dev/null
+++ b/Samples/UwpMsalProviderSample/LoginButton.xaml.cs
@@ -0,0 +1,70 @@
+// 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 System;
+using Windows.UI.Xaml;
+using Windows.UI.Xaml.Controls;
+
+namespace UwpMsalProviderSample
+{
+ ///
+ /// A simple button for triggering the globally configured IProvider to sign in and out.
+ ///
+ public partial class LoginButton : UserControl
+ {
+ public LoginButton()
+ {
+ InitializeComponent();
+
+ ProviderManager.Instance.ProviderUpdated += (s, e) => UpdateState();
+ UpdateState();
+ }
+
+ private void UpdateState()
+ {
+ var provider = ProviderManager.Instance.GlobalProvider;
+ if (provider == null || provider.State == ProviderState.Loading)
+ {
+ MyButton.Content = "Sign in";
+ IsEnabled = false;
+ return;
+ }
+
+ switch (provider.State)
+ {
+ case ProviderState.SignedIn:
+ MyButton.Content = "Sign out";
+ break;
+
+ case ProviderState.SignedOut:
+ MyButton.Content = "Sign in";
+ break;
+ }
+
+ IsEnabled = true;
+ }
+
+ private async void MyButton_Click(object sender, RoutedEventArgs e)
+ {
+ await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
+ {
+ var provider = ProviderManager.Instance.GlobalProvider;
+ if (provider != null)
+ {
+ switch (provider.State)
+ {
+ case ProviderState.SignedOut:
+ provider.SignInAsync();
+ break;
+
+ case ProviderState.SignedIn:
+ provider.SignOutAsync();
+ break;
+ }
+ }
+ });
+ }
+ }
+}
diff --git a/Samples/UwpMsalProviderSample/MainPage.xaml b/Samples/UwpMsalProviderSample/MainPage.xaml
index ddbc7a0..04a45b0 100644
--- a/Samples/UwpMsalProviderSample/MainPage.xaml
+++ b/Samples/UwpMsalProviderSample/MainPage.xaml
@@ -5,12 +5,11 @@
xmlns:local="using:UwpMsalProviderSample"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:controls="using:CommunityToolkit.Graph.Uwp"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
-
+
diff --git a/Samples/UwpMsalProviderSample/MainPage.xaml.cs b/Samples/UwpMsalProviderSample/MainPage.xaml.cs
index d2d3af2..c43e0fc 100644
--- a/Samples/UwpMsalProviderSample/MainPage.xaml.cs
+++ b/Samples/UwpMsalProviderSample/MainPage.xaml.cs
@@ -12,7 +12,7 @@ public sealed partial class MainPage : Page
{
public MainPage()
{
- this.InitializeComponent();
+ InitializeComponent();
ProviderManager.Instance.ProviderUpdated += OnProviderUpdated;
}
diff --git a/Samples/UwpMsalProviderSample/UwpMsalProviderSample.csproj b/Samples/UwpMsalProviderSample/UwpMsalProviderSample.csproj
index 1639e03..c069145 100644
--- a/Samples/UwpMsalProviderSample/UwpMsalProviderSample.csproj
+++ b/Samples/UwpMsalProviderSample/UwpMsalProviderSample.csproj
@@ -119,6 +119,9 @@
App.xaml
+
+ LoginButton.xaml
+
MainPage.xaml
@@ -144,6 +147,10 @@
MSBuild:Compile
Designer
+
+ MSBuild:Compile
+ Designer
+
MSBuild:Compile
Designer
@@ -167,10 +174,6 @@
{b2246169-0cd8-473c-aff6-172310e2c3f6}
CommunityToolkit.Graph
-
- {42252ee8-7e68-428f-972b-6d2dd3aa12cc}
- CommunityToolkit.Graph.Uwp
-
diff --git a/Samples/UwpWindowsProviderSample/LoginButton.xaml b/Samples/UwpWindowsProviderSample/LoginButton.xaml
new file mode 100644
index 0000000..cc96a68
--- /dev/null
+++ b/Samples/UwpWindowsProviderSample/LoginButton.xaml
@@ -0,0 +1,14 @@
+
+
+
+
+
diff --git a/Samples/UwpWindowsProviderSample/LoginButton.xaml.cs b/Samples/UwpWindowsProviderSample/LoginButton.xaml.cs
new file mode 100644
index 0000000..7d3c616
--- /dev/null
+++ b/Samples/UwpWindowsProviderSample/LoginButton.xaml.cs
@@ -0,0 +1,70 @@
+// 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 System;
+using Windows.UI.Xaml;
+using Windows.UI.Xaml.Controls;
+
+namespace UwpWindowsProviderSample
+{
+ ///
+ /// A simple button for triggering the globally configured IProvider to sign in and out.
+ ///
+ public partial class LoginButton : UserControl
+ {
+ public LoginButton()
+ {
+ InitializeComponent();
+
+ ProviderManager.Instance.ProviderUpdated += (s, e) => UpdateState();
+ UpdateState();
+ }
+
+ private void UpdateState()
+ {
+ var provider = ProviderManager.Instance.GlobalProvider;
+ if (provider == null || provider.State == ProviderState.Loading)
+ {
+ MyButton.Content = "Sign in";
+ IsEnabled = false;
+ return;
+ }
+
+ switch (provider.State)
+ {
+ case ProviderState.SignedIn:
+ MyButton.Content = "Sign out";
+ break;
+
+ case ProviderState.SignedOut:
+ MyButton.Content = "Sign in";
+ break;
+ }
+
+ IsEnabled = true;
+ }
+
+ private async void MyButton_Click(object sender, RoutedEventArgs e)
+ {
+ await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
+ {
+ var provider = ProviderManager.Instance.GlobalProvider;
+ if (provider != null)
+ {
+ switch (provider.State)
+ {
+ case ProviderState.SignedOut:
+ provider.SignInAsync();
+ break;
+
+ case ProviderState.SignedIn:
+ provider.SignOutAsync();
+ break;
+ }
+ }
+ });
+ }
+ }
+}
diff --git a/Samples/UwpWindowsProviderSample/MainPage.xaml b/Samples/UwpWindowsProviderSample/MainPage.xaml
index 15f17ed..e309926 100644
--- a/Samples/UwpWindowsProviderSample/MainPage.xaml
+++ b/Samples/UwpWindowsProviderSample/MainPage.xaml
@@ -5,12 +5,11 @@
xmlns:local="using:UwpWindowsProviderSample"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:controls="using:CommunityToolkit.Graph.Uwp"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
-
+
diff --git a/Samples/UwpWindowsProviderSample/MainPage.xaml.cs b/Samples/UwpWindowsProviderSample/MainPage.xaml.cs
index a6444f6..81e60f1 100644
--- a/Samples/UwpWindowsProviderSample/MainPage.xaml.cs
+++ b/Samples/UwpWindowsProviderSample/MainPage.xaml.cs
@@ -12,7 +12,7 @@ public sealed partial class MainPage : Page
{
public MainPage()
{
- this.InitializeComponent();
+ InitializeComponent();
ProviderManager.Instance.ProviderUpdated += OnProviderUpdated;
}
diff --git a/Samples/UwpWindowsProviderSample/UwpWindowsProviderSample.csproj b/Samples/UwpWindowsProviderSample/UwpWindowsProviderSample.csproj
index 3b3bd97..f5a8616 100644
--- a/Samples/UwpWindowsProviderSample/UwpWindowsProviderSample.csproj
+++ b/Samples/UwpWindowsProviderSample/UwpWindowsProviderSample.csproj
@@ -119,6 +119,9 @@
App.xaml
+
+ LoginButton.xaml
+
MainPage.xaml
@@ -144,6 +147,10 @@
MSBuild:Compile
Designer
+
+ MSBuild:Compile
+ Designer
+
MSBuild:Compile
Designer
@@ -167,10 +174,6 @@
{2E4A708A-DF53-4863-B797-E14CDC6B90FA}
CommunityToolkit.Authentication.Uwp
-
- {42252ee8-7e68-428f-972b-6d2dd3aa12cc}
- CommunityToolkit.Graph.Uwp
-
diff --git a/UnitTests/UnitTests.UWP/RoamingSettings/Test_OneDriveDataStore.cs b/UnitTests/UnitTests.UWP/RoamingSettings/Test_OneDriveDataStore.cs
deleted file mode 100644
index d2b3157..0000000
--- a/UnitTests/UnitTests.UWP/RoamingSettings/Test_OneDriveDataStore.cs
+++ /dev/null
@@ -1,154 +0,0 @@
-// 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 CommunityToolkit.Uwp.Graph.Helpers.RoamingSettings;
-using Microsoft.Toolkit.Uwp;
-using Microsoft.Toolkit.Uwp.Helpers;
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using System;
-using System.Threading.Tasks;
-
-namespace UnitTests.UWP.Helpers
-{
- [TestClass]
- public class Test_OneDriveDataStore : VisualUITestBase
- {
- ///
- /// Test the dafault state of a new instance of the OneDriveDataStore.
- ///
- [TestCategory("RoamingSettings")]
- [TestMethod]
- public async Task Test_Default()
- {
- var tcs = new TaskCompletionSource();
-
- void test()
- {
- try
- {
- string userId = "TestUserId";
- string dataStoreId = "RoamingData.json";
- IObjectSerializer serializer = new SystemSerializer();
-
- IRoamingSettingsDataStore dataStore = new OneDriveDataStore(userId, dataStoreId, serializer, false);
-
- // Evaluate the default state is as expected
- Assert.IsFalse(dataStore.AutoSync);
- Assert.IsNotNull(dataStore.Cache);
- Assert.AreEqual(dataStoreId, dataStore.Id);
- Assert.AreEqual(userId, dataStore.UserId);
-
- tcs.SetResult(true);
- }
- catch (Exception ex)
- {
- tcs.SetException(ex);
- }
- };
-
- PrepareProvider(test);
-
- await tcs.Task;
- }
-
- ///
- /// Test the dafault state of a new instance of the OneDriveDataStore.
- ///
- [TestCategory("RoamingSettings")]
- [TestMethod]
- public async Task Test_Sync()
- {
- var tcs = new TaskCompletionSource();
-
- async void test()
- {
- try
- {
- string userId = "TestUserId";
- string dataStoreId = "RoamingData.json";
- IObjectSerializer serializer = new SystemSerializer();
-
- IRoamingSettingsDataStore dataStore = new OneDriveDataStore(userId, dataStoreId, serializer, false);
-
- try
- {
- // Attempt to delete the remote first.
- await dataStore.Delete();
- }
- catch
- {
- }
-
- dataStore.SyncCompleted += async (s, e) =>
- {
- try
- {
- // Create a second instance to ensure that the Cache doesn't yield a false positive.
- IRoamingSettingsDataStore dataStore2 = new OneDriveDataStore(userId, dataStoreId, serializer, false);
- await dataStore2.Sync();
-
- var foo = dataStore.Read("foo");
- Assert.AreEqual("bar", foo);
-
- tcs.SetResult(true);
- }
- catch (Exception ex)
- {
- tcs.SetException(ex);
- }
- };
-
- dataStore.SyncFailed = (s, e) =>
- {
- try
- {
- Assert.Fail("Sync Failed");
- }
- catch (Exception ex)
- {
- tcs.SetException(ex);
- }
- };
-
- dataStore.Save("foo", "bar");
- await dataStore.Sync();
- }
- catch (Exception ex)
- {
- tcs.SetException(ex);
- }
- }
-
- PrepareProvider(test);
-
- var result = await tcs.Task;
- Assert.IsTrue(result);
- }
-
- ///
- /// Create a new instance of IProvider and check that it has the proper default state, then execute the provided action.
- ///
- private async void PrepareProvider(Action test)
- {
- await App.DispatcherQueue.EnqueueAsync(async () =>
- {
- var provider = new WindowsProvider(new string[] { "User.Read", "Files.ReadWrite" }, autoSignIn: false);
-
- ProviderManager.Instance.ProviderUpdated += (s, e) =>
- {
- var providerManager = s as ProviderManager;
- if (providerManager.GlobalProvider.State == ProviderState.SignedIn)
- {
- test.Invoke();
- }
- };
-
- ProviderManager.Instance.GlobalProvider = provider;
-
- await provider.SignInAsync();
- });
- }
- }
-}
diff --git a/UnitTests/UnitTests.UWP/RoamingSettings/Test_UserExtensionDataStore.cs b/UnitTests/UnitTests.UWP/RoamingSettings/Test_UserExtensionDataStore.cs
deleted file mode 100644
index 2de3ae5..0000000
--- a/UnitTests/UnitTests.UWP/RoamingSettings/Test_UserExtensionDataStore.cs
+++ /dev/null
@@ -1,154 +0,0 @@
-// 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 CommunityToolkit.Uwp.Graph.Helpers.RoamingSettings;
-using Microsoft.Toolkit.Uwp;
-using Microsoft.Toolkit.Uwp.Helpers;
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using System;
-using System.Threading.Tasks;
-
-namespace UnitTests.UWP.Helpers
-{
- [TestClass]
- public class Test_UserExtensionDataStore
- {
- ///
- /// Test the dafault state of a new instance of the UserExtensionDataStore.
- ///
- [TestCategory("RoamingSettings")]
- [TestMethod]
- public async Task Test_Default()
- {
- var tcs = new TaskCompletionSource();
-
- void test()
- {
- try
- {
- string userId = "TestUserId";
- string dataStoreId = "RoamingData";
- IObjectSerializer serializer = new SystemSerializer();
-
- IRoamingSettingsDataStore dataStore = new UserExtensionDataStore(userId, dataStoreId, serializer, false);
-
- // Evaluate the default state is as expected
- Assert.IsFalse(dataStore.AutoSync);
- Assert.IsNotNull(dataStore.Cache);
- Assert.AreEqual(dataStoreId, dataStore.Id);
- Assert.AreEqual(userId, dataStore.UserId);
-
- tcs.SetResult(true);
- }
- catch (Exception ex)
- {
- tcs.SetException(ex);
- }
- };
-
- PrepareProvider(test);
-
- await tcs.Task;
- }
-
- ///
- /// Test the dafault state of a new instance of the UserExtensionDataStore.
- ///
- [TestCategory("RoamingSettings")]
- [TestMethod]
- public async Task Test_Sync()
- {
- var tcs = new TaskCompletionSource();
-
- async void test()
- {
- try
- {
- string userId = "TestUserId";
- string dataStoreId = "RoamingData";
- IObjectSerializer serializer = new SystemSerializer();
-
- IRoamingSettingsDataStore dataStore = new UserExtensionDataStore(userId, dataStoreId, serializer, false);
-
- try
- {
- // Attempt to delete the remote first.
- await dataStore.Delete();
- }
- catch
- {
- }
-
- dataStore.SyncCompleted += async (s, e) =>
- {
- try
- {
- // Create a second instance to ensure that the Cache doesn't yield a false positive.
- IRoamingSettingsDataStore dataStore2 = new OneDriveDataStore(userId, dataStoreId, serializer, false);
- await dataStore2.Sync();
-
- var foo = dataStore.Read("foo");
- Assert.AreEqual("bar", foo);
-
- tcs.SetResult(true);
- }
- catch (Exception ex)
- {
- tcs.SetException(ex);
- }
- };
-
- dataStore.SyncFailed = (s, e) =>
- {
- try
- {
- Assert.Fail("Sync Failed");
- }
- catch (Exception ex)
- {
- tcs.SetException(ex);
- }
- };
-
- dataStore.Save("foo", "bar");
- await dataStore.Sync();
- }
- catch (Exception ex)
- {
- tcs.SetException(ex);
- }
- }
-
- PrepareProvider(test);
-
- var result = await tcs.Task;
- Assert.IsTrue(result);
- }
-
- ///
- /// Create a new instance of IProvider and check that it has the proper default state, then execute the provided action.
- ///
- private async void PrepareProvider(Action test)
- {
- await App.DispatcherQueue.EnqueueAsync(async () =>
- {
- var provider = new WindowsProvider(new string[] { "User.ReadWrite" }, autoSignIn: false);
-
- ProviderManager.Instance.ProviderUpdated += (s, e) =>
- {
- var providerManager = s as ProviderManager;
- if (providerManager.GlobalProvider.State == ProviderState.SignedIn)
- {
- test.Invoke();
- }
- };
-
- ProviderManager.Instance.GlobalProvider = provider;
-
- await provider.SignInAsync();
- });
- }
- }
-}
diff --git a/UnitTests/UnitTests.UWP/UnitTests.UWP.csproj b/UnitTests/UnitTests.UWP/UnitTests.UWP.csproj
index 9fde621..cc0e331 100644
--- a/UnitTests/UnitTests.UWP/UnitTests.UWP.csproj
+++ b/UnitTests/UnitTests.UWP/UnitTests.UWP.csproj
@@ -123,8 +123,6 @@
-
-
UnitTestApp.xaml
@@ -193,10 +191,6 @@
{2E4A708A-DF53-4863-B797-E14CDC6B90FA}
CommunityToolkit.Authentication.Uwp
-
- {42252EE8-7E68-428F-972B-6D2DD3AA12CC}
- CommunityToolkit.Graph.Uwp
-
14.0
diff --git a/Windows-Toolkit-Graph-Controls.sln b/Windows-Toolkit-Graph-Controls.sln
index d86724f..0555a62 100644
--- a/Windows-Toolkit-Graph-Controls.sln
+++ b/Windows-Toolkit-Graph-Controls.sln
@@ -4,8 +4,6 @@ VisualStudioVersion = 16.0.29230.61
MinimumVisualStudioVersion = 15.0.26124.0
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CommunityToolkit.Graph", "CommunityToolkit.Graph\CommunityToolkit.Graph.csproj", "{B2246169-0CD8-473C-AFF6-172310E2C3F6}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CommunityToolkit.Graph.Uwp", "CommunityToolkit.Graph.Uwp\CommunityToolkit.Graph.Uwp.csproj", "{42252EE8-7E68-428F-972B-6D2DD3AA12CC}"
-EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build Config", "Build Config", "{B7903632-1BFF-4BA6-BD7A-9F8A897F7542}"
ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig
@@ -23,8 +21,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build Config", "Build Confi
version.json = version.json
EndProjectSection
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SampleTest", "SampleTest\SampleTest.csproj", "{26F5807A-25B5-4E09-8C72-1749C4C59591}"
-EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CommunityToolkit.Authentication", "CommunityToolkit.Authentication\CommunityToolkit.Authentication.csproj", "{B323A2E1-66EF-4037-95B7-2DEFA051B4B1}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CommunityToolkit.Authentication.Msal", "CommunityToolkit.Authentication.Msal\CommunityToolkit.Authentication.Msal.csproj", "{CA4042D2-33A2-450B-8B9D-C286B9F3F3F4}"
@@ -35,12 +31,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "UnitTests", "UnitTests", "{
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTests.UWP", "UnitTests\UnitTests.UWP\UnitTests.UWP.csproj", "{6B33B26C-008B-4ADB-B317-EF996CD6755B}"
EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Docs", "Docs", "{EACBCDF3-8CCC-4A30-87E9-75FCA815831E}"
- ProjectSection(SolutionItems) = preProject
- Docs\QuickStart-WindowsProvider.md = Docs\QuickStart-WindowsProvider.md
- Docs\WindowsProvider.md = Docs\WindowsProvider.md
- EndProjectSection
-EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Samples", "Samples", "{022BF202-8D0D-4A6B-8A5B-92376D2EB5DA}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UwpMsalProviderSample", "Samples\UwpMsalProviderSample\UwpMsalProviderSample.csproj", "{D0F6A1EB-806E-424A-BDCA-9F749F12774F}"
@@ -113,84 +103,6 @@ Global
{B2246169-0CD8-473C-AFF6-172310E2C3F6}.Release|x64.Build.0 = Release|Any CPU
{B2246169-0CD8-473C-AFF6-172310E2C3F6}.Release|x86.ActiveCfg = Release|Any CPU
{B2246169-0CD8-473C-AFF6-172310E2C3F6}.Release|x86.Build.0 = Release|Any CPU
- {42252EE8-7E68-428F-972B-6D2DD3AA12CC}.CI|Any CPU.ActiveCfg = Release|Any CPU
- {42252EE8-7E68-428F-972B-6D2DD3AA12CC}.CI|Any CPU.Build.0 = Release|Any CPU
- {42252EE8-7E68-428F-972B-6D2DD3AA12CC}.CI|ARM.ActiveCfg = Release|Any CPU
- {42252EE8-7E68-428F-972B-6D2DD3AA12CC}.CI|ARM.Build.0 = Release|Any CPU
- {42252EE8-7E68-428F-972B-6D2DD3AA12CC}.CI|ARM64.ActiveCfg = Release|Any CPU
- {42252EE8-7E68-428F-972B-6D2DD3AA12CC}.CI|ARM64.Build.0 = Release|Any CPU
- {42252EE8-7E68-428F-972B-6D2DD3AA12CC}.CI|x64.ActiveCfg = Release|Any CPU
- {42252EE8-7E68-428F-972B-6D2DD3AA12CC}.CI|x64.Build.0 = Release|Any CPU
- {42252EE8-7E68-428F-972B-6D2DD3AA12CC}.CI|x86.ActiveCfg = CI|x86
- {42252EE8-7E68-428F-972B-6D2DD3AA12CC}.CI|x86.Build.0 = CI|x86
- {42252EE8-7E68-428F-972B-6D2DD3AA12CC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {42252EE8-7E68-428F-972B-6D2DD3AA12CC}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {42252EE8-7E68-428F-972B-6D2DD3AA12CC}.Debug|ARM.ActiveCfg = Debug|Any CPU
- {42252EE8-7E68-428F-972B-6D2DD3AA12CC}.Debug|ARM.Build.0 = Debug|Any CPU
- {42252EE8-7E68-428F-972B-6D2DD3AA12CC}.Debug|ARM64.ActiveCfg = Debug|Any CPU
- {42252EE8-7E68-428F-972B-6D2DD3AA12CC}.Debug|ARM64.Build.0 = Debug|Any CPU
- {42252EE8-7E68-428F-972B-6D2DD3AA12CC}.Debug|x64.ActiveCfg = Debug|Any CPU
- {42252EE8-7E68-428F-972B-6D2DD3AA12CC}.Debug|x64.Build.0 = Debug|Any CPU
- {42252EE8-7E68-428F-972B-6D2DD3AA12CC}.Debug|x86.ActiveCfg = Debug|Any CPU
- {42252EE8-7E68-428F-972B-6D2DD3AA12CC}.Debug|x86.Build.0 = Debug|Any CPU
- {42252EE8-7E68-428F-972B-6D2DD3AA12CC}.Native|Any CPU.ActiveCfg = Debug|Any CPU
- {42252EE8-7E68-428F-972B-6D2DD3AA12CC}.Native|Any CPU.Build.0 = Debug|Any CPU
- {42252EE8-7E68-428F-972B-6D2DD3AA12CC}.Native|ARM.ActiveCfg = Debug|Any CPU
- {42252EE8-7E68-428F-972B-6D2DD3AA12CC}.Native|ARM.Build.0 = Debug|Any CPU
- {42252EE8-7E68-428F-972B-6D2DD3AA12CC}.Native|ARM64.ActiveCfg = Debug|Any CPU
- {42252EE8-7E68-428F-972B-6D2DD3AA12CC}.Native|ARM64.Build.0 = Debug|Any CPU
- {42252EE8-7E68-428F-972B-6D2DD3AA12CC}.Native|x64.ActiveCfg = Debug|Any CPU
- {42252EE8-7E68-428F-972B-6D2DD3AA12CC}.Native|x64.Build.0 = Debug|Any CPU
- {42252EE8-7E68-428F-972B-6D2DD3AA12CC}.Native|x86.ActiveCfg = Debug|Any CPU
- {42252EE8-7E68-428F-972B-6D2DD3AA12CC}.Native|x86.Build.0 = Debug|Any CPU
- {42252EE8-7E68-428F-972B-6D2DD3AA12CC}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {42252EE8-7E68-428F-972B-6D2DD3AA12CC}.Release|Any CPU.Build.0 = Release|Any CPU
- {42252EE8-7E68-428F-972B-6D2DD3AA12CC}.Release|ARM.ActiveCfg = Release|Any CPU
- {42252EE8-7E68-428F-972B-6D2DD3AA12CC}.Release|ARM.Build.0 = Release|Any CPU
- {42252EE8-7E68-428F-972B-6D2DD3AA12CC}.Release|ARM64.ActiveCfg = Release|Any CPU
- {42252EE8-7E68-428F-972B-6D2DD3AA12CC}.Release|ARM64.Build.0 = Release|Any CPU
- {42252EE8-7E68-428F-972B-6D2DD3AA12CC}.Release|x64.ActiveCfg = Release|Any CPU
- {42252EE8-7E68-428F-972B-6D2DD3AA12CC}.Release|x64.Build.0 = Release|Any CPU
- {42252EE8-7E68-428F-972B-6D2DD3AA12CC}.Release|x86.ActiveCfg = Release|Any CPU
- {42252EE8-7E68-428F-972B-6D2DD3AA12CC}.Release|x86.Build.0 = Release|Any CPU
- {26F5807A-25B5-4E09-8C72-1749C4C59591}.CI|Any CPU.ActiveCfg = Release|x86
- {26F5807A-25B5-4E09-8C72-1749C4C59591}.CI|ARM.ActiveCfg = Release|ARM
- {26F5807A-25B5-4E09-8C72-1749C4C59591}.CI|ARM64.ActiveCfg = Release|ARM64
- {26F5807A-25B5-4E09-8C72-1749C4C59591}.CI|x64.ActiveCfg = Release|x64
- {26F5807A-25B5-4E09-8C72-1749C4C59591}.CI|x86.ActiveCfg = CI|x86
- {26F5807A-25B5-4E09-8C72-1749C4C59591}.Debug|Any CPU.ActiveCfg = Debug|x86
- {26F5807A-25B5-4E09-8C72-1749C4C59591}.Debug|Any CPU.Build.0 = Debug|x86
- {26F5807A-25B5-4E09-8C72-1749C4C59591}.Debug|Any CPU.Deploy.0 = Debug|x86
- {26F5807A-25B5-4E09-8C72-1749C4C59591}.Debug|ARM.ActiveCfg = Debug|ARM
- {26F5807A-25B5-4E09-8C72-1749C4C59591}.Debug|ARM.Build.0 = Debug|ARM
- {26F5807A-25B5-4E09-8C72-1749C4C59591}.Debug|ARM.Deploy.0 = Debug|ARM
- {26F5807A-25B5-4E09-8C72-1749C4C59591}.Debug|ARM64.ActiveCfg = Debug|ARM64
- {26F5807A-25B5-4E09-8C72-1749C4C59591}.Debug|ARM64.Build.0 = Debug|ARM64
- {26F5807A-25B5-4E09-8C72-1749C4C59591}.Debug|ARM64.Deploy.0 = Debug|ARM64
- {26F5807A-25B5-4E09-8C72-1749C4C59591}.Debug|x64.ActiveCfg = Debug|x64
- {26F5807A-25B5-4E09-8C72-1749C4C59591}.Debug|x64.Build.0 = Debug|x64
- {26F5807A-25B5-4E09-8C72-1749C4C59591}.Debug|x64.Deploy.0 = Debug|x64
- {26F5807A-25B5-4E09-8C72-1749C4C59591}.Debug|x86.ActiveCfg = Debug|x86
- {26F5807A-25B5-4E09-8C72-1749C4C59591}.Debug|x86.Build.0 = Debug|x86
- {26F5807A-25B5-4E09-8C72-1749C4C59591}.Debug|x86.Deploy.0 = Debug|x86
- {26F5807A-25B5-4E09-8C72-1749C4C59591}.Native|Any CPU.ActiveCfg = Debug|x86
- {26F5807A-25B5-4E09-8C72-1749C4C59591}.Native|ARM.ActiveCfg = Debug|ARM
- {26F5807A-25B5-4E09-8C72-1749C4C59591}.Native|ARM64.ActiveCfg = Debug|ARM64
- {26F5807A-25B5-4E09-8C72-1749C4C59591}.Native|x64.ActiveCfg = Debug|x64
- {26F5807A-25B5-4E09-8C72-1749C4C59591}.Native|x86.ActiveCfg = Debug|x86
- {26F5807A-25B5-4E09-8C72-1749C4C59591}.Release|Any CPU.ActiveCfg = Release|x86
- {26F5807A-25B5-4E09-8C72-1749C4C59591}.Release|ARM.ActiveCfg = Release|ARM
- {26F5807A-25B5-4E09-8C72-1749C4C59591}.Release|ARM.Build.0 = Release|ARM
- {26F5807A-25B5-4E09-8C72-1749C4C59591}.Release|ARM.Deploy.0 = Release|ARM
- {26F5807A-25B5-4E09-8C72-1749C4C59591}.Release|ARM64.ActiveCfg = Release|ARM64
- {26F5807A-25B5-4E09-8C72-1749C4C59591}.Release|ARM64.Build.0 = Release|ARM64
- {26F5807A-25B5-4E09-8C72-1749C4C59591}.Release|ARM64.Deploy.0 = Release|ARM64
- {26F5807A-25B5-4E09-8C72-1749C4C59591}.Release|x64.ActiveCfg = Release|x64
- {26F5807A-25B5-4E09-8C72-1749C4C59591}.Release|x64.Build.0 = Release|x64
- {26F5807A-25B5-4E09-8C72-1749C4C59591}.Release|x64.Deploy.0 = Release|x64
- {26F5807A-25B5-4E09-8C72-1749C4C59591}.Release|x86.ActiveCfg = Release|x86
- {26F5807A-25B5-4E09-8C72-1749C4C59591}.Release|x86.Build.0 = Release|x86
- {26F5807A-25B5-4E09-8C72-1749C4C59591}.Release|x86.Deploy.0 = Release|x86
{B323A2E1-66EF-4037-95B7-2DEFA051B4B1}.CI|Any CPU.ActiveCfg = Release|Any CPU
{B323A2E1-66EF-4037-95B7-2DEFA051B4B1}.CI|Any CPU.Build.0 = Release|Any CPU
{B323A2E1-66EF-4037-95B7-2DEFA051B4B1}.CI|ARM.ActiveCfg = Release|Any CPU