Update toss and remove more async
This commit is contained in:
parent
a638caadcb
commit
ade7be594e
16 changed files with 109 additions and 116 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
|
@ -1313,7 +1313,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "toss"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/Garmelon/toss.git?rev=57788a9dd9688bdf3e59bf7366ba6276fc660715#57788a9dd9688bdf3e59bf7366ba6276fc660715"
|
||||
source = "git+https://github.com/Garmelon/toss.git?rev=f414db40d526295c74cbcae6c3d194088da8f1d9#f414db40d526295c74cbcae6c3d194088da8f1d9"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"crossterm",
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ features = ["bot"]
|
|||
|
||||
[dependencies.toss]
|
||||
git = "https://github.com/Garmelon/toss.git"
|
||||
rev = "57788a9dd9688bdf3e59bf7366ba6276fc660715"
|
||||
rev = "f414db40d526295c74cbcae6c3d194088da8f1d9"
|
||||
|
||||
# [patch."https://github.com/Garmelon/toss.git"]
|
||||
# toss = { path = "../toss/" }
|
||||
|
|
|
|||
|
|
@ -209,6 +209,7 @@ impl Ui {
|
|||
|
||||
key_bindings_list
|
||||
.widget(list_state)
|
||||
.desync()
|
||||
.above(widget)
|
||||
.boxed_async()
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ use std::sync::Arc;
|
|||
use async_trait::async_trait;
|
||||
use parking_lot::FairMutex;
|
||||
use toss::widgets::EditorState;
|
||||
use toss::{AsyncWidget, Frame, Pos, Size, Terminal, WidthDb};
|
||||
use toss::{AsyncWidget, Frame, Pos, Size, Terminal, WidgetExt, WidthDb};
|
||||
|
||||
use crate::store::{Msg, MsgStore};
|
||||
use crate::ui::input::{key, InputEvent, KeyBindingsList};
|
||||
|
|
@ -488,7 +488,7 @@ where
|
|||
for (range, block) in renderer.into_visible_blocks() {
|
||||
let widget = block.into_widget();
|
||||
frame.push(Pos::new(0, range.top), widget.size());
|
||||
widget.draw(frame).await.infallible();
|
||||
widget.desync().draw(frame).await.infallible();
|
||||
frame.pop();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
use crossterm::style::Stylize;
|
||||
use euphoxide::api::PersonalAccountView;
|
||||
use euphoxide::conn;
|
||||
use toss::widgets::{BoxedAsync, EditorState, Empty, Join3, Join4, Text};
|
||||
use toss::{Style, Terminal, WidgetExt};
|
||||
use toss::widgets::{EditorState, Empty, Join3, Join4, Text};
|
||||
use toss::{Style, Terminal, Widget, WidgetExt};
|
||||
|
||||
use crate::euph::{self, Room};
|
||||
use crate::ui::input::{key, InputEvent, KeyBindingsList};
|
||||
|
|
@ -30,7 +30,7 @@ impl LoggedOut {
|
|||
}
|
||||
}
|
||||
|
||||
fn widget(&mut self) -> BoxedAsync<'_, UiError> {
|
||||
fn widget(&mut self) -> impl Widget<UiError> + '_ {
|
||||
let bold = Style::new().bold();
|
||||
Join4::vertical(
|
||||
Text::new(("Not logged in", bold.yellow())).segment(),
|
||||
|
|
@ -57,14 +57,13 @@ impl LoggedOut {
|
|||
)
|
||||
.segment(),
|
||||
)
|
||||
.boxed_async()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct LoggedIn(PersonalAccountView);
|
||||
|
||||
impl LoggedIn {
|
||||
fn widget(&self) -> BoxedAsync<'_, UiError> {
|
||||
fn widget(&self) -> impl Widget<UiError> {
|
||||
let bold = Style::new().bold();
|
||||
Join3::vertical(
|
||||
Text::new(("Logged in", bold.green())).segment(),
|
||||
|
|
@ -78,7 +77,6 @@ impl LoggedIn {
|
|||
)
|
||||
.segment(),
|
||||
)
|
||||
.boxed_async()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -112,15 +110,15 @@ impl AccountUiState {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn widget(&mut self) -> BoxedAsync<'_, UiError> {
|
||||
pub fn widget(&mut self) -> impl Widget<UiError> + '_ {
|
||||
let inner = match self {
|
||||
Self::LoggedOut(logged_out) => logged_out.widget(),
|
||||
Self::LoggedIn(logged_in) => logged_in.widget(),
|
||||
Self::LoggedOut(logged_out) => logged_out.widget().first2(),
|
||||
Self::LoggedIn(logged_in) => logged_in.widget().second2(),
|
||||
}
|
||||
.resize()
|
||||
.with_min_width(40);
|
||||
|
||||
Popup::new(inner, "Account").boxed_async()
|
||||
Popup::new(inner, "Account")
|
||||
}
|
||||
|
||||
pub fn list_key_bindings(&self, bindings: &mut KeyBindingsList) {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
use toss::widgets::{BoxedAsync, EditorState};
|
||||
use toss::{Terminal, WidgetExt};
|
||||
use toss::widgets::EditorState;
|
||||
use toss::{Terminal, Widget};
|
||||
|
||||
use crate::euph::Room;
|
||||
use crate::ui::input::{key, InputEvent, KeyBindingsList};
|
||||
|
|
@ -10,12 +10,11 @@ pub fn new() -> EditorState {
|
|||
EditorState::new()
|
||||
}
|
||||
|
||||
pub fn widget(editor: &mut EditorState) -> BoxedAsync<'_, UiError> {
|
||||
pub fn widget(editor: &mut EditorState) -> impl Widget<UiError> + '_ {
|
||||
Popup::new(
|
||||
editor.widget().with_hidden_default_placeholder(),
|
||||
"Enter password",
|
||||
)
|
||||
.boxed_async()
|
||||
}
|
||||
|
||||
pub fn list_key_bindings(bindings: &mut KeyBindingsList) {
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
use crossterm::style::Stylize;
|
||||
use euphoxide::api::{Message, NickEvent, SessionView};
|
||||
use euphoxide::conn::SessionInfo;
|
||||
use toss::widgets::{BoxedAsync, Text};
|
||||
use toss::{Style, Styled, WidgetExt};
|
||||
use toss::widgets::Text;
|
||||
use toss::{Style, Styled, Widget};
|
||||
|
||||
use crate::ui::input::{key, InputEvent, KeyBindingsList};
|
||||
use crate::ui::widgets::Popup;
|
||||
|
|
@ -88,7 +88,7 @@ fn message_lines(mut text: Styled, msg: &Message) -> Styled {
|
|||
text
|
||||
}
|
||||
|
||||
pub fn session_widget(session: &SessionInfo) -> BoxedAsync<'static, UiError> {
|
||||
pub fn session_widget(session: &SessionInfo) -> impl Widget<UiError> {
|
||||
let heading_style = Style::new().bold();
|
||||
|
||||
let text = match session {
|
||||
|
|
@ -102,10 +102,10 @@ pub fn session_widget(session: &SessionInfo) -> BoxedAsync<'static, UiError> {
|
|||
}
|
||||
};
|
||||
|
||||
Popup::new(Text::new(text), "Inspect session").boxed_async()
|
||||
Popup::new(Text::new(text), "Inspect session")
|
||||
}
|
||||
|
||||
pub fn message_widget(msg: &Message) -> BoxedAsync<'static, UiError> {
|
||||
pub fn message_widget(msg: &Message) -> impl Widget<UiError> {
|
||||
let heading_style = Style::new().bold();
|
||||
|
||||
let mut text = Styled::new("Message", heading_style).then_plain("\n");
|
||||
|
|
@ -119,7 +119,7 @@ pub fn message_widget(msg: &Message) -> BoxedAsync<'static, UiError> {
|
|||
|
||||
text = session_view_lines(text, &msg.sender);
|
||||
|
||||
Popup::new(Text::new(text), "Inspect message").boxed_async()
|
||||
Popup::new(Text::new(text), "Inspect message")
|
||||
}
|
||||
|
||||
pub fn list_key_bindings(bindings: &mut KeyBindingsList) {
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@ use std::io;
|
|||
|
||||
use crossterm::style::Stylize;
|
||||
use linkify::{LinkFinder, LinkKind};
|
||||
use toss::widgets::{BoxedAsync, Text};
|
||||
use toss::{Style, Styled, WidgetExt};
|
||||
use toss::widgets::Text;
|
||||
use toss::{Style, Styled, Widget};
|
||||
|
||||
use crate::ui::input::{key, InputEvent, KeyBindingsList};
|
||||
use crate::ui::widgets::{ListBuilder, ListState, Popup};
|
||||
|
|
@ -38,7 +38,7 @@ impl LinksState {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn widget(&mut self) -> BoxedAsync<'_, UiError> {
|
||||
pub fn widget(&mut self) -> impl Widget<UiError> + '_ {
|
||||
let style_selected = Style::new().black().on_white();
|
||||
|
||||
let mut list_builder = ListBuilder::new();
|
||||
|
|
@ -74,7 +74,7 @@ impl LinksState {
|
|||
}
|
||||
}
|
||||
|
||||
Popup::new(list_builder.build(&mut self.list), "Links").boxed_async()
|
||||
Popup::new(list_builder.build(&mut self.list), "Links")
|
||||
}
|
||||
|
||||
fn open_link_by_id(&self, id: usize) -> EventResult {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use euphoxide::conn::Joined;
|
||||
use toss::widgets::{BoxedAsync, EditorState};
|
||||
use toss::{Style, Terminal, WidgetExt};
|
||||
use toss::widgets::EditorState;
|
||||
use toss::{Style, Terminal, Widget};
|
||||
|
||||
use crate::euph::{self, Room};
|
||||
use crate::ui::input::{key, InputEvent, KeyBindingsList};
|
||||
|
|
@ -11,12 +11,12 @@ pub fn new(joined: Joined) -> EditorState {
|
|||
EditorState::with_initial_text(joined.session.name)
|
||||
}
|
||||
|
||||
pub fn widget(editor: &mut EditorState) -> BoxedAsync<'_, UiError> {
|
||||
pub fn widget(editor: &mut EditorState) -> impl Widget<UiError> + '_ {
|
||||
let inner = editor
|
||||
.widget()
|
||||
.with_highlight(|s| euph::style_nick_exact(s, Style::new()));
|
||||
|
||||
Popup::new(inner, "Choose nick").boxed_async()
|
||||
Popup::new(inner, "Choose nick")
|
||||
}
|
||||
|
||||
fn nick_char(c: char) -> bool {
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@ use std::iter;
|
|||
use crossterm::style::{Color, Stylize};
|
||||
use euphoxide::api::{NickEvent, SessionId, SessionType, SessionView, UserId};
|
||||
use euphoxide::conn::{Joined, SessionInfo};
|
||||
use toss::widgets::{BoxedAsync, Empty, Text};
|
||||
use toss::{Style, Styled, WidgetExt};
|
||||
use toss::widgets::{Background, Text};
|
||||
use toss::{Style, Styled, Widget, WidgetExt};
|
||||
|
||||
use crate::euph;
|
||||
use crate::ui::widgets::{ListBuilder, ListState};
|
||||
|
|
@ -14,10 +14,10 @@ pub fn widget<'a>(
|
|||
list: &'a mut ListState<SessionId>,
|
||||
joined: &Joined,
|
||||
focused: bool,
|
||||
) -> BoxedAsync<'a, UiError> {
|
||||
) -> impl Widget<UiError> + 'a {
|
||||
let mut list_builder = ListBuilder::new();
|
||||
render_rows(&mut list_builder, joined, focused);
|
||||
list_builder.build(list).boxed_async()
|
||||
list_builder.build(list)
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||
|
|
@ -59,7 +59,7 @@ impl HalfSession {
|
|||
}
|
||||
|
||||
fn render_rows(
|
||||
list_builder: &mut ListBuilder<'_, SessionId, BoxedAsync<'static, UiError>>,
|
||||
list_builder: &mut ListBuilder<'_, SessionId, Background<Text>>,
|
||||
joined: &Joined,
|
||||
focused: bool,
|
||||
) {
|
||||
|
|
@ -94,7 +94,7 @@ fn render_rows(
|
|||
}
|
||||
|
||||
fn render_section(
|
||||
list_builder: &mut ListBuilder<'_, SessionId, BoxedAsync<'static, UiError>>,
|
||||
list_builder: &mut ListBuilder<'_, SessionId, Background<Text>>,
|
||||
name: &str,
|
||||
sessions: &[HalfSession],
|
||||
own_session: &SessionView,
|
||||
|
|
@ -107,13 +107,13 @@ fn render_section(
|
|||
let heading_style = Style::new().bold();
|
||||
|
||||
if !list_builder.is_empty() {
|
||||
list_builder.add_unsel(Empty::new().boxed_async());
|
||||
list_builder.add_unsel(Text::new("").background());
|
||||
}
|
||||
|
||||
let row = Styled::new_plain(" ")
|
||||
.then(name, heading_style)
|
||||
.then_plain(format!(" ({})", sessions.len()));
|
||||
list_builder.add_unsel(Text::new(row).boxed_async());
|
||||
list_builder.add_unsel(Text::new(row).background());
|
||||
|
||||
for session in sessions {
|
||||
render_row(list_builder, session, own_session, focused);
|
||||
|
|
@ -121,7 +121,7 @@ fn render_section(
|
|||
}
|
||||
|
||||
fn render_row(
|
||||
list_builder: &mut ListBuilder<'_, SessionId, BoxedAsync<'static, UiError>>,
|
||||
list_builder: &mut ListBuilder<'_, SessionId, Background<Text>>,
|
||||
session: &HalfSession,
|
||||
own_session: &SessionView,
|
||||
focused: bool,
|
||||
|
|
@ -163,15 +163,12 @@ fn render_row(
|
|||
let text = Styled::new_plain(owner)
|
||||
.then(name, style_inv)
|
||||
.then(perms, perms_style_inv);
|
||||
Text::new(text)
|
||||
.background()
|
||||
.with_style(style_inv)
|
||||
.boxed_async()
|
||||
Text::new(text).background().with_style(style_inv)
|
||||
} else {
|
||||
let text = Styled::new_plain(owner)
|
||||
.then(&name, style)
|
||||
.then_plain(perms);
|
||||
Text::new(text).boxed_async()
|
||||
Text::new(text).background()
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use crossterm::style::Stylize;
|
||||
use toss::widgets::{BoxedAsync, Text};
|
||||
use toss::{Style, Styled, WidgetExt};
|
||||
use toss::widgets::Text;
|
||||
use toss::{Style, Styled, Widget};
|
||||
|
||||
use crate::ui::widgets::Popup;
|
||||
use crate::ui::UiError;
|
||||
|
|
@ -10,19 +10,18 @@ pub enum RoomPopup {
|
|||
}
|
||||
|
||||
impl RoomPopup {
|
||||
fn server_error_widget(description: &str, reason: &str) -> BoxedAsync<'static, UiError> {
|
||||
fn server_error_widget(description: &str, reason: &str) -> impl Widget<UiError> {
|
||||
let border_style = Style::new().red().bold();
|
||||
let text = Styled::new_plain(description)
|
||||
.then_plain("\n\n")
|
||||
.then("Reason:", Style::new().bold())
|
||||
.then_plain(" ")
|
||||
.then_plain(reason);
|
||||
Popup::new(Text::new(text), ("Error", border_style))
|
||||
.with_border_style(border_style)
|
||||
.boxed_async()
|
||||
|
||||
Popup::new(Text::new(text), ("Error", border_style)).with_border_style(border_style)
|
||||
}
|
||||
|
||||
pub fn widget(&self) -> BoxedAsync<'static, UiError> {
|
||||
pub fn widget(&self) -> impl Widget<UiError> {
|
||||
match self {
|
||||
Self::Error {
|
||||
description,
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ use parking_lot::FairMutex;
|
|||
use tokio::sync::oneshot::error::TryRecvError;
|
||||
use tokio::sync::{mpsc, oneshot};
|
||||
use toss::widgets::{BoxedAsync, EditorState, Join2, Layer, Text};
|
||||
use toss::{AsyncWidget, Style, Styled, Terminal, WidgetExt};
|
||||
use toss::{Style, Styled, Terminal, Widget, WidgetExt};
|
||||
|
||||
use crate::config;
|
||||
use crate::euph;
|
||||
|
|
@ -223,16 +223,20 @@ impl EuphRoom {
|
|||
|
||||
match &mut self.state {
|
||||
State::Normal => {}
|
||||
State::Auth(editor) => layers.push(auth::widget(editor)),
|
||||
State::Nick(editor) => layers.push(nick::widget(editor)),
|
||||
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)),
|
||||
State::Auth(editor) => layers.push(auth::widget(editor).desync().boxed_async()),
|
||||
State::Nick(editor) => layers.push(nick::widget(editor).desync().boxed_async()),
|
||||
State::Account(account) => layers.push(account.widget().desync().boxed_async()),
|
||||
State::Links(links) => layers.push(links.widget().desync().boxed_async()),
|
||||
State::InspectMessage(message) => {
|
||||
layers.push(inspect::message_widget(message).desync().boxed_async())
|
||||
}
|
||||
State::InspectSession(session) => {
|
||||
layers.push(inspect::session_widget(session).desync().boxed_async())
|
||||
}
|
||||
}
|
||||
|
||||
for popup in &self.popups {
|
||||
layers.push(popup.widget());
|
||||
layers.push(popup.widget().desync().boxed_async());
|
||||
}
|
||||
|
||||
Layer::new(layers).boxed_async()
|
||||
|
|
@ -240,12 +244,12 @@ impl EuphRoom {
|
|||
|
||||
fn widget_without_nick_list(
|
||||
chat: &mut EuphChatState,
|
||||
status_widget: impl AsyncWidget<UiError> + Send + Sync + 'static,
|
||||
status_widget: impl Widget<UiError> + Send + Sync + 'static,
|
||||
) -> BoxedAsync<'_, UiError> {
|
||||
let chat_widget = chat.widget(String::new(), true);
|
||||
|
||||
Join2::vertical(
|
||||
status_widget.segment().with_fixed(true),
|
||||
status_widget.desync().segment().with_fixed(true),
|
||||
chat_widget.segment(),
|
||||
)
|
||||
.boxed_async()
|
||||
|
|
@ -253,7 +257,7 @@ impl EuphRoom {
|
|||
|
||||
fn widget_with_nick_list<'a>(
|
||||
chat: &'a mut EuphChatState,
|
||||
status_widget: impl AsyncWidget<UiError> + Send + Sync + 'static,
|
||||
status_widget: impl Widget<UiError> + Send + Sync + 'static,
|
||||
nick_list: &'a mut ListState<SessionId>,
|
||||
joined: &Joined,
|
||||
focus: Focus,
|
||||
|
|
@ -261,13 +265,14 @@ impl EuphRoom {
|
|||
let nick_list_widget = nick_list::widget(nick_list, joined, focus == Focus::NickList)
|
||||
.padding()
|
||||
.with_right(1)
|
||||
.border();
|
||||
.border()
|
||||
.desync();
|
||||
|
||||
let chat_widget = chat.widget(joined.session.name.clone(), focus == Focus::Chat);
|
||||
|
||||
Join2::horizontal(
|
||||
Join2::vertical(
|
||||
status_widget.segment().with_fixed(true),
|
||||
status_widget.desync().segment().with_fixed(true),
|
||||
chat_widget.segment(),
|
||||
)
|
||||
.segment(),
|
||||
|
|
@ -276,7 +281,7 @@ impl EuphRoom {
|
|||
.boxed_async()
|
||||
}
|
||||
|
||||
async fn status_widget(&self, state: Option<&euph::State>) -> BoxedAsync<'static, UiError> {
|
||||
async fn status_widget(&self, state: Option<&euph::State>) -> impl Widget<UiError> {
|
||||
let room_style = Style::new().bold().blue();
|
||||
let mut info = Styled::new(format!("&{}", self.name()), room_style);
|
||||
|
||||
|
|
@ -309,11 +314,7 @@ impl EuphRoom {
|
|||
.then_plain(")");
|
||||
}
|
||||
|
||||
Text::new(info)
|
||||
.padding()
|
||||
.with_horizontal(1)
|
||||
.border()
|
||||
.boxed_async()
|
||||
Text::new(info).padding().with_horizontal(1).border()
|
||||
}
|
||||
|
||||
async fn list_chat_key_bindings(&self, bindings: &mut KeyBindingsList) {
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@ use std::convert::Infallible;
|
|||
|
||||
use crossterm::event::{Event, KeyCode, KeyModifiers};
|
||||
use crossterm::style::Stylize;
|
||||
use toss::widgets::{BoxedAsync, Empty, Join2, Text};
|
||||
use toss::{Style, Styled, WidgetExt};
|
||||
use toss::widgets::{Empty, Join2, Text};
|
||||
use toss::{Style, Styled, Widget, WidgetExt};
|
||||
|
||||
use super::widgets::{ListBuilder, ListState};
|
||||
use super::UiError;
|
||||
|
|
@ -96,11 +96,11 @@ impl KeyBindingsList {
|
|||
Style::new().cyan()
|
||||
}
|
||||
|
||||
fn row_widget(row: Row) -> BoxedAsync<'static, UiError> {
|
||||
fn row_widget(row: Row) -> impl Widget<UiError> {
|
||||
match row {
|
||||
Row::Empty => Empty::new().boxed_async(),
|
||||
Row::Empty => Text::new("").first3(),
|
||||
|
||||
Row::Heading(name) => Text::new((name, Style::new().bold())).boxed_async(),
|
||||
Row::Heading(name) => Text::new((name, Style::new().bold())).first3(),
|
||||
|
||||
Row::Binding(binding, description) => Join2::horizontal(
|
||||
Text::new((binding, Self::binding_style()))
|
||||
|
|
@ -111,17 +111,17 @@ impl KeyBindingsList {
|
|||
.segment(),
|
||||
Text::new(description).segment(),
|
||||
)
|
||||
.boxed_async(),
|
||||
.second3(),
|
||||
|
||||
Row::BindingContd(description) => Join2::horizontal(
|
||||
Empty::new().with_width(Self::BINDING_WIDTH).segment(),
|
||||
Text::new(description).segment(),
|
||||
)
|
||||
.boxed_async(),
|
||||
.third3(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn widget(self, list_state: &mut ListState<Infallible>) -> BoxedAsync<'_, UiError> {
|
||||
pub fn widget(self, list_state: &mut ListState<Infallible>) -> impl Widget<UiError> + '_ {
|
||||
let binding_style = Self::binding_style();
|
||||
|
||||
let hint_text = Styled::new("jk/↓↑", binding_style)
|
||||
|
|
@ -150,7 +150,6 @@ impl KeyBindingsList {
|
|||
.background()
|
||||
.float()
|
||||
.with_center()
|
||||
.boxed_async()
|
||||
}
|
||||
|
||||
pub fn empty(&mut self) {
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ use euphoxide::conn::{self, Joined};
|
|||
use parking_lot::FairMutex;
|
||||
use tokio::sync::mpsc;
|
||||
use toss::widgets::{BoxedAsync, EditorState, Empty, Join2, Text};
|
||||
use toss::{Style, Styled, Terminal, WidgetExt};
|
||||
use toss::{Style, Styled, Terminal, Widget, WidgetExt};
|
||||
|
||||
use crate::config::{Config, RoomsSortOrder};
|
||||
use crate::euph;
|
||||
|
|
@ -171,9 +171,10 @@ impl Rooms {
|
|||
}
|
||||
|
||||
match &mut self.state {
|
||||
State::ShowList => {
|
||||
Self::rooms_widget(&mut self.list, &self.euph_rooms, self.order).await
|
||||
}
|
||||
State::ShowList => Self::rooms_widget(&mut self.list, &self.euph_rooms, self.order)
|
||||
.await
|
||||
.desync()
|
||||
.boxed_async(),
|
||||
|
||||
State::ShowRoom(name) => {
|
||||
self.euph_rooms
|
||||
|
|
@ -187,6 +188,7 @@ impl Rooms {
|
|||
Self::rooms_widget(&mut self.list, &self.euph_rooms, self.order)
|
||||
.await
|
||||
.below(Self::new_room_widget(editor))
|
||||
.desync()
|
||||
.boxed_async()
|
||||
}
|
||||
|
||||
|
|
@ -194,12 +196,13 @@ impl Rooms {
|
|||
Self::rooms_widget(&mut self.list, &self.euph_rooms, self.order)
|
||||
.await
|
||||
.below(Self::delete_room_widget(name, editor))
|
||||
.desync()
|
||||
.boxed_async()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn new_room_widget(editor: &mut EditorState) -> BoxedAsync<'_, UiError> {
|
||||
fn new_room_widget(editor: &mut EditorState) -> impl Widget<UiError> + '_ {
|
||||
let room_style = Style::new().bold().blue();
|
||||
|
||||
let inner = Join2::horizontal(
|
||||
|
|
@ -210,10 +213,13 @@ impl Rooms {
|
|||
.segment(),
|
||||
);
|
||||
|
||||
Popup::new(inner, "Connect to").boxed_async()
|
||||
Popup::new(inner, "Connect to")
|
||||
}
|
||||
|
||||
fn delete_room_widget<'a>(name: &str, editor: &'a mut EditorState) -> BoxedAsync<'a, UiError> {
|
||||
fn delete_room_widget<'a>(
|
||||
name: &str,
|
||||
editor: &'a mut EditorState,
|
||||
) -> impl Widget<UiError> + 'a {
|
||||
let warn_style = Style::new().bold().red();
|
||||
let room_style = Style::new().bold().blue();
|
||||
let text = Styled::new_plain("Are you sure you want to delete ")
|
||||
|
|
@ -249,9 +255,7 @@ impl Rooms {
|
|||
.segment(),
|
||||
);
|
||||
|
||||
Popup::new(inner, "Delete room")
|
||||
.with_border_style(warn_style)
|
||||
.boxed_async()
|
||||
Popup::new(inner, "Delete room").with_border_style(warn_style)
|
||||
}
|
||||
|
||||
fn format_pbln(joined: &Joined) -> String {
|
||||
|
|
@ -387,7 +391,7 @@ impl Rooms {
|
|||
list: &'a mut ListState<String>,
|
||||
euph_rooms: &HashMap<String, EuphRoom>,
|
||||
order: Order,
|
||||
) -> BoxedAsync<'a, UiError> {
|
||||
) -> impl Widget<UiError> + 'a {
|
||||
let heading_style = Style::new().bold();
|
||||
let heading_text =
|
||||
Styled::new("Rooms", heading_style).then_plain(format!(" ({})", euph_rooms.len()));
|
||||
|
|
@ -399,7 +403,6 @@ impl Rooms {
|
|||
Text::new(heading_text).segment().with_fixed(true),
|
||||
list_builder.build(list).segment(),
|
||||
)
|
||||
.boxed_async()
|
||||
}
|
||||
|
||||
fn room_char(c: char) -> bool {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
use std::vec;
|
||||
|
||||
use async_trait::async_trait;
|
||||
use toss::{AsyncWidget, Frame, Pos, Size, WidthDb};
|
||||
use toss::{Frame, Pos, Size, Widget, WidthDb};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct Cursor<Id> {
|
||||
|
|
@ -298,13 +297,12 @@ pub struct List<'a, Id, W> {
|
|||
rows: Vec<W>,
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl<Id, E, W> AsyncWidget<E> for List<'_, Id, W>
|
||||
impl<Id, E, W> Widget<E> for List<'_, Id, W>
|
||||
where
|
||||
Id: Clone + Eq + Send + Sync,
|
||||
W: AsyncWidget<E> + Send + Sync,
|
||||
Id: Clone + Eq,
|
||||
W: Widget<E>,
|
||||
{
|
||||
async fn size(
|
||||
fn size(
|
||||
&self,
|
||||
widthdb: &mut WidthDb,
|
||||
max_width: Option<u16>,
|
||||
|
|
@ -312,14 +310,14 @@ where
|
|||
) -> Result<Size, E> {
|
||||
let mut width = 0;
|
||||
for row in &self.rows {
|
||||
let size = row.size(widthdb, max_width, Some(1)).await?;
|
||||
let size = row.size(widthdb, max_width, Some(1))?;
|
||||
width = width.max(size.width);
|
||||
}
|
||||
let height = self.rows.len().try_into().unwrap_or(u16::MAX);
|
||||
Ok(Size::new(width, height))
|
||||
}
|
||||
|
||||
async fn draw(self, frame: &mut Frame) -> Result<(), E> {
|
||||
fn draw(self, frame: &mut Frame) -> Result<(), E> {
|
||||
let size = frame.size();
|
||||
|
||||
self.state.last_height = size.height;
|
||||
|
|
@ -332,7 +330,7 @@ where
|
|||
.enumerate()
|
||||
{
|
||||
frame.push(Pos::new(0, y as i32), Size::new(size.width, 1));
|
||||
row.draw(frame).await?;
|
||||
row.draw(frame)?;
|
||||
frame.pop();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,10 @@
|
|||
use async_trait::async_trait;
|
||||
use toss::widgets::{Background, Border, Float, Layer2, Padding, Text};
|
||||
use toss::{AsyncWidget, Frame, Size, Style, Styled, WidgetExt, WidthDb};
|
||||
use toss::widgets::{Background, Border, Desync, Float, Layer2, Padding, Text};
|
||||
use toss::{Frame, Size, Style, Styled, Widget, WidgetExt, WidthDb};
|
||||
|
||||
type Body<I> = Background<Border<Padding<I>>>;
|
||||
type Title = Float<Padding<Background<Padding<Text>>>>;
|
||||
|
||||
pub struct Popup<I>(Float<Layer2<Body<I>, Title>>);
|
||||
pub struct Popup<I>(Float<Layer2<Body<I>, Desync<Title>>>);
|
||||
|
||||
impl<I> Popup<I> {
|
||||
pub fn new<S: Into<Styled>>(inner: I, title: S) -> Self {
|
||||
|
|
@ -19,7 +18,8 @@ impl<I> Popup<I> {
|
|||
.with_horizontal(2)
|
||||
.float()
|
||||
.with_top()
|
||||
.with_left();
|
||||
.with_left()
|
||||
.desync();
|
||||
|
||||
let body = inner.padding().with_horizontal(1).border().background();
|
||||
|
||||
|
|
@ -33,22 +33,20 @@ impl<I> Popup<I> {
|
|||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl<E, I> AsyncWidget<E> for Popup<I>
|
||||
impl<E, I> Widget<E> for Popup<I>
|
||||
where
|
||||
E: Send,
|
||||
I: AsyncWidget<E> + Send + Sync,
|
||||
I: Widget<E>,
|
||||
{
|
||||
async fn size(
|
||||
fn size(
|
||||
&self,
|
||||
widthdb: &mut WidthDb,
|
||||
max_width: Option<u16>,
|
||||
max_height: Option<u16>,
|
||||
) -> Result<Size, E> {
|
||||
self.0.size(widthdb, max_width, max_height).await
|
||||
self.0.size(widthdb, max_width, max_height)
|
||||
}
|
||||
|
||||
async fn draw(self, frame: &mut Frame) -> Result<(), E> {
|
||||
self.0.draw(frame).await
|
||||
fn draw(self, frame: &mut Frame) -> Result<(), E> {
|
||||
self.0.draw(frame)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue