diff --git a/.meteor/packages b/.meteor/packages index e6911f08e..10d89875e 100644 --- a/.meteor/packages +++ b/.meteor/packages @@ -60,7 +60,6 @@ reactive-var@1.0.11 fortawesome:fontawesome mousetrap:mousetrap mquandalle:jquery-textcomplete -mquandalle:jquery-ui-drag-drop-sort mquandalle:mousetrap-bindglobal peerlibrary:blaze-components@=0.15.1 templates:tabs diff --git a/.meteor/versions b/.meteor/versions index 76647b8a0..0f1be0e1d 100644 --- a/.meteor/versions +++ b/.meteor/versions @@ -76,6 +76,7 @@ matb33:collection-hooks@0.9.1 matteodem:easy-search@1.6.4 mdg:validation-error@0.5.1 meteor@1.9.3 +meteor-autosize@5.0.1 meteor-base@1.4.0 meteor-platform@1.2.6 meteorhacks:aggregate@1.3.0 @@ -106,7 +107,6 @@ mquandalle:collection-mutations@0.1.0 mquandalle:jade@0.4.9 mquandalle:jade-compiler@0.4.5 mquandalle:jquery-textcomplete@0.8.0_1 -mquandalle:jquery-ui-drag-drop-sort@0.2.0 mquandalle:moment@1.0.1 mquandalle:mousetrap-bindglobal@0.0.1 msavin:usercache@1.8.0 @@ -219,7 +219,6 @@ url@1.3.2 useraccounts:core@1.14.2 useraccounts:flow-routing@1.14.2 useraccounts:unstyled@1.14.2 -meteor-autosize@5.0.1 webapp@1.10.1 webapp-hashing@1.1.0 wekan-accounts-cas@0.1.0 diff --git a/client/components/boards/boardsList.js b/client/components/boards/boardsList.js index fc8331b8c..290b45c32 100644 --- a/client/components/boards/boardsList.js +++ b/client/components/boards/boardsList.js @@ -1,5 +1,4 @@ const subManager = new SubsManager(); -const { calculateIndex, enableClickOnTouch } = Utils; Template.boardListHeaderBar.events({ 'click .js-open-archived-board'() { @@ -56,7 +55,7 @@ BlazeComponent.extendComponent({ // of the previous and the following card -- if any. const prevBoardDom = ui.item.prev('.js-board').get(0); const nextBoardBom = ui.item.next('.js-board').get(0); - const sortIndex = calculateIndex(prevBoardDom, nextBoardBom, 1); + const sortIndex = Utils.calculateIndex(prevBoardDom, nextBoardBom, 1); const boardDomElement = ui.item.get(0); const board = Blaze.getData(boardDomElement); @@ -73,9 +72,6 @@ BlazeComponent.extendComponent({ }, }); - // ugly touch event hotfix - enableClickOnTouch(itemsSelector); - // Disable drag-dropping if the current user is not a board member or is comment only this.autorun(() => { if (Utils.isMiniScreenOrShowDesktopDragHandles()) { diff --git a/client/components/cards/labels.js b/client/components/cards/labels.js index 2b599aa66..fc48f75f4 100644 --- a/client/components/cards/labels.js +++ b/client/components/cards/labels.js @@ -73,7 +73,6 @@ BlazeComponent.extendComponent({ card.board().setNewLabelOrder(newLabelOrderOnlyIds); }, }); - Utils.enableClickOnTouch(itemsSelector); // Disable drag-dropping if the current user is not a board member or is comment only this.autorun(() => { diff --git a/client/components/lists/list.js b/client/components/lists/list.js index b5f829f25..3a0f9d66f 100644 --- a/client/components/lists/list.js +++ b/client/components/lists/list.js @@ -1,3 +1,5 @@ +require('/client/lib/jquery-ui.js') + const { calculateIndex } = Utils; BlazeComponent.extendComponent({ @@ -114,6 +116,43 @@ BlazeComponent.extendComponent({ } boardComponent.setIsDragging(false); }, + sort(event, ui) { + const $boardCanvas = $('.board-canvas'); + const boardCanvas = $boardCanvas[0]; + + if (event.pageX < 10) + { // scroll to the left + boardCanvas.scrollLeft -= 15; + ui.helper[0].offsetLeft -= 15; + } + if ( + event.pageX > boardCanvas.offsetWidth - 10 && + boardCanvas.scrollLeft < $boardCanvas.data('scrollLeftMax') // don't scroll more than possible + ) + { // scroll to the right + boardCanvas.scrollLeft += 15; + } + if ( + event.pageY > boardCanvas.offsetHeight - 10 && + boardCanvas.scrollTop < $boardCanvas.data('scrollTopMax') // don't scroll more than possible + ) + { // scroll to the bottom + boardCanvas.scrollTop += 15; + } + if (event.pageY < 10) + { // scroll to the top + boardCanvas.scrollTop -= 15; + } + }, + activate(event, ui) { + const $boardCanvas = $('.board-canvas'); + const boardCanvas = $boardCanvas[0]; + // scrollTopMax and scrollLeftMax only available at Firefox (https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollTopMax) + // https://stackoverflow.com/questions/12965296/how-to-get-maximum-document-scrolltop-value/12965383#12965383 + $boardCanvas.data('scrollTopMax', $(document).height() - $(window).height()); + // https://stackoverflow.com/questions/5138373/how-do-i-get-the-max-value-of-scrollleft/5704386#5704386 + $boardCanvas.data('scrollLeftMax', boardCanvas.scrollWidth - boardCanvas.clientWidth); + }, }); this.autorun(() => { diff --git a/client/lib/jquery-ui.js b/client/lib/jquery-ui.js new file mode 100644 index 000000000..6bdcf2f5a --- /dev/null +++ b/client/lib/jquery-ui.js @@ -0,0 +1,20 @@ +// https://bugs.jqueryui.com/ticket/15020 +// required for sortable +require('jquery-ui/ui/widget') +require('jquery-ui/ui/scroll-parent') +require('jquery-ui/ui/data') +require('jquery-ui/ui/widgets/mouse') +require('jquery-ui/ui/ie') +require('jquery-ui/ui/widgets/sortable') + +// required for draggable +require('jquery-ui/ui/plugin') +require('jquery-ui/ui/safe-active-element') +require('jquery-ui/ui/safe-blur') +require('jquery-ui/ui/widgets/draggable') + +// everything already required for droppable +require('jquery-ui/ui/widgets/droppable') + +// enable touch on mobile +require('jquery-ui-touch-punch') diff --git a/client/lib/tests/Utils.tests.js b/client/lib/tests/Utils.tests.js index 5a368876c..1ffcd8105 100644 --- a/client/lib/tests/Utils.tests.js +++ b/client/lib/tests/Utils.tests.js @@ -163,18 +163,6 @@ describe('Utils', function() { it('has no tests yet'); }); - describe(Utils.isTouchDevice.name, function() { - it('has no tests yet'); - }); - - describe(Utils.calculateTouchDistance.name, function() { - it('has no tests yet'); - }); - - describe(Utils.enableClickOnTouch.name, function() { - it('has no tests yet'); - }); - describe(Utils.manageCustomUI.name, function() { it('has no tests yet'); }); diff --git a/client/lib/utils.js b/client/lib/utils.js index 6395fe741..fba13c74d 100644 --- a/client/lib/utils.js +++ b/client/lib/utils.js @@ -364,67 +364,6 @@ Utils = { }; }, - // Detect touch device - isTouchDevice() { - const isTouchable = (() => { - const prefixes = ' -webkit- -moz- -o- -ms- '.split(' '); - const mq = function(query) { - return window.matchMedia(query).matches; - }; - - if ( - 'ontouchstart' in window || - (window.DocumentTouch && document instanceof window.DocumentTouch) - ) { - return true; - } - - // include the 'heartz' as a way to have a non matching MQ to help terminate the join - // https://git.io/vznFH - const query = [ - '(', - prefixes.join('touch-enabled),('), - 'heartz', - ')', - ].join(''); - return mq(query); - })(); - Utils.isTouchDevice = () => isTouchable; - return isTouchable; - }, - - calculateTouchDistance(touchA, touchB) { - return Math.sqrt( - Math.pow(touchA.screenX - touchB.screenX, 2) + - Math.pow(touchA.screenY - touchB.screenY, 2), - ); - }, - - enableClickOnTouch(selector) { - let touchStart = null; - let lastTouch = null; - - $(document).on('touchstart', selector, function(e) { - touchStart = e.originalEvent.touches[0]; - }); - $(document).on('touchmove', selector, function(e) { - const touches = e.originalEvent.touches; - lastTouch = touches[touches.length - 1]; - }); - $(document).on('touchend', selector, function(e) { - if ( - touchStart && - lastTouch && - Utils.calculateTouchDistance(touchStart, lastTouch) <= 20 - ) { - e.preventDefault(); - const clickEvent = document.createEvent('MouseEvents'); - clickEvent.initEvent('click', true, true); - e.target.dispatchEvent(clickEvent); - } - }); - }, - manageCustomUI() { Meteor.call('getCustomUI', (err, data) => { if (err && err.error[0] === 'var-not-exist') { diff --git a/package-lock.json b/package-lock.json index aa323f882..88f497d66 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1802,6 +1802,24 @@ "semver": "^6.3.0" } }, + "jquery": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/jquery/-/jquery-2.2.4.tgz", + "integrity": "sha1-LInWiJterFIqfuoywUUhVZxsvwI=" + }, + "jquery-ui": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/jquery-ui/-/jquery-ui-1.13.0.tgz", + "integrity": "sha512-Osf7ECXNTYHtKBkn9xzbIf9kifNrBhfywFEKxOeB/OVctVmLlouV9mfc2qXCp6uyO4Pn72PXKOnj09qXetopCw==", + "requires": { + "jquery": ">=1.8.0 <4.0.0" + } + }, + "jquery-ui-touch-punch": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/jquery-ui-touch-punch/-/jquery-ui-touch-punch-0.2.3.tgz", + "integrity": "sha1-7tgiQnM7okP0az6HwYQbMIGR2mg=" + }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", diff --git a/package.json b/package.json index 0ea0e6779..68d6b3356 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,9 @@ "exceljs": "^4.2.1", "fibers": "^5.0.0", "gridfs-stream": "https://github.com/wekan/gridfs-stream/tarball/master", + "jquery": "^2.2.4", + "jquery-ui": "^1.13.0", + "jquery-ui-touch-punch": "^0.2.3", "jszip": "^3.7.1", "ldapjs": "^2.3.1", "markdown-it": "^12.2.0",