fix: properly check notification permission result, show toast feedback on Safari

This commit is contained in:
spinline
2026-02-06 13:26:37 +03:00
parent 22672f7aaa
commit a3321c7cf1
3 changed files with 83 additions and 8 deletions

View File

@@ -10,7 +10,7 @@
@layer base { @layer base {
html, html,
body { body {
@apply min-h-[100dvh] w-full overflow-hidden bg-base-100 text-base-content overscroll-y-none; @apply min-h-dvh w-full overflow-hidden bg-base-100 text-base-content overscroll-y-none;
} }
} }

View File

@@ -305,7 +305,45 @@ pub fn StatusBar() -> impl IntoView {
// Request push notification permission when settings button is clicked // Request push notification permission when settings button is clicked
spawn_local(async { spawn_local(async {
log::info!("Settings button clicked - requesting push notification permission"); log::info!("Settings button clicked - requesting push notification permission");
// Check current permission state before requesting
let window = web_sys::window().expect("window should exist");
let _current_perm = js_sys::Reflect::get(&window, &"Notification".into())
.ok()
.and_then(|n| js_sys::Reflect::get(&n, &"permission".into()).ok())
.and_then(|p| p.as_string())
.unwrap_or_default();
crate::store::subscribe_to_push_notifications().await; crate::store::subscribe_to_push_notifications().await;
// Check permission after request
let new_perm = js_sys::Reflect::get(&window, &"Notification".into())
.ok()
.and_then(|n| js_sys::Reflect::get(&n, &"permission".into()).ok())
.and_then(|p| p.as_string())
.unwrap_or_default();
if let Some(store) = use_context::<crate::store::TorrentStore>() {
if new_perm == "granted" {
crate::store::show_toast_with_signal(
store.notifications,
shared::NotificationLevel::Success,
"Bildirimler etkinleştirildi! Torrent tamamlandığında bildirim alacaksınız.".to_string(),
);
} else if new_perm == "denied" {
crate::store::show_toast_with_signal(
store.notifications,
shared::NotificationLevel::Error,
"Bildirim izni reddedildi. Tarayıcı ayarlarından izin verebilirsiniz.".to_string(),
);
} else {
crate::store::show_toast_with_signal(
store.notifications,
shared::NotificationLevel::Warning,
"Bildirim izni verilemedi. Açılan izin penceresinde 'İzin Ver' seçeneğini seçin.".to_string(),
);
}
}
}); });
} }
> >

View File

@@ -309,34 +309,71 @@ pub async fn subscribe_to_push_notifications() {
// First, request notification permission if not already granted // First, request notification permission if not already granted
let window = web_sys::window().expect("window should exist"); let window = web_sys::window().expect("window should exist");
if let Ok(notification_class) = js_sys::Reflect::get(&window, &"Notification".into()) { let permission_granted = if let Ok(notification_class) = js_sys::Reflect::get(&window, &"Notification".into()) {
if !notification_class.is_undefined() { if notification_class.is_undefined() {
log::error!("Notification API not available");
return;
}
// Check current permission
let current_permission = js_sys::Reflect::get(&notification_class, &"permission".into())
.ok()
.and_then(|p| p.as_string())
.unwrap_or_default();
if current_permission == "granted" {
log::info!("Notification permission already granted");
true
} else if current_permission == "denied" {
log::warn!("Notification permission was denied");
return;
} else {
// Permission is "default" - need to request
log::info!("Requesting notification permission...");
if let Ok(request_fn) = js_sys::Reflect::get(&notification_class, &"requestPermission".into()) { if let Ok(request_fn) = js_sys::Reflect::get(&notification_class, &"requestPermission".into()) {
if request_fn.is_function() { if request_fn.is_function() {
let request_fn_typed = js_sys::Function::from(request_fn); let request_fn_typed = js_sys::Function::from(request_fn);
match request_fn_typed.call0(&notification_class) { match request_fn_typed.call0(&notification_class) {
Ok(promise_val) => { Ok(promise_val) => {
let request_future = wasm_bindgen_futures::JsFuture::from( let request_future = wasm_bindgen_futures::JsFuture::from(
web_sys::js_sys::Promise::from(promise_val) js_sys::Promise::from(promise_val)
); );
match request_future.await { match request_future.await {
Ok(_) => { Ok(result) => {
log::info!("Notification permission requested"); let result_str = result.as_string().unwrap_or_default();
log::info!("Permission request result: {}", result_str);
result_str == "granted"
} }
Err(e) => { Err(e) => {
log::warn!("Failed to request notification permission: {:?}", e); log::error!("Failed to request notification permission: {:?}", e);
false
} }
} }
} }
Err(e) => { Err(e) => {
log::warn!("Failed to call requestPermission: {:?}", e); log::error!("Failed to call requestPermission: {:?}", e);
} false
} }
} }
} else {
false
}
} else {
false
} }
} }
} else {
log::error!("Cannot access Notification class");
return;
};
if !permission_granted {
log::warn!("Notification permission not granted, cannot subscribe to push");
return;
} }
log::info!("Notification permission granted! Proceeding with push subscription...");
// 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,