From 9bee6f8de32c86d00f25f473952c36b691109be8 Mon Sep 17 00:00:00 2001 From: Phil Kulak Date: Mon, 8 May 2023 23:28:18 -0700 Subject: [PATCH] Some formatting changes. --- src/lib.rs | 29 +++++++++++++++++++++++++++-- src/matrix/username.rs | 5 ++--- src/widgets/chat.rs | 23 ++++++++++++++++++----- src/widgets/message.rs | 42 +++++++++++++++++------------------------- 4 files changed, 64 insertions(+), 35 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 9a4b456..95f9f12 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -26,10 +26,35 @@ pub mod settings; /// Using external apps to do our bidding pub mod spawn; -pub fn pretty_list(names: Vec<&str>) -> String { +pub fn limit_list(iter: T, limit: usize, total: usize, prefix: Option<&str>) -> Vec +where + T: Iterator, +{ + let mut vec: Vec = iter.take(limit).collect(); + + if vec.len() >= total { + return vec; + } + + let prefix = if let Some(p) = prefix { + format!("{} ", p) + } else { + "".to_string() + }; + + if total - vec.len() == 1 { + vec.push(format!("{}1 other", prefix)) + } else { + vec.push(format!("{}{} others", prefix, total - vec.len())) + } + + vec +} + +pub fn pretty_list(names: Vec) -> String { match names.len() { 0 => "".to_string(), - 1 => names.first().unwrap().to_string(), + 1 => names.into_iter().next().unwrap(), _ => format!( "{} and {}", names[0..names.len() - 1].join(", "), diff --git a/src/matrix/username.rs b/src/matrix/username.rs index fb767c4..9400dcf 100644 --- a/src/matrix/username.rs +++ b/src/matrix/username.rs @@ -1,5 +1,4 @@ use core::fmt; -use std::fmt::Debug; use matrix_sdk::room::RoomMember; use ruma::OwnedUserId; @@ -42,8 +41,8 @@ impl Username { impl fmt::Display for Username { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - if self.display_name.is_some() { - self.display_name.fmt(f) + if let Some(dn) = &self.display_name { + fmt::Display::fmt(&dn, f) } else { fmt::Display::fmt(&self.id, f) } diff --git a/src/widgets/chat.rs b/src/widgets/chat.rs index f40b1a1..f7c9525 100644 --- a/src/widgets/chat.rs +++ b/src/widgets/chat.rs @@ -10,7 +10,7 @@ use crate::widgets::react::React; use crate::widgets::react::ReactResult; use crate::widgets::EventResult::Consumed; use crate::widgets::{get_margin, EventResult}; -use crate::{consumed, pretty_list, truncate, KeyCombo}; +use crate::{consumed, limit_list, pretty_list, truncate, KeyCombo}; use anyhow::bail; use crossterm::event::{KeyCode, KeyEvent}; use log::info; @@ -353,11 +353,10 @@ impl Chat { return; } - let typing: Vec<&str> = self + let typing: Vec<&RoomMember> = self .members .iter() .filter(|m| ids.iter().any(|id| m.user_id() == id)) - .filter_map(|m| m.display_name()) .collect(); if typing.is_empty() { @@ -371,7 +370,18 @@ impl Chat { " is typing." }; - self.typing = Some(format!("{}{}", pretty_list(typing), suffix)); + let total = typing.len(); + + let iter = typing + .into_iter() + .map(|m| m.display_name().unwrap_or(m.user_id().as_str())) + .map(|n| n.to_string()); + + self.typing = Some(format!( + "{}{}", + pretty_list(limit_list(iter, 3, total, None)), + suffix + )); } pub fn receipt_event(&mut self, joined: &Joined, content: &ReceiptEventContent) { @@ -502,7 +512,10 @@ impl Chat { names.sort(); names.dedup(); - pretty_list(names.into_iter().take(10).collect()) + let total = names.len(); + let iter = names.into_iter().map(|n| n.to_string()); + + pretty_list(limit_list(iter, 5, total, Some("at least"))) }) } diff --git a/src/widgets/message.rs b/src/widgets/message.rs index 438fe85..a802d77 100644 --- a/src/widgets/message.rs +++ b/src/widgets/message.rs @@ -1,13 +1,12 @@ use chrono::TimeZone; use std::cell::Cell; use std::collections::BinaryHeap; -use std::iter; use std::time::{Duration, SystemTime}; use crate::matrix::matrix::{pad_emoji, Matrix}; use crate::matrix::username::Username; -use crate::pretty_list; use crate::spawn::view_text; +use crate::{limit_list, pretty_list}; use chrono::offset::Local; use matrix_sdk::room::RoomMember; use once_cell::unsync::OnceCell; @@ -502,18 +501,14 @@ impl Message { let iter = self .receipts .iter() - .map(Username::as_str) - .map(|n| n.split_whitespace().next().unwrap()); - - // but only show the first 4 - let receipts: Vec<&str> = if self.receipts.len() > 4 { - iter.take(4).chain(iter::once("others")).collect() - } else { - iter.collect() - }; + .map(Username::to_string) + .map(|n| n.split_whitespace().next().unwrap().to_string()); lines.push(vec![Span::styled( - format!("Seen by {}.", pretty_list(receipts)), + format!( + "Seen by {}.", + pretty_list(limit_list(iter, 4, self.receipts.len(), None)) + ), Style::default().fg(Color::DarkGray), )]) } @@ -583,19 +578,16 @@ impl Reaction { } pub fn pretty_senders(&self) -> String { - let all: Vec<&str> = self - .events - .iter() - .map(|s| { - s.sender - .as_str() - .split_whitespace() - .next() - .unwrap_or_default() - }) - .collect(); - - pretty_list(all) + let iter = self.events.iter().map(|s| { + s.sender + .as_str() + .split_whitespace() + .next() + .unwrap_or_default() + .to_string() + }); + + pretty_list(limit_list(iter, 5, self.events.len(), None)) } // cached to keep allocations out of the render loop