huellas/src/tui/state.rs

118 lines
2.8 KiB
Rust
Raw Normal View History

//! TUI state
use ratatui::widgets::TableState;
use crate::places::{
db_repository::DbPlacesRepository, models::Place, repository::PlacesRepository,
};
pub struct State {
pub height: u16,
pub page: u32,
pub mode: Mode,
places_repository: DbPlacesRepository,
pub places: Vec<Place>,
places_status: DataStatus,
pub confirmation: Option<ConfirmationStatus>,
pub selected_place: TableState,
pub quit: bool,
}
pub enum Mode {
List,
Edit,
}
enum DataStatus {
Fresh,
Old,
}
pub enum ConfirmationStatus {
Deletion(i64),
#[expect(dead_code)]
Save(i64),
}
impl State {
pub fn new(places_repository: DbPlacesRepository, height: u16) -> Self {
Self {
height,
page: 0,
mode: Mode::List,
places_repository,
places_status: DataStatus::Old,
places: vec![],
selected_place: TableState::default(),
confirmation: None,
quit: false,
}
}
pub fn next_page(&mut self) {
self.page += 1;
self.places_status = DataStatus::Old;
}
pub fn prev_page(&mut self) {
self.page = self.page.saturating_sub(1);
self.places_status = DataStatus::Old;
}
pub async fn fetch_places(&mut self) {
if let DataStatus::Fresh = self.places_status {
return;
}
let limit = (self.height as u8).saturating_sub(3);
let offset = (limit as u32) * self.page;
match self
.places_repository
.get_places_paginated(offset, limit)
.await
{
Ok(places) => {
self.places = places;
if !self.places.is_empty() {
self.selected_place.select(Some(0));
}
}
Err(err) => {
tracing::error!("{err}");
}
}
self.places_status = DataStatus::Fresh;
}
pub fn confirm_deletion(&mut self) {
if let Some(Some(id)) = self
.selected_place
.selected()
.map(|index| self.places.get(index).map(|p| p.id))
{
self.confirmation = Some(ConfirmationStatus::Deletion(id))
}
}
pub fn cancel_confirmation(&mut self) {
self.confirmation = None;
}
pub async fn proceed_confirmation(&mut self) {
let Some(confirmation) = &self.confirmation else {
return;
};
match confirmation {
ConfirmationStatus::Deletion(id) => {
if let Err(err) = self.places_repository.delete_place(*id).await {
tracing::error!("{err}");
}
}
ConfirmationStatus::Save(_) => todo!(),
}
self.confirmation = None;
self.places_status = DataStatus::Old;
}
}