diff options
author | Joris | 2022-02-13 12:17:00 +0100 |
---|---|---|
committer | Joris | 2022-02-13 12:17:00 +0100 |
commit | 8a29f30fb2a949c03b318c4f7699136a8001be37 (patch) | |
tree | 51decc33aa776201bc800dc2196bc4f8b72337d7 /src/gui | |
parent | 8170fb5e432cc81986479a6a3a400e009426d76a (diff) |
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.
Diffstat (limited to 'src/gui')
-rw-r--r-- | src/gui/gui.rs | 78 | ||||
-rw-r--r-- | src/gui/message.rs | 21 |
2 files changed, 72 insertions, 27 deletions
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<TermionBackend<AlternateScreen<RawTerminal<io::Stdout>>>>; + +pub fn terminal() -> Result<Term> { 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 + ) } } diff --git a/src/gui/message.rs b/src/gui/message.rs index 01d124e..28a1d2c 100644 --- a/src/gui/message.rs +++ b/src/gui/message.rs @@ -12,8 +12,9 @@ use tui::{ pub fn show<B: Backend>( terminal: &mut Terminal<B>, events: &Events, - title: &String, - message: &String, + title: &str, + message: &str, + wait: bool, ) -> Result<()> { loop { terminal.draw(|f| { @@ -26,16 +27,22 @@ pub fn show<B: Backend>( let d1 = util::title(title); f.render_widget(d1, chunks[0]); - let message = Paragraph::new(util::center_vertically(chunks[1], &message)) + let message = Paragraph::new(util::center_vertically(chunks[1], &message.to_string())) .alignment(Alignment::Center); f.render_widget(message, chunks[1]); })?; - if let Event::Input(key) = events.next()? { - match key { - Key::Char('q') => return Ok(()), - _ => (), + if wait { + if let Event::Input(key) = events.next()? { + match key { + Key::Char('q') => break, + _ => (), + } } + } else { + break; } } + + Ok(()) } |