106 lines
3.7 KiB
Rust
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)
|
|
}
|
|
}
|