2026-04-19 20:22:35 +03:00
|
|
|
use crate::data_provider::words::{delete_word, update_word};
|
2026-05-05 12:02:59 +03:00
|
|
|
use crate::lang::WordData;
|
2026-04-17 12:38:05 +03:00
|
|
|
use crate::Page::PreviousPage;
|
|
|
|
|
use crate::{AppState, NavigatedPage, Page, RootMessage, DEFAULT_SPACING};
|
|
|
|
|
use iced::widget::button::danger;
|
2026-04-19 20:22:35 +03:00
|
|
|
use iced::widget::{button, column, container, row, rule, scrollable, space, text, text_input};
|
2026-04-17 12:38:05 +03:00
|
|
|
use iced::{Element, Fill, Task};
|
|
|
|
|
use std::sync::{Arc, Mutex};
|
|
|
|
|
|
|
|
|
|
#[derive(Clone)]
|
|
|
|
|
pub struct WordState {
|
|
|
|
|
state: Arc<Mutex<AppState>>,
|
|
|
|
|
index: usize,
|
2026-05-05 12:02:59 +03:00
|
|
|
word: WordData,
|
2026-04-17 12:38:05 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl NavigatedPage<WordMessage> for WordState {
|
|
|
|
|
fn navigate(&self, message: &WordMessage) -> Option<Page> {
|
|
|
|
|
if let WordMessage::Back = message {
|
|
|
|
|
Some(PreviousPage)
|
|
|
|
|
} else {
|
|
|
|
|
None
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl WordState {
|
|
|
|
|
pub(crate) fn new(
|
2026-05-05 12:02:59 +03:00
|
|
|
word: WordData,
|
2026-04-17 12:38:05 +03:00
|
|
|
index: usize,
|
|
|
|
|
state: Arc<Mutex<AppState>>,
|
|
|
|
|
) -> WordState {
|
|
|
|
|
WordState { state, index, word }
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl WordState {
|
|
|
|
|
pub fn update(&mut self, message: WordMessage) -> Task<RootMessage> {
|
|
|
|
|
match message {
|
2026-04-19 20:22:35 +03:00
|
|
|
WordMessage::Back => {}
|
2026-04-17 12:38:05 +03:00
|
|
|
WordMessage::Save => {
|
|
|
|
|
let mut state = self.state.lock().unwrap();
|
|
|
|
|
state.dictionary[self.index] = self.word.clone();
|
|
|
|
|
update_word(&mut self.word, &state.connection)
|
|
|
|
|
}
|
|
|
|
|
WordMessage::Delete => {
|
|
|
|
|
let mut state = self.state.lock().unwrap();
|
|
|
|
|
state.dictionary.remove(self.index);
|
|
|
|
|
delete_word(&self.word, &state.connection);
|
2026-04-19 20:22:35 +03:00
|
|
|
return Task::done(RootMessage::Word(WordMessage::Back));
|
2026-04-17 12:38:05 +03:00
|
|
|
}
|
|
|
|
|
WordMessage::SetTags(n) => self.word.tags = n,
|
|
|
|
|
WordMessage::SetKey(n) => {
|
|
|
|
|
self.word.key = n;
|
|
|
|
|
}
|
|
|
|
|
WordMessage::SetValue(n) => {
|
|
|
|
|
self.word.value = n;
|
|
|
|
|
}
|
2026-04-19 20:22:35 +03:00
|
|
|
WordMessage::SetAdditional(key, value) => {
|
|
|
|
|
match key.as_str() {
|
|
|
|
|
"reading" => {
|
|
|
|
|
self.word.additional.insert(key, value.clone());
|
|
|
|
|
},
|
|
|
|
|
_ => todo!()
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
WordMessage::AddAdditional(key) => {
|
|
|
|
|
self.word.additional.insert(key, "".to_string());
|
|
|
|
|
},
|
2026-04-17 12:38:05 +03:00
|
|
|
}
|
|
|
|
|
Task::none()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn view(&self) -> Element<'_, WordMessage> {
|
2026-04-19 20:22:35 +03:00
|
|
|
let mut fast_add = row![];
|
|
|
|
|
if !self.word.additional.contains_key("reading") {
|
|
|
|
|
fast_add = fast_add.push(button("Чтение").style(button::text).on_press(WordMessage::AddAdditional("reading".to_string())));
|
|
|
|
|
}
|
|
|
|
|
let mut col = iced::widget::column![
|
|
|
|
|
button("Назад").on_press(WordMessage::Back),
|
|
|
|
|
text!("Ключ"),
|
|
|
|
|
text_input("key", &self.word.key).on_input(WordMessage::SetKey),
|
|
|
|
|
text!("Значение"),
|
|
|
|
|
text_input("value", &self.word.value).on_input(WordMessage::SetValue),
|
|
|
|
|
text!("Теги"),
|
|
|
|
|
text_input("tags", &self.word.tags).on_input(WordMessage::SetTags),
|
|
|
|
|
rule::horizontal(2),
|
|
|
|
|
scrollable(fast_add),
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
for more in &self.word.additional {
|
|
|
|
|
col = col.push(self.get_view_for_more(more));
|
|
|
|
|
}
|
2026-04-17 12:38:05 +03:00
|
|
|
container(
|
|
|
|
|
column![
|
2026-04-19 20:22:35 +03:00
|
|
|
col.spacing(DEFAULT_SPACING).width(Fill).height(Fill),
|
2026-04-17 12:38:05 +03:00
|
|
|
row![
|
|
|
|
|
button("Сохранить").on_press(WordMessage::Save),
|
|
|
|
|
button("Удалить")
|
|
|
|
|
.style(danger)
|
|
|
|
|
.on_press(WordMessage::Delete),
|
|
|
|
|
]
|
|
|
|
|
.spacing(DEFAULT_SPACING)
|
|
|
|
|
]
|
|
|
|
|
.spacing(DEFAULT_SPACING),
|
|
|
|
|
)
|
|
|
|
|
.padding(DEFAULT_SPACING)
|
|
|
|
|
.into()
|
|
|
|
|
}
|
2026-04-19 20:22:35 +03:00
|
|
|
|
|
|
|
|
fn get_view_for_more(&self, value: (&String, &String)) -> Element<'_, WordMessage> {
|
|
|
|
|
return match value.0.as_str() {
|
|
|
|
|
"reading" => self.reading_field(value),
|
|
|
|
|
_ => space().into(),
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn reading_field(&self, value: (&String, &String)) -> Element<'_, WordMessage> {
|
|
|
|
|
column![
|
|
|
|
|
text!("Чтение слова"),
|
|
|
|
|
text_input("reading", &value.1)
|
|
|
|
|
.on_input(|string| WordMessage::SetAdditional("reading".to_string(), string))
|
|
|
|
|
].spacing(DEFAULT_SPACING)
|
|
|
|
|
.into()
|
|
|
|
|
}
|
2026-04-17 12:38:05 +03:00
|
|
|
}
|
|
|
|
|
#[derive(Debug, Clone)]
|
|
|
|
|
pub enum WordMessage {
|
|
|
|
|
Save,
|
|
|
|
|
Back,
|
|
|
|
|
Delete,
|
|
|
|
|
SetTags(String),
|
|
|
|
|
SetKey(String),
|
|
|
|
|
SetValue(String),
|
2026-04-19 20:22:35 +03:00
|
|
|
AddAdditional(String),
|
|
|
|
|
SetAdditional(String, String),
|
2026-04-17 12:38:05 +03:00
|
|
|
}
|