Files
jap_learn/src/pages/repetition_settings.rs
T

212 lines
7.4 KiB
Rust
Raw Normal View History

2026-08-24 17:33:21 +03:00
use crate::app::AppState;
use crate::data::entities::DeckSettings;
2026-08-18 15:16:51 +03:00
use crate::data_provider::card_sets::{delete_set, update_deck};
2026-08-20 16:22:38 +03:00
use crate::data_provider::card_stats::{delete_stats, load_stats_of_deck};
2026-08-04 16:53:09 +03:00
use crate::navigation::Page::PreviousPage;
use crate::navigation::{NavigatedPage, Page, RootMessage};
2026-08-24 17:33:21 +03:00
use crate::notification::NotificationRequest;
2026-08-24 01:22:00 +03:00
use crate::pages::repetition_settings::RepetitionSettingsMessage::*;
2026-08-06 11:31:11 +03:00
use crate::styling::*;
use iced::widget::button::danger;
2026-08-19 23:51:41 +03:00
use iced::widget::text_input::Catalog;
2026-08-06 11:31:11 +03:00
use iced::widget::{button, column, row, scrollable, space, text, text_input};
2026-08-04 16:53:09 +03:00
use iced::{Element, Task};
2026-08-06 11:31:11 +03:00
use iced_core::Length::Fill;
2026-08-24 17:33:21 +03:00
use iced_core::{color, Padding, Theme};
2026-08-20 00:07:09 +03:00
use parking_lot::Mutex;
use std::sync::Arc;
2026-08-06 11:31:11 +03:00
use std::time::Duration;
pub struct RepetitionSettingsState {
2026-08-18 12:14:35 +03:00
set: DeckSettings,
2026-08-06 11:31:11 +03:00
index: usize,
state: Arc<Mutex<AppState>>,
real_delete: bool,
2026-08-18 17:45:50 +03:00
correct_filter: bool,
2026-08-20 16:22:38 +03:00
filter_changed: bool,
2026-08-06 11:31:11 +03:00
}
impl RepetitionSettingsState {
2026-08-20 00:07:09 +03:00
pub(crate) fn new(index: usize, state: Arc<Mutex<AppState>>) -> RepetitionSettingsState {
2026-08-06 11:31:11 +03:00
let set;
{
2026-08-20 00:07:09 +03:00
let local_state = state.lock();
2026-08-18 15:16:51 +03:00
set = local_state.decks[index].clone();
2026-08-06 11:31:11 +03:00
}
2026-08-18 17:45:50 +03:00
let filter_state = set.check_filter();
2026-08-06 11:31:11 +03:00
RepetitionSettingsState {
index,
set,
2026-08-20 00:07:09 +03:00
state,
2026-08-06 11:31:11 +03:00
real_delete: false,
2026-08-18 17:45:50 +03:00
correct_filter: filter_state,
2026-08-20 16:22:38 +03:00
filter_changed: false,
2026-08-06 11:31:11 +03:00
}
}
}
2026-08-04 16:53:09 +03:00
impl NavigatedPage<RepetitionSettingsMessage> for RepetitionSettingsState {
2026-08-18 12:14:35 +03:00
fn navigate(&mut self, message: &RepetitionSettingsMessage) -> Option<Page> {
2026-08-04 16:53:09 +03:00
if let Back = message {
Some(PreviousPage)
} else {
None
}
}
2026-08-06 23:20:14 +03:00
2026-08-15 21:32:24 +03:00
fn navigated(&mut self) {}
2026-08-13 22:03:47 +03:00
fn update(&mut self, message: RepetitionSettingsMessage) -> Task<RootMessage> {
2026-08-04 16:53:09 +03:00
match message {
Back => {}
2026-08-06 11:31:11 +03:00
Save => {
2026-08-20 00:07:09 +03:00
let mut state = self.state.lock();
2026-08-24 17:33:21 +03:00
if let Err(e) = update_deck(&mut self.set, &state.connection) {
return Task::done(RootMessage::PushNotification(NotificationRequest::Error(e)));
}
2026-08-20 16:22:38 +03:00
if self.filter_changed {
update_deck_stats(&self.set, &state);
}
2026-08-18 15:16:51 +03:00
state.decks[self.index] = self.set.clone();
2026-08-06 11:31:11 +03:00
}
SetName(new) => {
self.set.name = new;
}
SetForward(new) => {
self.set.forward = new;
}
SetBackward(backward) => {
self.set.backward = backward;
}
SetFilter(new) => {
self.set.filter = new;
2026-08-18 17:45:50 +03:00
self.correct_filter = self.set.check_filter();
2026-08-20 16:22:38 +03:00
self.filter_changed = true;
2026-08-06 11:31:11 +03:00
}
TryFilter => {
2026-08-20 00:07:09 +03:00
let state = self.state.lock();
2026-08-06 11:31:11 +03:00
let count = self.set.get_word_list(&state).len();
self.set.count = Some(count);
}
DeleteSet => {
2026-08-15 13:22:59 +03:00
if !self.real_delete {
2026-08-06 11:31:11 +03:00
self.real_delete = true;
return Task::future(async {
tokio::time::sleep(Duration::from_millis(3000)).await;
2026-08-15 13:22:59 +03:00
RootMessage::RepetitionSettings(RevertDeleteSet)
2026-08-06 11:31:11 +03:00
});
}
2026-08-20 00:07:09 +03:00
let mut state = self.state.lock();
2026-08-24 17:33:21 +03:00
if let Err(e) = delete_set(&self.set, &state.connection) {
return Task::done(RootMessage::PushNotification(NotificationRequest::Error(e)));
}
2026-08-18 15:16:51 +03:00
state.decks.remove(self.index);
2026-08-06 11:31:11 +03:00
return Task::done(RootMessage::RepetitionSettings(Back));
2026-08-15 21:32:24 +03:00
}
2026-08-06 11:31:11 +03:00
RevertDeleteSet => self.real_delete = false,
2026-08-04 16:53:09 +03:00
}
Task::none()
}
2026-08-13 22:03:47 +03:00
fn view(&self) -> Element<'_, RepetitionSettingsMessage> {
2026-08-04 16:53:09 +03:00
back_overlay(
2026-08-06 11:31:11 +03:00
iced::widget::column![
scrollable(
column![
column![
text!("Название набора"),
text_input("", &self.set.name).on_input(SetName),
]
.spacing(QUARTER_SPACING),
column![
text!("Передняя сторона"),
text_input("", &self.set.forward).on_input(SetForward),
]
.spacing(QUARTER_SPACING),
column![
text!("Задняя сторона"),
text_input("", &self.set.backward).on_input(SetBackward),
]
.spacing(QUARTER_SPACING),
column![
text!("Фильтр"),
2026-08-19 23:51:41 +03:00
text_input("", &self.set.filter)
.style(|x, status| {
let mut primary = Theme::default()(x, status);
if !self.correct_filter {
primary.border.color = color!(255, 255, 0);
}
primary
})
.on_input(SetFilter),
2026-08-06 11:31:11 +03:00
button("Проверить фильтр")
.style(jl_button)
.on_press(TryFilter),
self.count_view(&self.set),
]
.spacing(QUARTER_SPACING),
]
.spacing(DEFAULT_SPACING)
.padding(Padding {
top: 0.0,
right: DEFAULT_SPACING,
bottom: 0.0,
left: 0.0,
})
)
.height(Fill),
row![
button("Сохранить").style(jl_button).on_press(Save),
button(if self.real_delete {
"Вы уверены?"
} else {
"Удалить"
})
.style(danger)
.on_press(DeleteSet),
space().width(Fill),
]
.spacing(DEFAULT_SPACING),
]
2026-08-15 21:32:24 +03:00
.spacing(DEFAULT_SPACING)
.into(),
2026-08-04 16:53:09 +03:00
Back,
)
}
2026-08-13 22:03:47 +03:00
}
2026-08-20 16:22:38 +03:00
fn update_deck_stats(deck: &DeckSettings, state: &AppState) {
let mut db_stats = load_stats_of_deck(deck, &state.connection);
let filtered_words = deck.get_word_list(state);
filtered_words.iter().for_each(|word| {
let word_id = state.dictionary[*word].id;
if let Some(index) = db_stats.iter().position(|stat| stat.word_id == word_id) {
db_stats.remove(index);
}
});
delete_stats(db_stats.as_slice(), &state.connection);
}
2026-08-13 22:03:47 +03:00
impl RepetitionSettingsState {
2026-08-18 12:14:35 +03:00
fn count_view(&self, set: &DeckSettings) -> Element<'_, RepetitionSettingsMessage> {
2026-08-06 11:31:11 +03:00
if let Some(count) = set.count {
return text!("Количество слов: {}", count).into();
}
space().into()
}
2026-08-04 16:53:09 +03:00
}
#[derive(Clone)]
2026-08-06 11:31:11 +03:00
pub enum RepetitionSettingsMessage {
Back,
Save,
SetName(String),
SetForward(String),
SetBackward(String),
SetFilter(String),
TryFilter,
DeleteSet,
RevertDeleteSet,
}