Skip to content

Commit 5c8fc1b

Browse files
committed
ToastButton builders
1 parent 89ed383 commit 5c8fc1b

File tree

7 files changed

+570
-190
lines changed

7 files changed

+570
-190
lines changed

Microsoft.Toolkit.Uwp.Notifications/Toasts/Builder/ToastContentBuilder.Actions.cs

Lines changed: 18 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -48,26 +48,6 @@ private IList<IToastInput> InputList
4848
}
4949
}
5050

51-
/// <summary>
52-
/// Add a button to the current toast.
53-
/// </summary>
54-
/// <param name="content">Text to display on the button.</param>
55-
/// <param name="activationType">Type of activation this button will use when clicked. Defaults to Foreground.</param>
56-
/// <param name="arguments">App-defined arguments that the app can later retrieve once it is activated when the user clicks the button.</param>
57-
/// <returns>The current instance of <see cref="ToastContentBuilder"/></returns>
58-
#if WINRT
59-
[Windows.Foundation.Metadata.DefaultOverload]
60-
#endif
61-
public ToastContentBuilder AddButton(string content, ToastActivationType activationType, ToastArguments arguments)
62-
{
63-
AddButton(content, activationType, SerializeArgumentsIncludingGeneric(arguments));
64-
65-
// Remove this button from the custom arguments list
66-
_buttonsUsingCustomArguments.RemoveAt(_buttonsUsingCustomArguments.Count - 1);
67-
68-
return this;
69-
}
70-
7151
private string SerializeArgumentsIncludingGeneric(ToastArguments arguments)
7252
{
7353
if (_genericArguments.Count == 0)
@@ -86,27 +66,6 @@ private string SerializeArgumentsIncludingGeneric(ToastArguments arguments)
8666
return arguments.ToString();
8767
}
8868

89-
/// <summary>
90-
/// Add a button to the current toast.
91-
/// </summary>
92-
/// <param name="content">Text to display on the button.</param>
93-
/// <param name="activationType">Type of activation this button will use when clicked. Defaults to Foreground.</param>
94-
/// <param name="arguments">App-defined arguments that the app can later retrieve once it is activated when the user clicks the button.</param>
95-
/// <param name="imageUri">Optional image icon for the button to display (required for buttons adjacent to inputs like quick reply).</param>
96-
/// <returns>The current instance of <see cref="ToastContentBuilder"/></returns>
97-
#if WINRT
98-
[Windows.Foundation.Metadata.DefaultOverload]
99-
#endif
100-
public ToastContentBuilder AddButton(string content, ToastActivationType activationType, ToastArguments arguments, Uri imageUri)
101-
{
102-
AddButton(content, activationType, SerializeArgumentsIncludingGeneric(arguments), imageUri);
103-
104-
// Remove this button from the custom arguments list
105-
_buttonsUsingCustomArguments.RemoveAt(_buttonsUsingCustomArguments.Count - 1);
106-
107-
return this;
108-
}
109-
11069
/// <summary>
11170
/// Add a button to the current toast.
11271
/// </summary>
@@ -119,19 +78,6 @@ public ToastContentBuilder AddButton(string content, ToastActivationType activat
11978
return AddButton(content, activationType, arguments, default);
12079
}
12180

