From 23c551a5b75f6106aa2db09c7d3a626f583f479b Mon Sep 17 00:00:00 2001 From: Joscha Date: Wed, 15 Jun 2022 11:29:02 +0200 Subject: [PATCH] Make store room-specific --- cove-tui/src/chat.rs | 15 +-- cove-tui/src/chat/tree.rs | 18 ++-- cove-tui/src/chat/tree/cursor.rs | 172 +++++++++---------------------- cove-tui/src/chat/tree/layout.rs | 27 +++-- cove-tui/src/store.rs | 12 +-- cove-tui/src/store/dummy.rs | 12 +-- cove-tui/src/ui.rs | 2 +- 7 files changed, 85 insertions(+), 173 deletions(-) diff --git a/cove-tui/src/chat.rs b/cove-tui/src/chat.rs index 3bf776c..694650b 100644 --- a/cove-tui/src/chat.rs +++ b/cove-tui/src/chat.rs @@ -32,7 +32,6 @@ impl Cursor { pub struct Chat> { store: S, - room: String, cursor: Option>, mode: Mode, tree: TreeView, @@ -41,10 +40,9 @@ pub struct Chat> { } impl> Chat { - pub fn new(store: S, room: String) -> Self { + pub fn new(store: S) -> Self { Self { store, - room, cursor: None, mode: Mode::Tree, tree: TreeView::new(), @@ -57,14 +55,7 @@ impl> Chat { match self.mode { Mode::Tree => { self.tree - .handle_key_event( - &self.room, - &mut self.store, - &mut self.cursor, - frame, - size, - event, - ) + .handle_key_event(&mut self.store, &mut self.cursor, frame, size, event) .await } } @@ -74,7 +65,7 @@ impl> Chat { match self.mode { Mode::Tree => { self.tree - .render(&self.room, &mut self.store, &self.cursor, frame, pos, size) + .render(&mut self.store, &self.cursor, frame, pos, size) .await } } diff --git a/cove-tui/src/chat/tree.rs b/cove-tui/src/chat/tree.rs index 8cf094c..1fff340 100644 --- a/cove-tui/src/chat/tree.rs +++ b/cove-tui/src/chat/tree.rs @@ -29,7 +29,6 @@ impl TreeView { pub async fn handle_key_event>( &mut self, - r: &str, s: &mut S, c: &mut Option>, f: &mut Frame, @@ -37,13 +36,13 @@ impl TreeView { event: KeyEvent, ) { match event.code { - KeyCode::Char('z') | KeyCode::Char('Z') => self.center_cursor(r, s, c, f, z).await, - KeyCode::Char('k') => self.move_up(r, s, c, f, z).await, - KeyCode::Char('j') => self.move_down(r, s, c, f, z).await, - KeyCode::Char('K') => self.move_up_sibling(r, s, c, f, z).await, - KeyCode::Char('J') => self.move_down_sibling(r, s, c, f, z).await, - KeyCode::Char('g') => self.move_to_first(r, s, c, f, z).await, - KeyCode::Char('G') => self.move_to_last(r, s, c, f, z).await, + KeyCode::Char('z') | KeyCode::Char('Z') => self.center_cursor(s, c, f, z).await, + KeyCode::Char('k') => self.move_up(s, c, f, z).await, + KeyCode::Char('j') => self.move_down(s, c, f, z).await, + KeyCode::Char('K') => self.move_up_sibling(s, c, f, z).await, + KeyCode::Char('J') => self.move_down_sibling(s, c, f, z).await, + KeyCode::Char('g') => self.move_to_first(s, c, f, z).await, + KeyCode::Char('G') => self.move_to_last(s, c, f, z).await, KeyCode::Esc => *c = None, // TODO Make 'G' do the same thing? _ => {} } @@ -51,7 +50,6 @@ impl TreeView { pub async fn render>( &mut self, - room: &str, store: &mut S, cursor: &Option>, frame: &mut Frame, @@ -59,7 +57,7 @@ impl TreeView { size: Size, ) { let blocks = self - .layout_blocks(room, store, cursor.as_ref(), frame, size) + .layout_blocks(store, cursor.as_ref(), frame, size) .await; Self::render_blocks(frame, pos, size, &blocks); } diff --git a/cove-tui/src/chat/tree/cursor.rs b/cove-tui/src/chat/tree/cursor.rs index 91b2805..dc3949b 100644 --- a/cove-tui/src/chat/tree/cursor.rs +++ b/cove-tui/src/chat/tree/cursor.rs @@ -12,7 +12,6 @@ impl TreeView { #[allow(clippy::too_many_arguments)] async fn correct_cursor_offset>( &mut self, - room: &str, store: &S, frame: &mut Frame, size: Size, @@ -28,8 +27,8 @@ impl TreeView { // The cursor is not visible any more. However, we can estimate // whether it is above or below the previous cursor position by // lexicographically comparing both positions' paths. - let old_path = store.path(room, old_cursor_id).await; - let new_path = store.path(room, &cursor.id).await; + let old_path = store.path(old_cursor_id).await; + let new_path = store.path(&cursor.id).await; if new_path < old_path { // Because we moved upwards, the cursor should appear at the top // of the screen. @@ -49,9 +48,7 @@ impl TreeView { // isn't, we need to scroll the screen such that the cursor becomes fully // visible again. To do this, we'll need to re-layout because the cursor // could've moved anywhere. - let blocks = self - .layout_blocks(room, store, Some(cursor), frame, size) - .await; + let blocks = self.layout_blocks(store, Some(cursor), frame, size).await; let cursor_block = blocks.find(&cursor.id).expect("cursor must be in blocks"); // First, ensure the cursor's last line is not below the bottom of the // screen. Then, ensure its top line is not above the top of the screen. @@ -102,7 +99,6 @@ impl TreeView { /// Always stays at the same level of indentation. async fn find_prev_sibling>( &self, - room: &str, store: &S, tree: &mut Tree, id: &mut M::Id, @@ -122,8 +118,8 @@ impl TreeView { } else { // We're at the root of our tree, so we need to move to the root of // the previous tree. - if let Some(prev_tree_id) = store.prev_tree(room, tree.root()).await { - *tree = store.tree(room, &prev_tree_id).await; + if let Some(prev_tree_id) = store.prev_tree(tree.root()).await { + *tree = store.tree(&prev_tree_id).await; *id = prev_tree_id; true } else { @@ -137,7 +133,6 @@ impl TreeView { /// Always stays at the same level of indentation. async fn find_next_sibling>( &self, - room: &str, store: &S, tree: &mut Tree, id: &mut M::Id, @@ -157,8 +152,8 @@ impl TreeView { } else { // We're at the root of our tree, so we need to move to the root of // the next tree. - if let Some(next_tree_id) = store.next_tree(room, tree.root()).await { - *tree = store.tree(room, &next_tree_id).await; + if let Some(next_tree_id) = store.next_tree(tree.root()).await { + *tree = store.tree(&next_tree_id).await; *id = next_tree_id; true } else { @@ -170,14 +165,13 @@ impl TreeView { /// Move to the previous message, or don't move if this is not possible. async fn find_prev_msg>( &self, - room: &str, store: &S, tree: &mut Tree, id: &mut M::Id, ) -> bool { // Move to previous sibling, then to its last child // If not possible, move to parent - if self.find_prev_sibling(room, store, tree, id).await { + if self.find_prev_sibling(store, tree, id).await { while Self::find_last_child(tree, id) {} true } else { @@ -188,7 +182,6 @@ impl TreeView { /// Move to the next message, or don't move if this is not possible. async fn find_next_msg>( &self, - room: &str, store: &S, tree: &mut Tree, id: &mut M::Id, @@ -197,7 +190,7 @@ impl TreeView { return true; } - if self.find_next_sibling(room, store, tree, id).await { + if self.find_next_sibling(store, tree, id).await { return true; } @@ -205,7 +198,7 @@ impl TreeView { // can be found. let mut tmp_id = id.clone(); while Self::find_parent(tree, &mut tmp_id) { - if self.find_next_sibling(room, store, tree, &mut tmp_id).await { + if self.find_next_sibling(store, tree, &mut tmp_id).await { *id = tmp_id; return true; } @@ -216,26 +209,24 @@ impl TreeView { pub async fn move_up>( &mut self, - room: &str, store: &S, cursor: &mut Option>, frame: &mut Frame, size: Size, ) { let old_blocks = self - .layout_blocks(room, store, cursor.as_ref(), frame, size) + .layout_blocks(store, cursor.as_ref(), frame, size) .await; let old_cursor_id = cursor.as_ref().map(|c| c.id.clone()); if let Some(cursor) = cursor { // We have a cursor to move around - let path = store.path(room, &cursor.id).await; - let mut tree = store.tree(room, path.first()).await; - self.find_prev_msg(room, store, &mut tree, &mut cursor.id) - .await; - } else if let Some(last_tree) = store.last_tree(room).await { + let path = store.path(&cursor.id).await; + let mut tree = store.tree(path.first()).await; + self.find_prev_msg(store, &mut tree, &mut cursor.id).await; + } else if let Some(last_tree) = store.last_tree().await { // We need to select the last message of the last tree - let tree = store.tree(room, &last_tree).await; + let tree = store.tree(&last_tree).await; let mut id = last_tree; while Self::find_last_child(&tree, &mut id) {} *cursor = Some(Cursor::new(id)); @@ -244,74 +235,55 @@ impl TreeView { // message to move to. if let Some(cursor) = cursor { - self.correct_cursor_offset( - room, - store, - frame, - size, - &old_blocks, - &old_cursor_id, - cursor, - ) - .await; + self.correct_cursor_offset(store, frame, size, &old_blocks, &old_cursor_id, cursor) + .await; } } pub async fn move_down>( &mut self, - room: &str, store: &S, cursor: &mut Option>, frame: &mut Frame, size: Size, ) { let old_blocks = self - .layout_blocks(room, store, cursor.as_ref(), frame, size) + .layout_blocks(store, cursor.as_ref(), frame, size) .await; let old_cursor_id = cursor.as_ref().map(|c| c.id.clone()); if let Some(cursor) = cursor { - let path = store.path(room, &cursor.id).await; - let mut tree = store.tree(room, path.first()).await; - self.find_next_msg(room, store, &mut tree, &mut cursor.id) - .await; + let path = store.path(&cursor.id).await; + let mut tree = store.tree(path.first()).await; + self.find_next_msg(store, &mut tree, &mut cursor.id).await; } // If that condition doesn't hold, we're already at the bottom in // cursor-less mode and can't move further down anyways. if let Some(cursor) = cursor { - self.correct_cursor_offset( - room, - store, - frame, - size, - &old_blocks, - &old_cursor_id, - cursor, - ) - .await; + self.correct_cursor_offset(store, frame, size, &old_blocks, &old_cursor_id, cursor) + .await; } } pub async fn move_up_sibling>( &mut self, - room: &str, store: &S, cursor: &mut Option>, frame: &mut Frame, size: Size, ) { let old_blocks = self - .layout_blocks(room, store, cursor.as_ref(), frame, size) + .layout_blocks(store, cursor.as_ref(), frame, size) .await; let old_cursor_id = cursor.as_ref().map(|c| c.id.clone()); if let Some(cursor) = cursor { - let path = store.path(room, &cursor.id).await; - let mut tree = store.tree(room, path.first()).await; - self.find_prev_sibling(room, store, &mut tree, &mut cursor.id) + let path = store.path(&cursor.id).await; + let mut tree = store.tree(path.first()).await; + self.find_prev_sibling(store, &mut tree, &mut cursor.id) .await; - } else if let Some(last_tree) = store.last_tree(room).await { + } else if let Some(last_tree) = store.last_tree().await { // I think moving to the root of the last tree makes the most sense // here. Alternatively, we could just not move the cursor, but that // wouldn't be very useful. @@ -321,117 +293,82 @@ impl TreeView { // message to move to. if let Some(cursor) = cursor { - self.correct_cursor_offset( - room, - store, - frame, - size, - &old_blocks, - &old_cursor_id, - cursor, - ) - .await; + self.correct_cursor_offset(store, frame, size, &old_blocks, &old_cursor_id, cursor) + .await; } } pub async fn move_down_sibling>( &mut self, - room: &str, store: &S, cursor: &mut Option>, frame: &mut Frame, size: Size, ) { let old_blocks = self - .layout_blocks(room, store, cursor.as_ref(), frame, size) + .layout_blocks(store, cursor.as_ref(), frame, size) .await; let old_cursor_id = cursor.as_ref().map(|c| c.id.clone()); if let Some(cursor) = cursor { - let path = store.path(room, &cursor.id).await; - let mut tree = store.tree(room, path.first()).await; - self.find_next_sibling(room, store, &mut tree, &mut cursor.id) + let path = store.path(&cursor.id).await; + let mut tree = store.tree(path.first()).await; + self.find_next_sibling(store, &mut tree, &mut cursor.id) .await; } // If that condition doesn't hold, we're already at the bottom in // cursor-less mode and can't move further down anyways. if let Some(cursor) = cursor { - self.correct_cursor_offset( - room, - store, - frame, - size, - &old_blocks, - &old_cursor_id, - cursor, - ) - .await; + self.correct_cursor_offset(store, frame, size, &old_blocks, &old_cursor_id, cursor) + .await; } } pub async fn move_to_first>( &mut self, - room: &str, store: &S, cursor: &mut Option>, frame: &mut Frame, size: Size, ) { let old_blocks = self - .layout_blocks(room, store, cursor.as_ref(), frame, size) + .layout_blocks(store, cursor.as_ref(), frame, size) .await; let old_cursor_id = cursor.as_ref().map(|c| c.id.clone()); - if let Some(tree_id) = store.first_tree(room).await { + if let Some(tree_id) = store.first_tree().await { *cursor = Some(Cursor::new(tree_id)); } if let Some(cursor) = cursor { - self.correct_cursor_offset( - room, - store, - frame, - size, - &old_blocks, - &old_cursor_id, - cursor, - ) - .await; + self.correct_cursor_offset(store, frame, size, &old_blocks, &old_cursor_id, cursor) + .await; } } pub async fn move_to_last>( &mut self, - room: &str, store: &S, cursor: &mut Option>, frame: &mut Frame, size: Size, ) { let old_blocks = self - .layout_blocks(room, store, cursor.as_ref(), frame, size) + .layout_blocks(store, cursor.as_ref(), frame, size) .await; let old_cursor_id = cursor.as_ref().map(|c| c.id.clone()); - if let Some(tree_id) = store.last_tree(room).await { - let tree = store.tree(room, &tree_id).await; + if let Some(tree_id) = store.last_tree().await { + let tree = store.tree(&tree_id).await; let mut id = tree_id; while Self::find_last_child(&tree, &mut id) {} *cursor = Some(Cursor::new(id)); } if let Some(cursor) = cursor { - self.correct_cursor_offset( - room, - store, - frame, - size, - &old_blocks, - &old_cursor_id, - cursor, - ) - .await; + self.correct_cursor_offset(store, frame, size, &old_blocks, &old_cursor_id, cursor) + .await; } } @@ -440,7 +377,6 @@ impl TreeView { pub async fn center_cursor>( &mut self, - room: &str, store: &S, cursor: &mut Option>, frame: &mut Frame, @@ -451,20 +387,10 @@ impl TreeView { // Correcting the offset just to make sure that this function // behaves nicely if the cursor has too many lines. - let old_blocks = self - .layout_blocks(room, store, Some(cursor), frame, size) - .await; + let old_blocks = self.layout_blocks(store, Some(cursor), frame, size).await; let old_cursor_id = Some(cursor.id.clone()); - self.correct_cursor_offset( - room, - store, - frame, - size, - &old_blocks, - &old_cursor_id, - cursor, - ) - .await; + self.correct_cursor_offset(store, frame, size, &old_blocks, &old_cursor_id, cursor) + .await; } } } diff --git a/cove-tui/src/chat/tree/layout.rs b/cove-tui/src/chat/tree/layout.rs index a78506f..3fad499 100644 --- a/cove-tui/src/chat/tree/layout.rs +++ b/cove-tui/src/chat/tree/layout.rs @@ -54,7 +54,6 @@ fn layout_tree(frame: &mut Frame, size: Size, tree: Tree) -> Blocks TreeView { pub async fn expand_blocks_up>( - room: &str, store: &S, frame: &mut Frame, size: Size, @@ -63,13 +62,13 @@ impl TreeView { ) { while blocks.top_line > 0 { *tree_id = if let Some(tree_id) = tree_id { - store.prev_tree(room, tree_id).await + store.prev_tree(tree_id).await } else { break; }; if let Some(tree_id) = tree_id { - let tree = store.tree(room, tree_id).await; + let tree = store.tree(tree_id).await; blocks.prepend(layout_tree(frame, size, tree)); } else { break; @@ -78,7 +77,6 @@ impl TreeView { } pub async fn expand_blocks_down>( - room: &str, store: &S, frame: &mut Frame, size: Size, @@ -87,13 +85,13 @@ impl TreeView { ) { while blocks.bottom_line < size.height as i32 { *tree_id = if let Some(tree_id) = tree_id { - store.next_tree(room, tree_id).await + store.next_tree(tree_id).await } else { break; }; if let Some(tree_id) = tree_id { - let tree = store.tree(room, tree_id).await; + let tree = store.tree(tree_id).await; blocks.append(layout_tree(frame, size, tree)); } else { break; @@ -104,7 +102,6 @@ impl TreeView { // TODO Split up based on cursor presence pub async fn layout_blocks>( &mut self, - room: &str, store: &S, cursor: Option<&Cursor>, frame: &mut Frame, @@ -115,9 +112,9 @@ impl TreeView { // TODO Unfold all messages on path to cursor // Layout cursor subtree (with correct offsets based on cursor) - let cursor_path = store.path(room, &cursor.id).await; + let cursor_path = store.path(&cursor.id).await; let cursor_tree_id = cursor_path.first(); - let cursor_tree = store.tree(room, cursor_tree_id).await; + let cursor_tree = store.tree(cursor_tree_id).await; let mut blocks = layout_tree(frame, size, cursor_tree); blocks.calculate_offsets_with_cursor(cursor, size.height); @@ -136,18 +133,18 @@ impl TreeView { // // TODO Don't expand if there is a focus let mut top_tree_id = Some(cursor_tree_id.clone()); - Self::expand_blocks_up(room, store, frame, size, &mut blocks, &mut top_tree_id).await; + Self::expand_blocks_up(store, frame, size, &mut blocks, &mut top_tree_id).await; if blocks.top_line > 0 { blocks.offset(-blocks.top_line); } let mut bot_tree_id = Some(cursor_tree_id.clone()); - Self::expand_blocks_down(room, store, frame, size, &mut blocks, &mut bot_tree_id).await; + Self::expand_blocks_down(store, frame, size, &mut blocks, &mut bot_tree_id).await; if blocks.bottom_line < size.height as i32 - 1 { blocks.offset(size.height as i32 - 1 - blocks.bottom_line); } // If we only moved the blocks down, we need to expand upwards again // to make sure we fill the screen. - Self::expand_blocks_up(room, store, frame, size, &mut blocks, &mut top_tree_id).await; + Self::expand_blocks_up(store, frame, size, &mut blocks, &mut top_tree_id).await; blocks } else { @@ -157,12 +154,12 @@ impl TreeView { let mut blocks = Blocks::new_below(size.height as i32 - 1); // Expand upwards from last tree - if let Some(last_tree_id) = store.last_tree(room).await { - let last_tree = store.tree(room, &last_tree_id).await; + if let Some(last_tree_id) = store.last_tree().await { + let last_tree = store.tree(&last_tree_id).await; blocks.prepend(layout_tree(frame, size, last_tree)); let mut tree_id = Some(last_tree_id); - Self::expand_blocks_up(room, store, frame, size, &mut blocks, &mut tree_id).await; + Self::expand_blocks_up(store, frame, size, &mut blocks, &mut tree_id).await; } blocks diff --git a/cove-tui/src/store.rs b/cove-tui/src/store.rs index d6fd0f2..b5e93e9 100644 --- a/cove-tui/src/store.rs +++ b/cove-tui/src/store.rs @@ -103,10 +103,10 @@ impl Tree { #[async_trait] pub trait MsgStore { - async fn path(&self, room: &str, id: &M::Id) -> Path; - async fn tree(&self, room: &str, root: &M::Id) -> Tree; - async fn prev_tree(&self, room: &str, tree: &M::Id) -> Option; - async fn next_tree(&self, room: &str, tree: &M::Id) -> Option; - async fn first_tree(&self, room: &str) -> Option; - async fn last_tree(&self, room: &str) -> Option; + async fn path(&self, id: &M::Id) -> Path; + async fn tree(&self, root: &M::Id) -> Tree; + async fn prev_tree(&self, tree: &M::Id) -> Option; + async fn next_tree(&self, tree: &M::Id) -> Option; + async fn first_tree(&self) -> Option; + async fn last_tree(&self) -> Option; } diff --git a/cove-tui/src/store/dummy.rs b/cove-tui/src/store/dummy.rs index 5116bc2..17cb8db 100644 --- a/cove-tui/src/store/dummy.rs +++ b/cove-tui/src/store/dummy.rs @@ -111,7 +111,7 @@ impl DummyStore { #[async_trait] impl MsgStore for DummyStore { - async fn path(&self, _room: &str, id: &usize) -> Path { + async fn path(&self, id: &usize) -> Path { let mut id = *id; let mut segments = vec![id]; while let Some(parent) = self.msgs.get(&id).and_then(|msg| msg.parent) { @@ -122,13 +122,13 @@ impl MsgStore for DummyStore { Path::new(segments) } - async fn tree(&self, _room: &str, root: &usize) -> Tree { + async fn tree(&self, root: &usize) -> Tree { let mut msgs = vec![]; self.collect_tree(*root, &mut msgs); Tree::new(*root, msgs) } - async fn prev_tree(&self, _room: &str, tree: &usize) -> Option { + async fn prev_tree(&self, tree: &usize) -> Option { let trees = self.trees(); trees .iter() @@ -137,7 +137,7 @@ impl MsgStore for DummyStore { .map(|(t, _)| *t) } - async fn next_tree(&self, _room: &str, tree: &usize) -> Option { + async fn next_tree(&self, tree: &usize) -> Option { let trees = self.trees(); trees .iter() @@ -146,11 +146,11 @@ impl MsgStore for DummyStore { .map(|(_, t)| *t) } - async fn first_tree(&self, _room: &str) -> Option { + async fn first_tree(&self) -> Option { self.trees().first().cloned() } - async fn last_tree(&self, _room: &str) -> Option { + async fn last_tree(&self) -> Option { self.trees().last().cloned() } } diff --git a/cove-tui/src/ui.rs b/cove-tui/src/ui.rs index ef134ca..0c87ba5 100644 --- a/cove-tui/src/ui.rs +++ b/cove-tui/src/ui.rs @@ -55,7 +55,7 @@ impl Ui { .msg(DummyMsg::new(10, "abc123", "reply to reply to nothing").parent(8)) .msg(DummyMsg::new(11, "nick", "yet another reply to nothing").parent(7)) .msg(DummyMsg::new(12, "abc123", "beep\nboop").parent(11)); - let chat = Chat::new(store, "testroom".to_string()); + let chat = Chat::new(store); // Run main UI. //