fix: request notification permission before push subscription on iOS

This commit is contained in:
spinline
2026-02-06 00:51:41 +03:00
parent 3369853c06
commit 7b7cb58871
2 changed files with 34 additions and 19 deletions

View File

@@ -37,24 +37,9 @@ pub fn App() -> impl IntoView {
return; return;
} }
// Check if Notification API is available // Attempt to subscribe - this will request permission if needed
let window = web_sys::window().expect("window should exist"); log::info!("Attempting to subscribe to push notifications...");
if let Ok(notification_class) = js_sys::Reflect::get(&window, &"Notification".into()) { crate::store::subscribe_to_push_notifications().await;
if !notification_class.is_undefined() {
if let Ok(permission) = js_sys::Reflect::get(&notification_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");
}
}
}
}
}
}); });
}); });

View File

@@ -303,10 +303,40 @@ struct PushKeys {
} }
/// Subscribe user to push notifications /// 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() { pub async fn subscribe_to_push_notifications() {
use gloo_net::http::Request; 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(&notification_class, &"requestPermission".into()) {
if request_fn.is_function() {
let request_fn_typed = js_sys::Function::from(request_fn);
match request_fn_typed.call0(&notification_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 // Get VAPID public key from backend
let public_key_response = match Request::get("/api/push/public-key").send().await { let public_key_response = match Request::get("/api/push/public-key").send().await {
Ok(resp) => resp, Ok(resp) => resp,