diff options
author | Lauri Ojansivu <x@xet7.org> | 2018-07-07 08:50:19 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-07-07 08:50:19 +0300 |
commit | efb083aabf677f84822cb264b894cd21a6b20f7c (patch) | |
tree | 143e9bdb1544a1c783bd2c842ed6c3e0a01251de | |
parent | 6c7eab4456f8608ae3893d2200b759d426863cd2 (diff) | |
parent | 5c774070617357c25c7bb35b43f4b122eb4b3e34 (diff) | |
download | wekan-efb083aabf677f84822cb264b894cd21a6b20f7c.tar.gz wekan-efb083aabf677f84822cb264b894cd21a6b20f7c.tar.bz2 wekan-efb083aabf677f84822cb264b894cd21a6b20f7c.zip |
Merge pull request #1757 from Haocen/mobile-hotfix
Mobile hotfix
-rw-r--r-- | client/components/boards/boardBody.js | 5 | ||||
-rw-r--r-- | client/components/cards/cardDetails.js | 8 | ||||
-rw-r--r-- | client/components/cards/checklists.js | 5 | ||||
-rw-r--r-- | client/components/lists/list.js | 5 | ||||
-rw-r--r-- | client/components/main/header.styl | 2 | ||||
-rw-r--r-- | client/components/mixins/perfectScrollbar.js | 18 | ||||
-rw-r--r-- | client/components/swimlanes/swimlanes.js | 5 | ||||
-rw-r--r-- | client/lib/utils.js | 49 |
8 files changed, 84 insertions, 13 deletions
diff --git a/client/components/boards/boardBody.js b/client/components/boards/boardBody.js index 68ac8b27..b68c9b12 100644 --- a/client/components/boards/boardBody.js +++ b/client/components/boards/boardBody.js @@ -1,5 +1,5 @@ const subManager = new SubsManager(); -const { calculateIndex } = Utils; +const { calculateIndex, enableClickOnTouch } = Utils; BlazeComponent.extendComponent({ onCreated() { @@ -74,6 +74,9 @@ BlazeComponent.extendComponent({ }, }); + // ugly touch event hotfix + enableClickOnTouch('.js-swimlane:not(.placeholder)'); + function userIsMember() { return Meteor.user() && Meteor.user().isBoardMember() && !Meteor.user().isCommentOnly(); } diff --git a/client/components/cards/cardDetails.js b/client/components/cards/cardDetails.js index 5fee1680..b41bfc17 100644 --- a/client/components/cards/cardDetails.js +++ b/client/components/cards/cardDetails.js @@ -1,5 +1,5 @@ const subManager = new SubsManager(); -const { calculateIndexData } = Utils; +const { calculateIndexData, enableClickOnTouch } = Utils; BlazeComponent.extendComponent({ mixins() { @@ -132,6 +132,9 @@ BlazeComponent.extendComponent({ }, }); + // ugly touch event hotfix + enableClickOnTouch('.card-checklist-items .js-checklist'); + const $subtasksDom = this.$('.card-subtasks-items'); $subtasksDom.sortable({ @@ -167,6 +170,9 @@ BlazeComponent.extendComponent({ }, }); + // ugly touch event hotfix + enableClickOnTouch('.card-subtasks-items .js-subtasks'); + function userIsMember() { return Meteor.user() && Meteor.user().isBoardMember(); } diff --git a/client/components/cards/checklists.js b/client/components/cards/checklists.js index 519af629..e014abba 100644 --- a/client/components/cards/checklists.js +++ b/client/components/cards/checklists.js @@ -1,4 +1,4 @@ -const { calculateIndexData } = Utils; +const { calculateIndexData, enableClickOnTouch } = Utils; function initSorting(items) { items.sortable({ @@ -36,6 +36,9 @@ function initSorting(items) { checklistItem.move(checklistId, sortIndex.base); }, }); + + // ugly touch event hotfix + enableClickOnTouch('.js-checklist-item:not(.placeholder)'); } BlazeComponent.extendComponent({ diff --git a/client/components/lists/list.js b/client/components/lists/list.js index 38a87674..267af31c 100644 --- a/client/components/lists/list.js +++ b/client/components/lists/list.js @@ -1,4 +1,4 @@ -const { calculateIndex } = Utils; +const { calculateIndex, enableClickOnTouch } = Utils; BlazeComponent.extendComponent({ // Proxy @@ -83,6 +83,9 @@ 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(() => { $cards.sortable('option', 'disabled', !userIsMember()); diff --git a/client/components/main/header.styl b/client/components/main/header.styl index f9455f8e..495716e1 100644 --- a/client/components/main/header.styl +++ b/client/components/main/header.styl @@ -218,7 +218,7 @@ position: absolute right: 0px padding: 10px - margin: -10px + margin: -10px 0 -10px -10px .announcement, .offline-warning diff --git a/client/components/mixins/perfectScrollbar.js b/client/components/mixins/perfectScrollbar.js index f652f043..12f8a892 100644 --- a/client/components/mixins/perfectScrollbar.js +++ b/client/components/mixins/perfectScrollbar.js @@ -1,12 +1,16 @@ +const { isTouchDevice } = Utils; + Mixins.PerfectScrollbar = BlazeComponent.extendComponent({ onRendered() { - const component = this.mixinParent(); - const domElement = component.find('.js-perfect-scrollbar'); - Ps.initialize(domElement); + if (!isTouchDevice()) { + const component = this.mixinParent(); + const domElement = component.find('.js-perfect-scrollbar'); + Ps.initialize(domElement); - // XXX We should create an event map to be consistent with other components - // but since BlazeComponent doesn't merge Mixins events transparently I - // prefered to use a jQuery event (which is what an event map ends up doing) - component.$(domElement).on('mouseenter', () => Ps.update(domElement)); + // XXX We should create an event map to be consistent with other components + // but since BlazeComponent doesn't merge Mixins events transparently I + // prefered to use a jQuery event (which is what an event map ends up doing) + component.$(domElement).on('mouseenter', () => Ps.update(domElement)); + } }, }); diff --git a/client/components/swimlanes/swimlanes.js b/client/components/swimlanes/swimlanes.js index c67fe6af..865895a9 100644 --- a/client/components/swimlanes/swimlanes.js +++ b/client/components/swimlanes/swimlanes.js @@ -1,4 +1,4 @@ -const { calculateIndex } = Utils; +const { calculateIndex, enableClickOnTouch } = Utils; function currentCardIsInThisList(listId, swimlaneId) { const currentCard = Cards.findOne(Session.get('currentCard')); @@ -66,6 +66,9 @@ function initSortable(boardComponent, $listsDom) { }, }); + // ugly touch event hotfix + enableClickOnTouch('.js-list:not(.js-list-composer)'); + function userIsMember() { return Meteor.user() && Meteor.user().isBoardMember() && !Meteor.user().isCommentOnly(); } diff --git a/client/lib/utils.js b/client/lib/utils.js index 1f44c60d..6b8e3524 100644 --- a/client/lib/utils.js +++ b/client/lib/utils.js @@ -95,6 +95,55 @@ Utils = { increment, }; }, + + // 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); + } + }); + }, }; // A simple tracker dependency that we invalidate every time the window is |