Files
Lumotia/src-tauri/src/commands/nudges.rs
Claude 89c63891fa chore: rebrand from Kon/Corbie to Magnotia
Replace all instances of the legacy product names "Kon" and "Corbie" with
"Magnotia" across user-facing copy, code identifiers, package names, bundle
ids, file paths, and documentation. Preserves the unrelated "konsole" (KDE
terminal) reference and the parent CORBEL company name.

- Renames 10 Rust crates (kon-* → magnotia-*) and the tauri binary
- Updates package.json, tauri.conf.json (productName + identifier)
- Renames CSS classes (kon-rh-* → magnotia-rh-*) and animations
- Renames brand and roadmap docs
- Regenerates Cargo.lock and package-lock.json

Verified: svelte-check passes; pure-rust crates compile under new names.
2026-04-30 13:06:55 +00:00

64 lines
2.4 KiB
Rust

//! Phase 6 of the feature-complete roadmap: Margot soft-touch nudges.
//!
//! The nudge bus lives in the frontend (`nudgeBus.svelte.ts`) — it
//! owns trigger subscription, suppression rules, and the hourly cap.
//! This module is the thin Rust side that:
//!
//! - Guards delivery to the main window only (secondary windows like
//! the task float can't fire notifications at the user — they're
//! already beside the user's attention).
//! - Delegates to `tauri-plugin-notification` for cross-platform OS
//! delivery. The plugin handles the macOS Notification Center /
//! Linux org.freedesktop.Notifications / Windows toast plumbing.
//!
//! Permission handling happens on the JS side via the plugin's
//! `isPermissionGranted` / `requestPermission` API — before the first
//! `deliver_nudge` call, the nudge bus prompts the user. If denied,
//! subsequent calls return an error that the bus logs and swallows.
//!
//! No persistence for v1. Cooldown state is ephemeral; the roadmap's
//! nudge-audit table is deferred until a real need emerges.
use serde::Deserialize;
use tauri_plugin_notification::NotificationExt;
use crate::commands::security::ensure_main_window;
#[derive(Debug, Clone, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct DeliverNudgeInput {
pub title: String,
pub body: String,
}
/// Deliver a single OS notification. Does not apply suppression
/// logic — the frontend nudge bus is responsible for cadence and
/// cooldown, so this command is a blunt "push it now" primitive.
///
/// Returns an error if the notification plugin refuses the call
/// (typically because permission was denied by the user at the OS
/// level). The nudge bus logs and swallows these — nudges are
/// fire-and-forget and must never surface errors to the user.
#[tauri::command]
pub fn deliver_nudge(
app: tauri::AppHandle,
window: tauri::WebviewWindow,
input: DeliverNudgeInput,
) -> Result<(), String> {
ensure_main_window(&window)?;
let title = input.title.trim();
let body = input.body.trim();
if title.is_empty() && body.is_empty() {
// A blank nudge is worse than no nudge — stay quiet.
return Ok(());
}
app.notification()
.builder()
.title(if title.is_empty() { "Magnotia" } else { title })
.body(body)
.show()
.map_err(|e| format!("notification delivery failed: {e}"))
}