From 5c17ff406db3841c484a960de357ec12351a3ecd Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Thu, 4 Jan 2024 07:36:52 +0000 Subject: [PATCH] Store ids in all the TextFragments that will need them. 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 | 65 ++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 49 insertions(+), 16 deletions(-) diff --git a/src/text.rs b/src/text.rs index 74fca60..1f53100 100644 --- a/src/text.rs +++ b/src/text.rs @@ -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, account_desc: String, + account_id: String, + status_id: Option, para: Paragraph, } impl NotificationLog { pub fn new( timestamp: DateTime, 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 ¬.status { + None => None, + Some(st) => Some(&st.id as &str), + }; Self::new( not.created_at, &client.fq(¬.account.acct), ¬.account.display_name, + ¬.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, 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, reply_to_user: Paragraph, + reply_to_user_id: Option, language: Paragraph, visibility: Paragraph, sensitive: Paragraph, @@ -1658,7 +1683,7 @@ pub struct DetailedStatusDisplay { boosts: Paragraph, favourites: Paragraph, mentions_header: Option, - mentions: Vec, + 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)); } -- 2.30.2