From 92b019b072f5bb170fbc642120fb7d7c57d033b6 Mon Sep 17 00:00:00 2001 From: Mikhail Mitrofanov Date: Mon, 7 Sep 2026 18:00:50 +0300 Subject: [PATCH] Temporal dictionary display fix --- src/pages/dictionary.rs | 135 ++++++++++++++++++++-------------------- 1 file changed, 67 insertions(+), 68 deletions(-) diff --git a/src/pages/dictionary.rs b/src/pages/dictionary.rs index 8f1b275..82c4b5a 100644 --- a/src/pages/dictionary.rs +++ b/src/pages/dictionary.rs @@ -2,6 +2,7 @@ use crate::app::AppState; use crate::data::Id; use crate::data::entities::{EntityHandle, WordData, WordGroup}; use crate::data::repositories::{Query, Repository}; +use crate::data_provider::word_groups::{WordGroupDataLayer, WordGroupRepositoryInner}; use crate::data_provider::words::WordDataLayer; use crate::data_provider::words::WordRepositoryInner; use crate::navigation::Page::{Import, Word}; @@ -28,7 +29,6 @@ use rand::random_range; use std::ops::Add; use std::sync::Arc; use std::time::{Duration, Instant}; -use crate::data_provider::word_groups::{WordGroupDataLayer, WordGroupRepositoryInner}; pub struct DictionaryState { state: AppState, @@ -89,7 +89,7 @@ impl NavigatedPage for DictionaryState { words, self.reverse, self.no_typing, - self.state.clone() + self.state.clone(), ))); } if let WordAction(handle) = message @@ -206,6 +206,7 @@ impl NavigatedPage for DictionaryState { } SelectGroup(i) => { self.selected_group = i; + self.setup_words_query(i.id); self.update_words_include(i.id) } DeleteGroup => { @@ -241,7 +242,7 @@ impl NavigatedPage for DictionaryState { let mut dictionary = self.state.dictionary.write(); - let _ = dictionary.save(&mut handle); + let _ = dictionary.save(&mut handle); return Task::none(); } } @@ -299,11 +300,15 @@ impl DictionaryState { } fn init(&mut self) { - self.displayed_words_query = self.state.dictionary.read().query_par(Arc::new(|word| word.group_id == Id(1))); + self.displayed_words_query = self + .state + .dictionary + .read() + .query_par(Arc::new(|word| word.group_id == Id(1))); } fn setup_words_query(&mut self, id: Id) { - // self.displayed_words_query = self.state.dictionary.read().query_par(Arc::new(|word| word.group_id == Self::get_id(self))); + self.displayed_words_query = self.state.dictionary.read().query_par(Arc::new(move |word| word.group_id == id)); } fn launch_auto_save_offset(&mut self, handle: EntityHandle) -> Task { @@ -317,63 +322,60 @@ impl DictionaryState { } fn words_list(&self) -> iced::Element<'_, DictionaryMessage> { - 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 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, Self::word_line); + + col = col.push(lazy_line); + } + + info!("Words rendering time: {:?}", time.elapsed()); + scrollable(col).height(Fill).into() } - pub fn word_line(data: &WordLineState) -> Row<'_, DictionaryMessage> - { + pub fn word_line<'a>(data: &WordLineState) -> Row<'a, DictionaryMessage> { let mut line = Row::new().width(Fill).align_y(Center); + let handle = data.handle.clone(); line = line.push( checkbox(data.is_included) .label("") .spacing(15) - .on_toggle(move |b| Include(data.handle, b)), + .on_toggle(move |b| Include(handle, b)), ); - + // line = line.push( text_input("Слово", &data.key) .size(ACCENT_FONT_SIZE) .width(Fill) - .on_input(move |string| SetKey(data.handle, string)) + .on_input(move |string| SetKey(handle, string)) .style(|x, status| { let mut default_style = default(x, status); default_style.border.radius = 0.0.into(); @@ -384,7 +386,7 @@ impl DictionaryState { text_input("Перевод", &data.value) .size(ACCENT_FONT_SIZE) .width(Fill) - .on_input(move |string| SetValue(data.handle, string)) + .on_input(move |string| SetValue(handle, string)) .style(|x, status| { let mut default_style = default(x, status); default_style.border.radius = 0.0.into(); @@ -396,7 +398,7 @@ impl DictionaryState { text_input("Теги", data.tags.as_ref()) .size(ACCENT_FONT_SIZE) .width(Fill) - .on_input(move |string| SetTags(data.handle, string)) + .on_input(move |string| SetTags(handle, string)) .style(|x, status| { let mut default_style = default(x, status); default_style.border.radius = 0.0.into(); @@ -408,13 +410,15 @@ impl DictionaryState { 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, - }) + .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); } @@ -434,10 +438,7 @@ impl DictionaryState { .on_input(Search) .width(Fill), text!("Всего слов: {}", dict.len()), - text!( - "Выбрано слов: {}", - self.included.iter().count() - ), + text!("Выбрано слов: {}", self.included.iter().count()), self.tags_selector(), toggler(self.no_typing) .label("Без набора") @@ -529,17 +530,15 @@ impl DictionaryState { self.included.clear(); for (handle, tags) in &mut self.words_tags { - if let Some(word) = dict.get_ref(handle) { + if let Some(word) = dict.get_ref(handle) { if word.group_id != group_id { continue; } - if !tags.is_empty() - && tags.iter().all(|t| include_tags.contains(t)) { + if !tags.is_empty() && tags.iter().all(|t| include_tags.contains(t)) { self.included.insert(*handle); } - } - else { + } else { continue; } }