From 7b7cb588711ea52d6fd44fff2a63ddd6d5be4071 Mon Sep 17 00:00:00 2001 From: spinline Date: Fri, 6 Feb 2026 00:51:41 +0300 Subject: [PATCH] fix: request notification permission before push subscription on iOS --- frontend/src/app.rs | 21 +++------------------ frontend/src/store.rs | 32 +++++++++++++++++++++++++++++++- 2 files changed, 34 insertions(+), 19 deletions(-) diff --git a/frontend/src/app.rs b/frontend/src/app.rs index 1d5586b..ca6c952 100644 --- a/frontend/src/app.rs +++ b/frontend/src/app.rs @@ -37,24 +37,9 @@ pub fn App() -> impl IntoView { return; } - // Check if Notification API is available - let window = web_sys::window().expect("window should exist"); - if let Ok(notification_class) = js_sys::Reflect::get(&window, &"Notification".into()) { - if !notification_class.is_undefined() { - if let Ok(permission) = js_sys::Reflect::get(¬ification_class, &"permission".into()) { - if let Some(perm_str) = permission.as_string() { - // Subscribe if permission is granted or default (not denied) - // The browser will show permission prompt if needed - if perm_str != "denied" { - log::info!("Subscribing to push notifications (permission: {})", perm_str); - crate::store::subscribe_to_push_notifications().await; - } else { - log::info!("Notification permission denied"); - } - } - } - } - } + // Attempt to subscribe - this will request permission if needed + log::info!("Attempting to subscribe to push notifications..."); + crate::store::subscribe_to_push_notifications().await; }); }); diff --git a/frontend/src/store.rs b/frontend/src/store.rs index 24637d5..0480c6d 100644 --- a/frontend/src/store.rs +++ b/frontend/src/store.rs @@ -303,10 +303,40 @@ struct PushKeys { } /// Subscribe user to push notifications -/// Call this after service worker is registered and notification permission is granted +/// Requests notification permission if needed, then subscribes to push pub async fn subscribe_to_push_notifications() { use gloo_net::http::Request; + // First, request notification permission if not already granted + let window = web_sys::window().expect("window should exist"); + if let Ok(notification_class) = js_sys::Reflect::get(&window, &"Notification".into()) { + if !notification_class.is_undefined() { + if let Ok(request_fn) = js_sys::Reflect::get(¬ification_class, &"requestPermission".into()) { + if request_fn.is_function() { + let request_fn_typed = js_sys::Function::from(request_fn); + match request_fn_typed.call0(¬ification_class) { + Ok(promise_val) => { + let request_future = wasm_bindgen_futures::JsFuture::from( + web_sys::js_sys::Promise::from(promise_val) + ); + match request_future.await { + Ok(_) => { + log::info!("Notification permission requested"); + } + Err(e) => { + log::warn!("Failed to request notification permission: {:?}", e); + } + } + } + Err(e) => { + log::warn!("Failed to call requestPermission: {:?}", e); + } + } + } + } + } + } + // Get VAPID public key from backend let public_key_response = match Request::get("/api/push/public-key").send().await { Ok(resp) => resp,