use crate::app::AppState; use crate::core::srs::OrderModule::{Fsrs, RandomSRS, SemiRandomSRS, WorstWordsSRS}; use crate::core::srs::{ FsrsModule, OrderMode, OrderModule, RandomSRSModule, SRSModule, SemiRandomSRSModule, WordOpenMode, WorstWordsSRSModule, }; use crate::data::entities::*; use crate::data_provider::card_states::{load_stats_of_deck, update_stat_score}; use crate::data_provider::history::push_note; use crate::notification::{MaybeError, NotificationData}; use chrono::Utc; #[derive(Clone)] pub struct DeckData { pub(crate) words: Vec, pub(crate) set: Vec, current_word_index: Option, state: AppState, order_module: OrderModule, open_mode: OrderMode, settings: DeckSettings, } impl DeckData { pub fn new( settings: &DeckSettings, state: AppState, ) -> Result { todo!() // let state_for = state.clone(); // // let stats = state (settings, &state.connection.read())?; // let words = stats // .iter() // .map(|stat| { // state // .dictionary // .binary_search_by_key(&stat.word_id, |w| w.id) // .expect("No word found in dictionary") // }) // .map(|index| &state.dictionary[index]) // .cloned() // .collect(); // // Ok(Self { // set: stats, // words, // current_word_index: None, // state: state_for, // order_module: Fsrs(FsrsModule::new()), // open_mode: settings.open_mode, // settings: settings.clone(), // }) } pub fn next(&mut self) -> (WordData, CardState) { let index = match self.order_module { SemiRandomSRS(ref mut module) => { if !module.initialized { module.init(self.set.as_slice()) } module.next(self.set.as_slice()) } RandomSRS(ref mut module) => { if !module.initialized { module.init(self.set.as_slice()) } module.next(self.set.as_slice()) } WorstWordsSRS(ref mut module) => { if !module.initialized { module.init(self.set.as_slice()) } module.next(self.set.as_slice()) } Fsrs(ref mut module) => { if !module.initialized { module.init(self.set.as_slice()) } module.next(self.set.as_slice()) } }; self.current_word_index = Some(index); (self.words[index].clone(), self.set[index].clone()) } pub fn open(&mut self, status: WordOpenMode) -> MaybeError { if let Some(index) = self.current_word_index { let word: &mut CardState = &mut self.set[index]; let old_score = word.score; word.update(status); let new_score = word.score; match self.order_module { SemiRandomSRS(ref mut module) => { module.open(status, index, word); } RandomSRS(ref mut module) => { module.open(status, index, word); } WorstWordsSRS(ref mut module) => { module.open(status, index, word); } Fsrs(ref mut module) => { module.open(status, index, word); } } if let Fsrs(ref fsrs) = self.order_module && fsrs.finished() { self.order_module = match self.open_mode { OrderMode::Default => SemiRandomSRS(SemiRandomSRSModule::new()), OrderMode::TrainWorstFirst => WorstWordsSRS(WorstWordsSRSModule::new()), OrderMode::FullRandom => RandomSRS(RandomSRSModule::new()), } } update_stat_score(word, &self.state.connection.read())?; let _ = push_note( self.settings.id, HistoryItem { timestamp: Utc::now(), word_id: word.word_id, mode: status, before: old_score, after: new_score, }, ); } Ok(()) } pub fn len(&self) -> usize { self.set.len() } }