Render messages with less async
This commit is contained in:
parent
8182cc5d38
commit
a638caadcb
5 changed files with 62 additions and 100 deletions
12
Cargo.lock
generated
12
Cargo.lock
generated
|
|
@ -68,17 +68,6 @@ version = "1.0.70"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7de8ce5e0f9f8d88245311066a578d72b7af3e7088f32783804676302df237e4"
|
checksum = "7de8ce5e0f9f8d88245311066a578d72b7af3e7088f32783804676302df237e4"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "async-recursion"
|
|
||||||
version = "1.0.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "0e97ce7de6cf12de5d7226c73f5ba9811622f4db3a5b91b55c53e987e5f91cba"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn 2.0.13",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "async-trait"
|
name = "async-trait"
|
||||||
version = "0.1.68"
|
version = "0.1.68"
|
||||||
|
|
@ -251,7 +240,6 @@ name = "cove"
|
||||||
version = "0.6.1"
|
version = "0.6.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"async-recursion",
|
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"clap",
|
"clap",
|
||||||
"cookie",
|
"cookie",
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = "1.0.70"
|
anyhow = "1.0.70"
|
||||||
async-recursion = "1.0.4"
|
|
||||||
async-trait = "0.1.68"
|
async-trait = "0.1.68"
|
||||||
clap = { version = "4.2.1", features = ["derive", "deprecated"] }
|
clap = { version = "4.2.1", features = ["derive", "deprecated"] }
|
||||||
cookie = "0.17.0"
|
cookie = "0.17.0"
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,9 @@
|
||||||
|
|
||||||
use std::convert::Infallible;
|
use std::convert::Infallible;
|
||||||
|
|
||||||
use async_recursion::async_recursion;
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use toss::widgets::{EditorState, Empty, Predrawn, Resize};
|
use toss::widgets::{EditorState, Empty, Predrawn, Resize};
|
||||||
use toss::{AsyncWidget, Size, WidthDb};
|
use toss::{Size, Widget, WidthDb};
|
||||||
|
|
||||||
use crate::store::{Msg, MsgStore, Tree};
|
use crate::store::{Msg, MsgStore, Tree};
|
||||||
use crate::ui::chat::blocks::{Block, Blocks, Range};
|
use crate::ui::chat::blocks::{Block, Blocks, Range};
|
||||||
|
|
@ -122,26 +121,24 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn predraw<W>(widget: W, size: Size, widthdb: &mut WidthDb) -> Predrawn
|
fn predraw<W>(widget: W, size: Size, widthdb: &mut WidthDb) -> Predrawn
|
||||||
where
|
where
|
||||||
W: AsyncWidget<Infallible> + Send + Sync,
|
W: Widget<Infallible>,
|
||||||
{
|
{
|
||||||
Predrawn::new_async(Resize::new(widget).with_max_width(size.width), widthdb)
|
Predrawn::new(Resize::new(widget).with_max_width(size.width), widthdb).infallible()
|
||||||
.await
|
|
||||||
.infallible()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn zero_height_block(&mut self, parent: Option<&M::Id>) -> TreeBlock<M::Id> {
|
fn zero_height_block(&mut self, parent: Option<&M::Id>) -> TreeBlock<M::Id> {
|
||||||
let id = match parent {
|
let id = match parent {
|
||||||
Some(parent) => TreeBlockId::After(parent.clone()),
|
Some(parent) => TreeBlockId::After(parent.clone()),
|
||||||
None => TreeBlockId::Bottom,
|
None => TreeBlockId::Bottom,
|
||||||
};
|
};
|
||||||
|
|
||||||
let widget = Self::predraw(Empty::new(), self.context.size, self.widthdb).await;
|
let widget = Self::predraw(Empty::new(), self.context.size, self.widthdb);
|
||||||
Block::new(id, widget, false)
|
Block::new(id, widget, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn editor_block(&mut self, indent: usize, parent: Option<&M::Id>) -> TreeBlock<M::Id> {
|
fn editor_block(&mut self, indent: usize, parent: Option<&M::Id>) -> TreeBlock<M::Id> {
|
||||||
let id = match parent {
|
let id = match parent {
|
||||||
Some(parent) => TreeBlockId::After(parent.clone()),
|
Some(parent) => TreeBlockId::After(parent.clone()),
|
||||||
None => TreeBlockId::Bottom,
|
None => TreeBlockId::Bottom,
|
||||||
|
|
@ -149,7 +146,7 @@ where
|
||||||
|
|
||||||
// TODO Unhighlighted version when focusing on nick list
|
// TODO Unhighlighted version when focusing on nick list
|
||||||
let widget = widgets::editor::<M>(indent, &self.context.nick, self.editor);
|
let widget = widgets::editor::<M>(indent, &self.context.nick, self.editor);
|
||||||
let widget = Self::predraw(widget, self.context.size, self.widthdb).await;
|
let widget = Self::predraw(widget, self.context.size, self.widthdb);
|
||||||
let mut block = Block::new(id, widget, false);
|
let mut block = Block::new(id, widget, false);
|
||||||
|
|
||||||
// Since the editor was rendered when the `Predrawn` was created, the
|
// Since the editor was rendered when the `Predrawn` was created, the
|
||||||
|
|
@ -160,7 +157,7 @@ where
|
||||||
block
|
block
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn pseudo_block(&mut self, indent: usize, parent: Option<&M::Id>) -> TreeBlock<M::Id> {
|
fn pseudo_block(&mut self, indent: usize, parent: Option<&M::Id>) -> TreeBlock<M::Id> {
|
||||||
let id = match parent {
|
let id = match parent {
|
||||||
Some(parent) => TreeBlockId::After(parent.clone()),
|
Some(parent) => TreeBlockId::After(parent.clone()),
|
||||||
None => TreeBlockId::Bottom,
|
None => TreeBlockId::Bottom,
|
||||||
|
|
@ -168,11 +165,11 @@ where
|
||||||
|
|
||||||
// TODO Unhighlighted version when focusing on nick list
|
// TODO Unhighlighted version when focusing on nick list
|
||||||
let widget = widgets::pseudo::<M>(indent, &self.context.nick, self.editor);
|
let widget = widgets::pseudo::<M>(indent, &self.context.nick, self.editor);
|
||||||
let widget = Self::predraw(widget, self.context.size, self.widthdb).await;
|
let widget = Self::predraw(widget, self.context.size, self.widthdb);
|
||||||
Block::new(id, widget, false)
|
Block::new(id, widget, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn message_block(&mut self, indent: usize, msg: &M) -> TreeBlock<M::Id> {
|
fn message_block(&mut self, indent: usize, msg: &M) -> TreeBlock<M::Id> {
|
||||||
let msg_id = msg.id();
|
let msg_id = msg.id();
|
||||||
|
|
||||||
let highlighted = match self.cursor {
|
let highlighted = match self.cursor {
|
||||||
|
|
@ -182,15 +179,11 @@ where
|
||||||
|
|
||||||
// TODO Amount of folded messages
|
// TODO Amount of folded messages
|
||||||
let widget = widgets::msg(self.context.focused && highlighted, indent, msg, None);
|
let widget = widgets::msg(self.context.focused && highlighted, indent, msg, None);
|
||||||
let widget = Self::predraw(widget, self.context.size, self.widthdb).await;
|
let widget = Self::predraw(widget, self.context.size, self.widthdb);
|
||||||
Block::new(TreeBlockId::Msg(msg_id), widget, true)
|
Block::new(TreeBlockId::Msg(msg_id), widget, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn message_placeholder_block(
|
fn message_placeholder_block(&mut self, indent: usize, msg_id: &M::Id) -> TreeBlock<M::Id> {
|
||||||
&mut self,
|
|
||||||
indent: usize,
|
|
||||||
msg_id: &M::Id,
|
|
||||||
) -> TreeBlock<M::Id> {
|
|
||||||
let highlighted = match self.cursor {
|
let highlighted = match self.cursor {
|
||||||
Cursor::Msg(id) => id == msg_id,
|
Cursor::Msg(id) => id == msg_id,
|
||||||
_ => false,
|
_ => false,
|
||||||
|
|
@ -198,28 +191,23 @@ where
|
||||||
|
|
||||||
// TODO Amount of folded messages
|
// TODO Amount of folded messages
|
||||||
let widget = widgets::msg_placeholder(self.context.focused && highlighted, indent, None);
|
let widget = widgets::msg_placeholder(self.context.focused && highlighted, indent, None);
|
||||||
let widget = Self::predraw(widget, self.context.size, self.widthdb).await;
|
let widget = Self::predraw(widget, self.context.size, self.widthdb);
|
||||||
Block::new(TreeBlockId::Msg(msg_id.clone()), widget, true)
|
Block::new(TreeBlockId::Msg(msg_id.clone()), widget, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn layout_bottom(&mut self) -> TreeBlocks<M::Id> {
|
fn layout_bottom(&mut self) -> TreeBlocks<M::Id> {
|
||||||
let mut blocks = Blocks::new(0);
|
let mut blocks = Blocks::new(0);
|
||||||
|
|
||||||
match self.cursor {
|
match self.cursor {
|
||||||
Cursor::Editor { parent: None, .. } => {
|
Cursor::Editor { parent: None, .. } => blocks.push_bottom(self.editor_block(0, None)),
|
||||||
blocks.push_bottom(self.editor_block(0, None).await)
|
Cursor::Pseudo { parent: None, .. } => blocks.push_bottom(self.pseudo_block(0, None)),
|
||||||
}
|
_ => blocks.push_bottom(self.zero_height_block(None)),
|
||||||
Cursor::Pseudo { parent: None, .. } => {
|
|
||||||
blocks.push_bottom(self.pseudo_block(0, None).await)
|
|
||||||
}
|
|
||||||
_ => blocks.push_bottom(self.zero_height_block(None).await),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
blocks
|
blocks
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_recursion]
|
fn layout_subtree(
|
||||||
async fn layout_subtree(
|
|
||||||
&mut self,
|
&mut self,
|
||||||
tree: &Tree<M>,
|
tree: &Tree<M>,
|
||||||
indent: usize,
|
indent: usize,
|
||||||
|
|
@ -228,16 +216,16 @@ where
|
||||||
) {
|
) {
|
||||||
// Message itself
|
// Message itself
|
||||||
let block = if let Some(msg) = tree.msg(msg_id) {
|
let block = if let Some(msg) = tree.msg(msg_id) {
|
||||||
self.message_block(indent, msg).await
|
self.message_block(indent, msg)
|
||||||
} else {
|
} else {
|
||||||
self.message_placeholder_block(indent, msg_id).await
|
self.message_placeholder_block(indent, msg_id)
|
||||||
};
|
};
|
||||||
blocks.push_bottom(block);
|
blocks.push_bottom(block);
|
||||||
|
|
||||||
// Children, recursively
|
// Children, recursively
|
||||||
if let Some(children) = tree.children(msg_id) {
|
if let Some(children) = tree.children(msg_id) {
|
||||||
for child in children {
|
for child in children {
|
||||||
self.layout_subtree(tree, indent + 1, child, blocks).await;
|
self.layout_subtree(tree, indent + 1, child, blocks);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -245,21 +233,20 @@ where
|
||||||
let block = match self.cursor {
|
let block = match self.cursor {
|
||||||
Cursor::Editor {
|
Cursor::Editor {
|
||||||
parent: Some(id), ..
|
parent: Some(id), ..
|
||||||
} if id == msg_id => self.editor_block(indent + 1, Some(msg_id)).await,
|
} if id == msg_id => self.editor_block(indent + 1, Some(msg_id)),
|
||||||
|
|
||||||
Cursor::Pseudo {
|
Cursor::Pseudo {
|
||||||
parent: Some(id), ..
|
parent: Some(id), ..
|
||||||
} if id == msg_id => self.pseudo_block(indent + 1, Some(msg_id)).await,
|
} if id == msg_id => self.pseudo_block(indent + 1, Some(msg_id)),
|
||||||
|
|
||||||
_ => self.zero_height_block(Some(msg_id)).await,
|
_ => self.zero_height_block(Some(msg_id)),
|
||||||
};
|
};
|
||||||
blocks.push_bottom(block);
|
blocks.push_bottom(block);
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn layout_tree(&mut self, tree: Tree<M>) -> TreeBlocks<M::Id> {
|
fn layout_tree(&mut self, tree: Tree<M>) -> TreeBlocks<M::Id> {
|
||||||
let mut blocks = Blocks::new(0);
|
let mut blocks = Blocks::new(0);
|
||||||
self.layout_subtree(&tree, 0, tree.root(), &mut blocks)
|
self.layout_subtree(&tree, 0, tree.root(), &mut blocks);
|
||||||
.await;
|
|
||||||
blocks
|
blocks
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -275,9 +262,9 @@ where
|
||||||
|
|
||||||
let blocks = if let Some(root_id) = root_id {
|
let blocks = if let Some(root_id) = root_id {
|
||||||
let tree = self.store.tree(root_id).await?;
|
let tree = self.store.tree(root_id).await?;
|
||||||
self.layout_tree(tree).await
|
self.layout_tree(tree)
|
||||||
} else {
|
} else {
|
||||||
self.layout_bottom().await
|
self.layout_bottom()
|
||||||
};
|
};
|
||||||
self.blocks.append_bottom(blocks);
|
self.blocks.append_bottom(blocks);
|
||||||
|
|
||||||
|
|
@ -429,7 +416,7 @@ where
|
||||||
|
|
||||||
if let Some(prev_root_id) = prev_root_id {
|
if let Some(prev_root_id) = prev_root_id {
|
||||||
let tree = self.store.tree(&prev_root_id).await?;
|
let tree = self.store.tree(&prev_root_id).await?;
|
||||||
let blocks = self.layout_tree(tree).await;
|
let blocks = self.layout_tree(tree);
|
||||||
self.blocks.append_top(blocks);
|
self.blocks.append_top(blocks);
|
||||||
self.top_root_id = Some(prev_root_id);
|
self.top_root_id = Some(prev_root_id);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -448,11 +435,11 @@ where
|
||||||
let next_root_id = self.store.next_root_id(bottom_root_id).await?;
|
let next_root_id = self.store.next_root_id(bottom_root_id).await?;
|
||||||
if let Some(next_root_id) = next_root_id {
|
if let Some(next_root_id) = next_root_id {
|
||||||
let tree = self.store.tree(&next_root_id).await?;
|
let tree = self.store.tree(&next_root_id).await?;
|
||||||
let blocks = self.layout_tree(tree).await;
|
let blocks = self.layout_tree(tree);
|
||||||
self.blocks.append_bottom(blocks);
|
self.blocks.append_bottom(blocks);
|
||||||
self.bottom_root_id = Some(next_root_id);
|
self.bottom_root_id = Some(next_root_id);
|
||||||
} else {
|
} else {
|
||||||
let blocks = self.layout_bottom().await;
|
let blocks = self.layout_bottom();
|
||||||
self.blocks.append_bottom(blocks);
|
self.blocks.append_bottom(blocks);
|
||||||
self.blocks.end_bottom();
|
self.blocks.end_bottom();
|
||||||
self.bottom_root_id = None;
|
self.bottom_root_id = None;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
use std::convert::Infallible;
|
use std::convert::Infallible;
|
||||||
|
|
||||||
use crossterm::style::Stylize;
|
use crossterm::style::Stylize;
|
||||||
use toss::widgets::{BoxedAsync, EditorState, Join2, Join4, Join5, Text};
|
use toss::widgets::{Boxed, EditorState, Join2, Join4, Join5, Text};
|
||||||
use toss::{Style, Styled, WidgetExt};
|
use toss::{Style, Styled, WidgetExt};
|
||||||
|
|
||||||
use crate::store::Msg;
|
use crate::store::Msg;
|
||||||
|
|
@ -47,7 +47,7 @@ pub fn msg<M: Msg + ChatMsg>(
|
||||||
indent: usize,
|
indent: usize,
|
||||||
msg: &M,
|
msg: &M,
|
||||||
folded_info: Option<usize>,
|
folded_info: Option<usize>,
|
||||||
) -> BoxedAsync<'static, Infallible> {
|
) -> Boxed<'static, Infallible> {
|
||||||
let (nick, mut content) = msg.styled();
|
let (nick, mut content) = msg.styled();
|
||||||
|
|
||||||
if let Some(amount) = folded_info {
|
if let Some(amount) = folded_info {
|
||||||
|
|
@ -81,14 +81,14 @@ pub fn msg<M: Msg + ChatMsg>(
|
||||||
// TODO Minimizing and maximizing messages
|
// TODO Minimizing and maximizing messages
|
||||||
Text::new(content).segment(),
|
Text::new(content).segment(),
|
||||||
)
|
)
|
||||||
.boxed_async()
|
.boxed()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn msg_placeholder(
|
pub fn msg_placeholder(
|
||||||
highlighted: bool,
|
highlighted: bool,
|
||||||
indent: usize,
|
indent: usize,
|
||||||
folded_info: Option<usize>,
|
folded_info: Option<usize>,
|
||||||
) -> BoxedAsync<'static, Infallible> {
|
) -> Boxed<'static, Infallible> {
|
||||||
let mut content = Styled::new(PLACEHOLDER, style_placeholder());
|
let mut content = Styled::new(PLACEHOLDER, style_placeholder());
|
||||||
|
|
||||||
if let Some(amount) = folded_info {
|
if let Some(amount) = folded_info {
|
||||||
|
|
@ -110,14 +110,14 @@ pub fn msg_placeholder(
|
||||||
.with_fixed(true),
|
.with_fixed(true),
|
||||||
Text::new(content).segment(),
|
Text::new(content).segment(),
|
||||||
)
|
)
|
||||||
.boxed_async()
|
.boxed()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn editor<'a, M: ChatMsg>(
|
pub fn editor<'a, M: ChatMsg>(
|
||||||
indent: usize,
|
indent: usize,
|
||||||
nick: &str,
|
nick: &str,
|
||||||
editor: &'a mut EditorState,
|
editor: &'a mut EditorState,
|
||||||
) -> BoxedAsync<'a, Infallible> {
|
) -> Boxed<'a, Infallible> {
|
||||||
let (nick, content) = M::edit(nick, editor.text());
|
let (nick, content) = M::edit(nick, editor.text());
|
||||||
let editor = editor.widget().with_highlight(|_| content);
|
let editor = editor.widget().with_highlight(|_| content);
|
||||||
|
|
||||||
|
|
@ -144,14 +144,14 @@ pub fn editor<'a, M: ChatMsg>(
|
||||||
.with_fixed(true),
|
.with_fixed(true),
|
||||||
editor.segment(),
|
editor.segment(),
|
||||||
)
|
)
|
||||||
.boxed_async()
|
.boxed()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pseudo<'a, M: ChatMsg>(
|
pub fn pseudo<'a, M: ChatMsg>(
|
||||||
indent: usize,
|
indent: usize,
|
||||||
nick: &str,
|
nick: &str,
|
||||||
editor: &'a mut EditorState,
|
editor: &'a mut EditorState,
|
||||||
) -> BoxedAsync<'a, Infallible> {
|
) -> Boxed<'a, Infallible> {
|
||||||
let (nick, content) = M::edit(nick, editor.text());
|
let (nick, content) = M::edit(nick, editor.text());
|
||||||
|
|
||||||
Join5::horizontal(
|
Join5::horizontal(
|
||||||
|
|
@ -177,5 +177,5 @@ pub fn pseudo<'a, M: ChatMsg>(
|
||||||
.with_fixed(true),
|
.with_fixed(true),
|
||||||
Text::new(content).segment(),
|
Text::new(content).segment(),
|
||||||
)
|
)
|
||||||
.boxed_async()
|
.boxed()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,11 @@
|
||||||
use std::convert::Infallible;
|
use std::convert::Infallible;
|
||||||
|
|
||||||
use async_trait::async_trait;
|
|
||||||
use crossterm::style::Stylize;
|
use crossterm::style::Stylize;
|
||||||
use time::format_description::FormatItem;
|
use time::format_description::FormatItem;
|
||||||
use time::macros::format_description;
|
use time::macros::format_description;
|
||||||
use time::OffsetDateTime;
|
use time::OffsetDateTime;
|
||||||
use toss::widgets::{BoxedAsync, Empty, Text};
|
use toss::widgets::{Boxed, Empty, Text};
|
||||||
use toss::{AsyncWidget, Frame, Pos, Size, Style, WidgetExt, WidthDb};
|
use toss::{Frame, Pos, Size, Style, Widget, WidgetExt, WidthDb};
|
||||||
|
|
||||||
use crate::util::InfallibleExt;
|
use crate::util::InfallibleExt;
|
||||||
|
|
||||||
|
|
@ -24,9 +23,8 @@ impl Indent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
impl<E> Widget<E> for Indent {
|
||||||
impl<E> AsyncWidget<E> for Indent {
|
fn size(
|
||||||
async fn size(
|
|
||||||
&self,
|
&self,
|
||||||
_widthdb: &mut WidthDb,
|
_widthdb: &mut WidthDb,
|
||||||
_max_width: Option<u16>,
|
_max_width: Option<u16>,
|
||||||
|
|
@ -36,7 +34,7 @@ impl<E> AsyncWidget<E> for Indent {
|
||||||
Ok(Size::new(width, 0))
|
Ok(Size::new(width, 0))
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn draw(self, frame: &mut Frame) -> Result<(), E> {
|
fn draw(self, frame: &mut Frame) -> Result<(), E> {
|
||||||
let size = frame.size();
|
let size = frame.size();
|
||||||
let indent_string = INDENT_STR.repeat(self.level);
|
let indent_string = INDENT_STR.repeat(self.level);
|
||||||
|
|
||||||
|
|
@ -51,7 +49,7 @@ impl<E> AsyncWidget<E> for Indent {
|
||||||
const TIME_FORMAT: &[FormatItem<'_>] = format_description!("[year]-[month]-[day] [hour]:[minute]");
|
const TIME_FORMAT: &[FormatItem<'_>] = format_description!("[year]-[month]-[day] [hour]:[minute]");
|
||||||
const TIME_WIDTH: u16 = 16;
|
const TIME_WIDTH: u16 = 16;
|
||||||
|
|
||||||
pub struct Time(BoxedAsync<'static, Infallible>);
|
pub struct Time(Boxed<'static, Infallible>);
|
||||||
|
|
||||||
impl Time {
|
impl Time {
|
||||||
pub fn new(time: Option<OffsetDateTime>, style: Style) -> Self {
|
pub fn new(time: Option<OffsetDateTime>, style: Style) -> Self {
|
||||||
|
|
@ -60,70 +58,60 @@ impl Time {
|
||||||
Text::new((text, style))
|
Text::new((text, style))
|
||||||
.background()
|
.background()
|
||||||
.with_style(style)
|
.with_style(style)
|
||||||
.boxed_async()
|
.boxed()
|
||||||
} else {
|
} else {
|
||||||
Empty::new()
|
Empty::new()
|
||||||
.with_width(TIME_WIDTH)
|
.with_width(TIME_WIDTH)
|
||||||
.background()
|
.background()
|
||||||
.with_style(style)
|
.with_style(style)
|
||||||
.boxed_async()
|
.boxed()
|
||||||
};
|
};
|
||||||
Self(widget)
|
Self(widget)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
impl<E> Widget<E> for Time {
|
||||||
impl<E> AsyncWidget<E> for Time {
|
fn size(
|
||||||
async fn size(
|
|
||||||
&self,
|
&self,
|
||||||
widthdb: &mut WidthDb,
|
widthdb: &mut WidthDb,
|
||||||
max_width: Option<u16>,
|
max_width: Option<u16>,
|
||||||
max_height: Option<u16>,
|
max_height: Option<u16>,
|
||||||
) -> Result<Size, E> {
|
) -> Result<Size, E> {
|
||||||
Ok(self
|
Ok(self.0.size(widthdb, max_width, max_height).infallible())
|
||||||
.0
|
|
||||||
.size(widthdb, max_width, max_height)
|
|
||||||
.await
|
|
||||||
.infallible())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn draw(self, frame: &mut Frame) -> Result<(), E> {
|
fn draw(self, frame: &mut Frame) -> Result<(), E> {
|
||||||
self.0.draw(frame).await.infallible();
|
self.0.draw(frame).infallible();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Seen(BoxedAsync<'static, Infallible>);
|
pub struct Seen(Boxed<'static, Infallible>);
|
||||||
|
|
||||||
impl Seen {
|
impl Seen {
|
||||||
pub fn new(seen: bool) -> Self {
|
pub fn new(seen: bool) -> Self {
|
||||||
let widget = if seen {
|
let widget = if seen {
|
||||||
Empty::new().with_width(1).boxed_async()
|
Empty::new().with_width(1).boxed()
|
||||||
} else {
|
} else {
|
||||||
let style = Style::new().black().on_green();
|
let style = Style::new().black().on_green();
|
||||||
Text::new("*").background().with_style(style).boxed_async()
|
Text::new("*").background().with_style(style).boxed()
|
||||||
};
|
};
|
||||||
Self(widget)
|
Self(widget)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
impl<E> Widget<E> for Seen {
|
||||||
impl<E> AsyncWidget<E> for Seen {
|
fn size(
|
||||||
async fn size(
|
|
||||||
&self,
|
&self,
|
||||||
widthdb: &mut WidthDb,
|
widthdb: &mut WidthDb,
|
||||||
max_width: Option<u16>,
|
max_width: Option<u16>,
|
||||||
max_height: Option<u16>,
|
max_height: Option<u16>,
|
||||||
) -> Result<Size, E> {
|
) -> Result<Size, E> {
|
||||||
Ok(self
|
Ok(self.0.size(widthdb, max_width, max_height).infallible())
|
||||||
.0
|
|
||||||
.size(widthdb, max_width, max_height)
|
|
||||||
.await
|
|
||||||
.infallible())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn draw(self, frame: &mut Frame) -> Result<(), E> {
|
fn draw(self, frame: &mut Frame) -> Result<(), E> {
|
||||||
self.0.draw(frame).await.infallible();
|
self.0.draw(frame).infallible();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue