From 1f7f1c8756f0541cd2a733d9bd51d2bda41f83be Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Tue, 26 Dec 2023 07:57:03 +0000 Subject: [PATCH] Notification log formatting --- src/text.rs | 121 +++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 114 insertions(+), 7 deletions(-) diff --git a/src/text.rs b/src/text.rs index 96067dc..3544315 100644 --- a/src/text.rs +++ b/src/text.rs @@ -1,4 +1,6 @@ -use chrono::{DateTime, Utc, Local}; +use chrono::{DateTime, Local, Utc}; +#[cfg(test)] +use chrono::NaiveDateTime; use core::cmp::min; use std::collections::{HashMap, BTreeSet}; @@ -90,13 +92,14 @@ impl TextFragment for SeparatorLine { #[test] fn test_separator() { - // Would be nice to test time formatting here, but I'd have to - // think of a way to test it independently of TZ - assert_eq!(separator(None, true, false) + let t = NaiveDateTime::parse_from_str("2001-08-03 04:05:06", + "%Y-%m-%d %H:%M:%S") + .unwrap().and_local_timezone(Local).unwrap().with_timezone(&Utc); + assert_eq!(separator(Some(t), true, false) .render(60), vec! { ColouredString::general( - "------------------------------------------------------[F]--", - "SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSDSSS", + "--------------------------[F]--[Fri Aug 3 04:05:06 2001]--", + "SSSSSSSSSSSSSSSSSSSSSSSSSSSDSSSSDDDDDDDDDDDDDDDDDDDDDDDDSSS", ) }); } @@ -841,8 +844,112 @@ fn test_in_reply_to() { }); } +pub enum NotificationLogType { + Favourited, + Boosted, + Followed, +} + +pub struct NotificationLog { + timestamp: DateTime, + account_desc: String, + para: Paragraph, +} + +pub fn notification_log( + timestamp: DateTime, account: &str, nameline: &str, + ntype: NotificationLogType, post: Option<&Vec>) + -> Box { + + let mut para = Paragraph::new(); + + let verb = match ntype { + NotificationLogType::Favourited => "favourited: ", + NotificationLogType::Boosted => "boosted: ", + NotificationLogType::Followed => "followed you", + }; + para.push_text(&ColouredString::plain(verb), false); + + if let Some(paras) = post { + let currlen = para.words.len(); + for cpara in paras { + para.push_para(cpara); + } + para.delete_mention_words_from(currlen); + } + + Box::new(NotificationLog { + timestamp: timestamp, + account_desc: format!("{} ({})", nameline, account), + para: para, + }) +} + +impl TextFragment for NotificationLog { + fn render(&self, width: usize) -> Vec { + let mut full_para = Paragraph::new().set_indent(0, 2); + let datestr = self.timestamp.with_timezone(&Local) + .format("%a %b %e %H:%M:%S %Y ").to_string(); + full_para.push_text(&ColouredString::uniform(&datestr, ' '), false); + // FIXME: highlight account_desc if active + full_para.push_text( + &ColouredString::uniform(&self.account_desc, ' '), false); + full_para.push_para(&self.para); + let rendered_para = full_para.render(width); + if rendered_para.len() > 2 { + vec! { + rendered_para[0].clone(), + rendered_para[1].truncate(width-3).to_owned() + + ColouredString::plain("..."), + } + } else { + rendered_para + } + } +} + +#[test] +fn test_notification_log() { + let t = NaiveDateTime::parse_from_str("2001-08-03 04:05:06", + "%Y-%m-%d %H:%M:%S") + .unwrap().and_local_timezone(Local).unwrap().with_timezone(&Utc); + + let post = vec! { + Paragraph::new().add(&ColouredString::general( + "@stoat @weasel take a look at this otter!", + "@@@@@@ @@@@@@@ ")), + Paragraph::new().add(&ColouredString::general( + "@badger might also like it", + "@@@@@@@ ")), + }; + + assert_eq!(notification_log( + t, "foo@example.com", "Foo Bar", + NotificationLogType::Boosted, Some(&post)).render(80), vec! { + ColouredString::general("Fri Aug 3 04:05:06 2001 Foo Bar (foo@example.com) boosted: take a look at this", + " "), + ColouredString::general(" otter! @badger might also like it", + " @@@@@@@ "), + }); + + assert_eq!(notification_log( + t, "foo@example.com", "Foo Bar", + NotificationLogType::Favourited, Some(&post)).render(51), vec! { + ColouredString::general("Fri Aug 3 04:05:06 2001 Foo Bar (foo@example.com)", + " "), + ColouredString::general(" favourited: take a look at this otter! @badger...", + " @@@@@@@ "), + }); + + assert_eq!(notification_log( + t, "foo@example.com", "Foo Bar", + NotificationLogType::Followed, None).render(80), vec! { + ColouredString::general("Fri Aug 3 04:05:06 2001 Foo Bar (foo@example.com) followed you", + " "), + }); +} + // TODO: -// NotificationLog, also with included toot // UserListEntry // Media // FileStatusLine, with priorities -- 2.30.2