Sync solved

This commit is contained in:
micialware committed 2026-09-06 23:55:50 +03:00
1 parent 22c05250aa
commit 1afb7493f6
9 files changed
+164 -158

No files matched your search

+82 -95
View File
@@ -1,8 +1,9 @@
use crate::app::AppState;
use crate::core::deck::DeckData;
use crate::core::srs::{AppendMode, OrderMode};
use crate::data::Id;
use crate::data::entities::{CardState, DeckSettings};
use crate::data_provider::card_states::{add_stat_list, load_stats_of_deck};
use crate::data::entities::{CardState, DeckSettings, EntityHandle, WordData};
use crate::data::repositories::Repository;
use crate::data_provider::card_states::add_stat_list;
use crate::navigation::Page::{History, PreviousPage, Repetition, RepetitionSettings};
use crate::navigation::{NavigatedPage, Page, RootMessage};
use crate::notification::{MaybeError, NotificationRequest};
@@ -14,7 +15,7 @@ use crate::push_error;
use crate::push_error_task;
use crate::styling::*;
use chrono::{Days, Local, Utc};
use hashbrown::{HashMap, HashSet};
use hashbrown::HashSet;
pub use iced::widget::button::{Catalog, Style};
use iced::widget::button::{Status, danger};
use iced::widget::tooltip::Position::Top;
@@ -26,14 +27,12 @@ use iced::{Background, Border, Center, Color, Element, Fill, Length, Shadow, Tas
use iced_core::Padding;
use iced_core::border::Radius;
use iced_core::svg::Handle;
use parking_lot::Mutex;
use std::ops::Deref;
use std::sync::Arc;
#[derive(Clone)]
pub struct RepetitionsState {
word_id_index_map: HashMap<Id, usize>,
selected_deck_index: Option<usize>,
selected_deck_handle: Option<EntityHandle<DeckSettings>>,
decks: Vec<DeckViewData>,
state: AppState,
}
@@ -48,11 +47,10 @@ impl NavigatedPage<RepetitionsMessage> for RepetitionsState {
self.state.clone(),
)))
} else if let GoToRepetition = message {
let clone = self.state.clone();
let mut state_clone = self.state.clone();
let selected_set = self.selected_deck_mut().unwrap();
if selected_set.append_mode == AppendMode::Full {
if let Err(_err) = Self::append_all_words(&mut clone.lock(), selected_set) {
if let Err(_err) = Self::append_all_words(&mut state_clone, selected_set) {
return None;
}
selected_set.existing_words_indices = selected_set.available_words_indices.clone();
@@ -65,7 +63,7 @@ impl NavigatedPage<RepetitionsMessage> for RepetitionsState {
}
if let Ok(repetition_state) =
RepetitionState::new(selected_set.general_settings.clone(), clone)
RepetitionState::new(selected_set.general_settings.clone(), self.state.clone())
{
return Some(Repetition(repetition_state));
}
@@ -73,7 +71,7 @@ impl NavigatedPage<RepetitionsMessage> for RepetitionsState {
None
} else if let GoToSettings = message {
Some(RepetitionSettings(RepetitionSettingsState::new(
self.selected_deck().unwrap().index.unwrap(),
EntityHandle::from_id(self.selected_deck().unwrap().id),
self.state.clone(),
)))
} else {
@@ -81,23 +79,20 @@ impl NavigatedPage<RepetitionsMessage> for RepetitionsState {
}
}
fn navigated(&mut self) {
if let Some(index) = self.selected_deck_index {
let state = self.state.lock();
if let Some(global_deck) = state.decks.get(index) {
if global_deck.id != self.selected_deck().unwrap().id {
drop(state);
self.decks.remove(index);
self.clear_selection();
} else {
self.decks[index].general_settings = state.decks[index].clone();
drop(state);
let _ = self.fill_deck_word_indices();
}
} else {
drop(state);
self.decks.remove(index);
self.clear_selection()
if let Some(index) = self.selected_deck_handle {
let decks = self.state.decks.read();
if let None = decks.get_static(index) {
let position = self
.decks
.iter()
.position(|deck_view_data: &DeckViewData| deck_view_data.id == index.id)
.unwrap();
self.decks.remove(position);
drop(decks);
self.clear_selection();
}
} else {
let _ = self.fill_deck_word_indices();
}
}
fn update(&mut self, message: RepetitionsMessage) -> Task<RootMessage> {
@@ -116,25 +111,27 @@ impl NavigatedPage<RepetitionsMessage> for RepetitionsState {
available_words_indices: Default::default(),
indices_ready: false,
append_mode: Default::default(),
index: None,
count: None,
open_mode: OrderMode::Default,
});
}
DeleteSet => {
let index = self.selected_deck_index.unwrap();
let index = self.selected_deck_handle.unwrap();
self.clear_selection();
let deck = self.decks.remove(index);
if deck.id.is_valid() {
let mut state = self.state.lock();
state.decks.remove(index);
self.decks = self
.decks
.clone()
.into_iter()
.map(|mut deck| {
deck.index = state.decks.iter().position(|d| d.id == deck.id);
deck
})
.collect();
let deck = self.decks.remove(
self.decks
.iter()
.position(|dvd| dvd.id == index.id)
.unwrap(),
);
if index.real() {
let mut repo = self.state.decks.write();
if let Err(err) = repo.delete(index) {
return push_error_task!(err);
}
let index = self.decks.iter().position(|dvd| dvd.id == index.id);
self.decks.remove(index.unwrap());
}
}
SetName(value) => {
@@ -152,20 +149,19 @@ impl NavigatedPage<RepetitionsMessage> for RepetitionsState {
}
Save => {
let mut deck = self.selected_deck().unwrap().clone();
let mut state = self.state.lock();
{
if let Err(e) = update_deck(&mut deck.general_settings, &state.connection) {
return Task::done(RootMessage::PushNotification(
NotificationRequest::Error(e),
));
}
if let Some(index) = deck.index {
state.decks[index] = deck.general_settings.clone();
} else {
state.decks.push(deck.general_settings.clone());
deck.index = Some(state.decks.len() - 1);
self.decks[self.selected_deck_index.unwrap()] = deck.clone();
}
let handle = self.selected_deck_handle.unwrap();
let mut repo = self.state.decks.write();
repo.set_static(handle, *deck);
if let Err(err) = repo.save(&mut handle.clone()) {
return push_error_task!(err);
}
if let Some(index) = deck.index {
state.decks[index] = deck.general_settings.clone();
} else {
state.decks.push(deck.general_settings.clone());
deck.index = Some(state.decks.len() - 1);
self.decks[self.selected_deck_handle.unwrap()] = deck.clone();
}
}
SetForward(value) => {
@@ -181,23 +177,21 @@ impl NavigatedPage<RepetitionsMessage> for RepetitionsState {
deck.general_settings.filter = value;
}
TryFilter => {
let state = self.state.lock();
let deck = self.selected_deck().unwrap();
let count = deck.get_word_list(&state).len();
drop(state);
let count = DeckData::list(&deck, &self.state).len();
let deck = self.selected_deck_mut().unwrap();
deck.general_settings.count = Some(count);
deck.count = Some(count);
}
SetOpenMode(mode) => {
let deck = self.selected_deck_mut().unwrap();
deck.general_settings.open_mode = mode;
deck.open_mode = mode;
}
SetAppendMode(mode) => {
let deck = self.selected_deck_mut().unwrap();
deck.append_mode = mode;
}
AppendWords(count) => {
let adding: Vec<usize>;
let adding: Vec<EntityHandle<WordData>>;
{
{
let deck = self.selected_deck().unwrap();
@@ -257,22 +251,9 @@ impl NavigatedPage<RepetitionsMessage> for RepetitionsState {
impl RepetitionsState {
pub(crate) fn new(state: AppState) -> RepetitionsState {
let state_ = state.lock();
let mut map = HashMap::with_capacity(state_.dictionary.len());
state_
.dictionary
.iter()
.enumerate()
.for_each(|(index, word)| {
map.insert(word.id, index);
});
let decks = Self::get_decks_from_state(&state_);
drop(state_);
let decks = Self::get_decks_from_state(&state);
RepetitionsState {
word_id_index_map: map,
selected_deck_index: None,
selected_deck_handle: None,
decks,
state,
}
@@ -281,6 +262,7 @@ impl RepetitionsState {
fn get_decks_from_state(state: &AppState) -> Vec<DeckViewData> {
state
.decks
.read()
.iter()
.enumerate()
.map(|(index, deck)| DeckViewData {
@@ -289,7 +271,9 @@ impl RepetitionsState {
available_words_indices: Default::default(),
indices_ready: false,
append_mode: Default::default(),
count: None,
index: Some(index),
open_mode: OrderMode::Default,
})
.collect()
}
@@ -526,7 +510,7 @@ impl RepetitionsState {
text!("{} слова добавлено из {}", now, available).into()
}
fn count_view(&self, deck: &DeckSettings) -> Element<'_, RepetitionsMessage> {
if let Some(count) = deck.count {
if let Some(count) = self.decks.iter().find() {
return text!("Количество слов: {}", count).into();
}
space().into()
@@ -578,7 +562,7 @@ impl RepetitionsState {
fn append_words(
state: &mut AppState,
deck: &DeckSettings,
indices: impl Iterator<Item = usize>,
indices: impl Iterator<Item = EntityHandle<WordData>>,
) -> MaybeError {
let words = &state.dictionary;
let stats = &mut indices
@@ -591,7 +575,7 @@ impl RepetitionsState {
score: 1,
fsrs_opened: Utc::now().date_naive(),
fsrs_memory: None,
set_id: deck.id,
deck_id: deck.id,
fsrs_open_day: Utc::now().date_naive(),
}
})
@@ -605,32 +589,34 @@ impl RepetitionsState {
fn select_deck(&mut self, index: usize) {
if self.decks.get(index).is_some() {
self.selected_deck_index = Some(index);
self.selected_deck_handle = Some(index);
}
}
fn selected_deck(&self) -> Option<&DeckViewData> {
self.decks.get(self.selected_deck_index?)
self.decks.get(self.selected_deck_handle?)
}
fn selected_deck_mut(&mut self) -> Option<&mut DeckViewData> {
self.decks.get_mut(self.selected_deck_index?)
self.decks.get_mut(self.selected_deck_handle?)
}
fn clear_selection(&mut self) {
self.selected_deck_index = None;
self.selected_deck_handle = None;
}
fn fill_deck_word_indices(&mut self) -> MaybeError {
let state = &self.state.lock();
let card_states = self.state.card_states.read();
let deck_id = self.selected_deck().unwrap().id;
let added = card_states
.query_par(Arc::new(move |state| state.deck_id == deck_id))
.iter(&card_states)
.map(|state| EntityHandle::from_id(state.word_id))
.collect::<Vec<_>>();
let mut deck = self.selected_deck().unwrap().clone();
let added: Vec<_> = load_stats_of_deck(&deck, &state.connection)?
.iter()
.map(|c| self.word_id_index_map[&c.word_id])
.collect();
let total = deck.get_word_list(state);
let total = DeckData::list(&deck, &self.state)?;
deck.existing_words_indices = added;
deck.available_words_indices = total;
self.decks[self.selected_deck_index.unwrap()] = deck;
self.decks[self.selected_deck_handle.unwrap()] = deck;
Ok(())
}
}
@@ -658,11 +644,12 @@ pub enum RepetitionsMessage {
#[derive(Clone)]
struct DeckViewData {
general_settings: DeckSettings,
existing_words_indices: Vec<usize>,
available_words_indices: Vec<usize>,
existing_words_indices: Vec<EntityHandle<WordData>>,
available_words_indices: Vec<EntityHandle<WordData>>,
indices_ready: bool,
append_mode: AppendMode,
index: Option<usize>,
count: Option<usize>,
open_mode: OrderMode,
}
impl Deref for DeckViewData {