summaryrefslogtreecommitdiffstats
path: root/client/lib
diff options
context:
space:
mode:
Diffstat (limited to 'client/lib')
-rw-r--r--client/lib/datepicker.js10
-rw-r--r--client/lib/filter.js10
-rwxr-xr-xclient/lib/keyboard.js52
-rw-r--r--client/lib/textComplete.js11
-rw-r--r--client/lib/utils.js70
5 files changed, 120 insertions, 33 deletions
diff --git a/client/lib/datepicker.js b/client/lib/datepicker.js
index 8ad66c5f..aa05310c 100644
--- a/client/lib/datepicker.js
+++ b/client/lib/datepicker.js
@@ -10,12 +10,22 @@ DatePicker = BlazeComponent.extendComponent({
this.defaultTime = defaultTime;
},
+ startDayOfWeek() {
+ const currentUser = Meteor.user();
+ if (currentUser) {
+ return currentUser.getStartDayOfWeek();
+ } else {
+ return 1;
+ }
+ },
+
onRendered() {
const $picker = this.$('.js-datepicker')
.datepicker({
todayHighlight: true,
todayBtn: 'linked',
language: TAPi18n.getLanguage(),
+ weekStart: this.startDayOfWeek(),
})
.on(
'changeDate',
diff --git a/client/lib/filter.js b/client/lib/filter.js
index 592eb4ab..24ca320b 100644
--- a/client/lib/filter.js
+++ b/client/lib/filter.js
@@ -459,13 +459,21 @@ Filter = {
// before changing the schema.
labelIds: new SetFilter(),
members: new SetFilter(),
+ assignees: new SetFilter(),
archive: new SetFilter(),
hideEmpty: new SetFilter(),
customFields: new SetFilter('_id'),
advanced: new AdvancedFilter(),
lists: new AdvancedFilter(), // we need the ability to filter list by name as well
- _fields: ['labelIds', 'members', 'archive', 'hideEmpty', 'customFields'],
+ _fields: [
+ 'labelIds',
+ 'members',
+ 'assignees',
+ 'archive',
+ 'hideEmpty',
+ 'customFields',
+ ],
// We don't filter cards that have been added after the last filter change. To
// implement this we keep the id of these cards in this `_exceptions` fields
diff --git a/client/lib/keyboard.js b/client/lib/keyboard.js
index d3f974be..e861e416 100755
--- a/client/lib/keyboard.js
+++ b/client/lib/keyboard.js
@@ -1,6 +1,16 @@
// XXX There is no reason to define these shortcuts globally, they should be
// attached to a template (most of them will go in the `board` template).
+function getHoveredCardId() {
+ const card = $('.js-minicard:hover').get(0);
+ if (!card) return null;
+ return Blaze.getData(card)._id;
+}
+
+function getSelectedCardId() {
+ return Session.get('selectedCard') || getHoveredCardId();
+}
+
Mousetrap.bind('?', () => {
FlowRouter.go('shortcuts');
});
@@ -50,9 +60,9 @@ Mousetrap.bind(['down', 'up'], (evt, key) => {
}
});
-// XXX This shortcut should also work when hovering over a card in board view
Mousetrap.bind('space', evt => {
- if (!Session.get('currentCard')) {
+ const cardId = getSelectedCardId();
+ if (!cardId) {
return;
}
@@ -62,7 +72,7 @@ Mousetrap.bind('space', evt => {
}
if (Meteor.user().isBoardMember()) {
- const card = Cards.findOne(Session.get('currentCard'));
+ const card = Cards.findOne(cardId);
card.toggleMember(currentUserId);
// We should prevent scrolling in card when spacebar is clicked
// This should do it according to Mousetrap docs, but it doesn't
@@ -70,22 +80,46 @@ Mousetrap.bind('space', evt => {
}
});
+Mousetrap.bind('c', evt => {
+ const cardId = getSelectedCardId();
+ if (!cardId) {
+ return;
+ }
+
+ const currentUserId = Meteor.userId();
+ if (currentUserId === null) {
+ return;
+ }
+
+ if (
+ Meteor.user().isBoardMember() &&
+ !Meteor.user().isCommentOnly() &&
+ !Meteor.user().isWorker()
+ ) {
+ const card = Cards.findOne(cardId);
+ card.archive();
+ // We should prevent scrolling in card when spacebar is clicked
+ // This should do it according to Mousetrap docs, but it doesn't
+ evt.preventDefault();
+ }
+});
+
Template.keyboardShortcuts.helpers({
mapping: [
{
- keys: ['W'],
+ keys: ['w'],
action: 'shortcut-toggle-sidebar',
},
{
- keys: ['Q'],
+ keys: ['q'],
action: 'shortcut-filter-my-cards',
},
{
- keys: ['F'],
+ keys: ['f'],
action: 'shortcut-toggle-filterbar',
},
{
- keys: ['X'],
+ keys: ['x'],
action: 'shortcut-clear-filters',
},
{
@@ -104,5 +138,9 @@ Template.keyboardShortcuts.helpers({
keys: ['SPACE'],
action: 'shortcut-assign-self',
},
+ {
+ keys: ['c'],
+ action: 'archive-card',
+ },
],
});
diff --git a/client/lib/textComplete.js b/client/lib/textComplete.js
index 8b6dc1f7..e97d3853 100644
--- a/client/lib/textComplete.js
+++ b/client/lib/textComplete.js
@@ -48,6 +48,11 @@ $.fn.escapeableTextComplete = function(strategies, options, ...otherArgs) {
return this;
};
-EscapeActions.register('textcomplete', () => {}, () => dropdownMenuIsOpened, {
- noClickEscapeOn: '.textcomplete-dropdown',
-});
+EscapeActions.register(
+ 'textcomplete',
+ () => {},
+ () => dropdownMenuIsOpened,
+ {
+ noClickEscapeOn: '.textcomplete-dropdown',
+ },
+);
diff --git a/client/lib/utils.js b/client/lib/utils.js
index f4fc170a..c921fddc 100644
--- a/client/lib/utils.js
+++ b/client/lib/utils.js
@@ -24,18 +24,14 @@ Utils = {
currentUser = Meteor.user();
if (currentUser) {
return (currentUser.profile || {}).boardView;
+ } else if (cookies.get('boardView') === 'board-view-lists') {
+ return 'board-view-lists';
+ } else if (cookies.get('boardView') === 'board-view-swimlanes') {
+ return 'board-view-swimlanes';
+ } else if (cookies.get('boardView') === 'board-view-cal') {
+ return 'board-view-cal';
} else {
- if (cookies.get('boardView') === 'board-view-lists') {
- return 'board-view-lists';
- } else if (
- cookies.get('boardView') === 'board-view-swimlanes'
- ) {
- return 'board-view-swimlanes';
- } else if (cookies.get('boardView') === 'board-view-cal') {
- return 'board-view-cal';
- } else {
- return false;
- }
+ return false;
}
},
@@ -43,8 +39,8 @@ Utils = {
goBoardId(_id) {
const board = Boards.findOne(_id);
return (
- board
- && FlowRouter.go('board', {
+ board &&
+ FlowRouter.go('board', {
id: board._id,
slug: board.slug,
})
@@ -55,8 +51,8 @@ Utils = {
const card = Cards.findOne(_id);
const board = Boards.findOne(card.boardId);
return (
- board
- && FlowRouter.go('card', {
+ board &&
+ FlowRouter.go('card', {
cardId: card._id,
boardId: board._id,
slug: board.slug,
@@ -151,8 +147,38 @@ Utils = {
// in a small window (even on desktop), Wekan run in compact mode.
// we can easily debug with a small window of desktop browser. :-)
isMiniScreen() {
+ // OLD WINDOW WIDTH DETECTION:
this.windowResizeDep.depend();
return $(window).width() <= 800;
+
+ // NEW TOUCH DEVICE DETECTION:
+ // https://developer.mozilla.org/en-US/docs/Web/HTTP/Browser_detection_using_the_user_agent
+
+ /*
+ var hasTouchScreen = false;
+ if ("maxTouchPoints" in navigator) {
+ hasTouchScreen = navigator.maxTouchPoints > 0;
+ } else if ("msMaxTouchPoints" in navigator) {
+ hasTouchScreen = navigator.msMaxTouchPoints > 0;
+ } else {
+ var mQ = window.matchMedia && matchMedia("(pointer:coarse)");
+ if (mQ && mQ.media === "(pointer:coarse)") {
+ hasTouchScreen = !!mQ.matches;
+ } else if ('orientation' in window) {
+ hasTouchScreen = true; // deprecated, but good fallback
+ } else {
+ // Only as a last resort, fall back to user agent sniffing
+ var UA = navigator.userAgent;
+ hasTouchScreen = (
+ /\b(BlackBerry|webOS|iPhone|IEMobile)\b/i.test(UA) ||
+ /\b(Android|Windows Phone|iPad|iPod)\b/i.test(UA)
+ );
+ }
+ }
+ */
+ //if (hasTouchScreen)
+ // document.getElementById("exampleButton").style.padding="1em";
+ //return false;
},
calculateIndexData(prevData, nextData, nItems = 1) {
@@ -227,8 +253,8 @@ Utils = {
};
if (
- 'ontouchstart' in window
- || (window.DocumentTouch && document instanceof window.DocumentTouch)
+ 'ontouchstart' in window ||
+ (window.DocumentTouch && document instanceof window.DocumentTouch)
) {
return true;
}
@@ -249,8 +275,8 @@ Utils = {
calculateTouchDistance(touchA, touchB) {
return Math.sqrt(
- Math.pow(touchA.screenX - touchB.screenX, 2)
- + Math.pow(touchA.screenY - touchB.screenY, 2),
+ Math.pow(touchA.screenX - touchB.screenX, 2) +
+ Math.pow(touchA.screenY - touchB.screenY, 2),
);
},
@@ -267,9 +293,9 @@ Utils = {
});
$(document).on('touchend', selector, function(e) {
if (
- touchStart
- && lastTouch
- && Utils.calculateTouchDistance(touchStart, lastTouch) <= 20
+ touchStart &&
+ lastTouch &&
+ Utils.calculateTouchDistance(touchStart, lastTouch) <= 20
) {
e.preventDefault();
const clickEvent = document.createEvent('MouseEvents');