Hook up simple cursor movement

This commit is contained in:
Joscha 2022-07-20 17:34:32 +02:00
parent 48943f2316
commit 34e7af684b
4 changed files with 45 additions and 58 deletions

View file

@ -1,6 +1,7 @@
mod tree; mod tree;
use async_trait::async_trait; use async_trait::async_trait;
use crossterm::event::KeyEvent;
use toss::frame::{Frame, Size}; use toss::frame::{Frame, Size};
use crate::store::{Msg, MsgStore}; use crate::store::{Msg, MsgStore};
@ -47,23 +48,12 @@ impl<M: Msg, S: MsgStore<M>> ChatState<M, S> {
Mode::Tree => Chat::Tree(self.tree.widget()), Mode::Tree => Chat::Tree(self.tree.widget()),
} }
} }
}
impl<M: Msg, S: MsgStore<M>> Chat<M, S> { pub async fn handle_navigation(&mut self, event: KeyEvent) {
// pub async fn handle_navigation( match self.mode {
// &mut self, Mode::Tree => self.tree.handle_navigation(event).await,
// terminal: &mut Terminal, }
// size: Size, }
// event: KeyEvent,
// ) {
// match self.mode {
// Mode::Tree => {
// self.tree
// .handle_navigation(&mut self.store, &mut self.cursor, terminal, size, event)
// .await
// }
// }
// }
// pub async fn handle_messaging( // pub async fn handle_messaging(
// &mut self, // &mut self,
@ -85,16 +75,6 @@ impl<M: Msg, S: MsgStore<M>> Chat<M, S> {
// } // }
// } // }
// } // }
// pub async fn render(&mut self, frame: &mut Frame, pos: Pos, size: Size) {
// match self.mode {
// Mode::Tree => {
// self.tree
// .render(&mut self.store, &self.cursor, frame, pos, size)
// .await
// }
// }
// }
} }
//////////// ////////////

View file

@ -8,6 +8,7 @@ mod util;
use std::sync::Arc; use std::sync::Arc;
use async_trait::async_trait; use async_trait::async_trait;
use crossterm::event::{KeyCode, KeyEvent};
use tokio::sync::Mutex; use tokio::sync::Mutex;
use toss::frame::{Frame, Size}; use toss::frame::{Frame, Size};
@ -44,6 +45,16 @@ impl<M: Msg, S: MsgStore<M>> InnerTreeViewState<M, S> {
editor: (), editor: (),
} }
} }
async fn handle_navigation(&mut self, event: KeyEvent) {
match event.code {
KeyCode::Up | KeyCode::Char('k') => self.move_cursor_up().await,
KeyCode::Down | KeyCode::Char('j') => self.move_cursor_down().await,
KeyCode::Char('g') => self.move_cursor_to_top().await,
KeyCode::Char('G') => self.move_cursor_to_bottom().await,
_ => {}
}
}
} }
pub struct TreeViewState<M: Msg, S: MsgStore<M>>(Arc<Mutex<InnerTreeViewState<M, S>>>); pub struct TreeViewState<M: Msg, S: MsgStore<M>>(Arc<Mutex<InnerTreeViewState<M, S>>>);
@ -56,6 +67,10 @@ impl<M: Msg, S: MsgStore<M>> TreeViewState<M, S> {
pub fn widget(&self) -> TreeView<M, S> { pub fn widget(&self) -> TreeView<M, S> {
TreeView(self.0.clone()) TreeView(self.0.clone())
} }
pub async fn handle_navigation(&mut self, event: KeyEvent) {
self.0.lock().await.handle_navigation(event).await;
}
} }
//////////// ////////////

View file

