Migrate nick list to AsyncWidget
This commit is contained in:
parent
d8d3e64776
commit
c7cbd9856b
2 changed files with 62 additions and 49 deletions
|
|
@ -4,19 +4,21 @@ use std::iter;
|
||||||
use crossterm::style::{Color, Stylize};
|
use crossterm::style::{Color, Stylize};
|
||||||
use euphoxide::api::{NickEvent, SessionId, SessionType, SessionView, UserId};
|
use euphoxide::api::{NickEvent, SessionId, SessionType, SessionView, UserId};
|
||||||
use euphoxide::conn::{Joined, SessionInfo};
|
use euphoxide::conn::{Joined, SessionInfo};
|
||||||
use toss::{Style, Styled};
|
use toss::widgets::{BoxedAsync, Empty, Text};
|
||||||
|
use toss::{Style, Styled, WidgetExt};
|
||||||
|
|
||||||
use crate::euph;
|
use crate::euph;
|
||||||
use crate::ui::widgets::background::Background;
|
use crate::ui::widgets2::{List, ListState};
|
||||||
use crate::ui::widgets::empty::Empty;
|
use crate::ui::UiError;
|
||||||
use crate::ui::widgets::list::{List, ListState};
|
|
||||||
use crate::ui::widgets::text::Text;
|
|
||||||
use crate::ui::widgets::BoxedWidget;
|
|
||||||
|
|
||||||
pub fn widget(state: &ListState<SessionId>, joined: &Joined, focused: bool) -> BoxedWidget {
|
pub fn widget<'a>(
|
||||||
let mut list = state.widget().focus(focused);
|
list: &'a mut ListState<SessionId>,
|
||||||
render_rows(&mut list, joined);
|
joined: &Joined,
|
||||||
list.into()
|
focused: bool,
|
||||||
|
) -> BoxedAsync<'a, UiError> {
|
||||||
|
let mut list = list.widget();
|
||||||
|
render_rows(&mut list, joined, focused);
|
||||||
|
list.boxed_async()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
|
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
|
|
@ -57,7 +59,11 @@ impl HalfSession {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_rows(list: &mut List<SessionId>, joined: &Joined) {
|
fn render_rows(
|
||||||
|
list: &mut List<'_, SessionId, BoxedAsync<'static, UiError>>,
|
||||||
|
joined: &Joined,
|
||||||
|
focused: bool,
|
||||||
|
) {
|
||||||
let mut people = vec![];
|
let mut people = vec![];
|
||||||
let mut bots = vec![];
|
let mut bots = vec![];
|
||||||
let mut lurkers = vec![];
|
let mut lurkers = vec![];
|
||||||
|
|
@ -82,17 +88,18 @@ fn render_rows(list: &mut List<SessionId>, joined: &Joined) {
|
||||||
lurkers.sort_unstable();
|
lurkers.sort_unstable();
|
||||||
nurkers.sort_unstable();
|
nurkers.sort_unstable();
|
||||||
|
|
||||||
render_section(list, "People", &people, &joined.session);
|
render_section(list, "People", &people, &joined.session, focused);
|
||||||
render_section(list, "Bots", &bots, &joined.session);
|
render_section(list, "Bots", &bots, &joined.session, focused);
|
||||||
render_section(list, "Lurkers", &lurkers, &joined.session);
|
render_section(list, "Lurkers", &lurkers, &joined.session, focused);
|
||||||
render_section(list, "Nurkers", &nurkers, &joined.session);
|
render_section(list, "Nurkers", &nurkers, &joined.session, focused);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_section(
|
fn render_section(
|
||||||
list: &mut List<SessionId>,
|
list: &mut List<'_, SessionId, BoxedAsync<'static, UiError>>,
|
||||||
name: &str,
|
name: &str,
|
||||||
sessions: &[HalfSession],
|
sessions: &[HalfSession],
|
||||||
own_session: &SessionView,
|
own_session: &SessionView,
|
||||||
|
focused: bool,
|
||||||
) {
|
) {
|
||||||
if sessions.is_empty() {
|
if sessions.is_empty() {
|
||||||
return;
|
return;
|
||||||
|
|
@ -101,20 +108,25 @@ fn render_section(
|
||||||
let heading_style = Style::new().bold();
|
let heading_style = Style::new().bold();
|
||||||
|
|
||||||
if !list.is_empty() {
|
if !list.is_empty() {
|
||||||
list.add_unsel(Empty::new());
|
list.add_unsel(Empty::new().boxed_async());
|
||||||
}
|
}
|
||||||
|
|
||||||
let row = Styled::new_plain(" ")
|
let row = Styled::new_plain(" ")
|
||||||
.then(name, heading_style)
|
.then(name, heading_style)
|
||||||
.then_plain(format!(" ({})", sessions.len()));
|
.then_plain(format!(" ({})", sessions.len()));
|
||||||
list.add_unsel(Text::new(row));
|
list.add_unsel(Text::new(row).boxed_async());
|
||||||
|
|
||||||
for session in sessions {
|
for session in sessions {
|
||||||
render_row(list, session, own_session);
|
render_row(list, session, own_session, focused);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_row(list: &mut List<SessionId>, session: &HalfSession, own_session: &SessionView) {
|
fn render_row(
|
||||||
|
list: &mut List<'_, SessionId, BoxedAsync<'static, UiError>>,
|
||||||
|
session: &HalfSession,
|
||||||
|
own_session: &SessionView,
|
||||||
|
focused: bool,
|
||||||
|
) {
|
||||||
let (name, style, style_inv, perms_style_inv) = if session.name.is_empty() {
|
let (name, style, style_inv, perms_style_inv) = if session.name.is_empty() {
|
||||||
let name = "lurk";
|
let name = "lurk";
|
||||||
let style = Style::new().grey();
|
let style = Style::new().grey();
|
||||||
|
|
@ -146,15 +158,20 @@ fn render_row(list: &mut List<SessionId>, session: &HalfSession, own_session: &S
|
||||||
" "
|
" "
|
||||||
};
|
};
|
||||||
|
|
||||||
let normal = Styled::new_plain(owner)
|
let widget = if focused && list.state().selected() == Some(&session.session_id) {
|
||||||
.then(&name, style)
|
let text = Styled::new_plain(owner)
|
||||||
.then_plain(perms);
|
.then(name, style_inv)
|
||||||
let selected = Styled::new_plain(owner)
|
.then(perms, perms_style_inv);
|
||||||
.then(name, style_inv)
|
Text::new(text)
|
||||||
.then(perms, perms_style_inv);
|
.background()
|
||||||
list.add_sel(
|
.with_style(style_inv)
|
||||||
session.session_id.clone(),
|
.boxed_async()
|
||||||
Text::new(normal),
|
} else {
|
||||||
Background::new(Text::new(selected)).style(style_inv),
|
let text = Styled::new_plain(owner)
|
||||||
);
|
.then(&name, style)
|
||||||
|
.then_plain(perms);
|
||||||
|
Text::new(text).boxed_async()
|
||||||
|
};
|
||||||
|
|
||||||
|
list.add_sel(session.session_id.clone(), widget);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,9 +17,9 @@ use crate::macros::logging_unwrap;
|
||||||
use crate::ui::chat::{ChatState, Reaction};
|
use crate::ui::chat::{ChatState, Reaction};
|
||||||
use crate::ui::input::{key, InputEvent, KeyBindingsList};
|
use crate::ui::input::{key, InputEvent, KeyBindingsList};
|
||||||
use crate::ui::widgets::editor::EditorState as OldEditorState;
|
use crate::ui::widgets::editor::EditorState as OldEditorState;
|
||||||
use crate::ui::widgets::list::ListState as OldListState;
|
|
||||||
use crate::ui::widgets::WidgetWrapper;
|
use crate::ui::widgets::WidgetWrapper;
|
||||||
use crate::ui::{util, UiError, UiEvent};
|
use crate::ui::widgets2::ListState;
|
||||||
|
use crate::ui::{util2, UiError, UiEvent};
|
||||||
use crate::vault::EuphRoomVault;
|
use crate::vault::EuphRoomVault;
|
||||||
|
|
||||||
use super::account::{self, AccountUiState};
|
use super::account::{self, AccountUiState};
|
||||||
|
|
@ -60,7 +60,7 @@ pub struct EuphRoom {
|
||||||
chat: EuphChatState,
|
chat: EuphChatState,
|
||||||
last_msg_sent: Option<oneshot::Receiver<MessageId>>,
|
last_msg_sent: Option<oneshot::Receiver<MessageId>>,
|
||||||
|
|
||||||
nick_list: OldListState<SessionId>,
|
nick_list: ListState<SessionId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EuphRoom {
|
impl EuphRoom {
|
||||||
|
|
@ -80,7 +80,7 @@ impl EuphRoom {
|
||||||
popups: VecDeque::new(),
|
popups: VecDeque::new(),
|
||||||
chat: ChatState::new(vault),
|
chat: ChatState::new(vault),
|
||||||
last_msg_sent: None,
|
last_msg_sent: None,
|
||||||
nick_list: OldListState::new(),
|
nick_list: ListState::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -266,18 +266,14 @@ impl EuphRoom {
|
||||||
fn widget_with_nick_list<'a>(
|
fn widget_with_nick_list<'a>(
|
||||||
chat: &'a mut EuphChatState,
|
chat: &'a mut EuphChatState,
|
||||||
status_widget: impl AsyncWidget<UiError> + Send + Sync + 'static,
|
status_widget: impl AsyncWidget<UiError> + Send + Sync + 'static,
|
||||||
nick_list: &mut OldListState<SessionId>,
|
nick_list: &'a mut ListState<SessionId>,
|
||||||
joined: &Joined,
|
joined: &Joined,
|
||||||
focus: Focus,
|
focus: Focus,
|
||||||
) -> BoxedAsync<'a, UiError> {
|
) -> BoxedAsync<'a, UiError> {
|
||||||
let nick_list_widget = WidgetWrapper::new(nick_list::widget(
|
let nick_list_widget = nick_list::widget(nick_list, joined, focus == Focus::NickList)
|
||||||
nick_list,
|
.padding()
|
||||||
joined,
|
.with_right(1)
|
||||||
focus == Focus::NickList,
|
.border();
|
||||||
))
|
|
||||||
.padding()
|
|
||||||
.with_right(1)
|
|
||||||
.border();
|
|
||||||
|
|
||||||
let chat_widget =
|
let chat_widget =
|
||||||
WidgetWrapper::new(chat.widget(joined.session.name.clone(), focus == Focus::Chat));
|
WidgetWrapper::new(chat.widget(joined.session.name.clone(), focus == Focus::Chat));
|
||||||
|
|
@ -512,24 +508,24 @@ impl EuphRoom {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn list_nick_list_focus_key_bindings(&self, bindings: &mut KeyBindingsList) {
|
fn list_nick_list_focus_key_bindings(&self, bindings: &mut KeyBindingsList) {
|
||||||
util::list_list_key_bindings(bindings);
|
util2::list_list_key_bindings(bindings);
|
||||||
|
|
||||||
bindings.binding("i", "inspect session");
|
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) -> bool {
|
||||||
if util::handle_list_input_event(&mut self.nick_list, event) {
|
if util2::handle_list_input_event(&mut self.nick_list, event) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let key!('i') = event {
|
if let key!('i') = event {
|
||||||
if let Some(euph::State::Connected(_, conn::State::Joined(joined))) = self.room_state()
|
if let Some(euph::State::Connected(_, conn::State::Joined(joined))) = self.room_state()
|
||||||
{
|
{
|
||||||
if let Some(id) = self.nick_list.cursor() {
|
if let Some(id) = self.nick_list.selected() {
|
||||||
if id == joined.session.session_id {
|
if *id == joined.session.session_id {
|
||||||
self.state =
|
self.state =
|
||||||
State::InspectSession(SessionInfo::Full(joined.session.clone()));
|
State::InspectSession(SessionInfo::Full(joined.session.clone()));
|
||||||
} else if let Some(session) = joined.listing.get(&id) {
|
} else if let Some(session) = joined.listing.get(id) {
|
||||||
self.state = State::InspectSession(session.clone());
|
self.state = State::InspectSession(session.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue