118 lines
2.8 KiB
Rust
118 lines
2.8 KiB
Rust
|
|
//! 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;
|
||
|
|
}
|
||
|
|
}
|