diff options
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(())  } | 
