Fixing partial adding bug

This commit is contained in:
2026-08-16 14:23:00 +03:00
parent 51c8d7be74
commit 11b38479c1
4 changed files with 41 additions and 63 deletions
+1 -1
View File
@@ -17,7 +17,7 @@ pub fn load_sets(connection: &Connection) -> Vec<CardSetSettings> {
count: None, count: None,
worst_words_list: None, worst_words_list: None,
open_mode: OrderMode::Default, open_mode: OrderMode::Default,
append_mode: AppendMode::Full, append_mode: AppendMode::Manual,
}) })
}) })
.unwrap(); .unwrap();
+3
View File
@@ -27,6 +27,7 @@ pub fn load_stats_of_set(set: &CardSetSettings, connection: &Connection) -> Vec<
} }
pub fn add_stat_list(stat: &mut [CardStatistics], connection: &Connection) { pub fn add_stat_list(stat: &mut [CardStatistics], connection: &Connection) {
let time = Instant::now();
let inserting = stat let inserting = stat
.iter() .iter()
.map(|stat| { .map(|stat| {
@@ -63,6 +64,8 @@ pub fn add_stat_list(stat: &mut [CardStatistics], connection: &Connection) {
for (index, id) in (start_index..=last_index).enumerate() { for (index, id) in (start_index..=last_index).enumerate() {
stat[index].id = id; stat[index].id = id;
} }
println!("Added {} cards for {:?}", stat.len(), time.elapsed());
} }
// pub fn add_stat(stat: &mut CardStatistics, connection: &Connection) { // pub fn add_stat(stat: &mut CardStatistics, connection: &Connection) {
+1 -26
View File
@@ -655,7 +655,7 @@ impl CardSetSettings {
count: None, count: None,
worst_words_list: None, worst_words_list: None,
open_mode: OrderMode::Default, open_mode: OrderMode::Default,
append_mode: AppendMode::Full, append_mode: AppendMode::Manual,
} }
} }
@@ -719,29 +719,4 @@ impl CardSetSettings {
pub fn require_speech(&self) -> bool { pub fn require_speech(&self) -> bool {
self.forward == "speech" || self.backward == "speech" self.forward == "speech" || self.backward == "speech"
} }
pub(crate) fn update_worst_words(&mut self, state: &AppState) {
if self.worst_words_list.is_some() {
return;
}
let connection = &state.connection;
let mut stats = load_stats_of_set(self, connection);
stats.sort_by_key(|s| s.calculated_score() as i32);
let avg = stats.iter().map(|s| s.calculated_score()).sum::<f32>() / stats.len() as f32;
let avg = avg * 0.7;
let bad: Vec<WordData> = stats
.iter()
.take_while(|word| word.calculated_score() < avg)
.map(|stat| {
state.dictionary[state
.dictionary
.binary_search_by_key(&stat.word_id, |x| x.id)
.unwrap()]
.clone()
})
.collect();
self.worst_words_list = Some(bad.clone());
}
} }
+36 -36
View File
@@ -11,18 +11,17 @@ use crate::styling::*;
use crate::{AppState, RootMessage}; use crate::{AppState, RootMessage};
use chrono::{Days, Local, Utc}; use chrono::{Days, Local, Utc};
use hashbrown::{HashMap, HashSet}; use hashbrown::{HashMap, HashSet};
use iced::widget::button::{danger, Status};
pub use iced::widget::button::{Catalog, Style}; pub use iced::widget::button::{Catalog, Style};
use iced::widget::button::{Status, danger};
use iced::widget::container::bordered_box;
use iced::widget::tooltip::Position::Top; use iced::widget::tooltip::Position::Top;
use iced::widget::{ use iced::widget::{
Column, Row, button, column, container, lazy, radio, row, scrollable, space, svg, text, button, column, container, lazy, radio, row, scrollable, space, svg, text, text_input, tooltip,
text_input, tooltip, Column, Row,
}; };
use iced::{Background, Border, Center, Color, Element, Fill, Length, Shadow, Task, Theme}; use iced::{Background, Border, Center, Color, Element, Fill, Length, Shadow, Task, Theme};
use iced_core::Padding;
use iced_core::border::Radius; use iced_core::border::Radius;
use iced_core::svg::Handle; use iced_core::svg::Handle;
use iced_core::Padding;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
#[derive(Clone)] #[derive(Clone)]
@@ -30,6 +29,7 @@ pub struct RepetitionsState {
selected_set: Option<usize>, selected_set: Option<usize>,
correct_filters: Vec<bool>, correct_filters: Vec<bool>,
current_sets_cards_cache: HashMap<usize, (Vec<usize>, Vec<usize>)>, current_sets_cards_cache: HashMap<usize, (Vec<usize>, Vec<usize>)>,
word_id_index_map: HashMap<u32, usize>,
pub state: Arc<Mutex<AppState>>, pub state: Arc<Mutex<AppState>>,
} }
@@ -93,12 +93,16 @@ impl NavigatedPage<RepetitionsMessage> for RepetitionsState {
self.selected_set = Some(index); self.selected_set = Some(index);
let set = state.card_sets.get(index).unwrap().clone(); let set = state.card_sets.get(index).unwrap().clone();
if !self.current_sets_cards_cache.contains_key(&index) { if !self.current_sets_cards_cache.contains_key(&index) {
let added = load_stats_of_set(&set, &state.connection) let added: Vec<_> = load_stats_of_set(&set, &state.connection)
.iter() .iter()
.map(|c| c.word_id as usize) .map(|c| self.word_id_index_map[&c.word_id])
.collect(); .collect();
println!("Already exists {:?}", added);
let total = set.get_word_list(&state); let total = set.get_word_list(&state);
println!("Available{:?}", total);
self.current_sets_cards_cache.insert(index, (added, total)); self.current_sets_cards_cache.insert(index, (added, total));
} }
state.card_sets[index] = set; state.card_sets[index] = set;
} }
@@ -159,12 +163,21 @@ impl NavigatedPage<RepetitionsMessage> for RepetitionsState {
.take(count) .take(count)
.cloned() .cloned()
.collect(); .collect();
for x in &cache.0 {
println!("Already exists {:?}", state.dictionary.get(*x).unwrap());
}
for w in &adding {
println!("{:?}", state.dictionary.get(*w).unwrap());
}
let mut new_current = cache.0.clone(); let mut new_current = cache.0.clone();
new_current.append(&mut adding.clone()); new_current.append(&mut adding.clone());
total_cache.insert(index, (new_current, cache.1.clone())); total_cache.insert(index, (new_current, cache.1.clone()));
} }
Self::append_words(&state, set, adding.as_slice()); Self::append_words(&state, set, adding.into_iter());
} }
} }
Task::none() Task::none()
@@ -196,11 +209,18 @@ impl NavigatedPage<RepetitionsMessage> for RepetitionsState {
impl RepetitionsState { impl RepetitionsState {
pub(crate) fn new(state: Arc<Mutex<AppState>>) -> RepetitionsState { pub(crate) fn new(state: Arc<Mutex<AppState>>) -> RepetitionsState {
let count = state.lock().unwrap().card_sets.len(); let state_ = state.lock().unwrap();
let count = state_.card_sets.len();
let mut map = HashMap::with_capacity(state_.dictionary.len());
state_.dictionary.iter().enumerate().for_each(|(index, word)| {map.insert(word.id, index);});
drop(state_);
RepetitionsState { RepetitionsState {
selected_set: None, selected_set: None,
correct_filters: vec![true; count], correct_filters: vec![true; count],
current_sets_cards_cache: Default::default(), current_sets_cards_cache: Default::default(),
word_id_index_map: map,
state, state,
} }
} }
@@ -217,18 +237,15 @@ impl RepetitionsState {
let required = cache let required = cache
.1 .1
.iter() .iter()
.filter(|i| !created_set.contains(i)) .filter(|i| !created_set.contains(i)).cloned();
.cloned() Self::append_words(&self.state.lock().unwrap(), set, required);
.collect::<Vec<_>>();
Self::append_words(&self.state.lock().unwrap(), set, required.as_slice());
} }
fn append_words(state: &AppState, set: &CardSetSettings, indices: &[usize]) { fn append_words(state: &AppState, set: &CardSetSettings, indices: impl Iterator<Item = usize>) {
let words = &state.dictionary; let words = &state.dictionary;
let stats = &mut indices let stats = &mut indices
.iter()
.map(|i| { .map(|i| {
let word = words.get(*i).unwrap(); let word = words.get(i).unwrap();
CardStatistics { CardStatistics {
id: 0, id: 0,
word_id: word.id, word_id: word.id,
@@ -350,10 +367,10 @@ impl RepetitionsState {
.spacing(DEFAULT_SPACING), .spacing(DEFAULT_SPACING),
] ]
.spacing(DEFAULT_SPACING) .spacing(DEFAULT_SPACING)
.width(Length::FillPortion(3)) .width(Length::FillPortion(2))
.into(); .into();
} }
space().width(Length::FillPortion(3)).into() space().width(Length::FillPortion(2)).into()
} }
fn filled_set_data_view(&self, set: &CardSetSettings) -> Column<'_, RepetitionsMessage> { fn filled_set_data_view(&self, set: &CardSetSettings) -> Column<'_, RepetitionsMessage> {
@@ -440,15 +457,6 @@ impl RepetitionsState {
.into() .into()
} }
fn words_words_view(&self, set: &CardSetSettings) -> Element<'_, RepetitionsMessage> {
column![
text!("Худшие слова"),
container(scrollable(self.worst_words_list(set)).height(200)).style(bordered_box),
]
.spacing(DEFAULT_SPACING)
.into()
}
fn word_append_panel(&self, set: &CardSetSettings) -> Element<'_, RepetitionsMessage> { fn word_append_panel(&self, set: &CardSetSettings) -> Element<'_, RepetitionsMessage> {
column![ column![
text!("Режим добавления карточек"), text!("Режим добавления карточек"),
@@ -467,7 +475,7 @@ impl RepetitionsState {
) )
] ]
.spacing(HALF_SPACING), .spacing(HALF_SPACING),
self.adder_panel(&set), self.adder_panel(set),
] ]
.spacing(HALF_SPACING) .spacing(HALF_SPACING)
.into() .into()
@@ -486,14 +494,6 @@ impl RepetitionsState {
.into(), .into(),
} }
} }
fn worst_words_list(&self, set: &CardSetSettings) -> Element<'_, RepetitionsMessage> {
let mut column = Column::new();
for word in set.worst_words_list.clone().unwrap() {
column = column.push(text!("{} | {}", &word.key, &word.value));
}
column.into()
}
fn count_comparator_view(&self) -> Element<'_, RepetitionsMessage> { fn count_comparator_view(&self) -> Element<'_, RepetitionsMessage> {
let cache = &self.current_sets_cards_cache[&self.selected_set.unwrap()]; let cache = &self.current_sets_cards_cache[&self.selected_set.unwrap()];