diff --git a/cove/src/ui/chat/tree.rs b/cove/src/ui/chat/tree.rs index 297429b..f2f230a 100644 --- a/cove/src/ui/chat/tree.rs +++ b/cove/src/ui/chat/tree.rs @@ -439,6 +439,7 @@ where let mut renderer = TreeRenderer::new( context, &self.state.store, + &self.state.folded, self.cursor, self.editor, frame.widthdb(), diff --git a/cove/src/ui/chat/tree/renderer.rs b/cove/src/ui/chat/tree/renderer.rs index b7d358b..07edab0 100644 --- a/cove/src/ui/chat/tree/renderer.rs +++ b/cove/src/ui/chat/tree/renderer.rs @@ -1,5 +1,6 @@ //! A [`Renderer`] for message trees. +use std::collections::HashSet; use std::convert::Infallible; use async_trait::async_trait; @@ -79,6 +80,7 @@ pub struct TreeRenderer<'a, M: Msg, S: MsgStore> { context: TreeContext, store: &'a S, + folded: &'a HashSet, cursor: &'a mut Cursor, editor: &'a mut EditorState, widthdb: &'a mut WidthDb, @@ -105,6 +107,7 @@ where pub fn new( context: TreeContext, store: &'a S, + folded: &'a HashSet, cursor: &'a mut Cursor, editor: &'a mut EditorState, widthdb: &'a mut WidthDb, @@ -112,6 +115,7 @@ where Self { context, store, + folded, cursor, editor, widthdb, @@ -169,28 +173,38 @@ where Block::new(id, widget, false) } - fn message_block(&mut self, indent: usize, msg: &M) -> TreeBlock { + fn message_block( + &mut self, + indent: usize, + msg: &M, + folded_info: Option, + ) -> TreeBlock { let msg_id = msg.id(); let highlighted = match self.cursor { Cursor::Msg(id) => *id == msg_id, _ => false, }; + let highlighted = highlighted && self.context.focused; - // TODO Amount of folded messages - let widget = widgets::msg(self.context.focused && highlighted, indent, msg, None); + let widget = widgets::msg(highlighted, indent, msg, folded_info); let widget = Self::predraw(widget, self.context.size, self.widthdb); Block::new(TreeBlockId::Msg(msg_id), widget, true) } - fn message_placeholder_block(&mut self, indent: usize, msg_id: &M::Id) -> TreeBlock { + fn message_placeholder_block( + &mut self, + indent: usize, + msg_id: &M::Id, + folded_info: Option, + ) -> TreeBlock { let highlighted = match self.cursor { Cursor::Msg(id) => id == msg_id, _ => false, }; + let highlighted = highlighted && self.context.focused; - // TODO Amount of folded messages - let widget = widgets::msg_placeholder(self.context.focused && highlighted, indent, None); + let widget = widgets::msg_placeholder(highlighted, indent, folded_info); let widget = Self::predraw(widget, self.context.size, self.widthdb); Block::new(TreeBlockId::Msg(msg_id.clone()), widget, true) } @@ -214,18 +228,27 @@ where msg_id: &M::Id, blocks: &mut TreeBlocks, ) { + let folded = self.folded.contains(msg_id); + let folded_info = if folded { + Some(tree.subtree_size(msg_id)).filter(|s| *s > 0) + } else { + None + }; + // Message itself let block = if let Some(msg) = tree.msg(msg_id) { - self.message_block(indent, msg) + self.message_block(indent, msg, folded_info) } else { - self.message_placeholder_block(indent, msg_id) + self.message_placeholder_block(indent, msg_id, folded_info) }; blocks.push_bottom(block); // Children, recursively - if let Some(children) = tree.children(msg_id) { - for child in children { - self.layout_subtree(tree, indent + 1, child, blocks); + if !folded { + if let Some(children) = tree.children(msg_id) { + for child in children { + self.layout_subtree(tree, indent + 1, child, blocks); + } } } diff --git a/cove/src/ui/chat/tree/scroll.rs b/cove/src/ui/chat/tree/scroll.rs index 29b5d1e..8f565b3 100644 --- a/cove/src/ui/chat/tree/scroll.rs +++ b/cove/src/ui/chat/tree/scroll.rs @@ -33,7 +33,8 @@ where delta: i32, ) -> Result<(), S::Error> { let context = self.last_context(); - let mut renderer = TreeRenderer::new(context, &self.store, cursor, editor, widthdb); + let mut renderer = + TreeRenderer::new(context, &self.store, &self.folded, cursor, editor, widthdb); renderer.prepare_blocks_for_drawing().await?; renderer.scroll_by(delta).await?; @@ -53,7 +54,8 @@ where widthdb: &mut WidthDb, ) -> Result<(), S::Error> { let context = self.last_context(); - let mut renderer = TreeRenderer::new(context, &self.store, cursor, editor, widthdb); + let mut renderer = + TreeRenderer::new(context, &self.store, &self.folded, cursor, editor, widthdb); renderer.prepare_blocks_for_drawing().await?; renderer.center_cursor();