mod tree; use std::sync::Arc; use async_trait::async_trait; use crossterm::event::KeyEvent; use parking_lot::FairMutex; use toss::frame::{Frame, Size}; use toss::terminal::Terminal; use crate::store::{Msg, MsgStore}; use self::tree::{TreeView, TreeViewState}; use super::widgets::Widget; /////////// // State // /////////// pub enum Mode { Tree, // Thread, // Flat, } pub struct ChatState> { store: S, mode: Mode, tree: TreeViewState, // thread: ThreadView, // flat: FlatView, } impl + Clone> ChatState { pub fn new(store: S) -> Self { Self { mode: Mode::Tree, tree: TreeViewState::new(store.clone()), store, } } } impl> ChatState { pub fn store(&self) -> &S { &self.store } pub fn widget(&self) -> Chat { match self.mode { Mode::Tree => Chat::Tree(self.tree.widget()), } } pub async fn handle_navigation(&mut self, event: KeyEvent) -> bool { match self.mode { Mode::Tree => self.tree.handle_navigation(event).await, } } pub async fn handle_messaging( &mut self, terminal: &mut Terminal, crossterm_lock: &Arc>, event: KeyEvent, ) -> Option<(Option, String)> { match self.mode { Mode::Tree => { self.tree .handle_messaging(terminal, crossterm_lock, event) .await } } } } //////////// // Widget // //////////// pub enum Chat> { Tree(TreeView), } #[async_trait] impl Widget for Chat where M: Msg, M::Id: Send + Sync, S: MsgStore + Send + Sync, { fn size(&self, frame: &mut Frame, max_width: Option, max_height: Option) -> Size { match self { Self::Tree(tree) => tree.size(frame, max_width, max_height), } } async fn render(self: Box, frame: &mut Frame) { match *self { Self::Tree(tree) => Box::new(tree).render(frame).await, } } }