aboutsummaryrefslogtreecommitdiff
path: root/src/gui
diff options
context:
space:
mode:
authorJoris2022-02-13 12:17:00 +0100
committerJoris2022-02-13 12:17:00 +0100
commit8a29f30fb2a949c03b318c4f7699136a8001be37 (patch)
tree51decc33aa776201bc800dc2196bc4f8b72337d7 /src/gui
parent8170fb5e432cc81986479a6a3a400e009426d76a (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.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(())
}