multiverse/widgets/room_view/details/
read_receipts.rs1use matrix_sdk::Room;
2use matrix_sdk_base::read_receipts::RoomReadReceipts;
3use matrix_sdk_ui::timeline::TimelineItem;
4use ratatui::{
5 prelude::*,
6 widgets::{Block, Borders, Paragraph, Wrap},
7};
8
9use crate::{TEXT_COLOR, widgets::room_view::DetailsState};
10
11pub struct ReadReceipts<'a> {
12 state: &'a DetailsState<'a>,
13}
14
15impl<'a> ReadReceipts<'a> {
16 pub(super) fn new(state: &'a DetailsState<'a>) -> Self {
17 Self { state }
18 }
19}
20
21fn render_room_stats(room: &Room, area: Rect, buf: &mut Buffer) {
22 let RoomReadReceipts { num_unread, num_notifications, num_mentions, .. } = room.read_receipts();
23
24 let content = vec![
25 Line::from(format!("- unread: {num_unread}")),
26 Line::from(format!("- notifications: {num_notifications}")),
27 Line::from(format!("- mentions: {num_mentions}")),
28 Line::from(""),
29 Line::from("---"),
30 Line::from(format!("{:?}", room.read_receipts())),
31 Line::from("#"),
32 ];
33
34 Paragraph::new(content)
35 .fg(TEXT_COLOR)
36 .wrap(Wrap { trim: false })
37 .block(Block::new().borders(Borders::BOTTOM))
38 .render(area, buf);
39}
40
41impl Widget for &mut ReadReceipts<'_> {
42 fn render(self, area: Rect, buf: &mut Buffer)
43 where
44 Self: Sized,
45 {
46 if let Some(room) = self.state.selected_room {
47 match self.state.selected_item.as_deref() {
48 Some(selected_event) => {
49 if let Some(item) = format_timeline_item(selected_event) {
50 Paragraph::new(item)
51 .fg(TEXT_COLOR)
52 .wrap(Wrap { trim: false })
53 .block(Block::new().borders(Borders::BOTTOM))
54 .render(area, buf);
55 } else {
56 render_room_stats(room, area, buf);
57 }
58 }
59 None => render_room_stats(room, area, buf),
60 }
61 } else {
62 let content = "(room disappeared in the room list service)";
63 Paragraph::new(content).fg(TEXT_COLOR).wrap(Wrap { trim: false }).render(area, buf);
64 }
65 }
66}
67
68fn format_timeline_item(item: &TimelineItem) -> Option<Vec<Line<'_>>> {
69 let event = item.as_event()?;
70 let receipts = event.read_receipts();
71 let sender = event.sender();
72 let event_id = event.event_id();
73
74 let first_line = Line::from(format!("{sender} - {event_id:?}"));
75 let second_line = Line::from(format!("{receipts:?}"));
76
77 Some(vec![first_line, second_line])
78}