// src/client/terminal.rs use crossterm::event::{self, Event, KeyCode, KeyModifiers}; use crossterm::{ execute, terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen}, }; use ratatui::{backend::CrosstermBackend, Terminal}; use std::io::{self, stdout}; use tonic::transport::Channel; use crate::proto::multieko2::{ adresar_client::AdresarClient, Empty, CountResponse, PositionRequest, AdresarResponse, PostAdresarRequest }; use crate::client::config::Config; pub struct AppTerminal { terminal: Terminal>, grpc_client: AdresarClient, // gRPC client } impl AppTerminal { pub async fn new() -> Result> { enable_raw_mode()?; let mut stdout = stdout(); execute!(stdout, EnterAlternateScreen)?; let backend = CrosstermBackend::new(stdout); let terminal = Terminal::new(backend)?; // Initialize gRPC client let grpc_client = AdresarClient::connect("http://[::1]:50051").await?; Ok(Self { terminal, grpc_client }) } pub fn draw(&mut self, f: F) -> Result<(), Box> where F: FnOnce(&mut ratatui::Frame), { self.terminal.draw(f)?; Ok(()) } pub fn read_event(&self) -> Result> { Ok(event::read()?) } pub fn cleanup(&mut self) -> Result<(), Box> { disable_raw_mode()?; execute!(self.terminal.backend_mut(), LeaveAlternateScreen)?; Ok(()) } pub async fn handle_command( &mut self, action: &str, is_saved: &mut bool, // form_state: &mut FormState, form_data: &PostAdresarRequest, ) -> Result<(bool, String), Box> { match action { "save" => { // Send data to the server let request = tonic::Request::new(form_data.clone()); let response = self.grpc_client.post_adresar(request).await?; // form_state.has_unsaved_changes = false; *is_saved = true; Ok((false, format!("State saved. Response: {:?}", response))) } "quit" => { if *is_saved { self.cleanup()?; Ok((true, "Exiting.".to_string())) } else { Ok((false, "No changes saved. Use :q! to force quit.".to_string())) } } "force_quit" => { self.cleanup()?; Ok((true, "Force exiting without saving.".to_string())) } "save_and_quit" => { *is_saved = true; self.cleanup()?; Ok((true, "State saved. Exiting.".to_string())) } _ => Ok((false, format!("Action not recognized: {}", action))), } } // Add a method to get the total count of Adresar entries pub async fn get_adresar_count(&mut self) -> Result> { let request = tonic::Request::new(Empty::default()); let response: CountResponse = self.grpc_client.get_adresar_count(request).await?.into_inner(); Ok(response.count as u64) } // Add a method to get an Adresar entry by its position pub async fn get_adresar_by_position(&mut self, position: u64) -> Result> { let request = tonic::Request::new(PositionRequest { position: position as i64 }); let response: AdresarResponse = self.grpc_client.get_adresar_by_position(request).await?.into_inner(); Ok(response) } }