diff --git a/src/components/deck/deck_list.rs b/src/components/deck/deck_list.rs index 6404128..a5bb4b9 100644 --- a/src/components/deck/deck_list.rs +++ b/src/components/deck/deck_list.rs @@ -32,8 +32,11 @@ impl DeckListView { fn get_all_decks_and_stats(&self, collection: &Collection) -> Vec { let decks = get_decks(&collection.storage.conn); - let timing_at_stamp = - CollectionBuilder::timing_for_timestamp(chrono::Local::now().timestamp()); + let timing_at_stamp = CollectionBuilder::timing_for_timestamp( + &collection.storage.conn, + chrono::Local::now().timestamp(), + ); + let decks_stats = Deck::get_decks_stats(&collection.storage.conn, timing_at_stamp.days_elapsed).unwrap(); diff --git a/src/db.rs b/src/db.rs index 571a5b8..88a7ebc 100644 --- a/src/db.rs +++ b/src/db.rs @@ -28,5 +28,13 @@ pub fn init_db(conn: &Connection) -> Result<()> { [], )?; + conn.execute( + "CREATE TABLE IF NOT EXISTS sessions ( + id INTEGER PRIMARY KEY, + creation_stamp INTEGER NOT NULL + )", + [], + )?; + Ok(()) } diff --git a/src/models/collection.rs b/src/models/collection.rs index 5557b9e..c85cc1f 100644 --- a/src/models/collection.rs +++ b/src/models/collection.rs @@ -2,9 +2,13 @@ use std::path::PathBuf; use chrono::Local; use gpui::{AppContext, Global}; +use rusqlite::Connection; use crate::{ - errors::Result, repositories::flash_card::CardQueue, storage::sqlite::SqliteStorage, FlashCard, + errors::Result, + repositories::{flash_card::CardQueue, session::Session}, + storage::sqlite::SqliteStorage, + FlashCard, }; use super::{ @@ -23,9 +27,10 @@ impl CollectionBuilder { } } - pub(crate) fn timing_for_timestamp(now: i64) -> SchedTimingToday { + pub(crate) fn timing_for_timestamp(conn: &Connection, now: i64) -> SchedTimingToday { // Get current utc offset from the system - let days_elapsed = now / 86_400; + let creation_stamp = Session::get_creation_stamp(conn).unwrap(); + let days_elapsed = (now - creation_stamp) / 86_400; let next_day_at = (days_elapsed + 1) * 86_400; SchedTimingToday { @@ -46,7 +51,7 @@ impl Builder for CollectionBuilder { .unwrap_or_else(|| PathBuf::from(":memory:")); let storage = SqliteStorage::open_or_create(&col_path)?; - let timing = Self::timing_for_timestamp(Local::now().timestamp()); + let timing = Self::timing_for_timestamp(&storage.conn, Local::now().timestamp()); let col = Collection { storage, @@ -74,7 +79,7 @@ impl Collection { pub fn apply_state(&self, card: &mut FlashCard, next: CardState) { match next { CardState::New(next_new_state) => { - card.due = next_new_state.position as i32; + card.due = next_new_state.position as u32; card.set_queue(CardQueue::New); } CardState::Learning(next_learning_state) => { @@ -84,7 +89,7 @@ impl Collection { CardState::Review(next_review_state) => { card.set_queue(CardQueue::Review); card.interval = next_review_state.scheduled_days; - card.due = (self.timing.days_elapsed + next_review_state.scheduled_days) as i32; + card.due = (self.timing.days_elapsed + next_review_state.scheduled_days) as u32; card.memory_state = next_review_state.memory_state; } _ => {} diff --git a/src/repositories/deck.rs b/src/repositories/deck.rs index 3d1a990..1268f1f 100644 --- a/src/repositories/deck.rs +++ b/src/repositories/deck.rs @@ -236,8 +236,6 @@ impl Deck { ":day_cutoff" : day_elapsed, }; - println!("Day elapsed: {}", day_elapsed); - conn.prepare(include_str!("query_decks_stats.sql"))? .query_and_then(params, row_to_deck_stat)? .collect() @@ -366,7 +364,7 @@ mod test { let mut new_card = FlashCard::new(1, "Front", "Back", None); new_card.save(&conn).unwrap(); - let stats = Deck::get_decks_stats(&conn).unwrap(); + let stats = Deck::get_decks_stats(&conn, 1).unwrap(); assert_eq!(stats.len(), 1); let deck_stat = stats.get(&deck.id.unwrap()).unwrap(); diff --git a/src/repositories/flash_card.rs b/src/repositories/flash_card.rs index 383d79e..a0b2f18 100644 --- a/src/repositories/flash_card.rs +++ b/src/repositories/flash_card.rs @@ -10,7 +10,9 @@ use rusqlite::{ use time::OffsetDateTime; -use super::card_data::CardData; +use crate::models::collection::CollectionBuilder; + +use super::{card_data::CardData, session::Session}; #[derive(PartialEq, Debug, Clone)] pub enum Status { @@ -51,7 +53,7 @@ pub struct FlashCard { last_studied_time: Option, ef: f32, pub interval: u32, - pub due: i32, + pub due: u32, queue: CardQueue, pub data: CardData, pub memory_state: Option, @@ -115,8 +117,14 @@ impl FlashCard { F: FnMut(&FlashCard) -> (), { let mut stmt = conn.prepare(include_str!("query_cards_in_deck_by_queue.sql"))?; + let timing_at_stamp = + CollectionBuilder::timing_for_timestamp(conn, chrono::Local::now().timestamp()); - let mut rows = stmt.query(params![deck_id, queue as i8])?; + let mut rows = stmt.query(params![ + deck_id, + queue as i8, + timing_at_stamp.days_elapsed as u32 + ])?; while let row = rows.next()? { if let None = row { break; @@ -228,8 +236,8 @@ impl FlashCard { last_studied_time, ef: row.get(6)?, interval: row.get(7)?, - due: row.get(8).ok().unwrap_or_default(), - queue: row.get(9)?, + queue: row.get(8)?, + due: row.get(9)?, memory_state: data.memory_state(), data, }) diff --git a/src/repositories/mod.rs b/src/repositories/mod.rs index e4e67c0..2e05760 100644 --- a/src/repositories/mod.rs +++ b/src/repositories/mod.rs @@ -1,3 +1,4 @@ pub mod card_data; pub mod deck; pub mod flash_card; +pub mod session; diff --git a/src/repositories/query_cards_in_deck_by_queue.sql b/src/repositories/query_cards_in_deck_by_queue.sql index e90c20f..ef3a349 100644 --- a/src/repositories/query_cards_in_deck_by_queue.sql +++ b/src/repositories/query_cards_in_deck_by_queue.sql @@ -15,3 +15,4 @@ FROM WHERE deck_id = ? AND queue = ? + AND due <= ? diff --git a/src/repositories/session.rs b/src/repositories/session.rs new file mode 100644 index 0000000..dfa7fa2 --- /dev/null +++ b/src/repositories/session.rs @@ -0,0 +1,11 @@ +use rusqlite::{Connection, Result}; + +pub struct Session; + +impl Session { + pub fn get_creation_stamp(conn: &Connection) -> Result { + conn.prepare_cached("select creation_stamp from sessions")? + .query_row([], |row| row.get(0)) + .map_err(Into::into) + } +}