mirror of
https://github.com/tinyhumansai/openhuman.git
synced 2026-07-30 23:14:37 +00:00
fix(notifications): request OS permission at startup and fix socketService listener leak (#998)
This commit is contained in:
@@ -637,8 +637,13 @@ fn show_native_notification(
|
||||
tag: Option<String>,
|
||||
) -> Result<(), String> {
|
||||
use tauri_plugin_notification::NotificationExt;
|
||||
let permission_state = app
|
||||
.notification()
|
||||
.permission_state()
|
||||
.map(|s| format!("{s:?}"))
|
||||
.unwrap_or_else(|e| format!("err({e})"));
|
||||
log::debug!(
|
||||
"[notify] show_native_notification title_chars={} body_chars={} tag={:?}",
|
||||
"[notify] show_native_notification title_chars={} body_chars={} tag={:?} permission={permission_state}",
|
||||
title.len(),
|
||||
body.len(),
|
||||
tag
|
||||
@@ -647,11 +652,102 @@ fn show_native_notification(
|
||||
if !body.is_empty() {
|
||||
builder = builder.body(&body);
|
||||
}
|
||||
#[cfg(target_os = "macos")]
|
||||
{
|
||||
builder = builder.sound("default");
|
||||
}
|
||||
builder
|
||||
.show()
|
||||
.map_err(|e| format!("notification show failed: {e}"))
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
fn macos_notification_permission_state_inner() -> Result<String, String> {
|
||||
use std::ptr::NonNull;
|
||||
use std::sync::mpsc;
|
||||
|
||||
use block2::RcBlock;
|
||||
use objc2_user_notifications::{
|
||||
UNAuthorizationStatus, UNNotificationSettings, UNUserNotificationCenter,
|
||||
};
|
||||
|
||||
let center = UNUserNotificationCenter::currentNotificationCenter();
|
||||
let (tx, rx) = mpsc::channel::<String>();
|
||||
let completion = RcBlock::new(move |settings: NonNull<UNNotificationSettings>| {
|
||||
let status = unsafe { settings.as_ref().authorizationStatus() };
|
||||
let state = if status == UNAuthorizationStatus::Authorized {
|
||||
"granted"
|
||||
} else if status == UNAuthorizationStatus::Denied {
|
||||
"denied"
|
||||
} else if status == UNAuthorizationStatus::NotDetermined {
|
||||
"not_determined"
|
||||
} else if status == UNAuthorizationStatus::Provisional {
|
||||
"provisional"
|
||||
} else if status == UNAuthorizationStatus::Ephemeral {
|
||||
"ephemeral"
|
||||
} else {
|
||||
"unknown"
|
||||
};
|
||||
let _ = tx.send(state.to_string());
|
||||
});
|
||||
center.getNotificationSettingsWithCompletionHandler(&completion);
|
||||
rx.recv_timeout(std::time::Duration::from_secs(2))
|
||||
.map_err(|_| "timed out waiting for macOS notification settings".to_string())
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
fn macos_notification_permission_request_inner() -> Result<String, String> {
|
||||
use block2::RcBlock;
|
||||
use objc2::runtime::Bool;
|
||||
use objc2_foundation::NSError;
|
||||
use objc2_user_notifications::{UNAuthorizationOptions, UNUserNotificationCenter};
|
||||
use std::sync::mpsc;
|
||||
|
||||
let center = UNUserNotificationCenter::currentNotificationCenter();
|
||||
let (tx, rx) = mpsc::channel::<bool>();
|
||||
let options = UNAuthorizationOptions::Alert
|
||||
| UNAuthorizationOptions::Badge
|
||||
| UNAuthorizationOptions::Sound;
|
||||
let completion = RcBlock::new(move |granted: Bool, _error: *mut NSError| {
|
||||
let _ = tx.send(granted.as_bool());
|
||||
});
|
||||
center.requestAuthorizationWithOptions_completionHandler(options, &completion);
|
||||
let granted = rx
|
||||
.recv_timeout(std::time::Duration::from_secs(5))
|
||||
.map_err(|_| "timed out waiting for macOS permission prompt result".to_string())?;
|
||||
if granted {
|
||||
Ok("granted".to_string())
|
||||
} else {
|
||||
// If the user denies or notifications are disabled for the app,
|
||||
// macOS reports `false` here.
|
||||
Ok("denied".to_string())
|
||||
}
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
fn notification_permission_state() -> Result<String, String> {
|
||||
#[cfg(target_os = "macos")]
|
||||
{
|
||||
return macos_notification_permission_state_inner();
|
||||
}
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
{
|
||||
Ok("granted".to_string())
|
||||
}
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
fn notification_permission_request() -> Result<String, String> {
|
||||
#[cfg(target_os = "macos")]
|
||||
{
|
||||
return macos_notification_permission_request_inner();
|
||||
}
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
{
|
||||
Ok("granted".to_string())
|
||||
}
|
||||
}
|
||||
|
||||
fn show_main_window(app: &AppHandle<AppRuntime>) -> Result<(), String> {
|
||||
let window = app
|
||||
.get_webview_window("main")
|
||||
@@ -1383,6 +1479,8 @@ pub fn run() {
|
||||
gmail::gmail_trash,
|
||||
gmail::gmail_add_label,
|
||||
gmail::gmail_find_linkedin_profile_url,
|
||||
notification_permission_state,
|
||||
notification_permission_request,
|
||||
activate_main_window,
|
||||
show_native_notification
|
||||
])
|
||||
|
||||
Reference in New Issue
Block a user