Hook up simple cursor movement
This commit is contained in:
parent
48943f2316
commit
34e7af684b
4 changed files with 45 additions and 58 deletions
|
|
@ -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
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////
|
////////////
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////
|
////////////
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue