New edit process
This commit is contained in:
1 parent
097c3c033c
commit
47bc83d4ae
12 files changed
+584
-46
No files matched your search
+117
-26
@@ -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>,
|
||||
}
|
||||
Reference in new issue
Block a user