aboutsummaryrefslogtreecommitdiff
path: root/src/app/actions.rs
diff options
context:
space:
mode:
authorOgulcan Celik <ogulcancelik@gmail.com>2026-04-22 17:01:25 +0300
committerOgulcan Celik <ogulcancelik@gmail.com>2026-04-22 17:01:25 +0300
commit4b482f37a1e233b9aca6bf99b12e8b4da3e5c05e (patch)
tree69d1a56ad6335547eec9727691310cf96ebe9623 /src/app/actions.rs
parent5bd939fbfc92a8073d0eac11dfb02a31ea638b15 (diff)
feat: add terminal-delivered client notifications
Diffstat (limited to 'src/app/actions.rs')
-rw-r--r--src/app/actions.rs38
1 files changed, 24 insertions, 14 deletions
diff --git a/src/app/actions.rs b/src/app/actions.rs
index f9136b9c..33952b9f 100644
--- a/src/app/actions.rs
+++ b/src/app/actions.rs
@@ -35,7 +35,7 @@ pub fn notification_sound_for_state_change(
}
}
-fn notification_toast_for_state_change(
+pub fn notification_toast_for_state_change(
is_active_tab: bool,
prev_state: AgentState,
new_state: AgentState,
@@ -57,7 +57,7 @@ fn toast_agent_label(agent_label: &str) -> &str {
agent_label
}
-fn notification_context(
+pub fn notification_context(
ws: &crate::workspace::Workspace,
ws_idx: usize,
pane_id: PaneId,
@@ -469,11 +469,16 @@ impl AppState {
self.update_available = Some(version.clone());
self.latest_release_notes_available = true;
self.update_dismissed = true;
- self.toast = Some(ToastNotification {
- kind: ToastKind::UpdateInstalled,
- title: format!("v{version} available"),
- context: "detach, then run `herdr update`".to_string(),
- });
+ if matches!(
+ self.toast_config.delivery,
+ crate::config::ToastDelivery::Herdr
+ ) {
+ self.toast = Some(ToastNotification {
+ kind: ToastKind::UpdateInstalled,
+ title: format!("v{version} available"),
+ context: "detach, then run `herdr update`".to_string(),
+ });
+ }
Vec::new()
}
AppEvent::StateChanged {
@@ -575,7 +580,10 @@ impl AppState {
}
}
- if self.toast_config.enabled {
+ if matches!(
+ self.toast_config.delivery,
+ crate::config::ToastDelivery::Herdr
+ ) {
if let (Some(agent_label), Some(kind)) = (
change.agent_label.as_deref(),
notification_toast_for_state_change(
@@ -665,6 +673,7 @@ mod tests {
#[test]
fn update_ready_sets_explicit_upgrade_toast() {
let mut state = AppState::test_new();
+ state.toast_config.delivery = crate::config::ToastDelivery::Herdr;
let updates = state.handle_app_event(crate::events::AppEvent::UpdateReady {
version: "0.5.0".into(),
@@ -921,7 +930,7 @@ mod tests {
fn background_waiting_sets_attention_toast() {
let mut state = app_with_workspaces(&["active", "background"]);
state.active = Some(0);
- state.toast_config.enabled = true;
+ state.toast_config.delivery = crate::config::ToastDelivery::Herdr;
let bg_pane_id = *state.workspaces[1].panes.keys().next().unwrap();
state.handle_app_event(AppEvent::StateChanged {
@@ -940,7 +949,7 @@ mod tests {
fn hook_reported_unknown_agent_sets_toast_title_from_label() {
let mut state = app_with_workspaces(&["active", "background"]);
state.active = Some(0);
- state.toast_config.enabled = true;
+ state.toast_config.delivery = crate::config::ToastDelivery::Herdr;
let bg_pane_id = *state.workspaces[1].panes.keys().next().unwrap();
state.handle_app_event(AppEvent::HookStateReported {
@@ -961,7 +970,7 @@ mod tests {
fn background_idle_sets_finished_toast() {
let mut state = app_with_workspaces(&["active", "background"]);
state.active = Some(0);
- state.toast_config.enabled = true;
+ state.toast_config.delivery = crate::config::ToastDelivery::Herdr;
let bg_pane_id = *state.workspaces[1].panes.keys().next().unwrap();
state.workspaces[1]
.panes
@@ -985,7 +994,7 @@ mod tests {
fn background_toast_includes_tab_name_when_workspace_has_multiple_tabs() {
let mut state = app_with_workspaces(&["active", "background"]);
state.active = Some(0);
- state.toast_config.enabled = true;
+ state.toast_config.delivery = crate::config::ToastDelivery::Herdr;
state.workspaces[1].tabs[0].set_custom_name("main".into());
let second_tab = state.workspaces[1].test_add_tab(Some("logs"));
let bg_pane_id = state.workspaces[1].tabs[second_tab].root_pane;
@@ -1006,7 +1015,7 @@ mod tests {
fn background_tab_in_active_workspace_still_sets_toast() {
let mut state = app_with_workspaces(&["active"]);
state.active = Some(0);
- state.toast_config.enabled = true;
+ state.toast_config.delivery = crate::config::ToastDelivery::Herdr;
state.workspaces[0].tabs[0].set_custom_name("main".into());
let second_tab = state.workspaces[0].test_add_tab(Some("logs"));
let bg_pane_id = state.workspaces[0].tabs[second_tab].root_pane;
@@ -1027,7 +1036,7 @@ mod tests {
fn active_workspace_active_tab_does_not_set_toast() {
let mut state = app_with_workspaces(&["active"]);
state.active = Some(0);
- state.toast_config.enabled = true;
+ state.toast_config.delivery = crate::config::ToastDelivery::Herdr;
let pane_id = *state.workspaces[0].panes.keys().next().unwrap();
state.handle_app_event(AppEvent::StateChanged {
@@ -1042,6 +1051,7 @@ mod tests {
#[test]
fn update_ready_sets_manual_update_toast() {
let mut state = AppState::test_new();
+ state.toast_config.delivery = crate::config::ToastDelivery::Herdr;
let updates = state.handle_app_event(AppEvent::UpdateReady {
version: "0.5.0".into(),