diff --git a/CommunityToolkit.Graph.Uwp/Controls/GraphPresenter/GraphPresenter.cs b/CommunityToolkit.Graph.Uwp/Controls/GraphPresenter/GraphPresenter.cs index abc710b..f41e185 100644 --- a/CommunityToolkit.Graph.Uwp/Controls/GraphPresenter/GraphPresenter.cs +++ b/CommunityToolkit.Graph.Uwp/Controls/GraphPresenter/GraphPresenter.cs @@ -9,6 +9,7 @@ using System.Threading; using Microsoft.Graph; using Microsoft.Toolkit.Uwp; +using Windows.Foundation.Metadata; using Windows.System; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; @@ -18,9 +19,9 @@ namespace CommunityToolkit.Graph.Uwp.Controls /// /// Specialized to fetch and display data from the Microsoft Graph. /// + [Experimental] public class GraphPresenter : ContentPresenter { - /// /// Identifies the dependency property. /// diff --git a/CommunityToolkit.Graph.Uwp/Controls/GraphPresenter/QueryOption.cs b/CommunityToolkit.Graph.Uwp/Controls/GraphPresenter/QueryOption.cs index 9486c28..3859b22 100644 --- a/CommunityToolkit.Graph.Uwp/Controls/GraphPresenter/QueryOption.cs +++ b/CommunityToolkit.Graph.Uwp/Controls/GraphPresenter/QueryOption.cs @@ -7,6 +7,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; +using Windows.Foundation.Metadata; using Windows.UI.Xaml; namespace CommunityToolkit.Graph.Uwp.Controls @@ -14,6 +15,7 @@ namespace CommunityToolkit.Graph.Uwp.Controls /// /// XAML Proxy for . /// + [Experimental] public sealed class QueryOption { /// diff --git a/SampleTest/SampleTest.csproj b/SampleTest/SampleTest.csproj index fedf21a..d311dbb 100644 --- a/SampleTest/SampleTest.csproj +++ b/SampleTest/SampleTest.csproj @@ -126,8 +126,20 @@ GraphPresenterSample.xaml - - OneDriveStorageSample.xaml + + CalendarViewSample.xaml + + + MailMessagesSample.xaml + + + OneDriveSample.xaml + + + PlannerTasksSample.xaml + + + TeamsChannelMessagesSample.xaml PeoplePickerSample.xaml @@ -166,7 +178,23 @@ Designer MSBuild:Compile - + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + Designer MSBuild:Compile @@ -186,6 +214,12 @@ 6.2.12 + + 7.1.0-preview1 + + + 7.1.0-preview1 + diff --git a/SampleTest/Samples/GraphPresenter/CalendarViewSample.xaml b/SampleTest/Samples/GraphPresenter/CalendarViewSample.xaml new file mode 100644 index 0000000..c21b708 --- /dev/null +++ b/SampleTest/Samples/GraphPresenter/CalendarViewSample.xaml @@ -0,0 +1,72 @@ + + + + + + + + + + The following example shows the `Me.CalendarView` API. + + + My Upcoming Calendar Events: + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + diff --git a/SampleTest/Samples/GraphPresenter/CalendarViewSample.xaml.cs b/SampleTest/Samples/GraphPresenter/CalendarViewSample.xaml.cs new file mode 100644 index 0000000..2c30981 --- /dev/null +++ b/SampleTest/Samples/GraphPresenter/CalendarViewSample.xaml.cs @@ -0,0 +1,59 @@ +// 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.Authentication; +using CommunityToolkit.Graph.Extensions; +using Microsoft.Graph; +using Microsoft.Graph.Extensions; +using Windows.UI.Xaml.Controls; + +namespace SampleTest.Samples.GraphPresenter +{ + public sealed partial class CalendarViewSample : 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 CalendarViewRequestBuilder { get; set; } + + public CalendarViewSample() + { + this.InitializeComponent(); + + ProviderManager.Instance.ProviderUpdated += OnProviderUpdated; + ProviderManager.Instance.ProviderStateChanged += OnProviderStateChanged; + } + + private void OnProviderUpdated(object sender, IProvider provider) + { + if (provider == null) + { + ClearRequestBuilders(); + } + } + + private void OnProviderStateChanged(object sender, ProviderStateChangedEventArgs e) + { + if (e.NewState == ProviderState.SignedIn) + { + var graphClient = ProviderManager.Instance.GlobalProvider.GetClient(); + + CalendarViewRequestBuilder = graphClient.Me.CalendarView; + } + else + { + ClearRequestBuilders(); + } + } + + private void ClearRequestBuilders() + { + CalendarViewRequestBuilder = null; + } + } +} diff --git a/SampleTest/Samples/GraphPresenter/MailMessagesSample.xaml b/SampleTest/Samples/GraphPresenter/MailMessagesSample.xaml new file mode 100644 index 0000000..f27edaf --- /dev/null +++ b/SampleTest/Samples/GraphPresenter/MailMessagesSample.xaml @@ -0,0 +1,63 @@ + + + + + + + + + + The following example shows the `Me.Messages` API for getting a user's inbox mail messages. + + + My Messages: + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SampleTest/Samples/GraphPresenter/MailMessagesSample.xaml.cs b/SampleTest/Samples/GraphPresenter/MailMessagesSample.xaml.cs new file mode 100644 index 0000000..8385a09 --- /dev/null +++ b/SampleTest/Samples/GraphPresenter/MailMessagesSample.xaml.cs @@ -0,0 +1,57 @@ +// 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.Text.RegularExpressions; +using CommunityToolkit.Authentication; +using CommunityToolkit.Graph.Extensions; +using Microsoft.Graph; +using Windows.UI.Xaml.Controls; + +namespace SampleTest.Samples.GraphPresenter +{ + public sealed partial class MailMessagesSample : Page + { + public IBaseRequestBuilder MessagesRequestBuilder { get; set; } + + public MailMessagesSample() + { + this.InitializeComponent(); + ProviderManager.Instance.ProviderUpdated += OnProviderUpdated; + ProviderManager.Instance.ProviderStateChanged += OnProviderStateChanged; + } + + private void OnProviderUpdated(object sender, IProvider provider) + { + if (provider == null) + { + ClearRequestBuilders(); + } + } + + private void OnProviderStateChanged(object sender, ProviderStateChangedEventArgs e) + { + if (e.NewState == ProviderState.SignedIn) + { + var graphClient = ProviderManager.Instance.GlobalProvider.GetClient(); + + MessagesRequestBuilder = graphClient.Me.Messages; + } + else + { + ClearRequestBuilders(); + } + } + + private void ClearRequestBuilders() + { + MessagesRequestBuilder = null; + } + + public static string RemoveWhitespace(string value) + { + // Workaround for https://github.com/microsoft/microsoft-ui-xaml/issues/2654 + return Regex.Replace(value, @"\t|\r|\n", " "); + } + } +} diff --git a/SampleTest/Samples/GraphPresenter/OneDriveSample.xaml b/SampleTest/Samples/GraphPresenter/OneDriveSample.xaml new file mode 100644 index 0000000..dae6423 --- /dev/null +++ b/SampleTest/Samples/GraphPresenter/OneDriveSample.xaml @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SampleTest/Samples/GraphPresenter/OneDriveSample.xaml.cs b/SampleTest/Samples/GraphPresenter/OneDriveSample.xaml.cs new file mode 100644 index 0000000..35e56ce --- /dev/null +++ b/SampleTest/Samples/GraphPresenter/OneDriveSample.xaml.cs @@ -0,0 +1,101 @@ +// 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.Threading.Tasks; +using CommunityToolkit.Authentication; +using CommunityToolkit.Graph.Extensions; +using Microsoft.Graph; +using Microsoft.Toolkit; +using Microsoft.Toolkit.Mvvm.ComponentModel; +using Windows.UI.Xaml.Controls; +using Windows.UI.Xaml.Data; + +namespace SampleTest.Samples.GraphPresenter +{ + public sealed partial class OneDriveSample : Page + { + public IBaseRequestBuilder RecentDriveItemsRequestBuilder { get; set; } + + public OneDriveSample() + { + InitializeComponent(); + + ProviderManager.Instance.ProviderStateChanged += (s, e) => UpdateRequestBuilder(); + UpdateRequestBuilder(); + } + + private void UpdateRequestBuilder() + { + var provider = ProviderManager.Instance.GlobalProvider; + switch (provider?.State) + { + case ProviderState.SignedIn: + RecentDriveItemsRequestBuilder = provider.GetClient().Me.Drive.Recent(); + break; + + default: + RecentDriveItemsRequestBuilder = null; + break; + } + } + + private static readonly string[] Suffixes = { "B", "KB", "MB", "GB", "TB" }; + + public static string FormatFileSize(Int64? size) + { + float number = size ?? throw new ArgumentNullException(nameof(size)); + + var suffixIndex = 0; + string Output() => $"{Math.Round(number)}{Suffixes[suffixIndex]}"; + + do + { + if (number < 1024f) + { + return Output(); + } + + number = number / 1024f; + } + while (++suffixIndex < Suffixes.Length - 1); + + return Output(); + } + + public static AsyncResult GetThumbnail(RemoteItem ri) + { + // drives/${file.remoteItem.parentReference.driveId}/items/${file.remoteItem.id}/thumbnails/0/medium + var provider = ProviderManager.Instance.GlobalProvider; + if (provider?.State == ProviderState.SignedIn) + { + var graph = provider.GetClient(); + return new AsyncResult(graph.Drives[ri.ParentReference.DriveId].Items[ri.Id].Thumbnails["0"].Request().GetAsync()); + } + + return null; + } + + public sealed class AsyncResult : ObservableObject + { + private TaskNotifier taskNotifier; + + public Task Task + { + get => taskNotifier; + private set + { + SetPropertyAndNotifyOnCompletion(ref taskNotifier, value, nameof(ResultOrDefault)); + } + } + + public AsyncResult(Task task) + { + Task = task; + } + + public TResult ResultOrDefault => this.Task.GetResultOrDefault(); + } + } +} diff --git a/SampleTest/Samples/GraphPresenter/PlannerTasksSample.xaml b/SampleTest/Samples/GraphPresenter/PlannerTasksSample.xaml new file mode 100644 index 0000000..9cede26 --- /dev/null +++ b/SampleTest/Samples/GraphPresenter/PlannerTasksSample.xaml @@ -0,0 +1,81 @@ + + + + + + + + + The following example shows the `Me.Planner.Tasks` API for getting a user's tasks. + + My Tasks: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Due + + + + + + + + + + + + + + + diff --git a/SampleTest/Samples/GraphPresenter/PlannerTasksSample.xaml.cs b/SampleTest/Samples/GraphPresenter/PlannerTasksSample.xaml.cs new file mode 100644 index 0000000..822fbae --- /dev/null +++ b/SampleTest/Samples/GraphPresenter/PlannerTasksSample.xaml.cs @@ -0,0 +1,56 @@ +// 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 Windows.UI.Xaml.Controls; + +namespace SampleTest.Samples.GraphPresenter +{ + public sealed partial class PlannerTasksSample : Page + { + public IBaseRequestBuilder PlannerTasksRequestBuilder; + + public PlannerTasksSample() + { + this.InitializeComponent(); + + ProviderManager.Instance.ProviderUpdated += OnProviderUpdated; + ProviderManager.Instance.ProviderStateChanged += OnProviderStateChanged; + } + + private void OnProviderUpdated(object sender, IProvider provider) + { + if (provider == null) + { + ClearRequestBuilders(); + } + } + + private void OnProviderStateChanged(object sender, ProviderStateChangedEventArgs e) + { + if (e.NewState == ProviderState.SignedIn) + { + var graphClient = ProviderManager.Instance.GlobalProvider.GetClient(); + + PlannerTasksRequestBuilder = graphClient.Me.Planner.Tasks; + } + else + { + ClearRequestBuilders(); + } + } + + private void ClearRequestBuilders() + { + PlannerTasksRequestBuilder = null; + } + + public static bool IsTaskCompleted(int? percentCompleted) + { + return percentCompleted == 100; + } + } +} diff --git a/SampleTest/Samples/GraphPresenter/TeamsChannelMessagesSample.xaml b/SampleTest/Samples/GraphPresenter/TeamsChannelMessagesSample.xaml new file mode 100644 index 0000000..c3e7044 --- /dev/null +++ b/SampleTest/Samples/GraphPresenter/TeamsChannelMessagesSample.xaml @@ -0,0 +1,64 @@ + + + + + + + + + + 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/Samples/GraphPresenter/TeamsChannelMessagesSample.xaml.cs b/SampleTest/Samples/GraphPresenter/TeamsChannelMessagesSample.xaml.cs new file mode 100644 index 0000000..6ce8652 --- /dev/null +++ b/SampleTest/Samples/GraphPresenter/TeamsChannelMessagesSample.xaml.cs @@ -0,0 +1,51 @@ +// 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 Windows.UI.Xaml.Controls; + +namespace SampleTest.Samples.GraphPresenter +{ + public sealed partial class TeamsChannelMessagesSample : Page + { + public IBaseRequestBuilder TeamsChannelMessagesRequestBuilder { get; set; } + + public TeamsChannelMessagesSample() + { + this.InitializeComponent(); + + ProviderManager.Instance.ProviderUpdated += OnProviderUpdated; + ProviderManager.Instance.ProviderStateChanged += OnProviderStateChanged; + } + + private void OnProviderUpdated(object sender, IProvider provider) + { + if (provider == null) + { + ClearRequestBuilders(); + } + } + + private void OnProviderStateChanged(object sender, ProviderStateChangedEventArgs e) + { + if (e.NewState == ProviderState.SignedIn) + { + var graphClient = ProviderManager.Instance.GlobalProvider.GetClient(); + + TeamsChannelMessagesRequestBuilder = graphClient.Teams["02bd9fd6-8f93-4758-87c3-1fb73740a315"].Channels["19:d0bba23c2fc8413991125a43a54cc30e@thread.skype"].Messages; + } + else + { + ClearRequestBuilders(); + } + } + + private void ClearRequestBuilders() + { + TeamsChannelMessagesRequestBuilder = null; + } + } +} diff --git a/SampleTest/Samples/GraphPresenterSample.xaml b/SampleTest/Samples/GraphPresenterSample.xaml index cead7e3..14303d7 100644 --- a/SampleTest/Samples/GraphPresenterSample.xaml +++ b/SampleTest/Samples/GraphPresenterSample.xaml @@ -3,20 +3,11 @@ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:SampleTest.Samples" - xmlns:toolkit="using:Microsoft.Toolkit" - xmlns:global="using:System.Globalization" - xmlns:controls="using:CommunityToolkit.Graph.Uwp.Controls" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" - xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:graph="using:Microsoft.Graph" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:graphpresenter="using:SampleTest.Samples.GraphPresenter" mc:Ignorable="d" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> - - - - - - - @@ -24,7 +15,8 @@ - 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 `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. @@ -32,241 +24,20 @@ - - - - - - - - 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/Samples/GraphPresenterSample.xaml.cs b/SampleTest/Samples/GraphPresenterSample.xaml.cs index 93e71d1..f0207a5 100644 --- a/SampleTest/Samples/GraphPresenterSample.xaml.cs +++ b/SampleTest/Samples/GraphPresenterSample.xaml.cs @@ -14,58 +14,6 @@ namespace SampleTest.Samples { public sealed partial class GraphPresenterSample : 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 GraphPresenterSample() - { - InitializeComponent(); - - ProviderManager.Instance.ProviderUpdated += OnProviderUpdated; - ProviderManager.Instance.ProviderStateChanged += OnProviderStateChanged; - } - - private void OnProviderStateChanged(object sender, ProviderStateChangedEventArgs e) - { - if (e.NewState == 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 - { - ClearRequestBuilders(); - } - } - - private void OnProviderUpdated(object sender, IProvider provider) - { - if (provider == null) - { - ClearRequestBuilders(); - } - } - - private void ClearRequestBuilders() - { - 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 @@ -78,15 +26,9 @@ public static string ToLocalTime(DateTimeOffset? value) 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) + public GraphPresenterSample() { - return percentCompleted == 100; + InitializeComponent(); } } } diff --git a/SampleTest/Samples/OneDriveStorageSample.xaml b/SampleTest/Samples/OneDriveStorageSample.xaml deleted file mode 100644 index ea6260f..0000000 --- a/SampleTest/Samples/OneDriveStorageSample.xaml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - diff --git a/SampleTest/Samples/OneDriveStorageSample.xaml.cs b/SampleTest/Samples/OneDriveStorageSample.xaml.cs deleted file mode 100644 index 3ddea19..0000000 --- a/SampleTest/Samples/OneDriveStorageSample.xaml.cs +++ /dev/null @@ -1,16 +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 Windows.UI.Xaml.Controls; - -namespace SampleTest.Samples -{ - public sealed partial class OneDriveStorageSample : Page - { - public OneDriveStorageSample() - { - InitializeComponent(); - } - } -}