chiark / gitweb /
Store ids in all the TextFragments that will need them.
authorSimon Tatham <anakin@pobox.com>
Thu, 4 Jan 2024 07:36:52 +0000 (07:36 +0000)
committerSimon Tatham <anakin@pobox.com>
Thu, 4 Jan 2024 08:14:03 +0000 (08:14 +0000)
The method of finding out _what_ thing was highlighted has to return
it by its string id. So anything that will have to highlight a
contained object will also need a way to return its id, so they all
have to store those ids.

src/text.rs

index 74fca60fc6f2bea976bec8c738689eeb66d4c7c7..1f53100d951c0929424c9ff93e882cb5606ae54a 100644 (file)
@@ -288,24 +288,27 @@ pub struct UsernameHeader {
     colour: char,
     account: String,
     nameline: String,
+    id: String,
 }
 
 impl UsernameHeader {
-    pub fn from(account: &str, nameline: &str) -> Self {
+    pub fn from(account: &str, nameline: &str, id: &str) -> Self {
         UsernameHeader{
             header: "From".to_owned(),
             colour: 'F',
             account: account.to_owned(),
             nameline: nameline.to_owned(),
+            id: id.to_owned(),
         }
     }
 
-    pub fn via(account: &str, nameline: &str) -> Self {
+    pub fn via(account: &str, nameline: &str, id: &str) -> Self {
         UsernameHeader{
             header: "Via".to_owned(),
             colour: 'f',
             account: account.to_owned(),
             nameline: nameline.to_owned(),
+            id: id.to_owned(),
         }
     }
 }
@@ -325,14 +328,14 @@ impl TextFragment for UsernameHeader {
 
 #[test]
 fn test_userheader() {
-    assert_eq!(UsernameHeader::from("stoat@example.com", "Some Person")
+    assert_eq!(UsernameHeader::from("stoat@example.com", "Some Person", "123")
                .render(80), vec! {
             ColouredString::general(
                 "From: Some Person (stoat@example.com)",
                 "      FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
                 )
         });
-    assert_eq!(UsernameHeader::via("stoat@example.com", "Some Person")
+    assert_eq!(UsernameHeader::via("stoat@example.com", "Some Person", "123")
                .render(80), vec! {
             ColouredString::general(
                 "Via: Some Person (stoat@example.com)",
@@ -931,15 +934,18 @@ fn test_in_reply_to() {
 pub struct NotificationLog {
     timestamp: DateTime<Utc>,
     account_desc: String,
+    account_id: String,
+    status_id: Option<String>,
     para: Paragraph,
 }
 
 impl NotificationLog {
     pub fn new(
         timestamp: DateTime<Utc>, account: &str, nameline: &str,
-        ntype: NotificationType, post: Option<&Paragraph>)
-        -> Self {
-
+        account_id: &str, ntype: NotificationType, post: Option<&Paragraph>,
+        status_id: Option<&str>)
+        -> Self
+    {
         let mut para = Paragraph::new();
 
         let verb = match ntype {
@@ -956,9 +962,16 @@ impl NotificationLog {
             para.delete_mention_words_from(currlen);
         }
 
+        let status_id = match status_id {
+            None => None,
+            Some(s) => Some(s.to_owned()),
+        };
+
         NotificationLog {
             timestamp,
             account_desc: format!("{} ({})", nameline, account),
+            account_id: account_id.to_owned(),
+            status_id,
             para,
         }
     }
@@ -968,12 +981,18 @@ impl NotificationLog {
             None => None,
             Some(st) => Some(Html::new(&st.content).to_para()),
         };
+        let status_id = match &not.status {
+            None => None,
+            Some(st) => Some(&st.id as &str),
+        };
         Self::new(
             not.created_at,
             &client.fq(&not.account.acct),
             &not.account.display_name,
+            &not.account.id,
             not.ntype,
             para.as_ref(),
+            status_id,
         )
     }
 }
@@ -1015,7 +1034,7 @@ fn test_notification_log() {
     ));
 
     assert_eq!(NotificationLog::new(
-            t, "foo@example.com", "Foo Bar",
+            t, "foo@example.com", "Foo Bar", "123", None,
             NotificationType::Reblog, 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",
                                     "                                                                               "),
@@ -1024,7 +1043,7 @@ fn test_notification_log() {
         });
 
     assert_eq!(NotificationLog::new(
-            t, "foo@example.com", "Foo Bar",
+            t, "foo@example.com", "Foo Bar", "123", None,
             NotificationType::Favourite, Some(&post)).render(51), vec! {
             ColouredString::general("Fri Aug  3 04:05:06 2001 Foo Bar (foo@example.com)",
                                     "                                                  "),
@@ -1033,7 +1052,7 @@ fn test_notification_log() {
         });
 
     assert_eq!(NotificationLog::new(
-            t, "foo@example.com", "Foo Bar",
+            t, "foo@example.com", "Foo Bar", "123", None,
             NotificationType::Follow, None).render(80), vec! {
             ColouredString::general("Fri Aug  3 04:05:06 2001 Foo Bar (foo@example.com) followed you",
                                     "                                                               "),
@@ -1554,6 +1573,7 @@ pub struct StatusDisplay {
     content: Html,
     media: Vec<Media>,
     blank: BlankLine,
+    id: String,
 }
 
 impl StatusDisplay {
@@ -1569,12 +1589,14 @@ impl StatusDisplay {
             st.reblogged == Some(true));
 
         let from = UsernameHeader::from(
-            &client.fq(&st.account.acct), &st.account.display_name);
+            &client.fq(&st.account.acct), &st.account.display_name,
+            &st.account.id);
 
         let via = match via {
             None => None,
             Some(booster) => Some(UsernameHeader::via(
-                &client.fq(&booster.acct), &booster.display_name)),
+                &client.fq(&booster.acct), &booster.display_name,
+                &booster.id)),
         };
 
         let irt = match &st.in_reply_to_id {
@@ -1608,6 +1630,7 @@ impl StatusDisplay {
             content,
             media,
             blank: BlankLine::new(),
+            id: st.id.clone(),
         }
     }
 }
@@ -1649,7 +1672,9 @@ pub struct DetailedStatusDisplay {
     creation: Paragraph,
     lastedit: Paragraph,
     reply_to: Paragraph,
+    reply_to_id: Option<String>,
     reply_to_user: Paragraph,
+    reply_to_user_id: Option<String>,
     language: Paragraph,
     visibility: Paragraph,
     sensitive: Paragraph,
@@ -1658,7 +1683,7 @@ pub struct DetailedStatusDisplay {
     boosts: Paragraph,
     favourites: Paragraph,
     mentions_header: Option<Paragraph>,
-    mentions: Vec<Paragraph>,
+    mentions: Vec<(Paragraph, String)>,
     client_name: Paragraph,
     client_url: Paragraph,
     sep: SeparatorLine,
@@ -1688,11 +1713,13 @@ impl DetailedStatusDisplay {
             .add(&st.in_reply_to_id.as_ref().map_or_else(
                 || ColouredString::uniform("none", '0'),
                 |s| ColouredString::plain(s)));
+        let reply_to_id = st.in_reply_to_id.clone();
         let reply_to_user = Paragraph::new()
             .add(&ColouredString::plain("Reply to account: "))
             .add(&st.in_reply_to_account_id.as_ref().map_or_else(
                 || ColouredString::uniform("none", '0'),
                 |s| ColouredString::plain(s)));
+        let reply_to_user_id = st.in_reply_to_account_id.clone();
 
         let language = Paragraph::new()
             .add(&ColouredString::plain("Language: "))
@@ -1737,8 +1764,9 @@ impl DetailedStatusDisplay {
                 &format!("Favourites: {}", st.favourites_count)));
 
         let mentions: Vec<_> = st.mentions.iter().map(|m| {
-            Paragraph::new().set_indent(2, 2)
-                .add(&ColouredString::uniform(&client.fq(&m.acct), 'f'))
+            let para = Paragraph::new().set_indent(2, 2)
+                .add(&ColouredString::uniform(&client.fq(&m.acct), 'f'));
+            (para, m.id.to_owned())
         }).collect();
         let mentions_header = if mentions.is_empty() {
             None
@@ -1767,7 +1795,9 @@ impl DetailedStatusDisplay {
             creation,
             lastedit,
             reply_to,
+            reply_to_id,
             reply_to_user,
+            reply_to_user_id,
             language,
             visibility,
             sensitive,
@@ -1818,7 +1848,10 @@ impl TextFragment for DetailedStatusDisplay {
 
         if !self.mentions.is_empty() {
             push_fragment(&mut lines, self.mentions_header.render(width));
-            push_fragment(&mut lines, self.mentions.render(width));
+            for (para, _id) in &self.mentions {
+                let mut rendered = para.render(width);
+                push_fragment(&mut lines, rendered);
+            }
             push_fragment(&mut lines, self.blank.render(width));
         }