@@ -7,6 +7,7 @@ use tokio::sync::mpsc::unbounded_channel;
77use tracing:: error;
88
99use super :: Component ;
10+ use crate :: conduit:: ViewEnd ;
1011use crate :: ui:: action:: Action ;
1112use crate :: ui:: config:: {
1213 Config ,
@@ -20,6 +21,7 @@ use crate::ui::tui::{
2021pub struct App {
2122 pub config : Config ,
2223 pub should_quit : bool ,
24+ pub view_end : ViewEnd ,
2325 pub components : Arc < Mutex < Vec < Box < dyn Component > > > > ,
2426}
2527
@@ -32,16 +34,37 @@ impl App {
3234 // TODO: make a defer routine that restores the terminal on exit
3335 tui. enter ( ) ?;
3436
35- let mut event_receiver = tui. event_rx . take ( ) . expect ( "Missing event receiver" ) ;
37+ let mut terminal_event_receiver = tui. event_rx . take ( ) . expect ( "Missing event receiver" ) ;
3638 let components_clone = self . components . clone ( ) ;
3739
3840 // Render Task
3941 tokio:: spawn ( async move {
4042 while render_rx. recv ( ) . await . is_some ( ) {
4143 let mut components = components_clone. lock ( ) . await ;
4244 tui. terminal . draw ( |f| {
43- for component in components. iter_mut ( ) {
44- if let Err ( e) = component. draw ( f, f. area ( ) ) {
45+ use ratatui:: layout:: {
46+ Constraint ,
47+ Layout ,
48+ } ;
49+
50+ // Split the screen: chat window takes most space, input bar at bottom
51+ let chunks = Layout :: vertical ( [
52+ Constraint :: Min ( 1 ) , // Chat window takes remaining space
53+ Constraint :: Length ( 3 ) , // Input bar has fixed height of 3 lines
54+ ] )
55+ . split ( f. area ( ) ) ;
56+
57+ // Render each component in its designated area
58+ // First component (ChatWindow) gets the top area
59+ // Second component (InputBar) gets the bottom area
60+ for ( i, component) in components. iter_mut ( ) . enumerate ( ) {
61+ let rect = if i == 0 {
62+ chunks[ 0 ] // ChatWindow
63+ } else {
64+ chunks[ 1 ] // InputBar
65+ } ;
66+
67+ if let Err ( e) = component. draw ( f, rect) {
4568 error ! ( "Error rendering component {:?}" , e) ;
4669 }
4770 }
@@ -59,14 +82,12 @@ impl App {
5982 tokio:: spawn ( async move {
6083 let mut key_event_buf = Vec :: < crossterm:: event:: KeyEvent > :: new ( ) ;
6184
62- while let Some ( event) = event_receiver . recv ( ) . await {
63- let Ok ( action) = handle_events ( & event, & mut key_event_buf, & config) else {
64- error ! ( "Error covnerting tui events to action" ) ;
85+ while let Some ( event) = terminal_event_receiver . recv ( ) . await {
86+ let Ok ( action) = handle_ui_events ( & event, & mut key_event_buf, & config) else {
87+ error ! ( "Error converting tui events to action" ) ;
6588 continue ;
6689 } ;
6790
68- tracing:: info!( "action: {:?}" , action) ;
69-
7091 match action {
7192 Some ( action) => {
7293 if let Err ( e) = action_tx_clone. send ( action) {
@@ -79,7 +100,7 @@ impl App {
79100 let mut components = components_clone. lock ( ) . await ;
80101
81102 for component in components. iter_mut ( ) {
82- match component. handle_events ( event. clone ( ) ) {
103+ match component. handle_terminal_events ( event. clone ( ) ) {
83104 Ok ( action) => {
84105 if let Some ( action) = action {
85106 if let Err ( e) = action_tx_clone. send ( action) {
@@ -97,42 +118,76 @@ impl App {
97118 }
98119 } ) ;
99120
100- // Main loop
101- while let Some ( action) = action_rx. recv ( ) . await {
102- match action {
103- Action :: Render => {
104- if let Err ( e) = render_tx. send ( ( ) ) {
105- error ! ( "Error sending rendering message to rendering thread: {:?}" , e) ;
121+ loop {
122+ tokio:: select! {
123+ session_event = self . view_end. receiver. recv( ) => {
124+ let Some ( session_event) = session_event else {
125+ break ;
126+ } ;
127+
128+ let mut components = self . components. lock( ) . await ;
129+ for component in components. iter_mut( ) {
130+ match component. handle_session_events( session_event. clone( ) ) {
131+ Ok ( subsequent_action) => {
132+ if let Some ( subsequent_action) = subsequent_action {
133+ if let Err ( e) = action_tx. send( subsequent_action) {
134+ error!( "Error sending subsequent action: {:?}" , e) ;
135+ }
136+ }
137+ } ,
138+ Err ( e) => error!( "Error updating component: {:?}" , e) ,
139+ }
106140 }
107141 } ,
108- Action :: Tick => { } ,
109- Action :: Resize ( _, _) => { } ,
110- Action :: Quit => { } ,
111- Action :: ClearScreen => { } ,
112- Action :: Error ( _) => { } ,
113- Action :: Help => { } ,
114- }
142+ action = action_rx. recv( ) => {
143+ let Some ( action) = action else {
144+ break ;
145+ } ;
115146
116- let mut components = self . components . lock ( ) . await ;
117- for component in components. iter_mut ( ) {
118- match component. update ( action. clone ( ) ) {
119- Ok ( subsequent_action) => {
120- if let Some ( subsequent_action) = subsequent_action {
121- if let Err ( e) = action_tx. send ( subsequent_action) {
122- error ! ( "Error sending subsequent action: {:?}" , e) ;
147+ match & action {
148+ Action :: Render => {
149+ if let Err ( e) = render_tx. send( ( ) ) {
150+ error!( "Error sending rendering message to rendering thread: {:?}" , e) ;
151+ }
152+ } ,
153+ Action :: Tick => { } ,
154+ Action :: Resize ( _, _) => { } ,
155+ Action :: Quit => { } ,
156+ Action :: ClearScreen => { } ,
157+ Action :: Error ( _) => { } ,
158+ Action :: Help => { } ,
159+ Action :: Input ( input_event) => {
160+ if let Err ( e) = self . view_end. sender. send( input_event. clone( ) ) . await {
161+ error!( "Error sending input event to control end: {:?}" , e) ;
123162 }
124163 }
125- } ,
126- Err ( e) => error ! ( "Error updating component: {:?}" , e) ,
127- }
164+ }
165+
166+ let mut components = self . components. lock( ) . await ;
167+ for component in components. iter_mut( ) {
168+ match component. update( action. clone( ) ) {
169+ Ok ( subsequent_action) => {
170+ if let Some ( subsequent_action) = subsequent_action {
171+ if let Err ( e) = action_tx. send( subsequent_action) {
172+ error!( "Error sending subsequent action: {:?}" , e) ;
173+ }
174+ }
175+ } ,
176+ Err ( e) => error!( "Error updating component: {:?}" , e) ,
177+ }
178+ }
179+ } ,
180+
128181 }
129182 }
183+ // Main loop
130184
131185 Ok ( ( ) )
132186 }
133187}
134188
135- fn handle_events (
189+ #[ inline]
190+ fn handle_ui_events (
136191 event : & Event ,
137192 key_event_buf : & mut Vec < crossterm:: event:: KeyEvent > ,
138193 config : & Config ,
@@ -175,7 +230,7 @@ fn handle_events(
175230 } ,
176231 }
177232 } ,
178- _ | KeyEventKind :: Repeat => Ok ( None ) ,
233+ KeyEventKind :: Repeat => Ok ( None ) ,
179234 }
180235 } ,
181236 _ => Err ( eyre:: eyre!( "Event not yet supported" ) ) ,
0 commit comments