Seregon/StratoSDK

StratoSDK is a framework with a declarative approach similar to Flutter/React, written and designed entirely for Rust.

Rust/27.3 KB/No license
crates/strato-ui-renderer/src/windowing/winit/notifications/wasm.rs
1use crate::notification::NotificationSendError;
2use crate::notification::RequestPermissionsOutcome;
3use crate::platform::NotificationInfo;
4use crate::windowing::winit::app::RequestPermissionsCallback;
5use crate::windowing::winit::CustomEvent;
6use crate::WindowId;
7use wasm_bindgen_futures::JsFuture;
8use winit::event_loop::EventLoopProxy;
9 
10pub async fn send_notification(
11 notification_info: NotificationInfo,
12 _window_id: WindowId,
13 proxy: EventLoopProxy<CustomEvent>,
14) {
15 let NotificationInfo {
16 notification_content,
17 on_error,
18 } = notification_info;
19 
20 // First, we check to see if the page has permissions to send notifications. If not, we should prematurely
21 // execute the on_error callback. We can't rely on the result of the web_sys::Notification constructor to
22 // know whether the notification has the right permissions to actually send.
23 // https://developer.mozilla.org/en-US/docs/Web/API/Notification/Notification#return_value.
24 match web_sys::Notification::permission() {
25 web_sys::NotificationPermission::Granted => {
26 // If permissions are granted, send it! Constructing the Notification object is enough to launch it.
27 let _ = web_sys::Notification::new(notification_content.title());
28 }
29 web_sys::NotificationPermission::Default => {
30 let _ = proxy.send_event(CustomEvent::UpdateUIApp(Box::new(|ctx| {
31 on_error(NotificationSendError::PermissionsNotYetGranted, ctx)
32 })));
33 }
34 web_sys::NotificationPermission::Denied => {
35 let _ = proxy.send_event(CustomEvent::UpdateUIApp(Box::new(|ctx| {
36 on_error(NotificationSendError::PermissionsDenied, ctx)
37 })));
38 }
39 _ => {
40 let _ = proxy.send_event(CustomEvent::UpdateUIApp(Box::new(|ctx| {
41 on_error(
42 NotificationSendError::Other {
43 error_message: "unknown notifications permissions".to_string(),
44 },
45 ctx,
46 )
47 })));
48 }
49 }
50}
51 
52pub async fn request_notification_permissions(
53 callback: RequestPermissionsCallback,
54 proxy: EventLoopProxy<CustomEvent>,
55) {
56 // The web_sys request_permission method returns a Promise that resolves to a string indicating
57 // whether the permissions request was granted, denied, or default.
58 // See https://developer.mozilla.org/en-US/docs/Web/API/Notification/requestPermission_static.
59 let Ok(permissions_request_promise) = web_sys::Notification::request_permission() else {
60 let _ = proxy.send_event(CustomEvent::UpdateUIApp(Box::new(|ctx| {
61 callback(
62 RequestPermissionsOutcome::OtherError {
63 error_message: "Error sending notification permissions request".to_string(),
64 },
65 ctx,
66 );
67 })));
68 return;
69 };
70 
71 let request_outcome = match JsFuture::from(permissions_request_promise)
72 .await
73 .map(|r| r.as_string())
74 {
75 Ok(Some(user_response)) if user_response == "granted" => {
76 RequestPermissionsOutcome::Accepted
77 }
78 // Any response besides "granted" is considered a permissions denied.
79 Ok(Some(_)) => RequestPermissionsOutcome::PermissionsDenied,
80 _ => RequestPermissionsOutcome::OtherError {
81 error_message: "Error receiving response from notification permissions request"
82 .to_string(),
83 },
84 };
85 
86 // When the request has completed, we execute the callback with the outcome.
87 let _ = proxy.send_event(CustomEvent::UpdateUIApp(Box::new(|ctx| {
88 callback(request_outcome, ctx);
89 })));
90}
91