From 9c37bd2188f2cad1b12e4f72e7b4d6fa1d6f9f3b Mon Sep 17 00:00:00 2001 From: Proof of Prints Date: Sun, 7 Jun 2026 09:25:54 -0500 Subject: [PATCH] fix(alerts): working notification-settings deep link + muted visibility in lists - The 'Open Windows notification settings' button was dead: the shell plugin's open() URL validator only permits http(s)/mailto/tel, so the ms-settings: scheme was silently rejected. Add an open_notification_settings backend command that opens it via the OS opener (explorer on Windows, mirroring open_log_directory); banner now invokes it. - Make muted devices obvious in the ASIC and OverMobile list views: amber tint on the card and table row, and the status badge shows 'Muted' instead of the normal status. Selection highlight still takes precedence. --- src-tauri/src/commands/notifications.rs | 26 +++++++++++++ src-tauri/src/lib.rs | 3 +- src/components/NotificationBanner.tsx | 7 +++- src/pages/MinerList.tsx | 49 +++++++++++++++++++++---- src/pages/MobileMinerList.tsx | 46 +++++++++++++++++++---- 5 files changed, 114 insertions(+), 17 deletions(-) diff --git a/src-tauri/src/commands/notifications.rs b/src-tauri/src/commands/notifications.rs index c5d15b1..64196ec 100644 --- a/src-tauri/src/commands/notifications.rs +++ b/src-tauri/src/commands/notifications.rs @@ -101,6 +101,32 @@ pub fn get_notification_status(_app: tauri::AppHandle) -> Result Ok("enabled".to_string()) } +/// Open the OS notification-settings page. Done in the backend via the OS +/// opener because the shell plugin's `open` URL validator rejects non-web +/// schemes like `ms-settings:`, so the frontend can't deep-link to it directly. +#[tauri::command] +pub fn open_notification_settings() -> Result<(), String> { + #[cfg(target_os = "windows")] + std::process::Command::new("explorer") + .arg("ms-settings:notifications") + .spawn() + .map_err(|e| format!("Failed to open notification settings: {}", e))?; + + #[cfg(target_os = "macos")] + std::process::Command::new("open") + .arg("x-apple.systempreferences:com.apple.preference.notifications") + .spawn() + .map_err(|e| format!("Failed to open notification settings: {}", e))?; + + #[cfg(target_os = "linux")] + std::process::Command::new("gnome-control-center") + .arg("notifications") + .spawn() + .map_err(|e| format!("Failed to open notification settings: {}", e))?; + + Ok(()) +} + #[tauri::command] pub fn send_desktop_notification( app: tauri::AppHandle, diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index a44a68d..948164d 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -34,7 +34,7 @@ use commands::alerts::{ }; use commands::coins::{get_coins, add_coin, remove_coin}; use commands::email::{get_smtp_config, save_smtp_config, test_smtp_config, send_alert_email}; -use commands::notifications::{send_desktop_notification, get_notification_status}; +use commands::notifications::{send_desktop_notification, get_notification_status, open_notification_settings}; use commands::mute::{get_muted_devices, set_device_mute, clear_device_mute}; use commands::uptime::{record_uptime, get_uptime_stats, get_all_uptime_stats, clear_uptime_data}; use commands::export::{export_miners_csv, export_alert_history_csv, export_profitability_csv, export_farm_history_csv}; @@ -323,6 +323,7 @@ pub fn run() { send_alert_email, send_desktop_notification, get_notification_status, + open_notification_settings, add_farm_snapshot, get_farm_history, clear_farm_history, diff --git a/src/components/NotificationBanner.tsx b/src/components/NotificationBanner.tsx index ab5d9db..7359dac 100644 --- a/src/components/NotificationBanner.tsx +++ b/src/components/NotificationBanner.tsx @@ -1,6 +1,5 @@ import { useState, useEffect, useCallback } from "react"; import { invoke } from "@tauri-apps/api/core"; -import { open as openUrl } from "@tauri-apps/plugin-shell"; /** * Warns when Windows notifications are turned off for OverManager. When the @@ -47,7 +46,11 @@ export default function NotificationBanner() { Turn notifications back on in Windows Settings so alert toasts are delivered.

- - {miner.status} + + {isMuted ? "Muted" : miner.status} {onRemove && (