aboutsummaryrefslogtreecommitdiff
path: root/src/client/notifications.rs
diff options
context:
space:
mode:
authorCan Celik <ogulcancelik@gmail.com>2026-09-01 15:48:22 +0300
committerGitHub <noreply@github.com>2026-09-01 15:48:22 +0300
commit207be3c771d281baae6e5fa0fb74be9a056e97a2 (patch)
treed7b037ecdf629224a048c841d11659efdc23507d /src/client/notifications.rs
parent8a6d697308162874a236c84aac0b0f8c7ac01f83 (diff)
refactor: render the shell in the client (#3487)
* feat: add opt-in client-rendered shell * feat: add client-owned shell mouse controls * feat: complete client-owned shell chrome * feat: add client-owned shell settings and notifications * feat: run client shell custom commands * feat: render popup terminals in client shell * feat: add client-owned scrollback and copy mode * fix: preserve client worktree trust defaults * feat: render startup diagnostics in client shell * feat: render onboarding in client shell * feat: render product announcements in client shell * feat: render release notes in client shell * feat: render mobile switcher in client shell * feat: render kitty graphics in client shell * fix: preserve client shell lifecycle coherence * refactor: route client shell commands through endpoint connections * refactor: make the client-rendered shell the default * refactor: remove monolithic launch mode * refactor: complete client-rendered shell cutover * perf: retain client pane surface updates * perf: scale retained pane surface updates * perf: remove remote pane input latency * test: make client shell checks platform-independent * fix: prevent client timer starvation * test: fix client shell platform gates * test: accept retained surfaces in cross-area checks * test: make client mode assertions platform-neutral * fix: badge only outdated integrations
Diffstat (limited to 'src/client/notifications.rs')
-rw-r--r--src/client/notifications.rs102
1 files changed, 102 insertions, 0 deletions
diff --git a/src/client/notifications.rs b/src/client/notifications.rs
new file mode 100644
index 00000000..7c97742e
--- /dev/null
+++ b/src/client/notifications.rs
@@ -0,0 +1,102 @@
+use std::io;
+
+use tracing::{debug, warn};
+
+use crate::protocol::NotifyKind;
+
+use super::shell;
+
+pub(super) fn handle_shell_notification_effects(
+ effects: Vec<shell::ClientShellNotificationEffect>,
+ sound_config: &crate::config::SoundConfig,
+) {
+ for effect in effects {
+ match effect {
+ shell::ClientShellNotificationEffect::Sound { sound, agent } => {
+ let agent = agent.as_deref().and_then(crate::detect::parse_agent_label);
+ if sound_config.allows(agent) {
+ crate::sound::play(sound, sound_config);
+ }
+ }
+ shell::ClientShellNotificationEffect::Terminal { title, body } => {
+ if let Err(err) = crate::terminal_notify::show_notification(&title, body.as_deref())
+ {
+ warn!(err = %err, "failed to emit terminal notification");
+ }
+ }
+ shell::ClientShellNotificationEffect::System { title, body } => {
+ if let Err(err) =
+ crate::platform::show_desktop_notification(&title, body.as_deref())
+ {
+ warn!(err = %err, "failed to emit system notification");
+ }
+ }
+ }
+ }
+}
+
+pub(super) fn handle_notify(
+ kind: NotifyKind,
+ message: &str,
+ body: Option<&str>,
+ sound_config: &crate::config::SoundConfig,
+) {
+ handle_notify_with_notifiers(
+ kind,
+ message,
+ body,
+ sound_config,
+ crate::terminal_notify::show_notification,
+ crate::platform::show_desktop_notification,
+ );
+}
+
+pub(super) fn handle_notify_with_notifiers(
+ kind: NotifyKind,
+ message: &str,
+ body: Option<&str>,
+ sound_config: &crate::config::SoundConfig,
+ mut show_terminal_notification: impl FnMut(&str, Option<&str>) -> io::Result<bool>,
+ mut show_system_notification: impl FnMut(&str, Option<&str>) -> io::Result<bool>,
+) {
+ match kind {
+ NotifyKind::Sound => {
+ let Some(sound) = sound_from_notify_message(message) else {
+ warn!(
+ message = message,
+ "received unknown sound notification from server"
+ );
+ return;
+ };
+ if sound_config.enabled {
+ crate::sound::play(sound, sound_config);
+ }
+ }
+ NotifyKind::Toast => {
+ debug!(
+ message = message,
+ "received terminal toast notification from server"
+ );
+ if let Err(err) = show_terminal_notification(message, body) {
+ warn!(err = %err, "failed to emit terminal notification");
+ }
+ }
+ NotifyKind::SystemToast => {
+ debug!(
+ message = message,
+ "received system toast notification from server"
+ );
+ if let Err(err) = show_system_notification(message, body) {
+ warn!(err = %err, "failed to emit system notification");
+ }
+ }
+ }
+}
+
+pub(super) fn sound_from_notify_message(message: &str) -> Option<crate::sound::Sound> {
+ match message {
+ "agent done" => Some(crate::sound::Sound::Done),
+ "agent attention" => Some(crate::sound::Sound::Request),
+ _ => None,
+ }
+}