winrt_toast/toast.rs
1use std::{collections::HashMap, time::Duration};
2
3use crate::{Header, Image, Text, Action};
4
5/// Represents a Windows toast.
6///
7/// See <https://docs.microsoft.com/en-us/uwp/api/windows.ui.notifications.toastnotification>
8///
9#[derive(Debug, Clone, Default)]
10pub struct Toast {
11 pub(crate) header: Option<Header>,
12 pub(crate) text: (Option<Text>, Option<Text>, Option<Text>),
13 pub(crate) images: HashMap<u8, Image>,
14 pub(crate) tag: Option<String>,
15 pub(crate) group: Option<String>,
16 pub(crate) remote_id: Option<String>,
17 pub(crate) expires_in: Option<Duration>,
18 pub(crate) scenario: Option<Scenario>,
19 pub(crate) launch: Option<String>,
20 pub(crate) duration: Option<ToastDuration>,
21 pub(crate) actions: Vec<Action>,
22}
23
24impl Toast {
25 /// Creates an empty toast.
26 pub fn new() -> Self {
27 Self::default()
28 }
29
30 /// Add a [`Header`] to this toast.
31 pub fn header(&mut self, header: Header) -> &mut Toast {
32 self.header = header.into();
33 self
34 }
35
36 /// The first text element, usually the title.
37 ///
38 /// # Example
39 /// ```rust
40 /// # use winrt_toast::{Toast, Text};
41 /// # use winrt_toast::content::text::TextPlacement;
42 /// # let mut toast = Toast::new();
43 /// // You can use anything that is Into<String>
44 /// toast.text1("text");
45 ///
46 /// // Or you can use a `Text`
47 /// toast.text1(
48 /// Text::new("text").with_placement(TextPlacement::Attribution)
49 /// );
50 /// ```
51 pub fn text1<T: Into<Text>>(&mut self, text: T) -> &mut Toast {
52 self.text.0 = Some(text.into());
53 self
54 }
55
56 /// The second text element, usually the body.
57 pub fn text2<T: Into<Text>>(&mut self, text: T) -> &mut Toast {
58 self.text.1 = Some(text.into());
59 self
60 }
61
62 /// The third text element, usually the body or attribution.
63 pub fn text3<T: Into<Text>>(&mut self, text: T) -> &mut Toast {
64 self.text.2 = Some(text.into());
65 self
66 }
67
68 /// Add an image with the corresponding ID to the toast.
69 ///
70 /// # ID
71 /// The image element in the toast template that this image is intended for.
72 /// If a template has only one image, then this value is 1.
73 /// The number of available image positions is based on the template definition.
74 pub fn image(&mut self, id: u8, image: Image) -> &mut Toast {
75 self.images.insert(id, image);
76 self
77 }
78
79 /// Add a new action to the toast.
80 pub fn action(&mut self, action: Action) -> &mut Toast {
81 self.actions.push(action);
82 self
83 }
84
85 /// Set the tag of this toast.
86 ///
87 /// See <https://docs.microsoft.com/en-us/windows/apps/design/shell/tiles-and-notifications/send-local-toast-cpp-uwp?tabs=xml#provide-a-primary-key-for-your-toast>
88 pub fn tag(&mut self, tag: impl Into<String>) -> &mut Toast {
89 self.tag = Some(tag.into());
90 self
91 }
92
93 /// Set the group of this toast.
94 ///
95 /// See <https://docs.microsoft.com/en-us/windows/apps/design/shell/tiles-and-notifications/send-local-toast-cpp-uwp?tabs=xml#provide-a-primary-key-for-your-toast>
96 pub fn group(&mut self, group: impl Into<String>) -> &mut Toast {
97 self.group = Some(group.into());
98 self
99 }
100
101 /// Set a remote id for the notification that enables the system to correlate
102 /// this notification with another one generated on another device.
103 pub fn remote_id(&mut self, remote_id: impl Into<String>) -> &mut Toast {
104 self.remote_id = Some(remote_id.into());
105 self
106 }
107
108 /// Set the scenario of this toast.
109 ///
110 /// The scenario adjusts a few behaviors to create a consistent and unified user experience.
111 pub fn scenario(&mut self, scenario: Scenario) -> &mut Toast {
112 self.scenario = Some(scenario);
113 self
114 }
115
116 /// A string that is passed to the application when it is activated by the toast.
117 ///
118 /// The format and contents of this string are defined by the app for its own use.
119 /// When the user taps or clicks the toast to launch its associated app,
120 /// the launch string provides the context to the app that allows it to show the user a view relevant to the toast content,
121 /// rather than launching in its default way.
122 pub fn launch(&mut self, launch: impl Into<String>) -> &mut Toast {
123 self.launch = Some(launch.into());
124 self
125 }
126
127 /// The amount of time the toast should display.
128 pub fn duration(&mut self, duration: ToastDuration) -> &mut Toast {
129 self.duration = Some(duration);
130 self
131 }
132
133 /// Set the expiration time of this toats, starting from the moment it is shown.
134 ///
135 /// After expiration, the toast will be removed from the Notification Center.
136 pub fn expires_in(&mut self, duration: Duration) -> &mut Toast {
137 self.expires_in = Some(duration);
138 self
139 }
140}
141
142/// The scenario your toast is used for, like an alarm or reminder.
143///
144/// See [Microsoft documentation](https://docs.microsoft.com/en-us/windows/apps/design/shell/tiles-and-notifications/adaptive-interactive-toasts?tabs=xml#scenarios).
145#[derive(Debug, Clone)]
146pub enum Scenario {
147 /// A reminder notification. This will be displayed pre-expanded and stay on the user's screen till dismissed.
148 Reminder,
149 /// An alarm notification. This will be displayed pre-expanded and stay on the user's screen till dismissed.
150 /// Audio will loop by default and will use alarm audio.
151 Alarm,
152 /// An incoming call notification.
153 /// This will be displayed pre-expanded in a special call format and stay on the user's screen till dismissed.
154 /// Audio will loop by default and will use ringtone audio.
155 IncomingCall,
156 /// An important notification.
157 /// This allows users to have more control over what apps can send them high-priority toast notifications that can break through Focus Assist (Do not Disturb).
158 /// This can be modified in the notifications settings.
159 Urgent,
160}
161
162impl Scenario {
163 pub(crate) fn as_str(&self) -> &'static str {
164 match self {
165 Scenario::Reminder => "reminder",
166 Scenario::Alarm => "alarm",
167 Scenario::IncomingCall => "incomingCall",
168 Scenario::Urgent => "urgent",
169 }
170 }
171}
172
173/// The amount of time the toast should display
174#[derive(Debug, Clone)]
175pub enum ToastDuration {
176 /// The toast will display for a longer period of time.
177 Long,
178 /// The toast will display for a shorter period of time.
179 Short,
180}
181
182impl ToastDuration {
183 pub(crate) fn as_str(&self) -> &'static str {
184 match self {
185 ToastDuration::Long => "long",
186 ToastDuration::Short => "short",
187 }
188 }
189}