From bc0e360b968fcaf15b670416db3e15518a199802 Mon Sep 17 00:00:00 2001 From: Mikhail Mitrofanov Date: Mon, 20 Apr 2026 15:21:31 +0300 Subject: [PATCH] Repetition stats --- src/lang.rs | 4 ++++ src/repetition.rs | 25 +++++++++++++++---------- src/repetitions.rs | 4 ++++ 3 files changed, 23 insertions(+), 10 deletions(-) diff --git a/src/lang.rs b/src/lang.rs index 34c4017..4f832f1 100644 --- a/src/lang.rs +++ b/src/lang.rs @@ -392,4 +392,8 @@ impl CardSet { fn history_len(&self) -> usize { return min(MAX_HISTORY_LEN, (self.set.len() as f32 * MAX_HISTORY_LEN_PART) as usize); } + + pub fn len(&self) -> usize { + self.set.len() + } } diff --git a/src/repetition.rs b/src/repetition.rs index 53fcccc..e82b59a 100644 --- a/src/repetition.rs +++ b/src/repetition.rs @@ -1,3 +1,4 @@ +use std::collections::HashSet; use crate::data_provider::voice::get_voice; use crate::lang::{CardSet, DictionaryElement, WordOpenMode}; use crate::repetitions::CardSetSettings; @@ -19,6 +20,7 @@ pub struct RepetitionState { open: bool, can_play: bool, sink: Arc, + opened: HashSet, } impl NavigatedPage for RepetitionState { @@ -44,7 +46,8 @@ impl RepetitionState { current_word: word, open: false, can_play: true, - sink: Arc::new(sink_handle) + sink: Arc::new(sink_handle), + opened: HashSet::new(), } } } @@ -62,8 +65,9 @@ impl RepetitionState { self.can_play = false; let value = self.current_word.key.clone(); - - return Task::perform(play_sound(self.sink.clone(), value), |_| RootMessage::Repetition(RepetitionMessage::PlayFinished)); + if self.settings.require_speech() { + return Task::perform(play_sound(self.sink.clone(), value), |_| RootMessage::Repetition(RepetitionMessage::PlayFinished)); + } }, RepetitionMessage::PlayFinished => { self.can_play = true; @@ -77,11 +81,7 @@ impl RepetitionState { fn next(&mut self) -> Task { if self.open { - self.set.open(WordOpenMode::None); - self.current_word = self.set.next(); - self.open = false; - - return Task::perform(play_sound(self.sink.clone(), self.current_word.key.clone()), |_| RootMessage::Repetition(RepetitionMessage::PlayFinished)); + self.answer(WordOpenMode::None) } else { self.open = true; return Task::none(); @@ -95,9 +95,13 @@ impl RepetitionState { self.set.open(mode); self.open = false; + self.opened.insert(self.current_word.id); self.current_word = self.set.next(); - return Task::perform(play_sound(self.sink.clone(), self.current_word.key.clone()), |_| RootMessage::Repetition(RepetitionMessage::PlayFinished)); + if self.settings.require_speech() { + return Task::perform(play_sound(self.sink.clone(), self.current_word.key.clone()), |_| RootMessage::Repetition(RepetitionMessage::PlayFinished)); + } + Task::none() } pub fn view(&self) -> Element<'_, RepetitionMessage> { @@ -119,7 +123,8 @@ impl RepetitionState { container(self.answer_bar()) .width(Fill) .align_x(Center) - .height(30) + .height(30), + text!("Затронуто слов {}, {}%", self.opened.len(), (self.opened.len() as f32 / self.set.len() as f32 * 10000.0).round() / 100.0) ] .height(Fill) .width(Fill) diff --git a/src/repetitions.rs b/src/repetitions.rs index 5ad0516..1505b08 100644 --- a/src/repetitions.rs +++ b/src/repetitions.rs @@ -285,4 +285,8 @@ impl CardSetSettings { list } + + pub fn require_speech(&self) -> bool { + return self.forward == "speech" || self.backward == "speech" + } }