Skip to content

Commit

Permalink
Merge pull request #5 from andrewleader/toast-notifications
Browse files Browse the repository at this point in the history
Add toast notifications
  • Loading branch information
andrewleader authored Dec 10, 2021
2 parents f58c805 + f3d5345 commit 3f1d830
Show file tree
Hide file tree
Showing 7 changed files with 239 additions and 8 deletions.
99 changes: 93 additions & 6 deletions WindowsAppSDKGallery/App.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using Microsoft.UI.Xaml;
using Microsoft.Toolkit.Uwp.Notifications;
using Microsoft.UI.Dispatching;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Controls.Primitives;
using Microsoft.UI.Xaml.Data;
Expand All @@ -8,6 +10,7 @@
using Microsoft.UI.Xaml.Shapes;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
Expand All @@ -16,6 +19,7 @@
using Windows.ApplicationModel.Activation;
using Windows.Foundation;
using Windows.Foundation.Collections;
using WindowsAppSDKGallery.DataModel;
using WindowsAppSDKGallery.Helpers;

// To learn more about WinUI, the WinUI project structure,
Expand All @@ -28,6 +32,8 @@ namespace WindowsAppSDKGallery
/// </summary>
public partial class App : Application
{
public static DispatcherQueue DispatcherQueue { get; private set; }

/// <summary>
/// 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().
Expand All @@ -44,19 +50,100 @@ public App()
/// <param name="args">Details about the launch request and process.</param>
protected override void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args)
{
// Get the app-level dispatcher
DispatcherQueue = global::Microsoft.UI.Dispatching.DispatcherQueue.GetForCurrentThread();

// Register for activation redirection
Microsoft.Windows.AppLifecycle.AppInstance.GetCurrent().Activated += App_Activated;

m_window = new MainWindow();
m_window.Activate();
// Register for toast activation
ToastNotificationManagerCompat.OnActivated += ToastNotificationManagerCompat_OnActivated;

// If we weren't launched by a toast, launch our window like normal
// (Otherwise if launched by a toast, our OnActivated callback will be triggered)
if (!ToastNotificationManagerCompat.WasCurrentProcessToastActivated())
{
LaunchAndBringToForegroundIfNeeded();
}
}

private void LaunchAndBringToForegroundIfNeeded()
{
if (m_window == null)
{
m_window = new MainWindow();
m_window.Activate();

// Additionally we show using our helper, since if activated via a toast, it doesn't
// activate the window correctly
WindowHelper.ShowWindow(m_window);
}
else
{
WindowHelper.ShowWindow(m_window);
}
}

private void App_Activated(object sender, Microsoft.Windows.AppLifecycle.AppActivationArguments e)
{
WindowHelper.ShowWindow(m_window);
WindowHelper.ShowWindow(App.Window);
}

private void ToastNotificationManagerCompat_OnActivated(ToastNotificationActivatedEventArgsCompat e)
{
// Use the dispatcher from the window if present, otherwise the app dispatcher
var dispatcherQueue = App.Window?.DispatcherQueue ?? App.DispatcherQueue;

dispatcherQueue.TryEnqueue(delegate
{
HandleToastActivation(e);
});
}

private void HandleToastActivation(ToastNotificationActivatedEventArgsCompat e)
{
var args = ToastArguments.Parse(e.Argument);

args.TryGetValue("action", out string action);
if (action == null)
{
action = "";
}

switch (action)
{
// Send a background message
case "sendMessage":
string message = e.UserInput["textBox"].ToString();
new ToastContentBuilder()
.AddText("Here's what you typed...")
.AddText(message)
.Show();

// If the UI app isn't open
if (App.Current == null)
{
// Close since we're done
Process.GetCurrentProcess().Kill();
}

break;

case "viewToastSample":
LaunchAndBringToForegroundIfNeeded();

// Open the toast sample
App.Window.OpenSample(typeof(SamplePages.NotificationsSamples.ToastNotificationPage));

break;

default:
LaunchAndBringToForegroundIfNeeded();
break;
}
}

private static Window m_window;
public static Window Window => m_window;
private static MainWindow m_window;
public static MainWindow Window => m_window;
}
}
13 changes: 13 additions & 0 deletions WindowsAppSDKGallery/DataModel/SampleInfoDataSource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,19 @@ public sealed class SampleInfoDataSource
}
},

new SampleInfoDataGroup
{
Title = "Notifications",
Items =
{
new SampleInfoDataItem
{
Title = "Toast notifications",
PageType = typeof(SamplePages.NotificationsSamples.ToastNotificationPage)
}
}
},

new SampleInfoDataGroup
{
Title = "Auth & user identity",
Expand Down
20 changes: 20 additions & 0 deletions WindowsAppSDKGallery/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,5 +73,25 @@ private void SetUnselected()
NavigationViewControl.Header = "Select a sample on the left.";
rootFrame.Visibility = Visibility.Collapsed;
}

