diff options
author | Joscha <joscha@plugh.de> | 2022-09-25 23:16:45 +0200 |
---|---|---|
committer | Joscha <joscha@plugh.de> | 2022-09-25 23:18:18 +0200 |
commit | 2d88513a283594187c2ce57827dc8d232a94794c (patch) | |
tree | fac2d918c24b1dfeb17d16da09c07abaa104201d | |
parent | bbf6371f87f16d8fb95c23b0103af853c8a8bc45 (diff) |
Add message inspection popup
-rw-r--r-- | CHANGELOG.md | 2 | ||||
-rw-r--r-- | src/ui/euph/inspect.rs | 74 | ||||
-rw-r--r-- | src/ui/euph/nick_list.rs | 14 | ||||
-rw-r--r-- | src/ui/euph/room.rs | 49 |
4 files changed, 92 insertions, 47 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f6df89..8b6005e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,8 +15,10 @@ Procedure when bumping the version number: ## Unreleased ### Added +- Key bindings to navigate nick list - Room deletion confirmation popup - Message inspection popup +- Session inspection popup - Error popup when external editor fails ### Fixed diff --git a/src/ui/euph/inspect.rs b/src/ui/euph/inspect.rs index 1327b6c..99a605f 100644 --- a/src/ui/euph/inspect.rs +++ b/src/ui/euph/inspect.rs @@ -1,5 +1,5 @@ use crossterm::style::{ContentStyle, Stylize}; -use euphoxide::api::Message; +use euphoxide::api::{Message, SessionView}; use toss::styled::Styled; use crate::ui::input::{key, InputEvent, KeyBindingsList}; @@ -38,42 +38,64 @@ macro_rules! line { }; } -pub fn message_widget(msg: &Message) -> BoxedWidget { - let heading_style = ContentStyle::default().bold(); - - let mut text = Styled::new("Message", heading_style).then_plain("\n"); - line!(text, "id", msg.id); - line!(text, "parent", msg.parent, optional); - line!(text, "previous_edit_id", msg.previous_edit_id, optional); - line!(text, "time", msg.time.0); - line!(text, "encryption_key_id", &msg.encryption_key_id, optional); - line!(text, "edited", msg.edited.map(|t| t.0), optional); - line!(text, "deleted", msg.deleted.map(|t| t.0), optional); - line!(text, "truncated", msg.truncated, yes or no); - text = text.then_plain("\n"); - - text = text.then("Sender", heading_style).then_plain("\n"); - line!(text, "id", msg.sender.id); - line!(text, "name", msg.sender.name); - line!(text, "name (raw)", msg.sender.name, debug); - line!(text, "server_id", msg.sender.server_id); - line!(text, "server_era", msg.sender.server_era); - line!(text, "session_id", msg.sender.session_id); - line!(text, "is_staff", msg.sender.is_staff, yes or no); - line!(text, "is_manager", msg.sender.is_manager, yes or no); +fn session_lines(mut text: Styled, session: &SessionView) -> Styled { + line!(text, "id", session.id); + line!(text, "name", session.name); + line!(text, "name (raw)", session.name, debug); + line!(text, "server_id", session.server_id); + line!(text, "server_era", session.server_era); + line!(text, "session_id", session.session_id); + line!(text, "is_staff", session.is_staff, yes or no); + line!(text, "is_manager", session.is_manager, yes or no); line!( text, "client_address", - msg.sender.client_address.as_ref(), + session.client_address.as_ref(), optional ); line!( text, "real_client_address", - msg.sender.real_client_address.as_ref(), + session.real_client_address.as_ref(), optional ); + text +} + +fn message_lines(mut text: Styled, msg: &Message) -> Styled { + line!(text, "id", msg.id); + line!(text, "parent", msg.parent, optional); + line!(text, "previous_edit_id", msg.previous_edit_id, optional); + line!(text, "time", msg.time.0); + line!(text, "encryption_key_id", &msg.encryption_key_id, optional); + line!(text, "edited", msg.edited.map(|t| t.0), optional); + line!(text, "deleted", msg.deleted.map(|t| t.0), optional); + line!(text, "truncated", msg.truncated, yes or no); + + text +} + +pub fn session_widget(session: &SessionView) -> BoxedWidget { + let text = session_lines(Styled::default(), session); + + Popup::new(Text::new(text)).title("Inspect session").build() +} + +pub fn message_widget(msg: &Message) -> BoxedWidget { + let heading_style = ContentStyle::default().bold(); + + let mut text = Styled::new("Message", heading_style).then_plain("\n"); + + text = message_lines(text, msg); + + text = text + .then_plain("\n") + .then("Sender", heading_style) + .then_plain("\n"); + + text = session_lines(text, &msg.sender); + Popup::new(Text::new(text)).title("Inspect message").build() } diff --git a/src/ui/euph/nick_list.rs b/src/ui/euph/nick_list.rs index bdc200c..2b00c59 100644 --- a/src/ui/euph/nick_list.rs +++ b/src/ui/euph/nick_list.rs @@ -1,7 +1,7 @@ use std::iter; use crossterm::style::{Color, ContentStyle, Stylize}; -use euphoxide::api::{SessionType, SessionView}; +use euphoxide::api::{SessionType, SessionView, UserId}; use euphoxide::conn::Joined; use toss::styled::Styled; @@ -12,13 +12,13 @@ use crate::ui::widgets::list::{List, ListState}; use crate::ui::widgets::text::Text; use crate::ui::widgets::BoxedWidget; -pub fn widget(state: &ListState<String>, joined: &Joined, focused: bool) -> BoxedWidget { +pub fn widget(state: &ListState<UserId>, joined: &Joined, focused: bool) -> BoxedWidget { let mut list = state.widget().focus(focused); render_rows(&mut list, joined); list.into() } -fn render_rows(list: &mut List<String>, joined: &Joined) { +fn render_rows(list: &mut List<UserId>, joined: &Joined) { let mut people = vec![]; let mut bots = vec![]; let mut lurkers = vec![]; @@ -49,7 +49,7 @@ fn render_rows(list: &mut List<String>, joined: &Joined) { } fn render_section( - list: &mut List<String>, + list: &mut List<UserId>, name: &str, sessions: &[&SessionView], own_session: &SessionView, @@ -74,9 +74,7 @@ fn render_section( } } -fn render_row(list: &mut List<String>, session: &SessionView, own_session: &SessionView) { - let id = session.session_id.clone(); - +fn render_row(list: &mut List<UserId>, session: &SessionView, own_session: &SessionView) { let (name, style, style_inv, perms_style_inv) = if session.name.is_empty() { let name = "lurk"; let style = ContentStyle::default().grey(); @@ -113,7 +111,7 @@ fn render_row(list: &mut List<String>, session: &SessionView, own_session: &Sess .then(name, style_inv) .then(perms, perms_style_inv); list.add_sel( - id, + session.id.clone(), Text::new(normal), Background::new(Text::new(selected)).style(style_inv), ); diff --git a/src/ui/euph/room.rs b/src/ui/euph/room.rs index 671a8a7..467f68d 100644 --- a/src/ui/euph/room.rs +++ b/src/ui/euph/room.rs @@ -2,7 +2,7 @@ use std::collections::VecDeque; use std::sync::Arc; use crossterm::style::{ContentStyle, Stylize}; -use euphoxide::api::{Data, Message, PacketType, Snowflake}; +use euphoxide::api::{Data, Message, PacketType, SessionView, Snowflake, UserId}; use euphoxide::conn::{Joined, Joining, Status}; use parking_lot::FairMutex; use tokio::sync::oneshot::error::TryRecvError; @@ -45,7 +45,7 @@ enum State { Account(AccountUiState), Links(LinksState), InspectMessage(Message), - // TODO Inspect users + InspectSession(SessionView), } #[allow(clippy::large_enum_variant)] @@ -80,7 +80,7 @@ pub struct EuphRoom { chat: ChatState<euph::SmallMessage, EuphRoomVault>, last_msg_sent: Option<oneshot::Receiver<Snowflake>>, - nick_list: ListState<String>, + nick_list: ListState<UserId>, } impl EuphRoom { @@ -243,6 +243,7 @@ impl EuphRoom { State::Account(account) => layers.push(account.widget()), State::Links(links) => layers.push(links.widget()), State::InspectMessage(message) => layers.push(inspect::message_widget(message)), + State::InspectSession(session) => layers.push(inspect::session_widget(session)), } for popup in &self.popups { @@ -483,14 +484,32 @@ impl EuphRoom { fn list_nick_list_focus_key_bindings(&self, bindings: &mut KeyBindingsList) { util::list_list_key_bindings(bindings); + + bindings.binding("i", "inspect session"); } - fn handle_nick_list_focus_input_event(&mut self, event: &InputEvent) -> bool { + fn handle_nick_list_focus_input_event( + &mut self, + event: &InputEvent, + status: &RoomStatus, + ) -> bool { if util::handle_list_input_event(&mut self.nick_list, event) { return true; } - // TODO Inspect users + if let key!('i') = event { + if let RoomStatus::Connected(Status::Joined(joined)) = status { + // TODO Fix euphoxide to use session_id as hash + if let Some(id) = self.nick_list.cursor() { + if id == joined.session.id { + self.state = State::InspectSession(joined.session.clone()); + } else if let Some(session) = joined.listing.get(&id) { + self.state = State::InspectSession(session.clone()); + } + } + } + return true; + } false } @@ -550,7 +569,7 @@ impl EuphRoom { return true; } - if self.handle_nick_list_focus_input_event(event) { + if self.handle_nick_list_focus_input_event(event, &status) { return true; } } @@ -573,7 +592,9 @@ impl EuphRoom { State::Nick(_) => nick::list_key_bindings(bindings), State::Account(account) => account.list_key_bindings(bindings), State::Links(links) => links.list_key_bindings(bindings), - State::InspectMessage(_) => inspect::list_key_bindings(bindings), + State::InspectMessage(_) | State::InspectSession(_) => { + inspect::list_key_bindings(bindings) + } } } @@ -643,13 +664,15 @@ impl EuphRoom { true } }, - State::InspectMessage(_) => match inspect::handle_input_event(event) { - inspect::EventResult::NotHandled => false, - inspect::EventResult::Close => { - self.state = State::Normal; - true + State::InspectMessage(_) | State::InspectSession(_) => { + match inspect::handle_input_event(event) { + inspect::EventResult::NotHandled => false, + inspect::EventResult::Close => { + self.state = State::Normal; + true + } } - }, + } } } |