From 8a29f30fb2a949c03b318c4f7699136a8001be37 Mon Sep 17 00:00:00 2001 From: Joris Date: Sun, 13 Feb 2022 12:17:00 +0100 Subject: Synchronize deck only if necessary Look at the modification time of the deck, and synchronize if it has been modified after the last deck read. --- src/gui/gui.rs | 78 +++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 58 insertions(+), 20 deletions(-) (limited to 'src/gui/gui.rs') diff --git a/src/gui/gui.rs b/src/gui/gui.rs index 2f41a0b..2379cfb 100644 --- a/src/gui/gui.rs +++ b/src/gui/gui.rs @@ -1,28 +1,58 @@ +use crate::deck; use crate::util::time; use crate::{db::db, gui::message, gui::question, space_repetition, util::event::Events}; use anyhow::Result; use rusqlite::Connection; -use std::io; -use termion::{raw::IntoRawMode, screen::AlternateScreen}; +use std::{fs, io, time::Duration}; +use termion::{raw::IntoRawMode, raw::RawTerminal, screen::AlternateScreen}; use tui::{backend::TermionBackend, Terminal}; -pub fn start(conn: &Connection, deck_name: &String) -> Result<()> { +type Term = Terminal>>>; + +pub fn terminal() -> Result { let stdout = io::stdout().into_raw_mode()?; let stdout = AlternateScreen::from(stdout); let backend = TermionBackend::new(stdout); - let mut terminal = Terminal::new(backend)?; + Ok(Terminal::new(backend)?) +} + +pub fn synchronize( + conn: &Connection, + term: &mut Term, + events: &Events, + deck_path: &str, + deck_name: &str, +) -> Result<()> { + let last_modified = time::seconds_since_unix_epoch_of(fs::metadata(deck_path)?.modified()?)?; + let last_deck_read = db::last_deck_read(&conn); + let must_synchronize = last_deck_read.map(|r| r < last_modified).unwrap_or(true); - let events = Events::new(); + if must_synchronize { + let _ = message::show(term, events, &deck_name, "Synchronization du deck", false); + time::wait_at_least( + || db::synchronize(&conn, deck::read(&deck_path)?), + Duration::from_secs(1), + )?; + } + Ok(()) +} + +pub fn start( + conn: &Connection, + term: &mut Term, + events: &Events, + deck_name: &String, +) -> Result<()> { let mut answers = 0; loop { - let now = time::now()?; + let now = time::seconds_since_unix_epoch()?; let title = title(deck_name, answers, db::count_available(&conn).unwrap_or(0)); match db::pick_random_ready(&conn) { - Some(card) if card.ready <= now => { - let difficulty = question::ask(&mut terminal, &events, &title, &card)?; + Some(card) => { + let difficulty = question::ask(term, events, &title, &card)?; answers += 1; db::update( &conn, @@ -30,17 +60,15 @@ pub fn start(conn: &Connection, deck_name: &String) -> Result<()> { &space_repetition::update(card.state, difficulty), )?; } - Some(card) => { - let message = format!( - "Prochaine carte disponible dans {}.", - time::pp_duration(card.ready - now) - ); - let _ = message::show(&mut terminal, &events, &title, &message); - break; - } None => { - let message = format!("Aucune carte n’est disponible. Votre deck est-il vide ?"); - let _ = message::show(&mut terminal, &events, &title, &message); + let message = match db::next_ready(&conn) { + Some(ready) => format!( + "Prochaine carte disponible dans {}.", + time::pp_duration(ready - now) + ), + None => format!("Aucune carte n’est disponible. Votre deck est-il vide ?"), + }; + let _ = message::show(term, events, &title, &message, true); break; } } @@ -53,8 +81,18 @@ fn title(deck_name: &String, answers: i32, available_cards: i32) -> String { if answers == 0 && available_cards == 0 { deck_name.to_string() } else if available_cards == 0 { - format!("{} ({} / {})", deck_name, answers, answers + available_cards) + format!( + "{} ({} / {})", + deck_name, + answers, + answers + available_cards + ) } else { - format!("{} ({} / {})", deck_name, answers + 1, answers + available_cards) + format!( + "{} ({} / {})", + deck_name, + answers + 1, + answers + available_cards + ) } } -- cgit v1.2.3