aboutsummaryrefslogtreecommitdiff
path: root/src/gui
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/gui.rs78
-rw-r--r--src/gui/message.rs21
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(())
}