diff options
| author | Can Celik <ogulcancelik@gmail.com> | 2026-09-02 02:45:20 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-09-02 02:45:20 +0300 |
| commit | cc88b3b8e5bb9f7d9f23ed6ae85a52fd7b5b9ed6 (patch) | |
| tree | 4d37c760099070f1a1488b61c7b7271875aafef8 /src/client/shell/notifications.rs | |
| parent | 18e69891dca486d669a584facd80644bb51f54a2 (diff) | |
feat: add stable client endpoint compatibility (#3509)
* feat: add stable client endpoint compatibility
* fix: keep portable-pty patch checks composable
* ci: run maintenance checks in pull requests
* fix: reject endpoint errors from terminal clients
* feat: keep compatible servers running across updates
Diffstat (limited to 'src/client/shell/notifications.rs')
| -rw-r--r-- | src/client/shell/notifications.rs | 216 |
1 files changed, 143 insertions, 73 deletions
diff --git a/src/client/shell/notifications.rs b/src/client/shell/notifications.rs index 0310e57d..43fe566a 100644 --- a/src/client/shell/notifications.rs +++ b/src/client/shell/notifications.rs @@ -1,13 +1,16 @@ use super::*; use ratatui::{ + style::Color, text::{Line, Span}, widgets::{Block, Borders, Clear, Paragraph, Widget}, }; -pub(super) fn render_mobile_notification_banner( +fn render_mobile_notice_banner( buffer: &mut Buffer, area: Rect, - notification: &ClientVisibleNotification, + title: &str, + body: Option<&str>, + dot_color: Color, offset_for_warning: bool, palette: &Palette, ) -> Rect { @@ -23,6 +26,49 @@ pub(super) fn render_mobile_notification_banner( let background = palette.surface0; Clear.render(rect, buffer); buffer.set_style(rect, Style::default().bg(background)); + let mut x = rect.x; + for (text, style) in [ + (" ", Style::default().bg(background)), + ("●", Style::default().fg(dot_color).bg(background)), + (" ", Style::default().bg(background)), + ( + title, + Style::default() + .fg(palette.text) + .bg(background) + .add_modifier(Modifier::BOLD), + ), + ] { + x = super::render::put_segment(buffer, x, rect.y, rect.right(), text, style); + } + if let Some(body) = body.filter(|body| !body.is_empty()) { + x = super::render::put_segment( + buffer, + x, + rect.y, + rect.right(), + " · ", + Style::default().fg(palette.overlay0).bg(background), + ); + super::render::put_text( + buffer, + x, + rect.y, + rect.right().saturating_sub(x), + body, + Style::default().fg(palette.overlay0).bg(background), + ); + } + rect +} + +pub(super) fn render_mobile_notification_banner( + buffer: &mut Buffer, + area: Rect, + notification: &ClientVisibleNotification, + offset_for_warning: bool, + palette: &Palette, +) -> Rect { let event = ¬ification.event; let title = match event.kind { SemanticNotificationKind::NeedsAttention => event @@ -45,84 +91,55 @@ pub(super) fn render_mobile_notification_banner( palette.accent } }; - let mut x = rect.x; - x = super::render::put_segment( - buffer, - x, - rect.y, - rect.right(), - " ", - Style::default().bg(background), - ); - x = super::render::put_segment( - buffer, - x, - rect.y, - rect.right(), - "●", - Style::default().fg(dot_color).bg(background), - ); - x = super::render::put_segment( + render_mobile_notice_banner( buffer, - x, - rect.y, - rect.right(), - " ", - Style::default().bg(background), - ); - x = super::render::put_segment( - buffer, - x, - rect.y, - rect.right(), + area, &title, - Style::default() - .fg(palette.text) - .bg(background) - .add_modifier(Modifier::BOLD), - ); - if let Some(body) = event.body.as_deref().filter(|body| !body.is_empty()) { - x = super::render::put_segment( - buffer, - x, - rect.y, - rect.right(), - " · ", - Style::default().fg(palette.overlay0).bg(background), - ); - super::render::put_text( - buffer, - x, - rect.y, - rect.right().saturating_sub(x), - body, - Style::default().fg(palette.overlay0).bg(background), - ); - } - rect + event.body.as_deref(), + dot_color, + offset_for_warning, + palette, + ) } -pub(super) fn render_visible_notification( +pub(super) fn render_mobile_endpoint_notice_banner( buffer: &mut Buffer, area: Rect, - notification: &ClientVisibleNotification, - default_position: crate::config::ToastHerdrPosition, + notice: &ClientVisibleEndpointNotice, + offset_for_warning: bool, + palette: &Palette, +) -> Rect { + render_mobile_notice_banner( + buffer, + area, + ¬ice.title, + Some(¬ice.body), + palette.red, + offset_for_warning, + palette, + ) +} + +fn render_notification_card( + buffer: &mut Buffer, + area: Rect, + title: &str, + body: &str, + position: crate::config::ToastHerdrPosition, top_offset: u16, + dot_color: Color, palette: &Palette, ) -> Rect { if area.is_empty() { return Rect::default(); } - let event = ¬ification.event; - let body = event.body.as_deref().unwrap_or_default(); - let content_width = unicode_width::UnicodeWidthStr::width(event.title.as_str()) + let content_width = unicode_width::UnicodeWidthStr::width(title) .max(unicode_width::UnicodeWidthStr::width(body)) .saturating_add(6); let width = u16::try_from(content_width) .unwrap_or(u16::MAX) .min(area.width); let height: u16 = if body.is_empty() { 3 } else { 4 }.min(area.height); - let position = event.position.unwrap_or(default_position); let x = match position { crate::config::ToastHerdrPosition::TopLeft | crate::config::ToastHerdrPosition::BottomLeft => area.x, @@ -148,19 +165,10 @@ pub(super) fn render_visible_notification( let inner = block.inner(rect); block.render(rect, buffer); Paragraph::new(Line::from(vec