From f19a6f64c318a3bcc77bfc920307a4cc8398b67c Mon Sep 17 00:00:00 2001 From: Mikhail Mitrofanov Date: Thu, 3 Sep 2026 00:36:15 +0300 Subject: [PATCH] Dictionary partial rewritten and dictionary quiz rewritten --- src/pages/dictionary.rs | 197 ++++++++++++++++++----------------- src/pages/dictionary_quiz.rs | 16 ++- 2 files changed, 114 insertions(+), 99 deletions(-) diff --git a/src/pages/dictionary.rs b/src/pages/dictionary.rs index 55f81bc..6569884 100644 --- a/src/pages/dictionary.rs +++ b/src/pages/dictionary.rs @@ -88,6 +88,7 @@ impl NavigatedPage for DictionaryState { words, self.reverse, self.no_typing, + self.state.clone() ))); } if let WordAction(handle) = message @@ -315,105 +316,113 @@ impl DictionaryState { } fn words_list(&self) -> iced::Element<'_, DictionaryMessage> { - let time = Instant::now(); - let mut col = Column::new().width(Fill); + todo!("Make new display system") + // let time = Instant::now(); + // let mut col = Column::new().width(Fill); + // + // let query = &self.displayed_words_query; + // let dictionary = self.state.dictionary.read(); + // + // + // for access_index in 0..query.len() { + // let mut i = access_index; + // if self.reverse_list { + // i = query.len() - access_index - 1; + // } + // let word_handle = &query[i]; + // let word = dictionary.get_ref_static(*word_handle).unwrap(); + // + // if !self.search.is_empty() + // && !word.key.contains(&self.search) + // && !word.value.contains(&self.search) + // && !word.tags.contains(&self.search) + // { + // continue; + // } + // + // let word_line_data = WordLineState { + // is_included: self.included.contains(word_handle), + // key: word.key.clone().into(), + // value: word.value.clone().into(), + // tags: word.tags.clone().into(), + // handle: word_handle.clone(), + // }; + // + // + // let lazy_line = lazy(word_line_data, |data: &WordLineState| Self::word_line(data)); + // + // col = col.push(lazy_line); + // } + // + // info!("Words rendering time: {:?}", time.elapsed()); + // scrollable(col).height(Fill).into() + } - let query = &self.displayed_words_query; - let dictionary = self.state.dictionary.read(); + pub fn word_line(data: &WordLineState) -> Row<'_, DictionaryMessage> + { + let mut line = Row::new().width(Fill).align_y(Center); + line = line.push( + checkbox(data.is_included) + .label("") + .spacing(15) + .on_toggle(move |b| Include(data.handle, b)), + ); + line = line.push( + text_input("Слово", &data.key) + .size(ACCENT_FONT_SIZE) + .width(Fill) + .on_input(move |string| SetKey(data.handle, string)) + .style(|x, status| { + let mut default_style = default(x, status); + default_style.border.radius = 0.0.into(); + default_style + }), + ); + line = line.push( + text_input("Перевод", &data.value) + .size(ACCENT_FONT_SIZE) + .width(Fill) + .on_input(move |string| SetValue(data.handle, string)) + .style(|x, status| { + let mut default_style = default(x, status); + default_style.border.radius = 0.0.into(); + default_style + }), + ); - for access_index in 0..query.len() { - let mut i = access_index; - if self.reverse_list { - i = query.len() - access_index - 1; - } - let word_handle = &query[i]; - let word = dictionary.get_ref_static(*word_handle).unwrap(); + line = line.push( + text_input("Теги", data.tags.as_ref()) + .size(ACCENT_FONT_SIZE) + .width(Fill) + .on_input(move |string| SetTags(data.handle, string)) + .style(|x, status| { + let mut default_style = default(x, status); + default_style.border.radius = 0.0.into(); + default_style + }), + ); - if !self.search.is_empty() - && !word.key.contains(&self.search) - && !word.value.contains(&self.search) - && !word.tags.contains(&self.search) - { - continue; + let line_button = || { + if !data.handle.real() { + return button("-") + .on_press(WordAction(data.handle)) + .style(|_x: &iced::Theme, _status: iced::widget::button::Status| Style { + background: None, + text_color: Color::BLACK, + border: Border::default(), + shadow: Shadow::default(), + snap: false, + }) + .width(15); } - let word_line_data = WordLineState { - is_included: self.included.contains(word_handle), - key: word.key.clone().into(), - value: word.value.clone().into(), - tags: word.tags.clone().into(), - handle: word_handle.clone(), - }; - - - let lazy_line = lazy(word_line_data, move |data| { - let mut line = Row::new().width(Fill).align_y(Center); - line = line.push( - checkbox(data.is_included) - .label("") - .spacing(15) - .on_toggle(move |b| Include(data.handle, b)), - ); - - line = line.push( - text_input("Слово", &data.key) - .size(ACCENT_FONT_SIZE) - .width(Fill) - .on_input(move |string| SetKey(data.handle, string)) - .style(|x, status| { - let mut default_style = default(x, status); - default_style.border.radius = 0.0.into(); - default_style - }), - ); - line = line.push( - text_input("Перевод", &data.value) - .size(ACCENT_FONT_SIZE) - .width(Fill) - .on_input(move |string| SetValue(data.handle, string)) - .style(|x, status| { - let mut default_style = default(x, status); - default_style.border.radius = 0.0.into(); - default_style - }), - ); - - line = line.push( - text_input("Теги", data.tags.as_ref()) - .size(ACCENT_FONT_SIZE) - .width(Fill) - .on_input(move |string| SetTags(data.handle, string)) - .style(|x, status| { - let mut default_style = default(x, status); - default_style.border.radius = 0.0.into(); - default_style - }), - ); - - let line_button = || { - let action = WordAction(data.handle); - - if !data.handle.real() { - return button("-").on_press(action).style(|_x, _status| Style { - background: None, - text_color: Color::BLACK, - border: Border::default(), - shadow: Shadow::default(), - snap: false, - }); - } - - button("").on_press(WordAction(data.handle)).width(15) - }; - line.push(line_button()).push(space().width(10)) - }); - - col = col.push(lazy_line); - } - - info!("Words rendering time: {:?}", time.elapsed()); - scrollable(col).height(Fill).into() + button("") + .on_press(WordAction(data.handle)) + .style(button::primary) + .width(15) + }; + line.push(line_button()).push(space().width(10)) } fn filters(&self) -> iced::Element<'_, DictionaryMessage> { @@ -597,7 +606,7 @@ pub fn split_with_coma(ts: &str) -> Vec { .collect::>() } -#[derive(Hash, PartialEq, Eq)] +#[derive(Clone, Hash, PartialEq, Eq)] struct WordLineState { is_included: bool, key: Box, diff --git a/src/pages/dictionary_quiz.rs b/src/pages/dictionary_quiz.rs index 9e27dfb..d8fc4cf 100644 --- a/src/pages/dictionary_quiz.rs +++ b/src/pages/dictionary_quiz.rs @@ -12,8 +12,11 @@ use iced::widget::container::Style; use iced::widget::{Row, button, container, row, space, text, text_input}; use iced::{Border, Element, Fill, Task, Theme, alignment}; use rand::prelude::SliceRandom; +use crate::app::AppState; +use crate::data::repositories::Repository; pub struct DictionaryQuizState { + state: AppState, words: Vec>, current_set: Vec>, answer: String, @@ -103,8 +106,9 @@ impl NavigatedPage for DictionaryQuizState { } impl DictionaryQuizState { - pub fn new(words: Vec>, reverse: bool, no_typing: bool) -> DictionaryQuizState { + pub fn new(words: Vec>, reverse: bool, no_typing: bool, state: AppState) -> DictionaryQuizState { let state = DictionaryQuizState { + state, words, current_set: Vec::new(), answer: "".to_string(), @@ -181,12 +185,14 @@ impl DictionaryQuizState { } }; + let repo = self.state.dictionary.read(); + let next = repo.get_static(next).unwrap(); if self.reverse { - self.view = next.value.clone(); - self.correct = next.key.clone(); + self.view = next.value; + self.correct = next.key; } else { - self.view = next.key.clone(); - self.correct = next.value.clone(); + self.view = next.key; + self.correct = next.value; } }