use crate::persistence::app_state as prefs;
pub async fn show_desktop_notification(
room_name: &str,
sender_name: &str,
message_body: &str,
_room_id: &str,
) {
let enabled = match prefs::load_preferences().await {
Ok(p) => p.desktop_notifications,
Err(_) => true,
};
if !enabled {
return;
}
let show_preview = match prefs::load_preferences().await {
Ok(p) => p.show_message_preview,
Err(_) => true,
};
let title = format!("{sender_name} in {room_name}");
let body = if show_preview {
truncate_notification_body(message_body, 200)
} else {
"New message".to_string()
};
#[cfg(target_os = "windows")]
{
show_windows_notification(&title, &body);
}
#[cfg(target_os = "macos")]
{
show_macos_notification(&title, &body);
}
#[cfg(target_os = "linux")]
{
show_linux_notification(&title, &body);
}
#[cfg(target_family = "wasm")]
{
show_web_notification(&title, &body);
}
}
fn truncate_notification_body(body: &str, max_len: usize) -> String {
if body.len() <= max_len {
body.to_string()
} else {
format!("{}...", &body[..max_len])
}
}
#[cfg(target_os = "windows")]
fn show_windows_notification(title: &str, body: &str) {
let script = format!(
"[Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime] | Out-Null; \
$template = [Windows.UI.Notifications.ToastNotificationManager]::GetTemplateContent([Windows.UI.Notifications.ToastTemplateType]::ToastText02); \
$textNodes = $template.GetElementsByTagName('text'); \
$textNodes.Item(0).AppendChild($template.CreateTextNode('{}')) | Out-Null; \
$textNodes.Item(1).AppendChild($template.CreateTextNode('{}')) | Out-Null; \
$toast = [Windows.UI.Notifications.ToastNotification]::new($template); \
[Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier('Netrix').Show($toast)",
title.replace('\'', "''"),
body.replace('\'', "''")
);
let _ = std::process::Command::new("powershell")
.args(["-WindowStyle", "Hidden", "-Command", &script])
.spawn();
}
#[cfg(target_os = "macos")]
fn show_macos_notification(title: &str, body: &str) {
let script = format!(
"display notification \"{}\" with title \"{}\"",
body.replace('"', "\\\""),
title.replace('"', "\\\"")
);
let _ = std::process::Command::new("osascript")
.args(["-e", &script])
.spawn();
}
#[cfg(target_os = "linux")]
fn show_linux_notification(title: &str, body: &str) {
let _ = std::process::Command::new("notify-send")
.args(["-a", "Netrix", title, body])
.spawn();
}
#[cfg(target_family = "wasm")]
fn show_web_notification(title: &str, body: &str) {
tracing::debug!("Web notification: {title} - {body}");
}
pub fn matches_keywords(body: &str, keywords: &[String]) -> bool {
let body_lower = body.to_lowercase();
keywords.iter().any(|kw| body_lower.contains(&kw.to_lowercase()))
}
pub fn play_notification_sound() {
tracing::debug!("Notification sound requested");
}