New edit process

This commit is contained in:
micialware committed 2026-09-11 00:01:19 +03:00
1 parent 097c3c033c
commit 47bc83d4ae
12 files changed
+584 -46

No files matched your search

+117 -26
View File
@@ -13,13 +13,16 @@ use crate::pages::import::ImportState;
use crate::pages::word::WordState;
use crate::push_error_task;
use crate::styling::*;
use crate::widgets::hard_mouse_area::hard_mouse_area;
use crate::{jl_button, push_error};
use chrono::{DateTime, TimeDelta, Utc};
use hashbrown::{HashMap, HashSet};
use iced::alignment::Vertical::Center;
use iced::widget::button::Style;
use iced::widget::button::{danger, text};
use iced::widget::operation::focus;
use iced::widget::space::horizontal;
use iced::widget::text_input::Status::Active;
use iced::widget::text_input::default;
use iced::widget::*;
use iced::{Border, Color, Shadow, Task};
@@ -43,6 +46,8 @@ pub struct DictionaryState {
auto_save_queue: HashMap<EntityHandle<WordData>, DateTime<Utc>>,
displayed_words_query: Query<WordData, WordRepositoryInner, WordDataLayer>,
groups_query: Query<WordGroup, WordGroupRepositoryInner, WordGroupDataLayer>,
selected_cell: Option<(EntityHandle<WordData>, BasicWordFields)>,
hovered_cell: Option<(EntityHandle<WordData>, BasicWordFields)>,
}
#[derive(Clone)]
@@ -68,6 +73,15 @@ pub enum DictionaryMessage {
ChangeDirection,
TrySave(EntityHandle<WordData>),
GotoImport,
SelectField(EntityHandle<WordData>, BasicWordFields),
EditField(String),
}
#[derive(Clone, PartialEq, Eq, Hash, Copy)]
pub enum BasicWordFields {
Key,
Value,
Tags,
}
impl NavigatedPage<DictionaryMessage> for DictionaryState {
@@ -262,10 +276,37 @@ impl NavigatedPage<DictionaryMessage> for DictionaryState {
if reload_query {
self.displayed_words_query.load(&dictionary);
}
info!("Saved word");
return Task::none();
}
}
GotoImport => {}
SelectField(e, f) => {
info!("Editing word {}", e.id);
self.selected_cell = Some((e, f));
return focus(iced::widget::Id::new("editor"));
}
EditField(value) => {
if let Some(selected) = self.selected_cell.as_ref() {
{
let mut dictionary = self.state.dictionary.write();
let word = dictionary.get_mut_static(selected.0).unwrap();
match selected.1 {
BasicWordFields::Key => {
word.key = value;
}
BasicWordFields::Value => {
word.value = value;
}
BasicWordFields::Tags => {
word.key = value;
}
}
}
return self.launch_auto_save_offset(selected.0);
}
}
}
Task::none()
@@ -277,6 +318,29 @@ impl NavigatedPage<DictionaryMessage> for DictionaryState {
iced::widget::column![
self.groups_panel(),
row![horizontal().width(8), self.words_list(),],
{
let mut display = "".to_string();
if let Some(selected) = self.selected_cell.as_ref() {
let mut dictionary = self.state.dictionary.write();
let word = dictionary.get_mut_static(selected.0).unwrap();
match selected.1 {
BasicWordFields::Key => {
display = word.key.clone();
}
BasicWordFields::Value => {
display = word.value.clone();
}
BasicWordFields::Tags => {
display = word.tags.clone();
}
}
}
text_input("", display.as_str())
.width(Fill)
.id(iced::widget::Id::new("editor"))
.on_input(EditField)
},
row![
self.add_word_button(),
horizontal().width(Fill),
@@ -310,6 +374,8 @@ impl DictionaryState {
auto_save_queue: HashMap::new(),
displayed_words_query: words_query,
groups_query,
selected_cell: None,
hovered_cell: None,
};
result.init();
@@ -336,11 +402,11 @@ impl DictionaryState {
}
fn launch_auto_save_offset(&mut self, handle: EntityHandle<WordData>) -> Task<RootMessage> {
let save_time = Utc::now().add(TimeDelta::milliseconds(900));
let save_time = Utc::now().add(TimeDelta::milliseconds(500));
self.auto_save_queue.insert(handle, save_time);
let message = RootMessage::Dictionary(TrySave(handle));
Task::perform(
async { tokio::time::sleep(Duration::from_secs(1)).await },
async { tokio::time::sleep(Duration::from_millis(520)).await },
|_| message,
)
}
@@ -368,12 +434,29 @@ impl DictionaryState {
continue;
}
let mut selection = None;
let mut hovered = None;
if let Some(cell) = self.selected_cell.as_ref() {
if cell.0 == *word_handle {
selection = Some(cell.1);
}
}
if let Some(cell) = self.hovered_cell.as_ref() {
if cell.0 == *word_handle {
hovered = Some(cell.1);
}
}
let word_line_data = WordLineState {
is_included: self.included.contains(word_handle),
key: word.key.clone().into(),
value: word.value.clone().into(),
tags: word.tags.clone().into(),
handle: *word_handle,
selection,
hover: hovered,
};
let lazy_line = lazy(word_line_data, Self::word_line);
@@ -395,39 +478,45 @@ impl DictionaryState {
.on_toggle(move |b| Include(handle, b)),
);
line = line.push(
text_input("Слово", &data.key)
let field = |placeholder: &str, data: &str, selected: bool| {
text_input(placeholder, data)
.size(ACCENT_FONT_SIZE)
.width(Fill)
.on_input(move |string| SetKey(handle, string))
.style(|x, status| {
let mut default_style = default(x, status);
.style(move |x, _| {
let mut default_style = default(x, Active);
default_style.border.radius = 0.0.into();
if selected {
default_style.border.color = x.extended_palette().secondary.base.color;
default_style.border.width = 3.0_f32.into();
}
default_style
}),
})
};
line = line.push(
hard_mouse_area(field(
"Слово",
&data.key,
data.selection.is_some() && data.selection.unwrap() == BasicWordFields::Key,
))
.on_press(SelectField(data.handle, BasicWordFields::Key))
);
line = line.push(
text_input("Перевод", &data.value)
.size(ACCENT_FONT_SIZE)
.width(Fill)
.on_input(move |string| SetValue(handle, string))
.style(|x, status| {
let mut default_style = default(x, status);
default_style.border.radius = 0.0.into();
default_style
}),
hard_mouse_area(field(
"Перевод",
&data.value,
data.selection.is_some() && data.selection.unwrap() == BasicWordFields::Value,
))
.on_press(SelectField(data.handle, BasicWordFields::Value))
);
line = line.push(
text_input("Теги", data.tags.as_ref())
.size(ACCENT_FONT_SIZE)
.width(Fill)
.on_input(move |string| SetTags(handle, string))
.style(|x, status| {
let mut default_style = default(x, status);
default_style.border.radius = 0.0.into();
default_style
}),
hard_mouse_area(field(
"Теги",
&data.tags,
data.selection.is_some() && data.selection.unwrap() == BasicWordFields::Tags,
))
.on_press(SelectField(data.handle, BasicWordFields::Tags))
);
let line_button = || {
@@ -640,4 +729,6 @@ struct WordLineState {
value: Box<str>,
tags: Box<str>,
handle: EntityHandle<WordData>,
selection: Option<BasicWordFields>,
hover: Option<BasicWordFields>,
}
+3 -3
View File
@@ -9,11 +9,11 @@ use crate::pages::dictionary::split_with_coma;
use crate::pages::dictionary_quiz::DictionaryQuizMessage::*;
use crate::pages::quiz::Score;
use crate::styling::*;
use iced::Background::Color;
use iced::border::Radius;
use iced::widget::container::Style;
use iced::widget::{container, row, space, text, text_input, Row};
use iced::Background::Color;
use iced::{alignment, Border, Element, Fill, Task, Theme};
use iced::widget::{Row, container, row, space, text, text_input};
use iced::{Border, Element, Fill, Task, Theme, alignment};
use rand::prelude::SliceRandom;
pub struct DictionaryQuizState {
+1 -3
View File
@@ -64,9 +64,7 @@ impl HistoryState {
(word, item.clone())
})
.collect();
Self {
list: words,
}
Self { list: words }
}
fn history_lines(&self) -> Column<'_, HistoryMessage> {
+4 -4
View File
@@ -16,17 +16,17 @@ use crate::push_error_task;
use crate::styling::*;
use chrono::{Days, Local, Utc};
use hashbrown::HashSet;
use iced::widget::button::{danger, Status};
pub use iced::widget::button::{Catalog, Style};
use iced::widget::button::{Status, danger};
use iced::widget::tooltip::Position::Top;
use iced::widget::{
button, column, container, lazy, radio, row, scrollable, space, svg, text, text_input, tooltip,
Column, Row,
Column, Row, button, column, container, lazy, radio, row, scrollable, space, svg, text,
text_input, tooltip,
};
use iced::{Background, Border, Center, Color, Element, Fill, Length, Shadow, Task, Theme};
use iced_core::Padding;
use iced_core::border::Radius;
use iced_core::svg::Handle;
use iced_core::Padding;
use std::collections::BTreeMap;
use std::ops::Deref;
use std::sync::Arc;
+1 -1
View File
@@ -13,7 +13,7 @@ use crate::pages::writing::WritingState;
use crate::styling::*;
use iced::widget::button::{Status, Style};
use iced::widget::*;
use iced::{alignment, Element, Task};
use iced::{Element, Task, alignment};
use iced_core::Alignment::Center;
use iced_core::Background;
use iced_core::Color;