From 8f82e91ad7ef1eb757cb7c183569d0412a452bac Mon Sep 17 00:00:00 2001 From: Shane Weaver Date: Wed, 19 May 2021 17:18:39 -0700 Subject: [PATCH 1/3] Removed preview controls/helpers and any references --- CommunityToolkit.Graph.Uwp/Assets/person.png | Bin 5250 -> 0 bytes .../CommunityToolkit.Graph.Uwp.csproj | 66 ---- .../Controls/GraphPresenter/GraphPresenter.cs | 117 ------- .../Controls/GraphPresenter/QueryOption.cs | 34 -- .../LoginButton/LoginButton.Events.cs | 40 --- .../LoginButton/LoginButton.Properties.cs | 51 --- .../Controls/LoginButton/LoginButton.cs | 229 ------------- .../Controls/LoginButton/LoginButton.xaml | 59 ---- .../LoginButton/LoginFailedEventArgs.cs | 50 --- .../Controls/PeoplePicker/PeoplePicker.cs | 118 ------- .../Controls/PeoplePicker/PeoplePicker.xaml | 39 --- .../PersonView/PersonView.Properties.cs | 139 -------- .../Controls/PersonView/PersonView.cs | 228 ------------- .../Controls/PersonView/PersonView.xaml | 96 ------ .../Controls/PersonView/PersonViewType.cs | 27 -- .../Converters/ObjectToStringConverter.cs | 27 -- .../Converters/UserToPersonConverter.cs | 34 -- .../BaseRoamingSettingsDataStore.cs | 303 ----------------- .../IRoamingSettingsDataStore.cs | 65 ---- .../RoamingSettings/OneDriveDataSource.cs | 69 ---- .../RoamingSettings/OneDriveDataStore.cs | 154 --------- .../RoamingSettings/RoamingSettingsHelper.cs | 188 ----------- .../RoamingSettings/UserExtensionDataStore.cs | 201 ------------ .../UserExtensionsDataSource.cs | 204 ------------ .../Properties/AssemblyInfo.cs | 11 - ...CommunityToolkit.Uwp.Graph.Controls.rd.xml | 5 - .../Themes/Generic.xaml | 8 - .../VisualStudioToolsManifest.xml | 9 - SampleTest/App.xaml | 4 - SampleTest/App.xaml.cs | 146 --------- SampleTest/Assets/FileIcon.png | Bin 2838 -> 0 bytes .../Assets/LockScreenLogo.scale-200.png | Bin 1430 -> 0 bytes SampleTest/Assets/SplashScreen.scale-200.png | Bin 7700 -> 0 bytes .../Assets/Square150x150Logo.scale-200.png | Bin 2937 -> 0 bytes .../Assets/Square44x44Logo.scale-200.png | Bin 1647 -> 0 bytes ...x44Logo.targetsize-24_altform-unplated.png | Bin 1255 -> 0 bytes SampleTest/Assets/StoreLogo.png | Bin 1451 -> 0 bytes .../Assets/Wide310x150Logo.scale-200.png | Bin 3204 -> 0 bytes SampleTest/MainPage.xaml | 309 ------------------ SampleTest/MainPage.xaml.cs | 83 ----- SampleTest/Package.appxmanifest | 49 --- SampleTest/Properties/AssemblyInfo.cs | 31 -- SampleTest/Properties/Default.rd.xml | 31 -- SampleTest/SampleTest.csproj | 258 --------------- .../RoamingSettings/RoamingSettingsView.xaml | 79 ----- .../RoamingSettingsView.xaml.cs | 57 ---- .../RoamingSettingsViewModel.cs | 195 ----------- .../UwpMsalProviderSample/LoginButton.xaml | 14 + .../UwpMsalProviderSample/LoginButton.xaml.cs | 70 ++++ Samples/UwpMsalProviderSample/MainPage.xaml | 3 +- .../UwpMsalProviderSample/MainPage.xaml.cs | 2 +- .../UwpMsalProviderSample.csproj | 11 +- .../UwpWindowsProviderSample/LoginButton.xaml | 14 + .../LoginButton.xaml.cs | 70 ++++ .../UwpWindowsProviderSample/MainPage.xaml | 3 +- .../UwpWindowsProviderSample/MainPage.xaml.cs | 2 +- .../UwpWindowsProviderSample.csproj | 11 +- .../RoamingSettings/Test_OneDriveDataStore.cs | 154 --------- .../Test_UserExtensionDataStore.cs | 154 --------- UnitTests/UnitTests.UWP/UnitTests.UWP.csproj | 6 - Windows-Toolkit-Graph-Controls.sln | 88 ----- 61 files changed, 186 insertions(+), 4229 deletions(-) delete mode 100644 CommunityToolkit.Graph.Uwp/Assets/person.png delete mode 100644 CommunityToolkit.Graph.Uwp/CommunityToolkit.Graph.Uwp.csproj delete mode 100644 CommunityToolkit.Graph.Uwp/Controls/GraphPresenter/GraphPresenter.cs delete mode 100644 CommunityToolkit.Graph.Uwp/Controls/GraphPresenter/QueryOption.cs delete mode 100644 CommunityToolkit.Graph.Uwp/Controls/LoginButton/LoginButton.Events.cs delete mode 100644 CommunityToolkit.Graph.Uwp/Controls/LoginButton/LoginButton.Properties.cs delete mode 100644 CommunityToolkit.Graph.Uwp/Controls/LoginButton/LoginButton.cs delete mode 100644 CommunityToolkit.Graph.Uwp/Controls/LoginButton/LoginButton.xaml delete mode 100644 CommunityToolkit.Graph.Uwp/Controls/LoginButton/LoginFailedEventArgs.cs delete mode 100644 CommunityToolkit.Graph.Uwp/Controls/PeoplePicker/PeoplePicker.cs delete mode 100644 CommunityToolkit.Graph.Uwp/Controls/PeoplePicker/PeoplePicker.xaml delete mode 100644 CommunityToolkit.Graph.Uwp/Controls/PersonView/PersonView.Properties.cs delete mode 100644 CommunityToolkit.Graph.Uwp/Controls/PersonView/PersonView.cs delete mode 100644 CommunityToolkit.Graph.Uwp/Controls/PersonView/PersonView.xaml delete mode 100644 CommunityToolkit.Graph.Uwp/Controls/PersonView/PersonViewType.cs delete mode 100644 CommunityToolkit.Graph.Uwp/Converters/ObjectToStringConverter.cs delete mode 100644 CommunityToolkit.Graph.Uwp/Converters/UserToPersonConverter.cs delete mode 100644 CommunityToolkit.Graph.Uwp/Helpers/RoamingSettings/BaseRoamingSettingsDataStore.cs delete mode 100644 CommunityToolkit.Graph.Uwp/Helpers/RoamingSettings/IRoamingSettingsDataStore.cs delete mode 100644 CommunityToolkit.Graph.Uwp/Helpers/RoamingSettings/OneDriveDataSource.cs delete mode 100644 CommunityToolkit.Graph.Uwp/Helpers/RoamingSettings/OneDriveDataStore.cs delete mode 100644 CommunityToolkit.Graph.Uwp/Helpers/RoamingSettings/RoamingSettingsHelper.cs delete mode 100644 CommunityToolkit.Graph.Uwp/Helpers/RoamingSettings/UserExtensionDataStore.cs delete mode 100644 CommunityToolkit.Graph.Uwp/Helpers/RoamingSettings/UserExtensionsDataSource.cs delete mode 100644 CommunityToolkit.Graph.Uwp/Properties/AssemblyInfo.cs delete mode 100644 CommunityToolkit.Graph.Uwp/Properties/CommunityToolkit.Uwp.Graph.Controls.rd.xml delete mode 100644 CommunityToolkit.Graph.Uwp/Themes/Generic.xaml delete mode 100644 CommunityToolkit.Graph.Uwp/VisualStudioToolsManifest.xml delete mode 100644 SampleTest/App.xaml delete mode 100644 SampleTest/App.xaml.cs delete mode 100644 SampleTest/Assets/FileIcon.png delete mode 100644 SampleTest/Assets/LockScreenLogo.scale-200.png delete mode 100644 SampleTest/Assets/SplashScreen.scale-200.png delete mode 100644 SampleTest/Assets/Square150x150Logo.scale-200.png delete mode 100644 SampleTest/Assets/Square44x44Logo.scale-200.png delete mode 100644 SampleTest/Assets/Square44x44Logo.targetsize-24_altform-unplated.png delete mode 100644 SampleTest/Assets/StoreLogo.png delete mode 100644 SampleTest/Assets/Wide310x150Logo.scale-200.png delete mode 100644 SampleTest/MainPage.xaml delete mode 100644 SampleTest/MainPage.xaml.cs delete mode 100644 SampleTest/Package.appxmanifest delete mode 100644 SampleTest/Properties/AssemblyInfo.cs delete mode 100644 SampleTest/Properties/Default.rd.xml delete mode 100644 SampleTest/SampleTest.csproj delete mode 100644 SampleTest/Samples/RoamingSettings/RoamingSettingsView.xaml delete mode 100644 SampleTest/Samples/RoamingSettings/RoamingSettingsView.xaml.cs delete mode 100644 SampleTest/Samples/RoamingSettings/RoamingSettingsViewModel.cs create mode 100644 Samples/UwpMsalProviderSample/LoginButton.xaml create mode 100644 Samples/UwpMsalProviderSample/LoginButton.xaml.cs create mode 100644 Samples/UwpWindowsProviderSample/LoginButton.xaml create mode 100644 Samples/UwpWindowsProviderSample/LoginButton.xaml.cs delete mode 100644 UnitTests/UnitTests.UWP/RoamingSettings/Test_OneDriveDataStore.cs delete mode 100644 UnitTests/UnitTests.UWP/RoamingSettings/Test_UserExtensionDataStore.cs diff --git a/CommunityToolkit.Graph.Uwp/Assets/person.png b/CommunityToolkit.Graph.Uwp/Assets/person.png deleted file mode 100644 index 35668622a7d75a0a8b1ffbc795e94abde0f93188..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5250 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 IM6N<$g8G;6L;wH) 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 2617b15..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 -{ - /// - /// 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 6f1496b..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 -{ - /// - /// 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 1364158..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 -{ - /// - /// 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 b0ddbb6..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 -{ - /// - /// 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 9af8fa7..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 -{ - /// - /// 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 455da5f..0000000 --- a/CommunityToolkit.Graph.Uwp/Controls/LoginButton/LoginButton.xaml +++ /dev/null @@ -1,59 +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 fe6256e..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 -{ - /// - /// 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 fe39d8a..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 -{ - /// - /// 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 5e4cc75..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 79d8c15..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 -{ - /// - /// 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 8558d02..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 -{ - /// - /// 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 e45ae6e..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 961bd76..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 -{ - /// - /// 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/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 0435822f88e9f95066aa532bc10bbee46fea6a13..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2838 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 diff --git a/SampleTest/Assets/LockScreenLogo.scale-200.png b/SampleTest/Assets/LockScreenLogo.scale-200.png deleted file mode 100644 index 735f57adb5dfc01886d137b4e493d7e97cf13af3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1430 zcmaJ>TTC2P7~aKltDttVHYH6u8Io4i*}3fO&d$gd*bA_<3j~&e7%8(eXJLfhS!M@! zKrliY>>6yT4+Kr95$!DoD(Qn-5TP|{V_KS`k~E6(LGS@#`v$hQo&^^BKsw3HIsZBT z_y6C2n`lK@apunKojRQ^(_P}Mgewt$(^BBKCTZ;*xa?J3wQ7~@S0lUvbcLeq1Bg4o zH-bvQi|wt~L7q$~a-gDFP!{&TQfc3fX*6=uHv* zT&1&U(-)L%Xp^djI2?~eBF2cxC@YOP$+9d?P&h?lPy-9M2UT9fg5jKm1t$m#iWE{M zIf%q9@;fyT?0UP>tcw-bLkz;s2LlKl2qeP0w zECS7Ate+Awk|KQ+DOk;fl}Xsy4o^CY=pwq%QAAKKl628_yNPsK>?A>%D8fQG6IgdJ ztnxttBz#NI_a@fk7SU`WtrpsfZsNs9^0(2a z@C3#YO3>k~w7?2hipBf{#b6`}Xw1hlG$yi?;1dDs7k~xDAw@jiI*+tc;t2Lflg&bM)0!Y;0_@=w%`LW^8DsYpS#-bLOklX9r?Ei}TScw|4DbpW%+7 zFgAI)f51s}{y-eWb|vrU-Ya!GuYKP)J7z#*V_k^Xo>4!1Yqj*m)x&0L^tg3GJbVAJ zJ-Pl$R=NAabouV=^z_t;^K*0AvFs!vYU>_<|I^#c?>>CR<(T?=%{;U=aI*SbZADLH z&(f2wz_Y0??Tf|g;?|1Znw6}6U43Q#qNRwv1vp9uFn1)V#*4p&%$mP9x&15^OaBiDS(XppT|z^>;B{PLVEbS3IFYV yGvCsSX*m diff --git a/SampleTest/Assets/SplashScreen.scale-200.png b/SampleTest/Assets/SplashScreen.scale-200.png deleted file mode 100644 index 023e7f1feda78d5100569825acedfd213a0d84e9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7700 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 diff --git a/SampleTest/Assets/Square150x150Logo.scale-200.png b/SampleTest/Assets/Square150x150Logo.scale-200.png deleted file mode 100644 index af49fec1a5484db1d52a7f9b5ec90a27c7030186..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2937 zcma)84OCO-8BSud5)jwMLRVKgX(S?$n?Ld|vrsm<$CF7)&zTbyy1FE5bU`Q17MRv`9ue$;R(@8kR;#vJ*IM0>cJIAOte!d7oRgdH zd%ySjdB6L9=gX^A6)VzH7p2l@v~3zJAMw|DFy#^)F@@F*`mqUn=Il>l)8_+ab;nOW{%+iPx z+s{Eu|&pIs)Z7{La9~?xKfyl z#43?gjEL15d4WbOZo#SiP%>DB^+BcnJ=7dHEe;r#G=tuw|ka z%q@}##Uh7;tc%L_64m(kHtw74ty%BJMb)_1)#S0j`)F8_1jF7vScpsnH=0V19bO8y zR`0SjIdCUo&=>JwMQF8KHA<{ODHTiQh}0^@5QRmCA?gOH6_H3K^-_sNB^RrdNuK-R zOO*vOrKCVvDwgUck`kF(E7j{I#iiN;b*ZdCt4m@HPA`EuEqGGf4%!K<;(=I=&Vyrw z%TwcWtxa}8mCZ%Cyf&ActJ6_$ox5z6-D!0-dvnRx6t7y3d+h6QYpKWO;8OdnvERo7 zuEf>ih5`wqY)~o@OeVt-wM?Q!>QzdGRj!bz6fzYrfw$hZfAKzr2-M+D+R>}~oT574c;_3zquHcElqKIsryILt3g8n3jcMb+j?i?-L3FpZJ z2WRVBRdDPc+G5aaYg#5hpE+6nQ|(VSoxT3|biF;BUq#==-27Xi=gihDPYP$7?=9cP zYKE$jeQ|3~_L0VG-(F~2ZPyD0=k{J4Q~h(t__{-mz_w8{JDY9{`1ouzz!Vr5!ECdE z6U~O1k8c}24V7~zzXWTV-Pe4)y}wQJS&q%H5`Fo_f_JvIU489aCX$;P`u#!I-=^4ijC2{&9!O&h>mi?9oYD=GC#%)6{GzN6nQYw+Fal50!#x^asjBBR50i`+mho*ttoqV)ubM2KD9S~k7+FR4>{29?6 z{!l6kDdyTN0YJ9LgkPWeXm|gyi@zM3?0@{&pXT12w|78&W-q!RRF)&iLCEZVH<|fR zN0fr2^t8H(>L?>K#>^+jWROLral(Qy-xoBq1U7A&DV||wClb)Otd9?(gZ|8znMF}D zf<1haWz^s0qgecz;RFGt0C-B4g`jNGHsFU+;{<%t65v^sjk^h$lmWn#B0#_)9ij&d z-~lc`A)YYExi^7sBuPM^Y|wA2g*5?`K?#7tzELQYNxGo$UB$4J8RJp1k(8Jj+~hMT zlN~>M@KTTh^--8y3PK_NZ@AC!{PT=CziBzGd+wTJ^@icH!Bd}%)g8V)%K?|c&WTUk zy}qv1C%(fjRoZ4ozC3{O%@5?)XzH35zHns$pgU*Q?fj4v?fp1Qbm+j;3l;9jam9Da zXVcKjPlQ73x78QPu|Ffm6x?`~e3oD=gl=4kYK?={kD5j~QCXU)`HSdduNNENzA*2$ zOm3PzF!lN5e*06-f1Uot67wY#{o-S1!KZ7E=!~7ynnk9_iJR#kFoNbAOT#^2Gd17F zMmvU6>lndZQGd|ax9kUoXXO+$N?|j@6qpsF&_j7YXvwo_C{JpmLw5&#e6k>atv%es z5)7r*Wvv_JkUpT}M!_o!nVlEk1Zbl=a*2hQ*<|%*K1Glj^FcF`6kTzGQ3lz~2tCc@ z&x|tj;aH&1&9HwcJBcT`;{?a+pnej;M1HO(6Z{#J!cZA04hnFl;NXA+&`=7bjW_^o zfC40u3LMG?NdPtwGl>Tq6u}*QG)}-y;)lu-_>ee3kibW(69n0$0Zy!}9rQz%*v1iO zT9_H>99yIrSPYVy6^);rR}7Yo=J_T@hi+qhTZXnVWyf;JDYm5#eYLTxr*?kiNn!+Y zQ+LUkBafNJ#rH#C(?d5^;gw9o#%daEI{mA*LHPIHPU`#|H$hD zwm>0&+kahQ)E#%~k>&5@&#Vg82H?s%71=)(soi@174pi9--2{w{1$}Sz4zGn3Du&x bht0Iza^2ykEt4(epJ78uh5nDlX8(TxzDYwP diff --git a/SampleTest/Assets/Square44x44Logo.scale-200.png b/SampleTest/Assets/Square44x44Logo.scale-200.png deleted file mode 100644 index ce342a2ec8a61291ba76c54604aea7e9d20af11b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1647 zcmaJ?eM}Q)7(e+G1Q(|`V9JhTI2>MkceK4;p;PR&$Pi?ejk3YQ_3o`S&|W_dsOZ8# zWPTt69g`t$ab`0cj-Y0yiBSOqmd)tG7G(}M5aP0_%&9TijB#&)I{zSE^4@#z^FF`l z`8{8`o%wlL(UI|y2!cdsuVamHH~H86F!*-15em4)NqUpCQM5?aoC_eCf@lV4wvF2a zjDQn1JBL69f&@2M3rvzJcfE!eZ8FZUBlFlC5RD)it33{mF9#B82AiyQE%w)`vlwa> zv{<1sm&kSKK$&%2jSFn7$t&P%%6Ue>R=EAnG8N7fqynWG8L3p!4801a;8{+nliO(qd(jNJ_?+9W3#hLIDLoT6~3fx9=`CC-D}-AMrpEO7HK zt3$GicGPc?GmDjy7K2P@La;eu4!$zWCZ`ym{Z$b zu-O6RM&K4JT|BIZB`E-gxqG%FzanI#+2FFmqHqXG7yxWB=w55RGOM)$xMb(>kSNR z2w=1AZi%z=AmG~yea~XaXJR!v7vLn(RUnELfiB1|6D84ICOS}^Zo2AdN}<&*h}G_u z{xZ!(%>tLT3J3<5XhWy-tg+6)0nmUUENLW8TWA{R6bgVd3X;anYFZ^IRis*_P-C-r z;i>%1^eL3UI2-{w8nuFFcs0e~7J{O2k^~Ce%+Ly4U?|=!0LH=t6()xi<^I-rs+9sF z*q{E-CxZbGPeu#a;XJwE;9S1?#R&uns>^0G3p`hEUF*v`M?@h%T%J%RChmD|EVydq zmHWh*_=S%emRC*mhxaVLzT@>Z2SX0u9v*DIJ@WC^kLVdlGV6LpK$KIrlJqc zpJ921)+3JJdTx|<`G&kXpKkjGJv=76R`yYIQ{#c-`%+`#V(7}Q;&@6U8!Td1`d;?N z_9mnI#?AA}4J!r)LN4!E-@H5eXauuB7TOawS>Y|{-P?NNx-lq+z1W-+y(;39P&&LP zL{N80?&=C*qKmdA^moMZRuPcD!B<*mq$ch=0Cnlitw#txRWhb3%TQvPqjkC`F69G4b! ze7z9MZ#+;_#l?H37UqUhDFb^l&s2{oM$3I0o^Q!yx;;V)QmCMo)Tb_ui|mit8MS?U zm##6$sZZ1$@|s%?l@>4Z<*Q}sRBSKMhb4I{e5LdEhsHIHTe8Bod5c>6QtT>$XgUBz z6MK`kO$=jmt@FqggOhJ5j~e@ygRbG;<{Vu)*+nn9aQeo0;$#j;|MS=S$&L?BeV25z xs3B`@=#`5TF{^6(A1rvdY@|-RtQ|iS5{tyX+wH?;n8E)G$kykv-D^wh{{!TZT%7;_ 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 f6c02ce97e0a802b85f6021e822c89f8bf57d5cd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1255 zcmaJ>TWs4@7*5+{G#S+&C!qC#> zf>5N3P6jO*Cz>ug*(_DmW=)kea&m$gZ^+nyiF`;j%w@}y8)>p*SH}C`m?DXeieF2U zyQHecc_L%Gh!7GMt+hG06y;+|p4>m~}PjA}rKViGiEnn7G0ZO<>G|7q;2?NwGCM3s?eued6%hd$B+ z*kQJ{#~$S=DFE(%=E+UkmlEI*%3llUf~8Ja9YU1Vui0IbGBkW_gHB%Rd&!!ioX zs40O?i9I{};kle7GMvE7(rk`la=gTI)47=>%?q@^iL-nUo3}h4S}N-KHn8t5mVP8w z&bSErwp+37 zNJJ8?a|{r5Q3R0Z5s-LB1WHOwYC@7pCHWND#cL1cZ?{kJ368_*(UDWUDyb<}0y@o# zfMF016iMWPCb6obAxT$JlB6(2DrlXDTB&!0`!m??4F(qWMhjVZo?JXQmz`1*58Z=& zcDmB|S-E@j?BoFGix0flckqdS4jsPNzhfWyWIM98GxcLs89C(~dw%$_t;JjX-SD}E zfiGV;{8Q%8r}w9x>EEigW81>`kvnU@pK)4+xk9@+bNj9L!AAZ@SZ@q|)&BmY3+HZx zul~BeG4|}-;L%cHViQGQX?^zFfO0&#cHwel=d`lH9sJ-@Sl@n*(8J2>%Ac`IxyY?Q z{=GhWvC#gu-~Ia7*n{=+;qM?Ul_wy1+u7ho;=`>EwP^g~R@{unBds`!#@}tluZQpS zm)M~nYEifJWJGx?_6DcTy>#uh%>!H9=hb^(v`=m3F1{L>db=<5_tm+_&knAQ2EU$s Mu9UqpbNZeC0BbUo^Z)<= diff --git a/SampleTest/Assets/StoreLogo.png b/SampleTest/Assets/StoreLogo.png deleted file mode 100644 index 7385b56c0e4d3c6b0efe3324aa1194157d837826..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1451 zcmaJ>eN5D57_Z|bH;{0+1#mbl)eTU3{h)Wf7EZV?;HD@XL@{B`Ui%(2aMxQ~xdXSv z5nzWi(LW)U2=Vc-cY@s7nPt{i0hc6!7xN4NNHI#EQl>YNBy8l4%x9gr_W-j zEZMQmmTIy(>;lblRfh`dIyTgc9W5d!VP$L4(kKrN1c5G~(O_#xG zAJCNTstD^5SeXFB+&$h=ToJP2H>xr$iqPs-#O*;4(!Fjw25-!gEb*)mU}=)J;Iu>w zxK(5XoD0wrPSKQ~rbL^Cw6O_03*l*}i=ydbu7adJ6y;%@tjFeXIXT+ms30pmbOP%Q zX}S;+LBh8Tea~TSkHzvX6$rYb)+n&{kSbIqh|c7hmlxmwSiq5iVhU#iEQ<>a18|O^Sln-8t&+t`*{qBWo5M?wFM(JuimAOb5!K#D}XbslM@#1ZVz_;!9U zpfEpLAOz=0g@bd6Xj_ILi-x^!M}73h^o@}hM$1jflTs|Yuj9AL@A3<-?MV4!^4q`e z)fO@A;{9K^?W?DbnesnPr6kK>$zaKo&;FhFd(GYFCIU^T+OIMb%Tqo+P%oq(IdX7S zf6+HLO?7o0m+p>~Tp5UrXWh!UH!wZ5kv!E`_w)PTpI(#Iw{AS`gH4^b(bm^ZCq^FZ zY9DD7bH}rq9mg88+KgA$Zp!iWncuU2n1AuIa@=sWvUR-s`Qb{R*kk(SPU^`$6BXz8 zn#7yaFOIK%qGxyi`dYtm#&qqox0$h=pNi#u=M8zUG@bpiZ=3sT=1}Trr}39cC)H|v zbL?W)=&s4zrh)7>L(|cc%$1#!zfL?HjpeP%T+x_a+jZ16b^iKOHxFEX$7d|8${H-* zIrOJ5w&i$>*D>AKaIoYg`;{L@jM((Kt?$N$5OnuPqVvq**Nm}(f0wwOF%iX_Pba;V z;m@wxX&NcV3?<1+u?A{y_DIj7#m3Af1rCE)o`D&Y3}0%7E;iX1yMDiS)sh0wKi!36 zL!Wmq?P^Ku&rK~HJd97KkLTRl>ScGFYZNlYytWnhmuu|)L&ND8_PmkayQb{HOY640 bno1(wj@u8DCVuFR|31B*4ek@pZJqxCDDe1x diff --git a/SampleTest/Assets/Wide310x150Logo.scale-200.png b/SampleTest/Assets/Wide310x150Logo.scale-200.png deleted file mode 100644 index 288995b397fdbef1fb7e85afd71445d5de1952c5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3204 zcmbVPeQXow8NYmBd90>}0NP?GhXW~VaeThm=a0tV#EwJMI!)6M3}|c4_Bl3=Kd>G0 z(GHx1wl<7(tP?FsOQkTilSo*iIvF%uArExJ73~P zSv1xEy!U(Wd4A9D`FQV@W3@F^qJ@PEF$@z`Z!*BbFsS(^?B zyiAzJ+q})bkgiQHWqEb*jJD-coHYr1^iocg)l!Qa{Xqs-l~6J}p-|##ZHYofskQ3$ zI0;xzXyhazBeXhIsg5A=%ufo@f)1yy&ScKS0;HF^!r_2UE^lpZEom(+@duma3awTv zCrCL-%D_SvYWIcdHkmI}#50(fkUi)Qgx!80ju>g1za^}ff>JI8Z@^-iCiaCgg@TgF z+vtE?Q9{VQUX&MW9SYYmGcxA14%N2@7FwBTD4N<(2{nWgV8$e3?-F=L^&FrtWn~(U_Q~~^uYiyeY6-KoTnfh9AWz@ zIKje0)u!_Lw)E}G!#kEfwKVdNt(UAf9*f>tEL_(=xco-T%jTi@7YlC3hs2ik%Le0H ztj}RTeCF(5mwvi3_56>-yB?l;J>-1%!9~=fs|QcNG3J~a@JCu`4SB460s0ZO+##4fFUSGLcj_ja^fL4&BKALfb#$6$O?>P@qx2Agl^x0i&ugt zsy5Pyu=()`7HRMG3IB7F1@`_ z+-!J%#i6e^U$e#+C%Q>_qVRzWRsG^W_n+@OcX@vzI&z;mzHNb!GQ?LWA(wtpqHqTM z1OFw_{Zn?fD)p)`c`kOgv{de=v@suGRqY{N^U7gI1VF3*F=obwaXI6ob5__Yn zVTguS!%(NI09J8x#AO_aW!9W7k*UvB;IWDFC3srwftr{kHj%g)fvnAm;&h_dnl~

MY- zf+K}sCe8qU6Ujs`3ua{U0Of$R_gVQBuUA za0v=mu#vIOqiiAZOr&h*$WyOw&k-xr$;G4Ixa!#TJNr>95(h>l%)PUy4p+^SgR(uR zta%k*?ny-+nAr8spEk1fo{J4i!b^Fia`N{_F6@zidA2ZTTrjl#^5Z-2KfB@Cu}l9s z(*|Z2jc?p~vn2f)3y9i*7zJV1L{$?|&q)4oaT;uXi6>1GkRXVTOzAz(RHEmr=eFIi z`}<>-Q?K0GN8!IYxeP1XKXO+jsJbp~o^);Bc;%b7Flpe7;1`Ny@3r7ZR;?R)aJt8C ziNlEC<@3f_lIV4TwV}&e;D!Ee5_|e#g0LUh=5vmYWYm7&2h*M>QPKvGh9-)wfMMW3 z8J9b%1k7dzPzO0_NGQy92BZ^FR6R~6;^6?lqO;-QUP4BY%cG%3vEhbm#>4vIhPBh3 z-+pZGjh$x%Hp{?=FHsMp0&wNPlj00us{&`1ZOZTqs8%4X&xH=UDr*xyBW(Zp&Em94 zf)ZSfn#yg0N)>!1kWdkqJ^S*z0FF5|fj&qcE#Na|%OY0$uO>!&hP+1ywfD_WXk@4J(?MBftK7>$Nvqh@tDuarN%PrTLQ2Uzysx>UV=V zk^RrDSvdQ?0;=hY67EgII-f4`t=+i*yS=Y~!XlqIy_4x&%+OdfbKOFPXS2X5%4R{N z$SQMX^AK6(fA - - - - - - - - - - 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 @@ - - - - - - - - - - - -