summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoscha <joscha@plugh.de>2022-09-25 23:16:45 +0200
committerJoscha <joscha@plugh.de>2022-09-25 23:18:18 +0200
commit2d88513a283594187c2ce57827dc8d232a94794c (patch)
treefac2d918c24b1dfeb17d16da09c07abaa104201d
parentbbf6371f87f16d8fb95c23b0103af853c8a8bc45 (diff)
Add message inspection popup
-rw-r--r--CHANGELOG.md2
-rw-r--r--src/ui/euph/inspect.rs74
-rw-r--r--src/ui/euph/nick_list.rs14
-rw-r--r--src/ui/euph/room.rs49
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
+ }
}
- },
+ }
}
}