From 14125c1650e2ab0b95365b7f75ea1c095b9591f1 Mon Sep 17 00:00:00 2001 From: Joscha Date: Mon, 13 Jun 2022 10:17:30 +0200 Subject: [PATCH] Hook up Chat to UI --- cove-tui/src/chat.rs | 41 +++++++++++++++++++++++++++++++++++++++++ cove-tui/src/main.rs | 1 + cove-tui/src/store.rs | 13 ++++++------- cove-tui/src/ui.rs | 29 +++++++++++++++++++---------- 4 files changed, 67 insertions(+), 17 deletions(-) create mode 100644 cove-tui/src/chat.rs diff --git a/cove-tui/src/chat.rs b/cove-tui/src/chat.rs new file mode 100644 index 0000000..b291e9b --- /dev/null +++ b/cove-tui/src/chat.rs @@ -0,0 +1,41 @@ +use crossterm::event::KeyEvent; +use crossterm::style::ContentStyle; +use toss::frame::{Frame, Pos, Size}; + +use crate::traits::{Msg, MsgStore}; + +pub enum Mode { + Tree, + // Thread, + // Flat, +} + +pub struct Chat> { + cursor: Option, + store: S, + mode: Mode, + // tree: TreeView, + // thread: ThreadView, + // flat: FlatView, +} + +impl> Chat { + pub fn new(store: S) -> Self { + Self { + cursor: None, + store, + mode: Mode::Tree, + } + } +} + +impl> Chat { + pub fn handle_key_event(&mut self, key: KeyEvent, size: Size) { + // TODO + } + + pub fn render(&mut self, frame: &mut Frame, pos: Pos, size: Size) { + // TODO + frame.write(Pos::new(0, 0), "Hello world!", ContentStyle::default()); + } +} diff --git a/cove-tui/src/main.rs b/cove-tui/src/main.rs index f096e69..c5c77d3 100644 --- a/cove-tui/src/main.rs +++ b/cove-tui/src/main.rs @@ -1,6 +1,7 @@ #![warn(clippy::use_self)] mod chat; +mod store; mod traits; mod ui; diff --git a/cove-tui/src/store.rs b/cove-tui/src/store.rs index d703953..9a55802 100644 --- a/cove-tui/src/store.rs +++ b/cove-tui/src/store.rs @@ -1,7 +1,7 @@ use std::collections::HashMap; use async_trait::async_trait; -use chrono::{DateTime, Utc}; +use chrono::{DateTime, TimeZone, Utc}; use crate::traits::{Msg, MsgStore}; @@ -14,21 +14,20 @@ pub struct DummyMsg { } impl DummyMsg { - fn new(id: usize, time: T, nick: S, content: S) -> Self + pub fn new(id: usize, nick: S, content: S) -> Self where - T: Into>, S: Into, { Self { id, parent: None, - time: time.into(), + time: Utc.timestamp(0, 0), nick: nick.into(), content: content.into(), } } - fn parent(mut self, parent: usize) -> Self { + pub fn parent(mut self, parent: usize) -> Self { self.parent = Some(parent); self } @@ -59,13 +58,13 @@ pub struct DummyStore { } impl DummyStore { - fn new() -> Self { + pub fn new() -> Self { Self { msgs: HashMap::new(), } } - fn msg(mut self, msg: DummyMsg) -> Self { + pub fn msg(mut self, msg: DummyMsg) -> Self { self.msgs.insert(msg.id(), msg); self } diff --git a/cove-tui/src/ui.rs b/cove-tui/src/ui.rs index 297a7e3..81c709d 100644 --- a/cove-tui/src/ui.rs +++ b/cove-tui/src/ui.rs @@ -9,9 +9,12 @@ use parking_lot::FairMutex; use tokio::sync::mpsc::error::TryRecvError; use tokio::sync::mpsc::{self, UnboundedReceiver, UnboundedSender}; use tokio::task; -use toss::frame::{Frame, Pos}; +use toss::frame::{Frame, Pos, Size}; use toss::terminal::Terminal; +use crate::chat::Chat; +use crate::store::{DummyMsg, DummyStore}; + #[derive(Debug)] pub enum UiEvent { Redraw, @@ -25,6 +28,7 @@ enum EventHandleResult { pub struct Ui { event_tx: UnboundedSender, + chat: Chat, } impl Ui { @@ -41,6 +45,12 @@ impl Ui { Self::poll_crossterm_events(event_tx_clone, weak_crossterm_lock) }); + // Prepare dummy message store and chat for testing + let store = DummyStore::new() + .msg(DummyMsg::new(1, "nick", "content")) + .msg(DummyMsg::new(2, "Some1Else", "reply").parent(1)); + let chat = Chat::new(store); + // Run main UI. // // If the run_main method exits at any point or if this `run` method is @@ -50,7 +60,7 @@ impl Ui { // // On the other hand, if the crossterm_event_task stops for any reason, // the rest of the UI is also shut down and the client stops. - let mut ui = Self { event_tx }; + let mut ui = Self { event_tx, chat }; let result = tokio::select! { e = ui.run_main(terminal, event_rx, crossterm_lock) => e, Ok(e) = crossterm_event_task => e, @@ -97,9 +107,10 @@ impl Ui { None => return Ok(()), }; loop { + let size = terminal.frame().size(); let result = match event { UiEvent::Redraw => EventHandleResult::Continue, - UiEvent::Term(Event::Key(event)) => self.handle_key_event(event).await, + UiEvent::Term(Event::Key(event)) => self.handle_key_event(event, size).await, UiEvent::Term(Event::Mouse(event)) => self.handle_mouse_event(event).await?, UiEvent::Term(Event::Resize(_, _)) => EventHandleResult::Continue, }; @@ -117,17 +128,15 @@ impl Ui { } async fn render(&mut self, frame: &mut Frame) -> anyhow::Result<()> { - frame.write(Pos::new(0, 0), "Hello world!", ContentStyle::default()); - + self.chat.render(frame, Pos::new(0, 0), frame.size()); Ok(()) } - async fn handle_key_event(&mut self, event: KeyEvent) -> EventHandleResult { - match event.code { - KeyCode::Char('Q') => return EventHandleResult::Stop, - _ => {} + async fn handle_key_event(&mut self, event: KeyEvent, size: Size) -> EventHandleResult { + if let KeyCode::Char('Q') = event.code { + return EventHandleResult::Stop; } - + self.chat.handle_key_event(event, size); EventHandleResult::Continue }