diff --git a/src/session/model/notifications/mod.rs b/src/session/model/notifications/mod.rs index 7d9ab16d..8c7b8f8b 100644 --- a/src/session/model/notifications/mod.rs +++ b/src/session/model/notifications/mod.rs @@ -1,3 +1,5 @@ +use std::borrow::Cow; + use gettextrs::gettext; use gtk::{gdk, gio, glib, prelude::*, subclass::prelude::*}; use matrix_sdk::{sync::Notification, Room as MatrixRoom}; @@ -22,6 +24,16 @@ use crate::{ Application, Window, }; +/// The maximum number of lines we want to display for the body of a +/// notification. +// This is taken from GNOME Shell's behavior: +// +const MAX_BODY_LINES: usize = 6; +/// The maximum number of characters that we want to display for the body of a +/// notification. We assume that the system shows at most 100 characters per +/// line, so this is `MAX_BODY_LINES * 100`. +const MAX_BODY_CHARS: usize = MAX_BODY_LINES * 100; + mod imp { use std::{ cell::RefCell, @@ -101,7 +113,19 @@ impl Notifications { let notification = gio::Notification::new(title); notification.set_category(Some("im.received")); notification.set_priority(gio::NotificationPriority::High); - notification.set_body(Some(body)); + + // Truncate the body if necessary. + let body = if let Some((end, _)) = body.char_indices().nth(MAX_BODY_CHARS) { + let mut body = body[..end].trim_end().to_owned(); + if !body.ends_with('…') { + body.push('…'); + } + Cow::Owned(body) + } else { + Cow::Borrowed(body) + }; + + notification.set_body(Some(&body)); let action = intent.app_action_name(); let target_value = intent.to_variant_with_session_id(session_id);