From 90ab13136406ae359d1da6d15267d47cca9f6c50 Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Mon, 1 Jan 2024 11:36:50 +0000 Subject: [PATCH] Filled in most of the Examine User data. The missing part is Relationships, because those are a separate server-side data structure. --- src/text.rs | 128 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 124 insertions(+), 4 deletions(-) diff --git a/src/text.rs b/src/text.rs index d5ca242..4cfcb81 100644 --- a/src/text.rs +++ b/src/text.rs @@ -66,6 +66,10 @@ impl SeparatorLine { } } +fn format_date(date: DateTime) -> String { + date.with_timezone(&Local).format("%a %b %e %H:%M:%S %Y").to_string() +} + impl TextFragment for SeparatorLine { fn render(&self, width: usize) -> Vec { let mut suffix = ColouredString::plain(""); @@ -73,8 +77,7 @@ impl TextFragment for SeparatorLine { let display_post = ColouredString::uniform("]--", 'S'); match self.timestamp { Some(date) => { - let datestr = date.with_timezone(&Local) - .format("%a %b %e %H:%M:%S %Y").to_string(); + let datestr = format_date(date); suffix = &display_pre + ColouredString::uniform(&datestr, 'D') + &display_post + suffix; @@ -570,6 +573,16 @@ impl Html { para } + + pub fn render_indented(&self, width: usize, indent: usize) -> + Vec + { + let prefix = ColouredString::plain(" ").repeat(indent); + self.render(width.saturating_sub(indent)) + .into_iter() + .map(|line| &prefix + line) + .collect() + } } impl TextFragment for Html { @@ -819,8 +832,7 @@ impl NotificationLog { 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(); + let datestr = format_date(self.timestamp); full_para.push_text(&ColouredString::uniform(&datestr, ' '), false); // FIXME: highlight account_desc if active full_para.push_text( @@ -1468,6 +1480,19 @@ impl TextFragment for StatusDisplay { pub struct ExamineUserDisplay { name: Paragraph, + webaccount: Paragraph, + dispname: Paragraph, + bio_header: Paragraph, + bio: Html, + info_header: Paragraph, + info_fields: Vec<(Paragraph, Html)>, + id: Paragraph, + creation: Paragraph, + last_post: Paragraph, + post_count: Paragraph, + followers_count: Paragraph, + following_count: Paragraph, + blank: BlankLine, } impl ExamineUserDisplay { @@ -1475,11 +1500,78 @@ impl ExamineUserDisplay { let name = Paragraph::new() .add(&ColouredString::plain("Account name: ")) .add(&ColouredString::uniform(&client.fq(&ac.acct), 'f')); + let webaccount = Paragraph::new() + .add(&ColouredString::plain("On the web: ")) + .add(&ColouredString::uniform(&client.fq(&ac.url), 'u')); + + let dispname = Paragraph::new() + .add(&ColouredString::plain("Display name: ")) + .add(&ColouredString::plain(&ac.display_name)); + let bio_header = Paragraph::new() + .add(&ColouredString::plain("Bio:")); + let bio = Html::new(&ac.note); + + let info_header = Paragraph::new() + .add(&ColouredString::plain("Information:")); + let info_fields = ac.fields.iter().map(|field| { + let colour = if field.verified_at.is_some() { 'f' } else { ' ' }; + let title_text = field.name.trim(); + let title_text = title_text.strip_suffix(":").unwrap_or(title_text); + let title_text = title_text.to_owned() + ":"; + let title = Paragraph::new() + .add(&ColouredString::uniform(&title_text, colour)) + .set_indent(2, 2); + let content = Html::new(&field.value); + (title, content) + }).collect(); + + let id = Paragraph::new() + .add(&ColouredString::plain("Account id: ")) + .add(&ColouredString::plain(&ac.id)); + let creation = Paragraph::new() + .add(&ColouredString::plain("Account created: ")) + .add(&Self::format_option_approx_date(Some(ac.created_at))); + let last_post = Paragraph::new() + .add(&ColouredString::plain("Latest post: ")) + .add(&Self::format_option_approx_date(ac.last_status_at)); + let post_count = Paragraph::new() + .add(&ColouredString::plain( + &format!("Number of posts: {}", ac.statuses_count))); + let followers_count = Paragraph::new() + .add(&ColouredString::plain( + &format!("Number of followers: {}", ac.followers_count))); + let following_count = Paragraph::new() + .add(&ColouredString::plain( + &format!("Number of users followed: {}", ac.following_count))); Ok(ExamineUserDisplay { name, + webaccount, + dispname, + bio_header, + bio, + info_header, + info_fields, + id, + creation, + last_post, + post_count, + followers_count, + following_count, + blank: BlankLine::new(), }) } + + fn format_option_approx_date(date: Option) -> ColouredString + { + // Used for account creation dates and last-post times, which + // don't seem to bother having precise timestamps + match date { + None => ColouredString::uniform("none", '0'), + Some(ApproxDate(date)) => ColouredString::plain( + &date.format("%a %b %e %Y").to_string()), + } + } } impl TextFragment for ExamineUserDisplay { @@ -1487,6 +1579,34 @@ impl TextFragment for ExamineUserDisplay { let mut lines = Vec::new(); push_fragment(&mut lines, self.name.render(width)); + push_fragment(&mut lines, self.webaccount.render(width)); + push_fragment(&mut lines, self.blank.render(width)); + + push_fragment(&mut lines, self.dispname.render(width)); + push_fragment(&mut lines, self.bio_header.render(width)); + push_fragment(&mut lines, self.bio.render_indented(width, 2)); + push_fragment(&mut lines, self.blank.render(width)); + + if !self.info_fields.is_empty() { + push_fragment(&mut lines, self.info_header.render(width)); + for (key, value) in &self.info_fields { + push_fragment(&mut lines, key.render(width)); + push_fragment(&mut lines, value.render_indented(width, 4)); + } + push_fragment(&mut lines, self.blank.render(width)); + } + + // FIXME: relationships list + + push_fragment(&mut lines, self.id.render(width)); + push_fragment(&mut lines, self.creation.render(width)); + push_fragment(&mut lines, self.last_post.render(width)); + push_fragment(&mut lines, self.post_count.render(width)); + push_fragment(&mut lines, self.blank.render(width)); + + push_fragment(&mut lines, self.followers_count.render(width)); + push_fragment(&mut lines, self.following_count.render(width)); + push_fragment(&mut lines, self.blank.render(width)); lines } -- 2.30.2