[#181] fix some event issues ( dragging and dropping, mobile taps ), fix popover issues ( popovers properly disappear ), eslint cleanup fixes

This commit is contained in:
Robin Scholtes 2023-08-14 17:34:23 +12:00
parent 8afcfa0b45
commit 5e6327a400
5 changed files with 34 additions and 45 deletions

View file

@ -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();
}
/**

View file

@ -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

View file

@ -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);
}

View file

@ -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();
}
}
});

View file

@ -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;