From 5e6327a40094409f18d8bc5fcd1de9294d218806 Mon Sep 17 00:00:00 2001 From: Robin Scholtes Date: Mon, 14 Aug 2023 17:34:23 +1200 Subject: [PATCH] [#181] fix some event issues ( dragging and dropping, mobile taps ), fix popover issues ( popovers properly disappear ), eslint cleanup fixes --- src/web/App.mjs | 1 + src/web/TODO.md | 24 +---------------------- src/web/components/c-operation-li.mjs | 26 ++++++++++++------------- src/web/components/c-operation-list.mjs | 26 ++++++++++++++++++------- src/web/waiters/RecipeWaiter.mjs | 2 +- 5 files changed, 34 insertions(+), 45 deletions(-) diff --git a/src/web/App.mjs b/src/web/App.mjs index 6ce0940d..087da2bf 100755 --- a/src/web/App.mjs +++ b/src/web/App.mjs @@ -437,6 +437,7 @@ class App { // update all op-lists to reflect the current recipe list ( selected ops ) and favourite category list ( favourite ops ) this.manager.ops.updateListItemsClasses("#rec-list", "selected"); this.manager.ops.updateListItemsClasses("#catFavourites > c-operation-list > ul.op-list", "favourite"); + this.manager.recipe.initDragAndDrop(); } /** diff --git a/src/web/TODO.md b/src/web/TODO.md index 4134ee62..6a9e962d 100644 --- a/src/web/TODO.md +++ b/src/web/TODO.md @@ -1,25 +1,3 @@ -recipe: -- ignore dropped item outside of rec-list -- bit smoother sort experience would be nice - operations: -- can only drag an op to favourites 1 time -- popovers should also show on key up and down per operation -- after dragging op to rec, popover no longer works on original op ( see opSortEnd ) - -- stupid popovers on deleting favs for instance ( dont always close nicely ) - UI tests etc. - --------- - -x highlight strings -x esc on focused-op search results will add that op to recipe -x be able to tab from panel to panel, open and close them, use up and down arrows -x little line on click ( for all input fields, also ingredient focus ) -x native focus thingy is a bit ugly -x RecipeWaiter opSortEnd() - -wont do -x initial search is kinda slow - -Tim +- input in search > click X > dropdown doesn't close diff --git a/src/web/components/c-operation-li.mjs b/src/web/components/c-operation-li.mjs index ddc6e314..0dea45d9 100644 --- a/src/web/components/c-operation-li.mjs +++ b/src/web/components/c-operation-li.mjs @@ -34,7 +34,8 @@ export class COperationLi extends HTMLElement { this.build(); - this.addEventListener("click", this.handleClick.bind(this)); + // Use mousedown event instead of click to prevent accidentally firing the handler twice on mobile + this.addEventListener("mousedown", this.handleMousedown.bind(this)); this.addEventListener("dblclick", this.handleDoubleClick.bind(this)); if (this.includeStarIcon) { @@ -47,12 +48,14 @@ export class COperationLi extends HTMLElement { * Remove listeners on disconnectedCallback */ disconnectedCallback() { - this.removeEventListener("click", this.handleClick.bind(this)); + this.removeEventListener("mousedown", this.handleMousedown.bind(this)); this.removeEventListener("dblclick", this.handleDoubleClick.bind(this)); if (this.includeStarIcon) { this.observer.disconnect(); } + + $(this).find("[data-toggle=popover]").popover("dispose").popover("hide"); } /** @@ -68,11 +71,11 @@ export class COperationLi extends HTMLElement { } /** - * Handle click + * Handle mousedown * * @param {Event} e */ - handleClick(e) { + handleMousedown(e) { if (e.target === this.querySelector("i.star-icon")) { this.app.addFavourite(this.name); } @@ -124,24 +127,22 @@ export class COperationLi extends HTMLElement { * @param {HTMLElement} el - The element to start selecting from */ setPopover(el) { - $(el) + $(this) .find("[data-toggle=popover]") .addBack("[data-toggle=popover]") .popover({trigger: "manual"}) .on("mouseenter", function(e) { if (e.buttons > 0) return; // Mouse button held down - likely dragging an operation - const _this = this; - $(this).popover("show"); + $(el).popover("show"); $(".popover").on("mouseleave", function () { - $(_this).popover("hide"); + $(el).popover("hide"); }); }) .on("mouseleave", function () { - const _this = this; setTimeout(function() { // Determine if the popover associated with this element is being hovered over - if ($(_this).data("bs.popover") && ($(_this).data("bs.popover").tip && !$($(_this).data("bs.popover").tip).is(":hover"))) { - $(_this).popover("hide"); + if ($(el).data("bs.popover") && ($(el).data("bs.popover").tip && !$($(el).data("bs.popover").tip).is(":hover"))) { + $(el).popover("hide"); } }, 50); }); @@ -190,7 +191,6 @@ export class COperationLi extends HTMLElement { li.classList.add("favourite"); } - if (this.config.description) { let dataContent = this.config.description; @@ -200,9 +200,7 @@ export class COperationLi extends HTMLElement { li.setAttribute("data-container", "body"); li.setAttribute("data-toggle", "popover"); - li.setAttribute("data-placement", "left"); li.setAttribute("data-html", "true"); - li.setAttribute("data-trigger", "hover"); li.setAttribute("data-boundary", "viewport"); li.setAttribute("data-content", dataContent); } diff --git a/src/web/components/c-operation-list.mjs b/src/web/components/c-operation-list.mjs index 92fca0d5..0584588a 100644 --- a/src/web/components/c-operation-list.mjs +++ b/src/web/components/c-operation-list.mjs @@ -73,6 +73,7 @@ export class COperationList extends HTMLElement { group: "sorting", sort: true, draggable: "c-operation-li", + filter: "i.material-icons", onFilter: function (e) { const el = sortableList.closest(e.item); if (el && el.parentNode) { @@ -97,6 +98,17 @@ export class COperationList extends HTMLElement { * @param { string } targetListId * */ createCloneableList(ul, targetListName, targetListId) { + let dragOverRecList = false; + const recList = document.querySelector(`#${targetListId}`); + + Sortable.utils.on(recList, "dragover", function () { + dragOverRecList = true; + }); + + Sortable.utils.on(recList, "dragleave", function () { + dragOverRecList = false; + }); + Sortable.create(ul, { group: { name: targetListName, @@ -113,19 +125,19 @@ export class COperationList extends HTMLElement { // event bindings from the one left in the operations list. Without manually removing // these bindings, we cannot re-initialise the popover on the stub operation. $(e.item) - .popover("dispose") - .removeData("bs.popover") - .off("mouseenter") - .off("mouseleave") - .attr("data-toggle", "popover-disabled"); + .find("[data-toggle=popover]") + .popover("dispose"); $(e.clone) + .find("[data-toggle=popover]") .off(".popover") .removeData("bs.popover"); }, - onEnd: ({item}) => { - if (item.parentNode.id === targetListId) { + onEnd: ({item, to}) => { + if (item.parentNode.id === targetListId && dragOverRecList) { this.app.manager.recipe.addOperation(item.name); item.remove(); + } else if (!dragOverRecList && !to.classList.contains("op-list")) { + item.remove(); } } }); diff --git a/src/web/waiters/RecipeWaiter.mjs b/src/web/waiters/RecipeWaiter.mjs index 108fdba8..a1622e6c 100755 --- a/src/web/waiters/RecipeWaiter.mjs +++ b/src/web/waiters/RecipeWaiter.mjs @@ -40,7 +40,7 @@ class RecipeWaiter { if (this.app.isMobileView()) { swapThreshold = 0.60; animation = 400; - delay = 200; + delay = 50; } else { swapThreshold = 0.10; animation = 200;