chiark / gitweb /
Notification log formatting
authorSimon Tatham <anakin@pobox.com>
Tue, 26 Dec 2023 07:57:03 +0000 (07:57 +0000)
committerSimon Tatham <anakin@pobox.com>
Tue, 26 Dec 2023 07:57:03 +0000 (07:57 +0000)
src/text.rs

index 96067dc6f9674c6834f2dad053ff3a7de13732ad..3544315f48a2887678404edf3da44ac53e2b9a94 100644 (file)
@@ -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<Utc>,
+    account_desc: String,
+    para: Paragraph,
+}
+
+pub fn notification_log(
+    timestamp: DateTime<Utc>, account: &str, nameline: &str,
+    ntype: NotificationLogType, post: Option<&Vec<Paragraph>>)
+    -> Box<dyn TextFragment> {
+
+    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<ColouredString> {
+        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