Replace DragEvent data by a global state

This commit is contained in:
Greg Burri 2025-01-15 10:42:50 +01:00
parent b86cded45d
commit be769e4e3e

View file

@ -1,4 +1,4 @@
use std::rc; use std::{cell::RefCell, rc, sync::Mutex};
use gloo::{ use gloo::{
console::log, console::log,
@ -401,8 +401,9 @@ fn create_group_element(group: &ron_api::Group) -> Element {
if modal_dialog::show(&format!("Are you sure to delete the group '{}'", name)).await { if modal_dialog::show(&format!("Are you sure to delete the group '{}'", name)).await {
let body = ron_api::RemoveRecipeGroup { group_id }; let body = ron_api::RemoveRecipeGroup { group_id };
let _ = request::delete::<(), _>("recipe/remove_group", body).await; let _ = request::delete::<(), _>("recipe/remove_group", body).await;
by_id::<Element>(&format!("group-{}", group_id)).remove(); let group_element = by_id::<Element>(&format!("group-{}", group_id));
by_id::<Element>(&format!("dropzone-group-{}", group_id)).remove(); group_element.next_element_sibling().unwrap().remove();
group_element.remove();
} }
}); });
}) })
@ -534,8 +535,9 @@ fn create_step_element(group_element: &Element, step: &ron_api::Step) -> Element
if modal_dialog::show(&format!("Are you sure to delete the step '{}'", action)).await { if modal_dialog::show(&format!("Are you sure to delete the step '{}'", action)).await {
let body = ron_api::RemoveRecipeStep { step_id }; let body = ron_api::RemoveRecipeStep { step_id };
let _ = request::delete::<(), _>("recipe/remove_step", body).await; let _ = request::delete::<(), _>("recipe/remove_step", body).await;
by_id::<Element>(&format!("step-{}", step_id)).remove(); let step_element = by_id::<Element>(&format!("step-{}", step_id));
by_id::<Element>(&format!("dropzone-step-{}", step_id)).remove(); step_element.next_element_sibling().unwrap().remove();
step_element.remove();
} }
}); });
}) })
@ -674,9 +676,6 @@ fn create_ingredient_element(step_element: &Element, ingredient: &ron_api::Ingre
ingredient_element ingredient_element
} }
// "text/plain" is avoided to prevent dropping to a input text box.
const DRAG_AND_DROP_MIME_TYPE: &str = "recipes/element-id";
enum CursorPosition { enum CursorPosition {
UpperPart, UpperPart,
LowerPart, LowerPart,
@ -700,6 +699,12 @@ fn get_parent_with_id_starting_with(mut element: Element, prefix: &str) -> Eleme
element element
} }
// It replaces 'event.data_transfer().unwrap().get_data()/set_data()' because
// Chrome prevent to read this during draghover event which is the correct behavior
// according the specifications:
// * https://html.spec.whatwg.org/multipage/dnd.html#the-drag-data-store
static DATA_DRAGGED: Mutex<RefCell<String>> = Mutex::new(RefCell::new(String::new()));
/// Set an element as draggable and add an element before and after /// Set an element as draggable and add an element before and after
/// cloned from "#hidden-templates .dropzone". /// cloned from "#hidden-templates .dropzone".
/// All elements set as draggable in a given container can be dragged /// All elements set as draggable in a given container can be dragged
@ -731,11 +736,9 @@ where
EventListenerOptions::enable_prevent_default(), EventListenerOptions::enable_prevent_default(),
move |event| { move |event| {
let event: &DragEvent = event.dyn_ref::<DragEvent>().unwrap(); let event: &DragEvent = event.dyn_ref::<DragEvent>().unwrap();
let drag_data = event
.data_transfer() let drag_data_lock = DATA_DRAGGED.lock().unwrap();
.unwrap() let drag_data = drag_data_lock.borrow();
.get_data(DRAG_AND_DROP_MIME_TYPE)
.unwrap();
if drag_data.starts_with(&prefix_copied) { if drag_data.starts_with(&prefix_copied) {
let element: Element = by_id(&drag_data); let element: Element = by_id(&drag_data);
@ -777,11 +780,9 @@ where
let prefix_copied = prefix.to_string(); let prefix_copied = prefix.to_string();
EventListener::new(element, "dragleave", move |event| { EventListener::new(element, "dragleave", move |event| {
let event: &DragEvent = event.dyn_ref::<DragEvent>().unwrap(); let event: &DragEvent = event.dyn_ref::<DragEvent>().unwrap();
let drag_data = event
.data_transfer() let drag_data_lock = DATA_DRAGGED.lock().unwrap();
.unwrap() let drag_data = drag_data_lock.borrow();
.get_data(DRAG_AND_DROP_MIME_TYPE)
.unwrap();
if drag_data.starts_with(&prefix_copied) { if drag_data.starts_with(&prefix_copied) {
let element: Element = by_id(&drag_data); let element: Element = by_id(&drag_data);
@ -812,11 +813,9 @@ where
let prefix_copied = prefix.to_string(); let prefix_copied = prefix.to_string();
EventListener::new(element, "drop", move |event| { EventListener::new(element, "drop", move |event| {
let event: &DragEvent = event.dyn_ref::<DragEvent>().unwrap(); let event: &DragEvent = event.dyn_ref::<DragEvent>().unwrap();
let drag_data = event
.data_transfer() let drag_data_lock = DATA_DRAGGED.lock().unwrap();
.unwrap() let drag_data = drag_data_lock.borrow();
.get_data(DRAG_AND_DROP_MIME_TYPE)
.unwrap();
if drag_data.starts_with(&prefix_copied) { if drag_data.starts_with(&prefix_copied) {
let target: Element = event.current_target().unwrap().dyn_into().unwrap(); let target: Element = event.current_target().unwrap().dyn_into().unwrap();
@ -899,11 +898,10 @@ where
dp.set_class_name("dropzone active"); dp.set_class_name("dropzone active");
} }
} }
event
.data_transfer() let drag_data_lock = DATA_DRAGGED.lock().unwrap();
.unwrap() drag_data_lock.replace(target_element.id());
.set_data(DRAG_AND_DROP_MIME_TYPE, &target_element.id())
.unwrap();
event.data_transfer().unwrap().set_effect_allowed("move"); event.data_transfer().unwrap().set_effect_allowed("move");
} }
}) })
@ -938,11 +936,9 @@ where
EventListenerOptions::enable_prevent_default(), EventListenerOptions::enable_prevent_default(),
move |event| { move |event| {
let event: &DragEvent = event.dyn_ref::<DragEvent>().unwrap(); let event: &DragEvent = event.dyn_ref::<DragEvent>().unwrap();
let drag_data = event
.data_transfer() let drag_data_lock = DATA_DRAGGED.lock().unwrap();
.unwrap() let drag_data = drag_data_lock.borrow();
.get_data(DRAG_AND_DROP_MIME_TYPE)
.unwrap();
if drag_data.starts_with(&prefix_copied) { if drag_data.starts_with(&prefix_copied) {
let element: Element = by_id(&drag_data); let element: Element = by_id(&drag_data);
@ -973,11 +969,9 @@ where
let prefix_copied = prefix.to_string(); let prefix_copied = prefix.to_string();
EventListener::new(dropzone, "dragleave", move |event| { EventListener::new(dropzone, "dragleave", move |event| {
let event: &DragEvent = event.dyn_ref::<DragEvent>().unwrap(); let event: &DragEvent = event.dyn_ref::<DragEvent>().unwrap();
let drag_data = event
.data_transfer() let drag_data_lock = DATA_DRAGGED.lock().unwrap();
.unwrap() let drag_data = drag_data_lock.borrow();
.get_data(DRAG_AND_DROP_MIME_TYPE)
.unwrap();
if drag_data.starts_with(&prefix_copied) { if drag_data.starts_with(&prefix_copied) {
let element: Element = by_id(&drag_data); let element: Element = by_id(&drag_data);
@ -1005,11 +999,9 @@ where
let prefix_copied = prefix.to_string(); let prefix_copied = prefix.to_string();
EventListener::new(dropzone, "drop", move |event| { EventListener::new(dropzone, "drop", move |event| {
let event: &DragEvent = event.dyn_ref::<DragEvent>().unwrap(); let event: &DragEvent = event.dyn_ref::<DragEvent>().unwrap();
let drag_data = event
.data_transfer() let drag_data_lock = DATA_DRAGGED.lock().unwrap();
.unwrap() let drag_data = drag_data_lock.borrow();
.get_data(DRAG_AND_DROP_MIME_TYPE)
.unwrap();
if drag_data.starts_with(&prefix_copied) { if drag_data.starts_with(&prefix_copied) {
let target: Element = event.current_target().unwrap().dyn_into().unwrap(); let target: Element = event.current_target().unwrap().dyn_into().unwrap();