Add optional reading field

This commit is contained in:
2026-04-19 20:22:35 +03:00
parent d5803bfb81
commit f0379925f1
4 changed files with 928 additions and 29 deletions
Generated
+864 -3
View File
File diff suppressed because it is too large Load Diff
+2
View File
@@ -12,3 +12,5 @@ serde_json = "1.0.149"
rhai = "1.24.0" rhai = "1.24.0"
chrono = "0.4.44" chrono = "0.4.44"
rusqlite = { version = "0.39.0", features = ["chrono"] } rusqlite = { version = "0.39.0", features = ["chrono"] }
reqwest = { version = "0.12", features = ["json", "stream"] }
+8 -10
View File
@@ -4,9 +4,7 @@ use crate::Page::PreviousPage;
use crate::{AppState, KeyPressedPage, NavigatedPage, Page, RootMessage, DEFAULT_SPACING}; use crate::{AppState, KeyPressedPage, NavigatedPage, Page, RootMessage, DEFAULT_SPACING};
use iced::alignment::Horizontal::Center; use iced::alignment::Horizontal::Center;
use iced::keyboard::key::Physical::Code; use iced::keyboard::key::Physical::Code;
use iced::widget::container::rounded_box; use iced::widget::{button, column, container, row, rule, space, text};
use iced::widget::space::vertical;
use iced::widget::{button, column, container, row, space, text};
use iced::{alignment, keyboard, Element, Fill, Left, Task}; use iced::{alignment, keyboard, Element, Fill, Left, Task};
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
@@ -46,8 +44,8 @@ impl RepetitionState {
pub fn update(&mut self, message: RepetitionMessage) -> Task<RootMessage> { pub fn update(&mut self, message: RepetitionMessage) -> Task<RootMessage> {
match message { match message {
RepetitionMessage::Back => {} RepetitionMessage::Back => {}
RepetitionMessage::Next => {self.next()} RepetitionMessage::Next => self.next(),
RepetitionMessage::Answer(m) => {self.answer(m)} RepetitionMessage::Answer(m) => self.answer(m),
} }
Task::none() Task::none()
@@ -84,15 +82,16 @@ impl RepetitionState {
.height(Fill) .height(Fill)
.align_x(Center) .align_x(Center)
.align_y(alignment::Vertical::Center), .align_y(alignment::Vertical::Center),
container(vertical().height(5)).width(Fill).padding(5).style(rounded_box), rule::horizontal(2),
container(self.draw_backward()) container(self.draw_backward())
.width(Fill) .width(Fill)
.height(Fill) .height(Fill)
.align_x(Center) .align_x(Center)
.align_y(alignment::Vertical::Center), .align_y(alignment::Vertical::Center),
container( container(self.answer_bar())
self.answer_bar() .width(Fill)
).width(Fill).align_x(Center).height(30) .align_x(Center)
.height(30)
] ]
.height(Fill) .height(Fill)
.width(Fill) .width(Fill)
@@ -112,7 +111,6 @@ impl RepetitionState {
"value" => self.draw_value(word), "value" => self.draw_value(word),
_ => space().into(), _ => space().into(),
} }
} }
fn draw_backward(&self) -> Element<'_, RepetitionMessage> { fn draw_backward(&self) -> Element<'_, RepetitionMessage> {
+49 -11
View File
@@ -1,11 +1,11 @@
use crate::data_provider::words::{delete_word, update_word};
use crate::lang::DictionaryElement; use crate::lang::DictionaryElement;
use crate::Page::PreviousPage; use crate::Page::PreviousPage;
use crate::{AppState, NavigatedPage, Page, RootMessage, DEFAULT_SPACING}; use crate::{AppState, NavigatedPage, Page, RootMessage, DEFAULT_SPACING};
use iced::widget::button::danger; use iced::widget::button::danger;
use iced::widget::{button, column, container, row, text, text_input}; use iced::widget::{button, column, container, row, rule, scrollable, space, text, text_input};
use iced::{Element, Fill, Task}; use iced::{Element, Fill, Task};
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use crate::data_provider::words::{delete_word, update_word};
#[derive(Clone)] #[derive(Clone)]
pub struct WordState { pub struct WordState {
@@ -37,7 +37,7 @@ impl WordState {
impl WordState { impl WordState {
pub fn update(&mut self, message: WordMessage) -> Task<RootMessage> { pub fn update(&mut self, message: WordMessage) -> Task<RootMessage> {
match message { match message {
WordMessage::Back => {}, WordMessage::Back => {}
WordMessage::Save => { WordMessage::Save => {
let mut state = self.state.lock().unwrap(); let mut state = self.state.lock().unwrap();
state.dictionary[self.index] = self.word.clone(); state.dictionary[self.index] = self.word.clone();
@@ -47,7 +47,7 @@ impl WordState {
let mut state = self.state.lock().unwrap(); let mut state = self.state.lock().unwrap();
state.dictionary.remove(self.index); state.dictionary.remove(self.index);
delete_word(&self.word, &state.connection); delete_word(&self.word, &state.connection);
return Task::done(RootMessage::Word(WordMessage::Back)) return Task::done(RootMessage::Word(WordMessage::Back));
} }
WordMessage::SetTags(n) => self.word.tags = n, WordMessage::SetTags(n) => self.word.tags = n,
WordMessage::SetKey(n) => { WordMessage::SetKey(n) => {
@@ -56,14 +56,28 @@ impl WordState {
WordMessage::SetValue(n) => { WordMessage::SetValue(n) => {
self.word.value = n; self.word.value = n;
} }
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());
},
} }
Task::none() Task::none()
} }
pub fn view(&self) -> Element<'_, WordMessage> { pub fn view(&self) -> Element<'_, WordMessage> {
container( let mut fast_add = row![];
column![ if !self.word.additional.contains_key("reading") {
iced::widget::column![ 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), button("Назад").on_press(WordMessage::Back),
text!("Ключ"), text!("Ключ"),
text_input("key", &self.word.key).on_input(WordMessage::SetKey), text_input("key", &self.word.key).on_input(WordMessage::SetKey),
@@ -71,10 +85,16 @@ impl WordState {
text_input("value", &self.word.value).on_input(WordMessage::SetValue), text_input("value", &self.word.value).on_input(WordMessage::SetValue),
text!("Теги"), text!("Теги"),
text_input("tags", &self.word.tags).on_input(WordMessage::SetTags), text_input("tags", &self.word.tags).on_input(WordMessage::SetTags),
] rule::horizontal(2),
.spacing(DEFAULT_SPACING) scrollable(fast_add),
.width(Fill) ];
.height(Fill),
for more in &self.word.additional {
col = col.push(self.get_view_for_more(more));
}
container(
column![
col.spacing(DEFAULT_SPACING).width(Fill).height(Fill),
row![ row![
button("Сохранить").on_press(WordMessage::Save), button("Сохранить").on_press(WordMessage::Save),
button("Удалить") button("Удалить")
@@ -88,6 +108,22 @@ impl WordState {
.padding(DEFAULT_SPACING) .padding(DEFAULT_SPACING)
.into() .into()
} }
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()
}
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum WordMessage { pub enum WordMessage {
@@ -97,4 +133,6 @@ pub enum WordMessage {
SetTags(String), SetTags(String),
SetKey(String), SetKey(String),
SetValue(String), SetValue(String),
AddAdditional(String),
SetAdditional(String, String),
} }