Settings on new page

This commit is contained in:
2026-08-06 11:31:11 +03:00
parent da9dc8d781
commit 3f79444852
2 changed files with 214 additions and 70 deletions
+139 -7
View File
@@ -1,11 +1,41 @@
use crate::AppState;
use crate::data_provider::card_sets::{delete_set, update_card_set};
use crate::navigation::Page::PreviousPage; use crate::navigation::Page::PreviousPage;
use crate::navigation::{NavigatedPage, Page, RootMessage}; use crate::navigation::{NavigatedPage, Page, RootMessage};
use crate::repetition_settings::RepetitionSettingsMessage::*; use crate::repetition_settings::RepetitionSettingsMessage::*;
use crate::styling::back_overlay; use crate::repetitions::{CardSetSettings, RepetitionsMessage};
use iced::widget::row; use crate::styling::*;
use iced::widget::button::danger;
use iced::widget::{button, column, row, scrollable, space, text, text_input};
use iced::{Element, Task}; use iced::{Element, Task};
use iced_core::Length::Fill;
use iced_core::{Length, Padding};
use std::sync::{Arc, Mutex};
use std::time::Duration;
pub struct RepetitionSettingsState {
set: CardSetSettings,
index: usize,
state: Arc<Mutex<AppState>>,
real_delete: bool,
}
impl RepetitionSettingsState {
pub(crate) fn new(index: usize, p1: Arc<Mutex<AppState>>) -> RepetitionSettingsState {
let set;
{
let local_state = p1.lock().unwrap();
set = local_state.card_sets[index].clone();
}
RepetitionSettingsState {
index,
set,
state: p1,
real_delete: false,
}
}
}
pub struct RepetitionSettingsState {}
impl NavigatedPage<RepetitionSettingsMessage> for RepetitionSettingsState { impl NavigatedPage<RepetitionSettingsMessage> for RepetitionSettingsState {
fn navigate(&self, message: &RepetitionSettingsMessage) -> Option<Page> { fn navigate(&self, message: &RepetitionSettingsMessage) -> Option<Page> {
if let Back = message { if let Back = message {
@@ -20,19 +50,121 @@ impl RepetitionSettingsState {
pub fn update(&mut self, message: RepetitionSettingsMessage) -> Task<RootMessage> { pub fn update(&mut self, message: RepetitionSettingsMessage) -> Task<RootMessage> {
match message { match message {
Back => {} Back => {}
Save => {
let mut state = self.state.lock().unwrap();
update_card_set(&mut self.set, &state.connection);
state.card_sets[self.index] = self.set.clone();
}
SetName(new) => {
self.set.name = new;
}
SetForward(new) => {
self.set.forward = new;
}
SetBackward(backward) => {
self.set.backward = backward;
}
SetFilter(new) => {
self.set.filter = new;
}
TryFilter => {
let state = self.state.lock().unwrap();
let count = self.set.get_word_list(&state).len();
self.set.count = Some(count);
}
DeleteSet => {
if self.real_delete == false {
self.real_delete = true;
return Task::future(async {
tokio::time::sleep(Duration::from_millis(3000)).await;
return RootMessage::RepetitionSettings(RevertDeleteSet);
});
}
let mut state = self.state.lock().unwrap();
delete_set(&self.set, &state.connection);
state.card_sets.remove(self.index);
return Task::done(RootMessage::RepetitionSettings(Back));
},
RevertDeleteSet => self.real_delete = false,
} }
Task::none() Task::none()
} }
pub fn view(&self) -> Element<'_, RepetitionSettingsMessage> { pub fn view(&self) -> Element<'_, RepetitionSettingsMessage> {
back_overlay( back_overlay(
row![].into(), 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!("Фильтр"),
text_input("", &self.set.filter).on_input(SetFilter),
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),
]
.spacing(DEFAULT_SPACING)
.into(),
Back, Back,
) )
} }
fn count_view(&self, set: &CardSetSettings) -> Element<'_, RepetitionSettingsMessage> {
if let Some(count) = set.count {
return text!("Количество слов: {}", count).into();
}
space().into()
}
} }
#[derive(Clone)] #[derive(Clone)]
pub enum RepetitionSettingsMessage { pub enum RepetitionSettingsMessage {
Back Back,
} Save,
SetName(String),
SetForward(String),
SetBackward(String),
SetFilter(String),
TryFilter,
DeleteSet,
RevertDeleteSet,
}
+75 -63
View File
@@ -5,27 +5,24 @@ use crate::lang::{SetOrderMode, WordData};
use crate::navigation::Page::{History, PreviousPage, Repetition, RepetitionSettings}; use crate::navigation::Page::{History, PreviousPage, Repetition, RepetitionSettings};
use crate::navigation::{NavigatedPage, Page}; use crate::navigation::{NavigatedPage, Page};
use crate::repetition::RepetitionState; use crate::repetition::RepetitionState;
use crate::styling::*;
use crate::{AppState, RootMessage};
pub use iced::widget::button::{Catalog, Style};
use iced::widget::button::{Status, danger};
use iced::widget::container::bordered_box;
use iced::widget::{
Column, button, column, container, radio, row, scrollable, space, svg, text, text_input,
};
use iced::{Background, Border, Center, Color, Element, Fill, Length, Shadow, Task, Theme};
use iced_core::Padding;
use iced_core::svg::Handle;
use rhai::{Engine, Scope};
use std::sync::{Arc, Mutex};
use crate::repetition_settings::RepetitionSettingsState; use crate::repetition_settings::RepetitionSettingsState;
use crate::repetitions::RepetitionsMessage::*; use crate::repetitions::RepetitionsMessage::*;
use crate::styling::*;
use crate::{AppState, RootMessage};
use iced::widget::button::{danger, Status};
pub use iced::widget::button::{Catalog, Style};
use iced::widget::container::bordered_box;
use iced::widget::{button, column, container, radio, row, scrollable, space, svg, text, text_input, Column};
use iced::{Background, Border, Center, Color, Element, Fill, Length, Shadow, Task, Theme};
use iced_core::svg::Handle;
use iced_core::Padding;
use rhai::{Engine, Scope};
use std::sync::{Arc, Mutex};
#[derive(Clone)] #[derive(Clone)]
pub struct RepetitionsState { pub struct RepetitionsState {
selected_set: Option<usize>, selected_set: Option<usize>,
correct_filters: Vec<bool>, correct_filters: Vec<bool>,
pub state: Arc<Mutex<AppState>>, pub state: Arc<Mutex<AppState>>,
} }
@@ -46,11 +43,12 @@ impl NavigatedPage<RepetitionsMessage> for RepetitionsState {
card_set = self.state.lock().unwrap().card_sets[self.selected_set.unwrap()].clone(); card_set = self.state.lock().unwrap().card_sets[self.selected_set.unwrap()].clone();
} }
Some(Repetition(RepetitionState::new(card_set, clone))) Some(Repetition(RepetitionState::new(card_set, clone)))
} } else if let GoToSettings = message {
else if let GoToSettings = message { Some(RepetitionSettings(RepetitionSettingsState::new(
Some(RepetitionSettings(RepetitionSettingsState {})) self.selected_set.unwrap(),
} self.state.clone(),
else { )))
} else {
None None
} }
} }
@@ -103,11 +101,11 @@ impl RepetitionsState {
self.correct_filters[i] = state.card_sets[i].check_filter(); self.correct_filters[i] = state.card_sets[i].check_filter();
} }
let word = &mut state.card_sets[self.selected_set.unwrap()].clone(); let set = &mut state.card_sets[self.selected_set.unwrap()].clone();
update_card_set(word, &state.connection); update_card_set(set, &state.connection);
state.card_sets[self.selected_set.unwrap()] = word.clone(); state.card_sets[self.selected_set.unwrap()] = set.clone();
} }
SetForward(new) => { SetForward(new) => {
state.card_sets[self.selected_set.unwrap()].forward = new; state.card_sets[self.selected_set.unwrap()].forward = new;
@@ -129,7 +127,7 @@ impl RepetitionsState {
.get_mut(self.selected_set.unwrap()) .get_mut(self.selected_set.unwrap())
.unwrap() .unwrap()
.open_mode = mode; .open_mode = mode;
}, }
} }
Task::none() Task::none()
} }
@@ -157,23 +155,30 @@ impl RepetitionsState {
) )
} }
fn launch_button(&self) -> Element<'_, RepetitionsMessage> { fn launch_delete_button(&self, set: &CardSetSettings) -> Element<'_, RepetitionsMessage> {
if let Some(set) = self.selected_set if set.id != 0
&& self.state.lock().unwrap().card_sets[set].id != 0
{ {
return button(text!("Начать повторение").width(200).center()) return row![
.style(cta_button) space().width(Fill),
.on_press(GoToRepetition) button(text!("Начать повторение").width(200).center())
.into(); .style(cta_button)
.on_press(GoToRepetition)
]
.into();
} }
space().into() button("Удалить").style(danger).on_press(DeleteSet).into()
} }
fn selected_set_view(&self) -> Element<'_, RepetitionsMessage> { fn selected_set_view(&self) -> Element<'_, RepetitionsMessage> {
if let Some(index) = self.selected_set { if let Some(index) = self.selected_set {
let set; let set;
{ {
set = self.state.lock().unwrap().card_sets[index].clone();
let state = self.state.lock().unwrap();
if state.card_sets.len() <= index {
return space().width(Length::FillPortion(3)).into()
}
set = state.card_sets[index].clone();
} }
return column![ return column![
scrollable( scrollable(
@@ -182,30 +187,41 @@ impl RepetitionsState {
text!("Название набора"), text!("Название набора"),
row![ row![
text_input("", &set.name).on_input(SetName), text_input("", &set.name).on_input(SetName),
button(svg(Handle::from_memory(SETTINGS_ICON))).width(43).on_press(GoToSettings), button(svg(Handle::from_memory(SETTINGS_ICON)))
.width(43)
.on_press(GoToSettings),
] ]
.spacing(HALF_SPACING) .spacing(HALF_SPACING)
] ]
.spacing(QUARTER_SPACING), .spacing(QUARTER_SPACING),
column![ {
text!("Передняя сторона"), if set.id == 0 {
text_input("", &set.forward).on_input(SetForward), column![
] column![
.spacing(QUARTER_SPACING), text!("Передняя сторона"),
column![ text_input("", &set.forward).on_input(SetForward),
text!("Задняя сторона"), ]
text_input("", &set.backward).on_input(SetBackward), .spacing(QUARTER_SPACING),
] column![
.spacing(QUARTER_SPACING), text!("Задняя сторона"),
column![ text_input("", &set.backward).on_input(SetBackward),
text!("Фильтр"), ]
text_input("", &set.filter).on_input(SetFilter), .spacing(QUARTER_SPACING),
button("Проверить фильтр") column![
.style(jl_button) text!("Фильтр"),
.on_press(TryFilter), text_input("", &set.filter).on_input(SetFilter),
self.count_view(&set), button("Проверить фильтр")
] .style(jl_button)
.spacing(QUARTER_SPACING), .on_press(TryFilter),
self.count_view(&set),
]
.spacing(QUARTER_SPACING),
]
.spacing(DEFAULT_SPACING)
} else {
self.filled_set_data_view(&set)
}
},
radio( radio(
"Обычный режим", "Обычный режим",
SetOrderMode::Default, SetOrderMode::Default,
@@ -213,9 +229,7 @@ impl RepetitionsState {
SetOpenMode SetOpenMode
), ),
self.words_words_view(&set), self.words_words_view(&set),
button("История") button("История").style(jl_button).on_press(GoToHistory),
.style(jl_button)
.on_press(GoToHistory),
] ]
.spacing(DEFAULT_SPACING) .spacing(DEFAULT_SPACING)
.padding(Padding { .padding(Padding {
@@ -227,14 +241,8 @@ impl RepetitionsState {
) )
.height(Fill), .height(Fill),
row![ row![
button("Сохранить") button("Сохранить").style(jl_button).on_press(Save),
.style(jl_button) self.launch_delete_button(&set)
.on_press(Save),
button("Удалить")
.style(danger)
.on_press(DeleteSet),
space().width(Fill),
self.launch_button()
] ]
.spacing(DEFAULT_SPACING), .spacing(DEFAULT_SPACING),
] ]
@@ -245,6 +253,10 @@ impl RepetitionsState {
space().width(Length::FillPortion(3)).into() space().width(Length::FillPortion(3)).into()
} }
fn filled_set_data_view(&self, set: &CardSetSettings) -> Column<'_, RepetitionsMessage> {
column![].spacing(DEFAULT_SPACING).into()
}
fn words_words_view(&self, set: &CardSetSettings) -> Element<'_, RepetitionsMessage> { fn words_words_view(&self, set: &CardSetSettings) -> Element<'_, RepetitionsMessage> {
column![ column![
text!("Худшие слова"), text!("Худшие слова"),