122-
/// <summary>
123-
/// Add an button to the toast that will be display to the right of the input text box, achieving a quick reply scenario.
124-
/// </summary>
125-
/// <param name="textBoxId">ID of an existing <see cref="ToastTextBox"/> in order to have this button display to the right of the input, achieving a quick reply scenario.</param>
126-
/// <param name="content">Text to display on the button.</param>
127-
/// <param name="activationType">Type of activation this button will use when clicked. Defaults to Foreground.</param>
128-
/// <param name="arguments">App-defined arguments that the app can later retrieve once it is activated when the user clicks the button.</param>
129-
/// <returns>The current instance of <see cref="ToastContentBuilder"/></returns>
130-
public ToastContentBuilder AddButton(string textBoxId, string content, ToastActivationType activationType, ToastArguments arguments)
131-
{
132-
return AddButton(textBoxId, content, activationType, arguments, default);
133-
}
134-
13581
/// <summary>
13682
/// Add a button to the current toast.
13783
/// </summary>
@@ -140,6 +86,9 @@ public ToastContentBuilder AddButton(string textBoxId, string content, ToastActi
14086
/// <param name="arguments">App-defined string of arguments that the app can later retrieve once it is activated when the user clicks the button.</param>
14187
/// <param name="imageUri">Optional image icon for the button to display (required for buttons adjacent to inputs like quick reply).</param>
14288
/// <returns>The current instance of <see cref="ToastContentBuilder"/></returns>
89+
#if WINRT
90+
[Windows.Foundation.Metadata.DefaultOverload]
91+
#endif
14392
public ToastContentBuilder AddButton(string content, ToastActivationType activationType, string arguments, Uri imageUri)
14493
{
14594
// Add new button
@@ -156,48 +105,37 @@ public ToastContentBuilder AddButton(string content, ToastActivationType activat
156105
return AddButton(button);
157106
}
158107

159-
/// <summary>
160-
/// Add an button to the toast that will be display to the right of the input text box, achieving a quick reply scenario.
161-
/// </summary>
162-
/// <param name="textBoxId">ID of an existing <see cref="ToastTextBox"/> in order to have this button display to the right of the input, achieving a quick reply scenario.</param>
163-
/// <param name="content">Text to display on the button.</param>
164-
/// <param name="activationType">Type of activation this button will use when clicked. Defaults to Foreground.</param>
165-
/// <param name="arguments">App-defined arguments that the app can later retrieve once it is activated when the user clicks the button.</param>
166-
/// <param name="imageUri">An optional image icon for the button to display (required for buttons adjacent to inputs like quick reply)</param>
167-
/// <returns>The current instance of <see cref="ToastContentBuilder"/></returns>
168-
#if WINRT
169-
[Windows.Foundation.Metadata.DefaultOverload]
170-
#endif
171-
public ToastContentBuilder AddButton(string textBoxId, string content, ToastActivationType activationType, ToastArguments arguments, Uri imageUri)
172-
{
173-
AddButton(textBoxId, content, activationType, SerializeArgumentsIncludingGeneric(arguments), imageUri);
174-
175-
// Remove this button from the custom arguments list
176-
_buttonsUsingCustomArguments.RemoveAt(_buttonsUsingCustomArguments.Count - 1);
177-
178-
return this;
179-
}
180-
181108
/// <summary>
182109
/// Add a button to the current toast.
183110
/// </summary>
184111
/// <param name="button">An instance of class that implement <see cref="IToastButton"/> for the button that will be used on the toast.</param>
185112
/// <returns>The current instance of <see cref="ToastContentBuilder"/></returns>
186113
public ToastContentBuilder AddButton(IToastButton button)
187114
{
115+
if (button is ToastButton toastButton && toastButton.Content == null)
116+
{
117+
throw new InvalidOperationException("Content is required on button.");
118+
}
119+
188120
// List has max 5 buttons
189121
if (ButtonList.Count == 5)
190122
{
191123
throw new InvalidOperationException("A toast can't have more than 5 buttons");
192124
}
193125

194-
ButtonList.Add(button);
195-
196-
if (button is ToastButton b)
126+
if (button is ToastButton b && b.CanAddArguments())
197127
{
198-
_buttonsUsingCustomArguments.Add(b);
128+
foreach (var arg in _genericArguments)
129+
{
130+
if (!b.ContainsArgument(arg.Key))
131+
{
132+
b.AddArgument(arg.Key, arg.Value);
133+
}
134+
}
199135
}
200136

137+
ButtonList.Add(button);
138+
201139
return this;
202140
}
203141

Microsoft.Toolkit.Uwp.Notifications/Toasts/Builder/ToastContentBuilder.cs

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,14 @@ namespace Microsoft.Toolkit.Uwp.Notifications
1111
/// Builder class used to create <see cref="ToastContent"/>
1212
/// </summary>
1313
public partial class ToastContentBuilder
14+
#if !WINRT
15+
: IToastActivateableBuilder<ToastContentBuilder>
16+
#endif
1417
{
1518
private Dictionary<string, string> _genericArguments = new Dictionary<string, string>();
1619

1720
private bool _customArgumentsUsedOnToastItself;
1821

19-
private List<ToastButton> _buttonsUsingCustomArguments = new List<ToastButton>();
20-
2122
/// <summary>
2223
/// Gets internal instance of <see cref="ToastContent"/>. This is equivalent to the call to <see cref="ToastContentBuilder.GetToastContent"/>.
2324
/// </summary>
@@ -196,14 +197,9 @@ private ToastContentBuilder AddArgumentHelper(string key, string value)
196197
{
197198
foreach (var button in actions.Buttons)
198199
{
199-
if (button is ToastButton b && b.ActivationType != ToastActivationType.Protocol && !_buttonsUsingCustomArguments.Contains(b))
200+
if (button is ToastButton b && b.CanAddArguments() && !b.ContainsArgument(key))
200201
{
201-
var bArgs = ToastArguments.Parse(b.Arguments);
202-
if (!bArgs.Contains(key))
203-
{
204-
bArgs.Add(key, value);
205-
b.Arguments = bArgs.ToString();
206-
}
202+
b.AddArgument(key, value);
207203
}
208204
}
209205
}
@@ -243,9 +239,31 @@ private string AddArgumentHelper(string existing, string key, string value)
243239
/// <param name="protocol">The protocol to launch.</param>
244240
/// <returns>The current instance of <see cref="ToastContentBuilder"/></returns>
245241
public ToastContentBuilder SetProtocolActivation(Uri protocol)
242+
{
243+
return SetProtocolActivation(protocol, default);
244+
}
245+
246+
/// <summary>
247+
/// Configures the toast notification to launch the specified url when the toast body is clicked.
248+
/// </summary>
249+
/// <param name="protocol">The protocol to launch.</param>
250+
/// <param name="targetApplicationPfn">New in Creators Update: The target PFN, so that regardless of whether multiple apps are registered to handle the same protocol uri, your desired app will always be launched.</param>
251+
/// <returns>The current instance of <see cref="ToastContentBuilder"/></returns>
252+
public ToastContentBuilder SetProtocolActivation(Uri protocol, string targetApplicationPfn)
246253
{
247254
Content.Launch = protocol.ToString();
248255
Content.ActivationType = ToastActivationType.Protocol;
256+
257+
if (targetApplicationPfn != null)
258+
{
259+
if (Content.ActivationOptions == null)
260+
{
261+
Content.ActivationOptions = new ToastActivationOptions();
262+
}
263+
264+
Content.ActivationOptions.ProtocolActivationTargetApplicationPfn = targetApplicationPfn;
265+
}
266+
249267
return this;
250268
}
251269

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
5+
namespace Microsoft.Toolkit.Uwp.Notifications
6+
{
7+
/// <summary>
8+
/// Interfaces for classes that can have activation info added to them.
9+
/// </summary>
10+
/// <typeparam name="T">The type of the host object.</typeparam>
11+
internal interface IToastActivateableBuilder<T>
12+
{
13+
/// <summary>
14+
/// Adds a key (without value) to the activation arguments that will be returned when the content is clicked.
15+
/// </summary>
16+
/// <param name="key">The key.</param>
17+
/// <returns>The current instance of the object.</returns>
18+
T AddArgument(string key);
19+
20+
/// <summary>
21+
/// Adds a key/value to the activation arguments that will be returned when the content is clicked.
22+
/// </summary>
23+
/// <param name="key">The key for this value.</param>
24+
/// <param name="value">The value itself.</param>
25+
/// <returns>The current instance of the object.</returns>
26+
#if WINRT
27+
[Windows.Foundation.Metadata.DefaultOverload]
28+
#endif
29+
T AddArgument(string key, string value);
30+
31+
/// <summary>
32+
/// Adds a key/value to the activation arguments that will be returned when the content is clicked.
33+
/// </summary>
34+
/// <param name="key">The key for this value.</param>
35+
/// <param name="value">The value itself.</param>
36+
/// <returns>The current instance of the object.</returns>
37+
T AddArgument(string key, int value);
38+
39+
/// <summary>
40+
/// Adds a key/value to the activation arguments that will be returned when the content is clicked.
41+
/// </summary>
42+
/// <param name="key">The key for this value.</param>
43+
/// <param name="value">The value itself.</param>
44+
/// <returns>The current instance of the object.</returns>
45+
T AddArgument(string key, double value);
46+
47+
/// <summary>
48+
/// Adds a key/value to the activation arguments that will be returned when the content is clicked.
49+
/// </summary>
50+
/// <param name="key">The key for this value.</param>
51+
/// <param name="value">The value itself.</param>
52+
/// <returns>The current instance of the object.</returns>
53+
T AddArgument(string key, float value);
54+
55+
/// <summary>
56+
/// Adds a key/value to the activation arguments that will be returned when the content is clicked.
57+
/// </summary>
58+
/// <param name="key">The key for this value.</param>
59+
/// <param name="value">The value itself.</param>
60+
/// <returns>The current instance of the object.</returns>
61+
T AddArgument(string key, bool value);
62+
63+
#if !WINRT
64+
/// <summary>
65+
/// Adds a key/value to the activation arguments that will be returned when the content is clicked.
66+
/// </summary>
67+
/// <param name="key">The key for this value.</param>
68+
/// <param name="value">The value itself. Note that the enums are stored using their numeric value, so be aware that changing your enum number values might break existing activation of toasts currently in Action Center.</param>
69+
/// <returns>The current instance of the object.</returns>
70+
T AddArgument(string key, Enum value);
71+
#endif
72+
73+
/// <summary>
74+
/// Configures the content to use background activation when it is clicked.
75+
/// </summary>
76+
/// <returns>The current instance of the object.</returns>
77+
T SetBackgroundActivation();
78+
79+
/// <summary>
80+
/// Configures the content to use protocol activation when it is clicked.
81+
/// </summary>
82+
/// <param name="protocol">The protocol to launch.</param>
83+
/// <returns>The current instance of the object.</returns>
84+
T SetProtocolActivation(Uri protocol);
85+
86+
/// <summary>
87+
/// Configures the content to use protocol activation when it is clicked.
88+
/// </summary>
89+
/// <param name="protocol">The protocol to launch.</param>
90+
/// <param name="targetApplicationPfn">New in Creators Update: The target PFN, so that regardless of whether multiple apps are registered to handle the same protocol uri, your desired app will always be launched.</param>
91+
/// <returns>The current instance of the object.</returns>
92+
T SetProtocolActivation(Uri protocol, string targetApplicationPfn);
93+
}
94+
}

0 commit comments

Comments
 (0)