Files
komp_ac/src/client/terminal.rs
2025-02-19 15:25:07 +01:00

106 lines
3.7 KiB
Rust

// 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<CrosstermBackend<io::Stdout>>,
grpc_client: AdresarClient<Channel>, // gRPC client
}
impl AppTerminal {
pub async fn new() -> Result<Self, Box<dyn std::error::Error>> {
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<F>(&mut self, f: F) -> Result<(), Box<dyn std::error::Error>>
where
F: FnOnce(&mut ratatui::Frame),
{
self.terminal.draw(f)?;
Ok(())
}
pub fn read_event(&self) -> Result<Event, Box<dyn std::error::Error>> {
Ok(event::read()?)
}
pub fn cleanup(&mut self) -> Result<(), Box<dyn std::error::Error>> {
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<dyn std::error::Error>> {
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<u64, Box<dyn std::error::Error>> {
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<crate::proto::multieko2::AdresarResponse, Box<dyn std::error::Error>> {
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)
}
}