@ -78,15 +78,15 @@ impl<M: Msg, S: MsgStore<M>> InnerTreeViewState<M, S> {
/// Move to the previous sibling, or don't move if this is not possible. /// Move to the previous sibling, or don't move if this is not possible.
/// ///
/// Always stays at the same level of indentation. /// Always stays at the same level of indentation.
async fn find_prev_sibling(&self, tree: &mut Tree<M>, id: &mut M::Id) -> bool { async fn find_prev_sibling(store: &S, tree: &mut Tree<M>, id: &mut M::Id) -> bool {
if let Some(prev_sibling) = tree.prev_sibling(id) { if let Some(prev_sibling) = tree.prev_sibling(id) {
*id = prev_sibling; *id = prev_sibling;
true true
} else if tree.parent(id).is_none() { } else if tree.parent(id).is_none() {
// We're at the root of our tree, so we need to move to the root of // We're at the root of our tree, so we need to move to the root of
// the previous tree. // the previous tree.
if let Some(prev_tree_id) = self.store.prev_tree(tree.root()).await { if let Some(prev_tree_id) = store.prev_tree(tree.root()).await {
*tree = self.store.tree(&prev_tree_id).await; *tree = store.tree(&prev_tree_id).await;
*id = prev_tree_id; *id = prev_tree_id;
true true
} else { } else {
@ -100,15 +100,15 @@ impl<M: Msg, S: MsgStore<M>> InnerTreeViewState<M, S> {
/// Move to the next sibling, or don't move if this is not possible. /// Move to the next sibling, or don't move if this is not possible.
/// ///
/// Always stays at the same level of indentation. /// Always stays at the same level of indentation.
async fn find_next_sibling(&self, tree: &mut Tree<M>, id: &mut M::Id) -> bool { async fn find_next_sibling(store: &S, tree: &mut Tree<M>, id: &mut M::Id) -> bool {
if let Some(next_sibling) = tree.next_sibling(id) { if let Some(next_sibling) = tree.next_sibling(id) {
*id = next_sibling; *id = next_sibling;
true true
} else if tree.parent(id).is_none() { } else if tree.parent(id).is_none() {
// We're at the root of our tree, so we need to move to the root of // We're at the root of our tree, so we need to move to the root of
// the next tree. // the next tree.
if let Some(next_tree_id) = self.store.next_tree(tree.root()).await { if let Some(next_tree_id) = store.next_tree(tree.root()).await {
*tree = self.store.tree(&next_tree_id).await; *tree = store.tree(&next_tree_id).await;
*id = next_tree_id; *id = next_tree_id;
true true
} else { } else {
@ -120,10 +120,10 @@ impl<M: Msg, S: MsgStore<M>> InnerTreeViewState<M, S> {
} }
/// Move to the previous message, or don't move if this is not possible. /// Move to the previous message, or don't move if this is not possible.
async fn find_prev_msg(&self, tree: &mut Tree<M>, id: &mut M::Id) -> bool { async fn find_prev_msg(store: &S, tree: &mut Tree<M>, id: &mut M::Id) -> bool {
// Move to previous sibling, then to its last child // Move to previous sibling, then to its last child
// If not possible, move to parent // If not possible, move to parent
if self.find_prev_sibling(tree, id).await { if Self::find_prev_sibling(store, tree, id).await {
while Self::find_last_child(tree, id) {} while Self::find_last_child(tree, id) {}
true true
} else { } else {
@ -132,12 +132,12 @@ impl<M: Msg, S: MsgStore<M>> InnerTreeViewState<M, S> {
} }
/// Move to the next message, or don't move if this is not possible. /// Move to the next message, or don't move if this is not possible.
async fn find_next_msg(&self, tree: &mut Tree<M>, id: &mut M::Id) -> bool { async fn find_next_msg(store: &S, tree: &mut Tree<M>, id: &mut M::Id) -> bool {
if Self::find_first_child(tree, id) { if Self::find_first_child(tree, id) {
return true; return true;
} }
if self.find_next_sibling(tree, id).await { if Self::find_next_sibling(store, tree, id).await {
return true; return true;
} }
@ -145,7 +145,7 @@ impl<M: Msg, S: MsgStore<M>> InnerTreeViewState<M, S> {
// can be found. // can be found.
let mut tmp_id = id.clone(); let mut tmp_id = id.clone();
while Self::find_parent(tree, &mut tmp_id) { while Self::find_parent(tree, &mut tmp_id) {
if self.find_next_sibling(tree, &mut tmp_id).await { if Self::find_next_sibling(store, tree, &mut tmp_id).await {
*id = tmp_id; *id = tmp_id;
return true; return true;
} }
@ -154,43 +154,43 @@ impl<M: Msg, S: MsgStore<M>> InnerTreeViewState<M, S> {
false false
} }
pub async fn move_up(&mut self, cursor: &mut Cursor<M::Id>) { pub async fn move_cursor_up(&mut self) {
match cursor { match &mut self.cursor {
Cursor::Bottom => { Cursor::Bottom => {
if let Some(last_tree_id) = self.store.last_tree().await { if let Some(last_tree_id) = self.store.last_tree().await {
let tree = self.store.tree(&last_tree_id).await; let tree = self.store.tree(&last_tree_id).await;
let mut id = last_tree_id; let mut id = last_tree_id;
while Self::find_last_child(&tree, &mut id) {} while Self::find_last_child(&tree, &mut id) {}
*cursor = Cursor::Msg(id); self.cursor = Cursor::Msg(id);
} }
} }
Cursor::Msg(ref mut msg) => { Cursor::Msg(ref mut msg) => {
let path = self.store.path(msg).await; let path = self.store.path(msg).await;
let mut tree = self.store.tree(path.first()).await; let mut tree = self.store.tree(path.first()).await;
self.find_prev_msg(&mut tree, msg).await; Self::find_prev_msg(&self.store, &mut tree, msg).await;
} }
_ => {} _ => {}
} }
} }
pub async fn move_down(&mut self, cursor: &mut Cursor<M::Id>) { pub async fn move_cursor_down(&mut self) {
if let Cursor::Msg(ref mut msg) = cursor { if let Cursor::Msg(ref mut msg) = &mut self.cursor {
let path = self.store.path(msg).await; let path = self.store.path(msg).await;
let mut tree = self.store.tree(path.first()).await; let mut tree = self.store.tree(path.first()).await;
if !self.find_next_msg(&mut tree, msg).await { if !Self::find_next_msg(&self.store, &mut tree, msg).await {
*cursor = Cursor::Bottom; self.cursor = Cursor::Bottom;
} }
} }
} }
pub async fn move_to_first(&mut self, cursor: &mut Cursor<M::Id>) { pub async fn move_cursor_to_top(&mut self) {
if let Some(tree_id) = self.store.first_tree().await { if let Some(tree_id) = self.store.first_tree().await {
*cursor = Cursor::Msg(tree_id); self.cursor = Cursor::Msg(tree_id);
} }
} }
pub async fn move_to_last(&mut self, cursor: &mut Cursor<M::Id>) { pub async fn move_cursor_to_bottom(&mut self) {
*cursor = Cursor::Bottom; self.cursor = Cursor::Bottom;
} }
} }

View file

@ -295,15 +295,7 @@ impl EuphRoom {
crossterm_lock: &Arc<FairMutex<()>>, crossterm_lock: &Arc<FairMutex<()>>,
event: KeyEvent, event: KeyEvent,
) { ) {
// Position of vertical line between main part and nick list self.chat.handle_navigation(event).await;
let vsplit = size.width.saturating_sub(self.nick_list_width + 1) as i32;
// Position of horizontal line between status and chat
let hsplit = 1_i32;
let chat_size = Size::new(vsplit as u16, size.height.saturating_sub(hsplit as u16 + 1));
// self.chat
// .handle_navigation(terminal, chat_size, event)
// .await;
if let Some(room) = &self.room { if let Some(room) = &self.room {
if let Ok(Some(Status::Joined(_))) = room.status().await { if let Ok(Some(Status::Joined(_))) = room.status().await {