diff --git a/Cargo.lock b/Cargo.lock index d922d5730..1679a44e1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3399,6 +3399,7 @@ dependencies = [ "crossterm", "futures-util", "imbl", + "itertools 0.14.0", "matrix-sdk", "matrix-sdk-base", "matrix-sdk-common", diff --git a/labs/multiverse/Cargo.toml b/labs/multiverse/Cargo.toml index 24e0f944c..7c9f34580 100644 --- a/labs/multiverse/Cargo.toml +++ b/labs/multiverse/Cargo.toml @@ -15,6 +15,7 @@ clap = { version = "4.0.15", features = ["derive", "env"] } crossterm = "0.28.1" futures-util = { workspace = true } imbl = { workspace = true } +itertools = { workspace = true } matrix-sdk = { path = "../../crates/matrix-sdk", features = ["sso-login"] } matrix-sdk-base = { path = "../../crates/matrix-sdk-base" } matrix-sdk-common = { path = "../../crates/matrix-sdk-common" } diff --git a/labs/multiverse/src/events.rs b/labs/multiverse/src/events.rs new file mode 100644 index 000000000..9cb5093b2 --- /dev/null +++ b/labs/multiverse/src/events.rs @@ -0,0 +1,65 @@ +use itertools::Itertools; +use matrix_sdk_ui::room_list_service::Room; +use ratatui::{ + prelude::*, + widgets::{Block, Clear, Paragraph, Wrap}, +}; +use tokio::runtime::Handle; + +use crate::{popup_area, TEXT_COLOR}; + +pub struct EventsView<'a> { + room: Option<&'a Room>, +} + +impl<'a> EventsView<'a> { + pub fn new(room: Option<&'a Room>) -> Self { + Self { room } + } +} + +impl Widget for &mut EventsView<'_> { + fn render(self, area: Rect, buf: &mut Buffer) + where + Self: Sized, + { + let block = Block::bordered().title("Events"); + let area = popup_area(area, 80, 80); + Clear.render(area, buf); + + match self.room { + Some(room) => { + let events = tokio::task::block_in_place(|| { + Handle::current().block_on(async { + let (room_event_cache, _drop_handles) = room.event_cache().await.unwrap(); + let (events, _) = room_event_cache.subscribe().await; + events + }) + }); + + let separator = Line::from("\n"); + let events = events + .into_iter() + .map(|sync_timeline_item| sync_timeline_item.raw().json().to_string()) + .map(|item| Line::from(item)); + + let events = Itertools::intersperse(events, separator); + let lines: Vec<_> = [Line::from("")].into_iter().chain(events).collect(); + + Paragraph::new(lines) + .block(block.clone()) + .fg(TEXT_COLOR) + .wrap(Wrap { trim: false }) + .render(area, buf); + } + + None => { + Paragraph::new("(room disappeared in the room list service)") + .block(block.clone()) + .fg(TEXT_COLOR) + .wrap(Wrap { trim: false }) + .render(area, buf); + } + } + } +} diff --git a/labs/multiverse/src/main.rs b/labs/multiverse/src/main.rs index 8073fbca7..3680894a6 100644 --- a/labs/multiverse/src/main.rs +++ b/labs/multiverse/src/main.rs @@ -9,6 +9,7 @@ use std::{ use clap::Parser; use color_eyre::Result; use crossterm::event::{self, Event, KeyCode, KeyEventKind}; +use events::EventsView; use futures_util::{pin_mut, StreamExt as _}; use imbl::Vector; use layout::Flex; @@ -41,6 +42,7 @@ use tokio::{runtime::Handle, spawn, task::JoinHandle}; use tracing::{error, warn}; use tracing_subscriber::EnvFilter; +mod events; mod linked_chunk; mod read_receipts; mod room_list; @@ -516,6 +518,7 @@ impl App { .bg(HEADER_BG) .title("Room view") .title_alignment(Alignment::Center); + let inner_block = Block::default() .borders(Borders::NONE) .bg(NORMAL_ROW_COLOR) @@ -563,35 +566,16 @@ impl App { let room = rooms.get(&room_id); let mut linked_chunk_view = LinkedChunkView::new(room); - linked_chunk_view.render(inner_area, buf); } - DetailsMode::Events => match self.ui_rooms.lock().get(&room_id).cloned() { - Some(room) => { - let events = tokio::task::block_in_place(|| { - Handle::current().block_on(async { - let (room_event_cache, _drop_handles) = - room.event_cache().await.unwrap(); - let (events, _) = room_event_cache.subscribe().await; - events - }) - }); + DetailsMode::Events => { + let rooms = self.ui_rooms.lock(); + let room = rooms.get(&room_id); - let rendered_events = events - .into_iter() - .map(|sync_timeline_item| sync_timeline_item.raw().json().to_string()) - .collect::>() - .join("\n\n"); - - render_paragraph(buf, format!("Events:\n\n{rendered_events}")) - } - - None => render_paragraph( - buf, - "(room disappeared in the room list service)".to_owned(), - ), - }, + let mut events_view = EventsView::new(room); + events_view.render(inner_area, buf); + } } } else { render_paragraph(buf, "Nothing to see here...".to_owned())