Skip to content

Commit 2e269e8

Browse files
loneursidEric Langlois
andauthored
Using Builder instead of Raw XML in AppNotification Samples (#234)
* Using Builder instead of Raw XML * Code cleanup * Updating the C# sample * WindowsAppSDK now outputing builder API as designed * Updating textbox scenarios to use builder * Update CppUnpackagedAppNotifications.vcxproj.filters * Update CppUnpackagedAppNotifications.vcxproj.filters * Update CppUnpackagedAppNotifications.vcxproj.filters * Updating all samples to latest SDK * Updating to officaly published preview build * Nothing new in preview1 for push Co-authored-by: Eric Langlois <[email protected]>
1 parent 81d4e37 commit 2e269e8

File tree

13 files changed

+85
-215
lines changed

13 files changed

+85
-215
lines changed

Samples/Notifications/App/CppUnpackagedAppNotifications/CppUnpackagedAppNotifications/CppUnpackagedAppNotifications.vcxproj

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3-
<Import Project="..\packages\Microsoft.WindowsAppSDK.1.1.0\build\native\Microsoft.WindowsAppSDK.props" Condition="Exists('..\packages\Microsoft.WindowsAppSDK.1.1.0\build\native\Microsoft.WindowsAppSDK.props')" />
3+
<Import Project="..\packages\Microsoft.WindowsAppSDK.1.2.220902.1-preview1\build\native\Microsoft.WindowsAppSDK.props" Condition="Exists('..\packages\Microsoft.WindowsAppSDK.1.2.220902.1-preview1\build\native\Microsoft.WindowsAppSDK.props')" />
44
<Import Project="..\packages\Microsoft.Windows.SDK.BuildTools.10.0.22000.194\build\Microsoft.Windows.SDK.BuildTools.props" Condition="Exists('..\packages\Microsoft.Windows.SDK.BuildTools.10.0.22000.194\build\Microsoft.Windows.SDK.BuildTools.props')" />
55
<Import Project="..\packages\Microsoft.Windows.CppWinRT.2.0.210922.5\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('..\packages\Microsoft.Windows.CppWinRT.2.0.210922.5\build\native\Microsoft.Windows.CppWinRT.props')" />
66
<PropertyGroup Label="Globals">
@@ -168,7 +168,6 @@
168168
<DependentUpon>MainPage.xaml</DependentUpon>
169169
<SubType>Code</SubType>
170170
</ClCompile>
171-
<ClCompile Include="Notifications\Common.cpp" />
172171
<ClCompile Include="Notifications\NotificationManager.cpp" />
173172
<ClCompile Include="Notifications\ToastWithAvatar.cpp" />
174173
<ClCompile Include="Notifications\ToastWithTextBox.cpp" />
@@ -224,7 +223,7 @@
224223
<Import Project="..\packages\Microsoft.Windows.CppWinRT.2.0.210922.5\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('..\packages\Microsoft.Windows.CppWinRT.2.0.210922.5\build\native\Microsoft.Windows.CppWinRT.targets')" />
225224
<Import Project="..\packages\Microsoft.Windows.SDK.BuildTools.10.0.22000.194\build\Microsoft.Windows.SDK.BuildTools.targets" Condition="Exists('..\packages\Microsoft.Windows.SDK.BuildTools.10.0.22000.194\build\Microsoft.Windows.SDK.BuildTools.targets')" />
226225
<Import Project="..\packages\Microsoft.Windows.ImplementationLibrary.1.0.220201.1\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('..\packages\Microsoft.Windows.ImplementationLibrary.1.0.220201.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
227-
<Import Project="..\packages\Microsoft.WindowsAppSDK.1.1.0\build\native\Microsoft.WindowsAppSDK.targets" Condition="Exists('..\packages\Microsoft.WindowsAppSDK.1.1.0\build\native\Microsoft.WindowsAppSDK.targets')" />
226+
<Import Project="..\packages\Microsoft.WindowsAppSDK.1.2.220902.1-preview1\build\native\Microsoft.WindowsAppSDK.targets" Condition="Exists('..\packages\Microsoft.WindowsAppSDK.1.2.220902.1-preview1\build\native\Microsoft.WindowsAppSDK.targets')" />
228227
</ImportGroup>
229228
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
230229
<PropertyGroup>
@@ -235,7 +234,7 @@
235234
<Error Condition="!Exists('..\packages\Microsoft.Windows.SDK.BuildTools.10.0.22000.194\build\Microsoft.Windows.SDK.BuildTools.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Windows.SDK.BuildTools.10.0.22000.194\build\Microsoft.Windows.SDK.BuildTools.props'))" />
236235
<Error Condition="!Exists('..\packages\Microsoft.Windows.SDK.BuildTools.10.0.22000.194\build\Microsoft.Windows.SDK.BuildTools.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Windows.SDK.BuildTools.10.0.22000.194\build\Microsoft.Windows.SDK.BuildTools.targets'))" />
237236
<Error Condition="!Exists('..\packages\Microsoft.Windows.ImplementationLibrary.1.0.220201.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Windows.ImplementationLibrary.1.0.220201.1\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
238-
<Error Condition="!Exists('..\packages\Microsoft.WindowsAppSDK.1.1.0\build\native\Microsoft.WindowsAppSDK.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.WindowsAppSDK.1.1.0\build\native\Microsoft.WindowsAppSDK.props'))" />
239-
<Error Condition="!Exists('..\packages\Microsoft.WindowsAppSDK.1.1.0\build\native\Microsoft.WindowsAppSDK.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.WindowsAppSDK.1.1.0\build\native\Microsoft.WindowsAppSDK.targets'))" />
237+
<Error Condition="!Exists('..\packages\Microsoft.WindowsAppSDK.1.2.220902.1-preview1\build\native\Microsoft.WindowsAppSDK.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.WindowsAppSDK.1.2.220902.1-preview1\build\native\Microsoft.WindowsAppSDK.props'))" />
238+
<Error Condition="!Exists('..\packages\Microsoft.WindowsAppSDK.1.2.220902.1-preview1\build\native\Microsoft.WindowsAppSDK.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.WindowsAppSDK.1.2.220902.1-preview1\build\native\Microsoft.WindowsAppSDK.targets'))" />
240239
</Target>
241240
</Project>

Samples/Notifications/App/CppUnpackagedAppNotifications/CppUnpackagedAppNotifications/CppUnpackagedAppNotifications.vcxproj.filters

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,6 @@
1919
<ClCompile Include="$(GeneratedFilesDir)module.g.cpp" />
2020
<ClCompile Include="SampleConfiguration.cpp" />
2121
<ClCompile Include="NotifyUser.cpp" />
22-
<ClCompile Include="Notifications\Common.cpp">
23-
<Filter>Notifications</Filter>
24-
</ClCompile>
2522
<ClCompile Include="Notifications\NotificationManager.cpp">
2623
<Filter>Notifications</Filter>
2724
</ClCompile>
@@ -83,4 +80,4 @@
8380
<ItemGroup>
8481
<None Include="packages.config" />
8582
</ItemGroup>
86-
</Project>
83+
</Project>

Samples/Notifications/App/CppUnpackagedAppNotifications/CppUnpackagedAppNotifications/Notifications/Common.cpp

Lines changed: 0 additions & 41 deletions
This file was deleted.

Samples/Notifications/App/CppUnpackagedAppNotifications/CppUnpackagedAppNotifications/Notifications/Common.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,6 @@
55
struct Common
66
{
77
public:
8-
static std::optional<std::wstring> ExtractParamFromArgs(std::wstring const& args, std::wstring const& paramName);
9-
10-
static std::wstring MakeScenarioIdToken(unsigned Id);
11-
static std::optional<unsigned> ExtractScenarioIdFromArgs(std::wstring const& args);
8+
inline static const wchar_t* scenarioTag{ L"scenarioId" };
129
};
1310

Samples/Notifications/App/CppUnpackagedAppNotifications/CppUnpackagedAppNotifications/Notifications/NotificationManager.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,12 +66,12 @@ void NotificationManager::ProcessLaunchActivationArgs(winrt::AppNotificationActi
6666

6767
bool NotificationManager::DispatchNotification(winrt::AppNotificationActivatedEventArgs const& notificationActivatedEventArgs)
6868
{
69-
auto scenarioId{ Common::ExtractScenarioIdFromArgs(notificationActivatedEventArgs.Argument().c_str())};
70-
if (scenarioId.has_value())
69+
auto scenarioId{ notificationActivatedEventArgs.Arguments().Lookup(Common::scenarioTag) };
70+
if (!scenarioId.empty())
7171
{
7272
try
7373
{
74-
c_notificationHandlers.at(scenarioId.value())(notificationActivatedEventArgs); // Will throw if out of range
74+
c_notificationHandlers.at(std::stoul(std::wstring(scenarioId.c_str())))(notificationActivatedEventArgs); // Will throw if out of range
7575
return true;
7676
}
7777
catch (...)

Samples/Notifications/App/CppUnpackagedAppNotifications/CppUnpackagedAppNotifications/Notifications/ToastWithAvatar.cpp

Lines changed: 18 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -5,50 +5,43 @@
55
#include "ToastWithAvatar.h"
66
#include "Common.h"
77
#include <winrt/Microsoft.Windows.AppNotifications.h>
8+
#include <winrt/Microsoft.Windows.AppNotifications.Builder.h>
9+
#include <winrt/Windows.Foundation.h>
810
#include "App.xaml.h"
911
#include "MainPage.xaml.h"
1012

1113
namespace winrt
1214
{
1315
using namespace Microsoft::Windows::AppNotifications;
16+
using namespace Microsoft::Windows::AppNotifications::Builder;
1417
using namespace CppUnpackagedAppNotifications::implementation;
1518
}
1619

1720
const wchar_t* ToastWithAvatar::ScenarioName{ L"Local Toast with Avatar Image" };
1821

1922
bool ToastWithAvatar::SendToast()
2023
{
21-
// The ScenarioIdToken uniquely identify a scenario and is used to route the response received when the user clicks on a toast to the correct scenario.
22-
auto ScenarioIdToken{ Common::MakeScenarioIdToken(ToastWithAvatar::ScenarioId) };
23-
24-
winrt::hstring xmlPayload{
25-
L"<toast launch = \"action=ToastClick&amp;" + ScenarioIdToken + L"\">\
26-
<visual>\
27-
<binding template = \"ToastGeneric\">\
28-
<image placement = \"appLogoOverride\" hint-crop=\"circle\" src = \"" + winrt::App::GetFullPathToAsset(L"Square150x150Logo.png") + L"\"/>\
29-
<text>" + ScenarioName + L"</text>\
30-
<text>This is an example message using XML</text>\
31-
</binding>\
32-
</visual>\
33-
<actions>\
34-
<action\
35-
content = \"Open App\"\
36-
arguments = \"action=OpenApp&amp;" + ScenarioIdToken + L"\"/>\
37-
</actions>\
38-
</toast>" };
39-
40-
auto toast{ winrt::AppNotification(xmlPayload) };
41-
winrt::AppNotificationManager::Default().Show(toast);
42-
43-
return toast.Id() != 0; // return true (indicating success) if the toast was sent (if it has an Id)
24+
auto appNotification{ winrt::AppNotificationBuilder()
25+
.AddArgument(L"action", L"ToastClick")
26+
.AddArgument(Common::scenarioTag, std::to_wstring(ToastWithAvatar::ScenarioId))
27+
.SetAppLogoOverride(winrt::Windows::Foundation::Uri(L"file://" + winrt::App::GetFullPathToAsset(L"Square150x150Logo.png")), winrt::AppNotificationImageCrop::Circle)
28+
.AddText(ScenarioName)
29+
.AddText(L"This is an example message using XML")
30+
.AddButton(winrt::AppNotificationButton(L"Open App")
31+
.AddArgument(L"action", L"OpenApp")
32+
.AddArgument(Common::scenarioTag, std::to_wstring(ToastWithAvatar::ScenarioId)))
33+
.BuildNotification() };
34+
35+
winrt::AppNotificationManager::Default().Show(appNotification);
36+
37+
return appNotification.Id() != 0; // return true (indicating success) if the toast was sent (if it has an Id)
4438
}
4539

4640
void ToastWithAvatar::NotificationReceived(winrt::Microsoft::Windows::AppNotifications::AppNotificationActivatedEventArgs const& notificationActivatedEventArgs)
4741
{
4842
winrt::CppUnpackagedAppNotifications::Notification notification{};
4943
notification.Originator = ScenarioName;
50-
auto action{ Common::ExtractParamFromArgs(notificationActivatedEventArgs.Argument().c_str(), L"action") };
51-
notification.Action = action.has_value() ? action.value() : L"";
44+
notification.Action = notificationActivatedEventArgs.Arguments().Lookup(L"action");
5245
winrt::MainPage::Current().NotificationReceived(notification);
5346
winrt::App::ToForeground();
5447
}

Samples/Notifications/App/CppUnpackagedAppNotifications/CppUnpackagedAppNotifications/Notifications/ToastWithTextBox.cpp

Lines changed: 21 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,14 @@
55
#include "ToastWithTextBox.h"
66
#include "Common.h"
77
#include <winrt/Microsoft.Windows.AppNotifications.h>
8+
#include <winrt/Microsoft.Windows.AppNotifications.Builder.h>
89
#include "App.xaml.h"
910
#include "MainPage.xaml.h"
1011

1112
namespace winrt
1213
{
1314
using namespace Microsoft::Windows::AppNotifications;
15+
using namespace Microsoft::Windows::AppNotifications::Builder;
1416
using namespace CppUnpackagedAppNotifications::implementation;
1517
}
1618

@@ -19,34 +21,22 @@ auto textboxReplyId{ L"textboxReply" };
1921

2022
bool ToastWithTextBox::SendToast()
2123
{
22-
// The ScenarioIdToken uniquely identify a scenario and is used to route the response received when the user clicks on a toast to the correct scenario.
23-
auto ScenarioIdToken{ Common::MakeScenarioIdToken(ToastWithTextBox::ScenarioId) };
24-
25-
winrt::hstring xmlPayload{
26-
L"<toast launch = \"action=ToastClick&amp;" + ScenarioIdToken + L"\">\
27-
<visual>\
28-
<binding template = \"ToastGeneric\">\
29-
<image placement = \"appLogoOverride\" hint-crop=\"circle\" src = \"" + winrt::App::GetFullPathToAsset(L"Square150x150Logo.png") + L"\"/>\
30-
<text>" + ScenarioName + L"</text>\
31-
<text>This is an example message using XML</text>\
32-
</binding>\
33-
</visual>\
34-
<actions>\
35-
<input\
36-
id = \"" + textboxReplyId + L"\"\
37-
type = \"text\"\
38-
placeHolderContent = \"Type a reply\"/>\
39-
<action\
40-
content = \"Reply\"\
41-
arguments = \"action=Reply&amp;" + ScenarioIdToken + L"\"\
42-
hint-inputId=\"" + textboxReplyId + L"\"/>\
43-
</actions>\
44-
</toast>" };
45-
46-
auto toast{ winrt::AppNotification(xmlPayload) };
47-
winrt::AppNotificationManager::Default().Show(toast);
48-
49-
return toast.Id() != 0; // return true (indicating success) if the toast was sent (if it has an Id)
24+
auto appNotification{ winrt::AppNotificationBuilder()
25+
.AddArgument(L"action", L"ToastClick")
26+
.AddArgument(Common::scenarioTag, std::to_wstring(ToastWithTextBox::ScenarioId))
27+
.SetAppLogoOverride(winrt::Windows::Foundation::Uri(L"file://" + winrt::App::GetFullPathToAsset(L"Square150x150Logo.png")), winrt::AppNotificationImageCrop::Circle)
28+
.AddText(ScenarioName)
29+
.AddText(L"This is an example message using XML")
30+
.AddTextBox(textboxReplyId, L"Type a reply", L"Reply box")
31+
.AddButton(winrt::AppNotificationButton(L"Reply")
32+
.AddArgument(L"action", L"Reply")
33+
.AddArgument(Common::scenarioTag, std::to_wstring(ToastWithTextBox::ScenarioId))
34+
.SetInputId(textboxReplyId))
35+
.BuildNotification() };
36+
37+
winrt::AppNotificationManager::Default().Show(appNotification);
38+
39+
return appNotification.Id() != 0; // return true (indicating success) if the toast was sent (if it has an Id)
5040
}
5141

5242
void ToastWithTextBox::NotificationReceived(winrt::Microsoft::Windows::AppNotifications::AppNotificationActivatedEventArgs const& notificationActivatedEventArgs)
@@ -56,15 +46,13 @@ void ToastWithTextBox::NotificationReceived(winrt::Microsoft::Windows::AppNotifi
5646
// This is not something that can easily be demonstrated in a sample such as this one, as we need to show the UI to demonstrate how
5747
// the payload is routed internally
5848

59-
auto input{ notificationActivatedEventArgs.UserInput() };
60-
auto text{ input.Lookup(textboxReplyId) };
49+
6150

6251
winrt::CppUnpackagedAppNotifications::Notification notification{};
6352
notification.Originator = ScenarioName;
64-
auto action{ Common::ExtractParamFromArgs(notificationActivatedEventArgs.Argument().c_str(), L"action") };
65-
notification.Action = action.has_value() ? action.value() : L"";
53+
notification.Action = notificationActivatedEventArgs.Arguments().Lookup(L"action");
6654
notification.HasInput = true;
67-
notification.Input = text;
55+
notification.Input = notificationActivatedEventArgs.UserInput().Lookup(textboxReplyId);
6856
winrt::MainPage::Current().NotificationReceived(notification);
6957
winrt::App::ToForeground();
7058
}

Samples/Notifications/App/CppUnpackagedAppNotifications/CppUnpackagedAppNotifications/packages.config

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@
33
<package id="Microsoft.Windows.CppWinRT" version="2.0.210922.5" targetFramework="native" />
44
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.220201.1" targetFramework="native" />
55
<package id="Microsoft.Windows.SDK.BuildTools" version="10.0.22000.194" targetFramework="native" />
6-
<package id="Microsoft.WindowsAppSDK" version="1.1.0" targetFramework="native" />
6+
<package id="Microsoft.WindowsAppSDK" version="1.2.220902.1-preview1" targetFramework="native" />
77
</packages>

Samples/Notifications/App/CsUnpackagedAppNotifications/CsUnpackagedAppNotifications/CsUnpackagedAppNotifications.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
<ItemGroup>
1717
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.22000.194" />
1818
<PackageReference Include="Microsoft.Windows.CsWin32" Version="0.1.588-beta" PrivateAssets="all" />
19-
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.1.0" />
19+
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.2.220902.1-preview1" />
2020
</ItemGroup>
2121

2222
<ItemGroup>

Samples/Notifications/App/CsUnpackagedAppNotifications/CsUnpackagedAppNotifications/Notifications/Common.cs

Lines changed: 1 addition & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -3,44 +3,5 @@
33

44
class Common
55
{
6-
const string scenarioTag = "scenarioId";
7-
8-
public static string ExtractParamFromArgs(string args, string paramName)
9-
{
10-
var tag = paramName;
11-
tag += "=";
12-
13-
var tagStart = args.IndexOf(tag);
14-
if (tagStart == -1)
15-
{
16-
return null;
17-
}
18-
19-
var paramStart = tagStart + tag.Length;
20-
21-
var paramEnd = args.IndexOf("&", paramStart);
22-
if (paramEnd == -1)
23-
{
24-
paramEnd = args.Length;
25-
}
26-
27-
return args.Substring(paramStart, paramEnd - paramStart);
28-
}
29-
30-
public static string MakeScenarioIdToken(int id)
31-
{
32-
return scenarioTag + "=" + id.ToString();
33-
}
34-
35-
public static int ExtractScenarioIdFromArgs(string args)
36-
{
37-
var scenarioId = ExtractParamFromArgs(args, scenarioTag);
38-
39-
if (scenarioId == null)
40-
{
41-
return 0;
42-
}
43-
44-
return int.Parse(scenarioId);
45-
}
6+
public const string scenarioTag = "scenarioId";
467
}

0 commit comments

Comments
 (0)