App is building

This commit is contained in:
micialware committed 2026-09-07 10:53:09 +03:00
1 parent 7e1bb4bc22
commit f9c4bf9c03
5 files changed
+108 -94

No files matched your search

+75 -87
View File
@@ -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>>,