diff options
| author | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-04-22 17:01:25 +0300 |
|---|---|---|
| committer | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-04-22 17:01:25 +0300 |
| commit | 4b482f37a1e233b9aca6bf99b12e8b4da3e5c05e (patch) | |
| tree | 69d1a56ad6335547eec9727691310cf96ebe9623 /src/ui/settings.rs | |
| parent | 5bd939fbfc92a8073d0eac11dfb02a31ea638b15 (diff) | |
feat: add terminal-delivered client notifications
Diffstat (limited to 'src/ui/settings.rs')
| -rw-r--r-- | src/ui/settings.rs | 74 |
1 files changed, 27 insertions, 47 deletions
diff --git a/src/ui/settings.rs b/src/ui/settings.rs index 1123f408..5269f380 100644 --- a/src/ui/settings.rs +++ b/src/ui/settings.rs @@ -8,15 +8,18 @@ use ratatui::{ use super::widgets::{ action_button_row_rects, centered_popup_rect, modal_stack_areas, panel_contrast_fg, - render_action_button, render_panel_shell, ActionButtonSpec, + render_action_button, render_modal_choice_list, render_panel_shell, ActionButtonSpec, +}; +use crate::{ + app::{state::Palette, AppState}, + config::ToastDelivery, }; -use crate::app::{state::Palette, AppState}; pub(super) fn render_settings_overlay(app: &AppState, frame: &mut Frame, area: Rect) { use crate::app::state::SettingsSection; let p = &app.palette; - let Some(popup) = centered_popup_rect(area, 56, 20) else { + let Some(popup) = centered_popup_rect(area, 76, 22) else { return; }; @@ -87,14 +90,20 @@ pub(super) fn render_settings_overlay(app: &AppState, frame: &mut Frame, area: R ); } SettingsSection::Toast => { - render_settings_toggle( + render_modal_choice_list( frame, content_area, - p, - "visual toasts", - "show top-right notifications for background events", - app.toast_config.enabled, + "notification popups", + "choose where background popup notifications should appear", + &[ + ("off", ToastDelivery::Off), + ("inside herdr", ToastDelivery::Herdr), + ("via terminal", ToastDelivery::Terminal), + ], + app.toast_delivery(), app.settings.list.selected, + p, + 2, ); } } @@ -195,44 +204,15 @@ fn render_settings_toggle( current_value: bool, selected_idx: usize, ) { - let [desc_area, _, list_area] = Layout::vertical([ - Constraint::Length(1), - Constraint::Length(1), - Constraint::Min(2), - ]) - .areas::<3>(area); - - let max_desc_len = (desc_area.width as usize).saturating_sub(2); - let desc_text = if description.len() > max_desc_len { - format!(" {}…", &description[..max_desc_len.saturating_sub(2)]) - } else { - format!(" {description}") - }; - frame.render_widget( - Paragraph::new(Span::styled(desc_text, Style::default().fg(p.overlay1))), - desc_area, + render_modal_choice_list( + frame, + area, + title, + description, + &[("on", true), ("off", false)], + current_value, + selected_idx, + p, + 1, ); - - let items: Vec<ListItem> = ["on", "off"] - .into_iter() - .map(|label| { - let is_active = (label == "on") == current_value; - let marker = if is_active { " ✓" } else { "" }; - ListItem::new(Line::from(vec![ - Span::styled(format!("{title}: {label}"), Style::default().fg(p.subtext0)), - Span::styled(marker, Style::default().fg(p.green)), - ])) - }) - .collect(); - - let list = List::new(items) - .highlight_style( - Style::default() - .bg(p.surface0) - .fg(p.text) - .add_modifier(Modifier::BOLD), - ) - .highlight_symbol(" ▸ "); - let mut state = ListState::default().with_selected(Some(selected_idx.min(1))); - frame.render_stateful_widget(list, list_area, &mut state); } |
