summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--client/components/boards/boardBody.js5
-rw-r--r--client/components/cards/cardDetails.js8
-rw-r--r--client/components/cards/checklists.js5
-rw-r--r--client/components/lists/list.js5
-rw-r--r--client/components/main/header.styl2
-rw-r--r--client/components/mixins/perfectScrollbar.js18
-rw-r--r--client/components/swimlanes/swimlanes.js5
-rw-r--r--client/lib/utils.js49
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