Files
jap_learn/src/word.rs
T

166 lines
5.8 KiB
Rust
Raw Normal View History

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 {
2026-05-25 12:23:32 +03:00
pub(crate) fn new(word: WordData, index: usize, state: Arc<Mutex<AppState>>) -> WordState {
2026-04-17 12:38:05 +03:00
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();
2026-05-12 16:57:05 +03:00
update_word(&mut self.word, &state.connection);
2026-05-25 12:23:32 +03:00
return Task::done(RootMessage::Word(WordMessage::Back));
2026-04-17 12:38:05 +03:00
}
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-05-25 12:23:32 +03:00
WordMessage::SetAdditional(key, value) => match key.as_str() {
_ => {
self.word.additional.insert(key, value.clone());
2026-04-19 20:22:35 +03:00
}
},
WordMessage::AddAdditional(key) => {
self.word.additional.insert(key, "".to_string());
2026-05-25 12:23:32 +03:00
}
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") {
2026-05-25 12:23:32 +03:00
fast_add = fast_add.push(
button("Чтение")
.style(button::text)
.on_press(WordMessage::AddAdditional("reading".to_string())),
);
2026-04-19 20:22:35 +03:00
}
2026-05-10 22:15:03 +03:00
if !self.word.additional.contains_key("description") {
2026-05-25 12:23:32 +03:00
fast_add = fast_add.push(
button("Описание")
.style(button::text)
.on_press(WordMessage::AddAdditional("description".to_string())),
);
}
if !self.word.additional.contains_key("context") {
fast_add = fast_add.push(
button("В контексте")
.style(button::text)
.on_press(WordMessage::AddAdditional("context".to_string())),
);
2026-05-10 22:15:03 +03:00
}
2026-05-25 12:23:32 +03:00
2026-04-19 20:22:35 +03:00
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> {
2026-05-05 12:06:17 +03:00
match value.0.as_str() {
2026-04-19 20:22:35 +03:00
"reading" => self.reading_field(value),
2026-05-10 22:15:03 +03:00
"description" => self.description_field(value),
2026-05-25 12:23:32 +03:00
"context" => self.context_field(value),
2026-04-19 20:22:35 +03:00
_ => space().into(),
2026-05-05 12:06:17 +03:00
}
2026-04-19 20:22:35 +03:00
}
fn reading_field(&self, value: (&String, &String)) -> Element<'_, WordMessage> {
2026-05-25 12:23:32 +03:00
self.additional_field(value, "Чтение слова".to_string(), "reading".to_string())
2026-04-19 20:22:35 +03:00
}
2026-05-10 22:15:03 +03:00
fn description_field(&self, value: (&String, &String)) -> Element<'_, WordMessage> {
2026-05-25 12:23:32 +03:00
self.additional_field(value, "Описание".to_string(), "description".to_string())
}
fn context_field(&self, value: (&String, &String)) -> Element<'_, WordMessage> {
self.additional_field(value, "В контексте".to_string(), "context".to_string())
}
fn additional_field(&self, value: (&String, &String), name: String, id: String) -> Element<'_, WordMessage> {
2026-05-10 22:15:03 +03:00
column![
2026-05-25 12:23:32 +03:00
text!("{}", name),
text_input(id.clone().as_str(), &value.1)
.on_input(move |string| WordMessage::SetAdditional(id.clone(), 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
}