public void OpenSample(Type pageType)
{
var sampleItem = SampleInfoDataSource.Groups.SelectMany(i => i.Items).FirstOrDefault(i => i.PageType == pageType);

if (sampleItem != null)
{
foreach (var group in NavigationViewControl.MenuItems.OfType<NavigationViewItem>())
{
foreach (var item in group.MenuItems.OfType<NavigationViewItem>())
{
if (item.DataContext == sampleItem)
{
NavigationViewControl.SelectedItem = item;
return;
}
}
}
}
}
}
}
23 changes: 22 additions & 1 deletion WindowsAppSDKGallery/Package.appxmanifest
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
IgnorableNamespaces="uap rescap">
xmlns:com="http://schemas.microsoft.com/appx/manifest/com/windows10"
xmlns:desktop="http://schemas.microsoft.com/appx/manifest/desktop/windows10"
IgnorableNamespaces="uap rescap com desktop">

<Identity
Name="aleader.WindowsAppSDKGallery"
Expand Down Expand Up @@ -39,6 +41,25 @@
<uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png" />
<uap:SplashScreen Image="Assets\SplashScreen.png" />
</uap:VisualElements>

<Extensions>

<!--Specify which CLSID to activate when toast clicked-->
<desktop:Extension Category="windows.toastNotificationActivation">
<desktop:ToastNotificationActivation ToastActivatorCLSID="695a6f5d-81ae-4040-a7a4-d9fb94a861dd" />
</desktop:Extension>

<!--Register COM CLSID LocalServer32 registry key-->
<com:Extension Category="windows.comServer">
<com:ComServer>
<com:ExeServer Executable="WindowsAppSDKGallery.exe" Arguments="-ToastActivated" DisplayName="Toast activator">
<com:Class Id="695a6f5d-81ae-4040-a7a4-d9fb94a861dd" DisplayName="Toast activator"/>
</com:ExeServer>
</com:ComServer>
</com:Extension>

</Extensions>

</Application>
</Applications>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<Page
x:Class="WindowsAppSDKGallery.SamplePages.NotificationsSamples.ToastNotificationPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:WindowsAppSDKGallery.SamplePages.NotificationsSamples"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:controls="using:WindowsAppSDKGallery.Controls"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

<StackPanel>

<controls:SampleExample
HeaderText="Show a toast notification">

<Button
x:Name="ButtonShowToast"
Content="Show toast"
Click="ButtonShowToast_Click"/>

</controls:SampleExample>

<controls:ApiExample
x:Name="ClearNotifications"
HeaderText="Clear all notifications"
Api="ToastNotificationManagerCompat.History.Clear();"
ExecuteApi="ClearNotifications_ExecuteApi"/>

</StackPanel>
</Page>
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
using Microsoft.Toolkit.Uwp.Notifications;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Controls.Primitives;
using Microsoft.UI.Xaml.Data;
using Microsoft.UI.Xaml.Input;
using Microsoft.UI.Xaml.Media;
using Microsoft.UI.Xaml.Navigation;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;

// To learn more about WinUI, the WinUI project structure,
// and more about our project templates, see: http://aka.ms/winui-project-info.

namespace WindowsAppSDKGallery.SamplePages.NotificationsSamples
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class ToastNotificationPage : Page
{
public ToastNotificationPage()
{
this.InitializeComponent();
}

private void ButtonShowToast_Click(object sender, RoutedEventArgs e)
{
new ToastContentBuilder()
.AddText("Toast from Windows App SDK Gallery")
.AddText("Click the toast to open the app and navigate back to the toast sample. Or type a message to try background activation.")
.AddArgument("action", "viewToastSample")
.AddInputTextBox("textBox", "Type some text")
.AddButton(new ToastButton()
.SetTextBoxId("textBox")
.SetContent("Send")
.SetBackgroundActivation()
.AddArgument("action", "sendMessage"))
.Show();
}

private void ClearNotifications_ExecuteApi(object sender, Controls.ExecuteApiArgs e)
{
ToastNotificationManagerCompat.History.Clear();
}
}
}
9 changes: 8 additions & 1 deletion WindowsAppSDKGallery/WindowsAppSDKGallery.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
<None Remove="SamplePages\DialogSamples\MessageDialogPage.xaml" />
<None Remove="SamplePages\MediaSamples\PlaySoundsPage.xaml" />
<None Remove="SamplePages\MediaSamples\PlayVideosPage.xaml" />
<None Remove="SamplePages\NotificationsSamples\ToastNotificationPage.xaml" />
<None Remove="SamplePages\ShareSamples\DataTransferManagerPage.xaml" />
</ItemGroup>

Expand All @@ -54,6 +55,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Toolkit.Uwp.Notifications" Version="7.1.2" />
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.0.0" />
<PackageReference Include="System.Windows.Extensions" Version="6.0.0" />
<Manifest Include="$(ApplicationManifest)" />
Expand Down Expand Up @@ -179,6 +181,11 @@
Tools extension to be activated for this project even if the Windows App SDK Nuget
package has not yet been restored -->
<ItemGroup Condition="'$(DisableMsixProjectCapabilityAddedByProject)'!='true' and '$(EnablePreviewMsixTooling)'=='true'">
<ProjectCapability Include="Msix"/>
<ProjectCapability Include="Msix" />
</ItemGroup>
<ItemGroup>
<Page Update="SamplePages\NotificationsSamples\ToastNotificationPage.xaml">
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
</Project>

0 comments on commit 3f1d830

Please sign in to comment.