Sync solved
This commit is contained in:
1 parent
22c05250aa
commit
1afb7493f6
9 files changed
+164
-158
No files matched your search
+82
-95
@@ -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 {
|
||||
|
||||
Reference in new issue
Block a user