App is building
This commit is contained in:
1 parent
7e1bb4bc22
commit
f9c4bf9c03
5 files changed
+108
-94
No files matched your search
+75
-87
@@ -2,11 +2,10 @@ use crate::app::AppState;
|
||||
use crate::core::deck::DeckData;
|
||||
use crate::core::srs::{AppendMode, OrderMode};
|
||||
use crate::data::entities::{CardState, DeckSettings, EntityHandle, WordData};
|
||||
use crate::data::repositories::Repository;
|
||||
use crate::data_provider::card_states::add_stat_list;
|
||||
use crate::data::repositories::{BatchedRepository, Repository};
|
||||
use crate::navigation::Page::{History, PreviousPage, Repetition, RepetitionSettings};
|
||||
use crate::navigation::{NavigatedPage, Page, RootMessage};
|
||||
use crate::notification::{MaybeError, NotificationRequest};
|
||||
use crate::notification::MaybeError;
|
||||
use crate::pages::history::HistoryState;
|
||||
use crate::pages::repetition::RepetitionState;
|
||||
use crate::pages::repetition_settings::RepetitionSettingsState;
|
||||
@@ -15,7 +14,7 @@ use crate::push_error;
|
||||
use crate::push_error_task;
|
||||
use crate::styling::*;
|
||||
use chrono::{Days, Local, Utc};
|
||||
use hashbrown::HashSet;
|
||||
use hashbrown::{HashMap, HashSet};
|
||||
pub use iced::widget::button::{Catalog, Style};
|
||||
use iced::widget::button::{Status, danger};
|
||||
use iced::widget::tooltip::Position::Top;
|
||||
@@ -33,7 +32,7 @@ use std::sync::Arc;
|
||||
#[derive(Clone)]
|
||||
pub struct RepetitionsState {
|
||||
selected_deck_handle: Option<EntityHandle<DeckSettings>>,
|
||||
decks: Vec<DeckViewData>,
|
||||
decks: HashMap<EntityHandle<DeckSettings>, DeckViewData>,
|
||||
state: AppState,
|
||||
}
|
||||
|
||||
@@ -82,12 +81,7 @@ impl NavigatedPage<RepetitionsMessage> for RepetitionsState {
|
||||
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);
|
||||
self.decks.remove(&index);
|
||||
drop(decks);
|
||||
self.clear_selection();
|
||||
}
|
||||
@@ -105,33 +99,32 @@ impl NavigatedPage<RepetitionsMessage> for RepetitionsState {
|
||||
|
||||
CreateSet => {
|
||||
let index = self.decks.len() + 1;
|
||||
self.decks.push(DeckViewData {
|
||||
general_settings: DeckSettings::with_name(format!("Колода #{}", index)),
|
||||
existing_words_indices: Default::default(),
|
||||
available_words_indices: Default::default(),
|
||||
indices_ready: false,
|
||||
append_mode: Default::default(),
|
||||
count: None,
|
||||
open_mode: OrderMode::Default,
|
||||
});
|
||||
let general = DeckSettings::with_name(format!("Колода #{}", index));
|
||||
let handle = self.state.decks.write().create(general.clone());
|
||||
self.decks.insert(
|
||||
handle,
|
||||
DeckViewData {
|
||||
settings_handle: handle,
|
||||
general_settings: general,
|
||||
existing_words_indices: Default::default(),
|
||||
available_words_indices: Default::default(),
|
||||
indices_ready: false,
|
||||
append_mode: Default::default(),
|
||||
count: None,
|
||||
open_mode: OrderMode::Default,
|
||||
},
|
||||
);
|
||||
}
|
||||
DeleteSet => {
|
||||
let index = self.selected_deck_handle.unwrap();
|
||||
self.clear_selection();
|
||||
let deck = self.decks.remove(
|
||||
self.decks
|
||||
.iter()
|
||||
.position(|dvd| dvd.id == index.id)
|
||||
.unwrap(),
|
||||
);
|
||||
let deck = self.decks.remove(&index);
|
||||
|
||||
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) => {
|
||||
@@ -148,21 +141,14 @@ impl NavigatedPage<RepetitionsMessage> for RepetitionsState {
|
||||
}
|
||||
}
|
||||
Save => {
|
||||
let mut deck = self.selected_deck().unwrap().clone();
|
||||
let deck = self.selected_deck().unwrap().clone();
|
||||
let handle = self.selected_deck_handle.unwrap();
|
||||
let mut repo = self.state.decks.write();
|
||||
|
||||
repo.set_static(handle, *deck);
|
||||
repo.set_static(handle, deck.general_settings.clone());
|
||||
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) => {
|
||||
let deck = self.selected_deck_mut().unwrap();
|
||||
@@ -213,10 +199,10 @@ impl NavigatedPage<RepetitionsMessage> for RepetitionsState {
|
||||
deck.existing_words_indices.append(&mut adding.clone());
|
||||
}
|
||||
|
||||
let deck = self.selected_deck().unwrap();
|
||||
let mut state = self.state.lock();
|
||||
let deck = self.selected_deck().unwrap().clone();
|
||||
let state = &mut self.state;
|
||||
if let Err(err) =
|
||||
Self::append_words(&mut state, &deck.general_settings, adding.into_iter())
|
||||
Self::append_words(state, &deck.general_settings, adding.into_iter())
|
||||
{
|
||||
return push_error_task!(err);
|
||||
}
|
||||
@@ -259,23 +245,28 @@ impl RepetitionsState {
|
||||
}
|
||||
}
|
||||
|
||||
fn get_decks_from_state(state: &AppState) -> Vec<DeckViewData> {
|
||||
fn get_decks_from_state(state: &AppState) -> HashMap<EntityHandle<DeckSettings>, DeckViewData> {
|
||||
state
|
||||
.decks
|
||||
.read()
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(index, deck)| DeckViewData {
|
||||
general_settings: deck.clone(),
|
||||
existing_words_indices: Default::default(),
|
||||
available_words_indices: Default::default(),
|
||||
indices_ready: false,
|
||||
append_mode: Default::default(),
|
||||
count: None,
|
||||
index: Some(index),
|
||||
open_mode: OrderMode::Default,
|
||||
.map(|(index, deck)| {
|
||||
(
|
||||
EntityHandle::new(deck.id, index, true),
|
||||
DeckViewData {
|
||||
settings_handle: EntityHandle::new(deck.id, index, true),
|
||||
general_settings: deck.clone(),
|
||||
existing_words_indices: Default::default(),
|
||||
available_words_indices: Default::default(),
|
||||
indices_ready: false,
|
||||
append_mode: Default::default(),
|
||||
count: None,
|
||||
open_mode: OrderMode::Default,
|
||||
},
|
||||
)
|
||||
})
|
||||
.collect()
|
||||
.collect::<HashMap<_, _>>()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -395,22 +386,20 @@ impl RepetitionsState {
|
||||
fn activity_bar(&self, deck: &DeckSettings) -> Element<'_, RepetitionsMessage> {
|
||||
const MAX_DAY_COUNT: f32 = 128.0;
|
||||
|
||||
let state = self.state.lock();
|
||||
let history = state.activity.get(&deck.id);
|
||||
let history = self.state.history.read();
|
||||
let history = history.activity_of_deck(deck.id);
|
||||
let mut counts: Vec<u32> = vec![0; 30 * 7];
|
||||
let now = Local::now().date_naive();
|
||||
|
||||
if let Some(history) = history {
|
||||
for (date, activity) in history {
|
||||
let distance = now - *date;
|
||||
let index = counts.len() as i64 - distance.num_days() - 1;
|
||||
for (date, activity) in history {
|
||||
let distance = now - date;
|
||||
let index = counts.len() as i64 - distance.num_days() - 1;
|
||||
|
||||
if index < 0 {
|
||||
continue;
|
||||
}
|
||||
|
||||
counts[index as usize] = *activity;
|
||||
if index < 0 {
|
||||
continue;
|
||||
}
|
||||
|
||||
counts[index as usize] = activity;
|
||||
}
|
||||
|
||||
lazy((counts, now), |(counts, now)| {
|
||||
@@ -509,8 +498,8 @@ impl RepetitionsState {
|
||||
let available = selected_deck.available_words_indices.len();
|
||||
text!("{} слова добавлено из {}", now, available).into()
|
||||
}
|
||||
fn count_view(&self, deck: &DeckSettings) -> Element<'_, RepetitionsMessage> {
|
||||
if let Some(count) = self.decks.iter().find() {
|
||||
fn count_view(&self, deck: &DeckViewData) -> Element<'_, RepetitionsMessage> {
|
||||
if let Some(count) = deck.count {
|
||||
return text!("Количество слов: {}", count).into();
|
||||
}
|
||||
space().into()
|
||||
@@ -518,10 +507,10 @@ impl RepetitionsState {
|
||||
fn decks_list(&self) -> Column<'_, RepetitionsMessage> {
|
||||
let mut column = Column::new();
|
||||
|
||||
for (i, deck) in self.decks.iter().enumerate() {
|
||||
for (i, (handle, deck)) in self.decks.iter().enumerate() {
|
||||
column = column.push(
|
||||
button(text!("{}", &deck.name))
|
||||
.on_press_with(move || SelectSet(i))
|
||||
.on_press_with(move || SelectSet(*handle))
|
||||
.style(move |_x: &Theme, status: Status| Style {
|
||||
background: if status == Status::Hovered {
|
||||
Some(Background::Color(Color::WHITE.scale_alpha(0.2)))
|
||||
@@ -566,38 +555,36 @@ impl RepetitionsState {
|
||||
) -> MaybeError {
|
||||
let words = &state.dictionary;
|
||||
let stats = &mut indices
|
||||
.map(|i| {
|
||||
let word = &words[i];
|
||||
CardState {
|
||||
id: 0.into(),
|
||||
word_id: word.id,
|
||||
last_open: Utc::now(),
|
||||
score: 1,
|
||||
fsrs_opened: Utc::now().date_naive(),
|
||||
fsrs_memory: None,
|
||||
deck_id: deck.id,
|
||||
fsrs_open_day: Utc::now().date_naive(),
|
||||
}
|
||||
.map(|i| CardState {
|
||||
id: 0.into(),
|
||||
word_id: i.id,
|
||||
last_open: Utc::now(),
|
||||
score: 1,
|
||||
fsrs_opened: Utc::now().date_naive(),
|
||||
fsrs_memory: None,
|
||||
deck_id: deck.id,
|
||||
fsrs_open_day: Utc::now().date_naive(),
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
if !stats.is_empty() {
|
||||
add_stat_list(stats, &mut state.connection)?;
|
||||
let mut repo = state.card_states.write();
|
||||
repo.create_now_many(stats.as_mut_slice())?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn select_deck(&mut self, index: usize) {
|
||||
if self.decks.get(index).is_some() {
|
||||
fn select_deck(&mut self, index: EntityHandle<DeckSettings>) {
|
||||
if self.decks.contains_key(&index) {
|
||||
self.selected_deck_handle = Some(index);
|
||||
}
|
||||
}
|
||||
|
||||
fn selected_deck(&self) -> Option<&DeckViewData> {
|
||||
self.decks.get(self.selected_deck_handle?)
|
||||
self.decks.get(&self.selected_deck_handle?)
|
||||
}
|
||||
fn selected_deck_mut(&mut self) -> Option<&mut DeckViewData> {
|
||||
self.decks.get_mut(self.selected_deck_handle?)
|
||||
self.decks.get_mut(&self.selected_deck_handle?)
|
||||
}
|
||||
|
||||
fn clear_selection(&mut self) {
|
||||
@@ -613,10 +600,10 @@ impl RepetitionsState {
|
||||
.map(|state| EntityHandle::from_id(state.word_id))
|
||||
.collect::<Vec<_>>();
|
||||
let mut deck = self.selected_deck().unwrap().clone();
|
||||
let total = DeckData::list(&deck, &self.state)?;
|
||||
let total = DeckData::list(&deck, &self.state);
|
||||
deck.existing_words_indices = added;
|
||||
deck.available_words_indices = total;
|
||||
self.decks[self.selected_deck_handle.unwrap()] = deck;
|
||||
self.decks.insert(self.selected_deck_handle.unwrap(), deck);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -628,7 +615,7 @@ pub enum RepetitionsMessage {
|
||||
CreateSet,
|
||||
DeleteSet,
|
||||
SetName(String),
|
||||
SelectSet(usize),
|
||||
SelectSet(EntityHandle<DeckSettings>),
|
||||
Save,
|
||||
SetForward(String),
|
||||
SetBackward(String),
|
||||
@@ -643,6 +630,7 @@ pub enum RepetitionsMessage {
|
||||
|
||||
#[derive(Clone)]
|
||||
struct DeckViewData {
|
||||
settings_handle: EntityHandle<DeckSettings>,
|
||||
general_settings: DeckSettings,
|
||||
existing_words_indices: Vec<EntityHandle<WordData>>,
|
||||
available_words_indices: Vec<EntityHandle<WordData>>,
|
||||
|
||||
Reference in new issue
Block a user