Browse Source

Set drag handle on touch screen not miniscreen

Repmovs 2 years ago
parent
commit
d7bb0b4cc0

+ 8 - 8
client/components/boards/boardBody.js

@@ -193,7 +193,7 @@ BlazeComponent.extendComponent({
     });
 
     this.autorun(() => {
-      if (Utils.isMiniScreenOrShowDesktopDragHandles()) {
+      if (Utils.isTouchScreenOrShowDesktopDragHandles()) {
         $swimlanesDom.sortable({
           handle: '.js-swimlane-header-handle',
         });
@@ -228,10 +228,10 @@ BlazeComponent.extendComponent({
     }
   },
 
-  notDisplayThisBoard(){
+  notDisplayThisBoard() {
     let allowPrivateVisibilityOnly = TableVisibilityModeSettings.findOne('tableVisibilityMode-allowPrivateOnly');
     let currentBoard = Boards.findOne(Session.get('currentBoard'));
-    if(allowPrivateVisibilityOnly !== undefined && allowPrivateVisibilityOnly.booleanValue && currentBoard.permission == 'public'){
+    if (allowPrivateVisibilityOnly !== undefined && allowPrivateVisibilityOnly.booleanValue && currentBoard.permission == 'public') {
       return true;
     }
 
@@ -319,7 +319,7 @@ BlazeComponent.extendComponent({
 
 BlazeComponent.extendComponent({
   onRendered() {
-    this.autorun(function() {
+    this.autorun(function () {
       $('#calendar-view').fullCalendar('refetchEvents');
     });
   },
@@ -351,7 +351,7 @@ BlazeComponent.extendComponent({
       events(start, end, timezone, callback) {
         const currentBoard = Boards.findOne(Session.get('currentBoard'));
         const events = [];
-        const pushEvent = function(card, title, start, end, extraCls) {
+        const pushEvent = function (card, title, start, end, extraCls) {
           start = start || card.startAt;
           end = end || card.endAt;
           title = title || card.title;
@@ -375,12 +375,12 @@ BlazeComponent.extendComponent({
         };
         currentBoard
           .cardsInInterval(start.toDate(), end.toDate())
-          .forEach(function(card) {
+          .forEach(function (card) {
             pushEvent(card);
           });
         currentBoard
           .cardsDueInBetween(start.toDate(), end.toDate())
-          .forEach(function(card) {
+          .forEach(function (card) {
             pushEvent(
               card,
               `${card.title} ${TAPi18n.__('card-due')}`,
@@ -388,7 +388,7 @@ BlazeComponent.extendComponent({
               new Date(card.dueAt.getTime() + 36e5),
             );
           });
-        events.sort(function(first, second) {
+        events.sort(function (first, second) {
           return first.id > second.id ? 1 : -1;
         });
         callback(events);

+ 2 - 2
client/components/boards/boardsList.jade

@@ -62,7 +62,7 @@ template(name="boardList")
                     i.fa.js-has-spenttime-cards(
                       class="fa-circle{{#if hasOvertimeCards}} has-overtime-card-active{{else}} no-overtime-card-active{{/if}}"
                       title="{{#if hasOvertimeCards}}{{_ 'has-overtime-cards'}}{{else}}{{_ 'has-spenttime-cards'}}{{/if}}")
-                  if isMiniScreenOrShowDesktopDragHandles
+                  if isTouchScreenOrShowDesktopDragHandles
                     i.fa.board-handle(
                         class="fa-arrows"
                         title="{{_ 'Drag board'}}")
@@ -114,7 +114,7 @@ template(name="boardList")
                     i.fa.js-has-spenttime-cards(
                       class="fa-circle{{#if hasOvertimeCards}} has-overtime-card-active{{else}} no-overtime-card-active{{/if}}"
                       title="{{#if hasOvertimeCards}}{{_ 'has-overtime-cards'}}{{else}}{{_ 'has-spenttime-cards'}}{{/if}}")
-                  if isMiniScreenOrShowDesktopDragHandles
+                  if isTouchScreenOrShowDesktopDragHandles
                     i.fa.board-handle(
                         class="fa-arrows"
                         title="{{_ 'Drag board'}}")

+ 49 - 51
client/components/boards/boardsList.js

@@ -30,7 +30,7 @@ BlazeComponent.extendComponent({
     Meteor.subscribe('tableVisibilityModeSettings');
     let currUser = Meteor.user();
     let userLanguage;
-    if(currUser && currUser.profile){
+    if (currUser && currUser.profile) {
       userLanguage = currUser.profile.language
     }
     if (userLanguage) {
@@ -79,54 +79,54 @@ BlazeComponent.extendComponent({
 
     // Disable drag-dropping if the current user is not a board member or is comment only
     this.autorun(() => {
-      if (Utils.isMiniScreenOrShowDesktopDragHandles()) {
+      if (Utils.isTouchScreenOrShowDesktopDragHandles()) {
         $boards.sortable({
           handle: '.board-handle',
         });
       }
     });
   },
-  userHasTeams(){
-    if(Meteor.user() != null && Meteor.user().teams && Meteor.user().teams.length > 0)
+  userHasTeams() {
+    if (Meteor.user() != null && Meteor.user().teams && Meteor.user().teams.length > 0)
       return true;
     else
       return false;
   },
   teamsDatas() {
-    if(Meteor.user().teams)
+    if (Meteor.user().teams)
       return Meteor.user().teams.sort((a, b) => a.teamDisplayName.localeCompare(b.teamDisplayName));
     else
       return [];
   },
-  userHasOrgs(){
-    if(Meteor.user() != null && Meteor.user().orgs && Meteor.user().orgs.length > 0)
+  userHasOrgs() {
+    if (Meteor.user() != null && Meteor.user().orgs && Meteor.user().orgs.length > 0)
       return true;
     else
       return false;
   },
-/*
-  userHasTemplates(){
-    if(Meteor.user() != null && Meteor.user().orgs && Meteor.user().orgs.length > 0)
-      return true;
-    else
-      return false;
-  },
-*/
+  /*
+    userHasTemplates(){
+      if(Meteor.user() != null && Meteor.user().orgs && Meteor.user().orgs.length > 0)
+        return true;
+      else
+        return false;
+    },
+  */
   orgsDatas() {
-    if(Meteor.user().orgs)
+    if (Meteor.user().orgs)
       return Meteor.user().orgs.sort((a, b) => a.orgDisplayName.localeCompare(b.orgDisplayName));
     else
       return [];
   },
-  userHasOrgsOrTeams(){
+  userHasOrgsOrTeams() {
     let boolUserHasOrgs;
-    if(Meteor.user() != null && Meteor.user().orgs && Meteor.user().orgs.length > 0)
+    if (Meteor.user() != null && Meteor.user().orgs && Meteor.user().orgs.length > 0)
       boolUserHasOrgs = true;
     else
       boolUserHasOrgs = false;
 
     let boolUserHasTeams;
-    if(Meteor.user() != null && Meteor.user().teams && Meteor.user().teams.length > 0)
+    if (Meteor.user() != null && Meteor.user().teams && Meteor.user().teams.length > 0)
       boolUserHasTeams = true;
     else
       boolUserHasTeams = false;
@@ -139,18 +139,18 @@ BlazeComponent.extendComponent({
       // { type: { $in: ['board','template-container'] } },
       $and: [
         { archived: false },
-        { type: { $in: ['board','template-container'] } },
-        { $or:[] }
+        { type: { $in: ['board', 'template-container'] } },
+        { $or: [] }
       ]
     };
 
     let allowPrivateVisibilityOnly = TableVisibilityModeSettings.findOne('tableVisibilityMode-allowPrivateOnly');
 
-    if (FlowRouter.getRouteName() === 'home'){
-      query.$and[2].$or.push({'members.userId': Meteor.userId()});
+    if (FlowRouter.getRouteName() === 'home') {
+      query.$and[2].$or.push({ 'members.userId': Meteor.userId() });
 
-      if(allowPrivateVisibilityOnly !== undefined && allowPrivateVisibilityOnly.booleanValue){
-        query.$and.push({'permission': 'private'});
+      if (allowPrivateVisibilityOnly !== undefined && allowPrivateVisibilityOnly.booleanValue) {
+        query.$and.push({ 'permission': 'private' });
       }
       const currUser = Users.findOne(Meteor.userId());
 
@@ -162,27 +162,27 @@ BlazeComponent.extendComponent({
       // });
 
       let orgIdsUserBelongs = currUser !== undefined && currUser.teams !== 'undefined' ? currUser.orgIdsUserBelongs() : '';
-      if(orgIdsUserBelongs && orgIdsUserBelongs != ''){
+      if (orgIdsUserBelongs && orgIdsUserBelongs != '') {
         let orgsIds = orgIdsUserBelongs.split(',');
         // for(let i = 0; i < orgsIds.length; i++){
         //   query.$and[2].$or.push({'orgs.orgId': orgsIds[i]});
         // }
 
         //query.$and[2].$or.push({'orgs': {$elemMatch : {orgId: orgsIds[0]}}});
-        query.$and[2].$or.push({'orgs.orgId': {$in : orgsIds}});
+        query.$and[2].$or.push({ 'orgs.orgId': { $in: orgsIds } });
       }
 
       let teamIdsUserBelongs = currUser !== undefined && currUser.teams !== 'undefined' ? currUser.teamIdsUserBelongs() : '';
-      if(teamIdsUserBelongs && teamIdsUserBelongs != ''){
+      if (teamIdsUserBelongs && teamIdsUserBelongs != '') {
         let teamsIds = teamIdsUserBelongs.split(',');
         // for(let i = 0; i < teamsIds.length; i++){
         //   query.$or[2].$or.push({'teams.teamId': teamsIds[i]});
         // }
         //query.$and[2].$or.push({'teams': { $elemMatch : {teamId: teamsIds[0]}}});
-        query.$and[2].$or.push({'teams.teamId': {$in : teamsIds}});
+        query.$and[2].$or.push({ 'teams.teamId': { $in: teamsIds } });
       }
     }
-    else if(allowPrivateVisibilityOnly !== undefined && !allowPrivateVisibilityOnly.booleanValue){
+    else if (allowPrivateVisibilityOnly !== undefined && !allowPrivateVisibilityOnly.booleanValue) {
       query = {
         archived: false,
         //type: { $in: ['board','template-container'] },
@@ -197,9 +197,9 @@ BlazeComponent.extendComponent({
   },
   boardLists(boardId) {
     let boardLists = [];
-    const lists = Lists.find({'boardId' : boardId, 'archived': false})
+    const lists = Lists.find({ 'boardId': boardId, 'archived': false })
     lists.forEach(list => {
-      let cardCount = Cards.find({'boardId':boardId, 'listId':list._id}).count()
+      let cardCount = Cards.find({ 'boardId': boardId, 'listId': list._id }).count()
       boardLists.push(`${list.title}: ${cardCount}`);
     });
     return boardLists
@@ -207,7 +207,7 @@ BlazeComponent.extendComponent({
 
   boardMembers(boardId) {
     let boardMembers = [];
-    const lists = Boards.findOne({'_id' : boardId})
+    const lists = Boards.findOne({ '_id': boardId })
     let members = lists.members
     members.forEach(member => {
       boardMembers.push(member.userId);
@@ -291,10 +291,10 @@ BlazeComponent.extendComponent({
             }
           });
         },
-        'click #resetBtn'(event){
+        'click #resetBtn'(event) {
           let allBoards = document.getElementsByClassName("js-board");
           let currBoard;
-          for(let i=0; i < allBoards.length; i++){
+          for (let i = 0; i < allBoards.length; i++) {
             currBoard = allBoards[i];
             currBoard.style.display = "block";
           }
@@ -302,57 +302,55 @@ BlazeComponent.extendComponent({
         'click #filterBtn'(event) {
           event.preventDefault();
           let selectedTeams = document.querySelectorAll('#jsAllBoardTeams option:checked');
-          let selectedTeamsValues = Array.from(selectedTeams).map(function(elt){return elt.value});
+          let selectedTeamsValues = Array.from(selectedTeams).map(function (elt) { return elt.value });
           let index = selectedTeamsValues.indexOf("-1");
           if (index > -1) {
             selectedTeamsValues.splice(index, 1);
           }
 
           let selectedOrgs = document.querySelectorAll('#jsAllBoardOrgs option:checked');
-          let selectedOrgsValues = Array.from(selectedOrgs).map(function(elt){return elt.value});
+          let selectedOrgsValues = Array.from(selectedOrgs).map(function (elt) { return elt.value });
           index = selectedOrgsValues.indexOf("-1");
           if (index > -1) {
             selectedOrgsValues.splice(index, 1);
           }
 
-          if(selectedTeamsValues.length > 0 || selectedOrgsValues.length > 0){
+          if (selectedTeamsValues.length > 0 || selectedOrgsValues.length > 0) {
             const query = {
               $and: [
                 { archived: false },
                 { type: 'board' },
-                { $or:[] }
+                { $or: [] }
               ]
             };
-            if(selectedTeamsValues.length > 0)
-            {
-              query.$and[2].$or.push({'teams.teamId': {$in : selectedTeamsValues}});
+            if (selectedTeamsValues.length > 0) {
+              query.$and[2].$or.push({ 'teams.teamId': { $in: selectedTeamsValues } });
             }
-            if(selectedOrgsValues.length > 0)
-            {
-              query.$and[2].$or.push({'orgs.orgId': {$in : selectedOrgsValues}});
+            if (selectedOrgsValues.length > 0) {
+              query.$and[2].$or.push({ 'orgs.orgId': { $in: selectedOrgsValues } });
             }
 
             let filteredBoards = Boards.find(query, {}).fetch();
             let allBoards = document.getElementsByClassName("js-board");
             let currBoard;
-            if(filteredBoards.length > 0){
+            if (filteredBoards.length > 0) {
               let currBoardId;
               let found;
-              for(let i=0; i < allBoards.length; i++){
+              for (let i = 0; i < allBoards.length; i++) {
                 currBoard = allBoards[i];
                 currBoardId = currBoard.classList[0];
-                found = filteredBoards.find(function(board){
+                found = filteredBoards.find(function (board) {
                   return board._id == currBoardId;
                 });
 
-                if(found !== undefined)
+                if (found !== undefined)
                   currBoard.style.display = "block";
                 else
                   currBoard.style.display = "none";
               }
             }
-            else{
-              for(let i=0; i < allBoards.length; i++){
+            else {
+              for (let i = 0; i < allBoards.length; i++) {
                 currBoard = allBoards[i];
                 currBoard.style.display = "none";
               }

+ 38 - 40
client/components/cards/cardDetails.js

@@ -87,27 +87,27 @@ BlazeComponent.extendComponent({
     const cardPanelWidth = 600;
     const parentComponent = this.parentComponent();
 
-/*
-    // Incomplete fix about bug where opening card scrolls to wrong place
-    // https://github.com/wekan/wekan/issues/4572#issuecomment-1184149395
-    // TODO sometimes parentComponent is not available, maybe because it's not
-    // yet created?!
-    if (!parentComponent) return;
-    const bodyBoardComponent = parentComponent.parentComponent();
-*/
+    /*
+        // Incomplete fix about bug where opening card scrolls to wrong place
+        // https://github.com/wekan/wekan/issues/4572#issuecomment-1184149395
+        // TODO sometimes parentComponent is not available, maybe because it's not
+        // yet created?!
+        if (!parentComponent) return;
+        const bodyBoardComponent = parentComponent.parentComponent();
+    */
 
     //On Mobile View Parent is Board, Not Board Body. I cant see how this funciton should work then.
     if (bodyBoardComponent === null) return;
     const $cardView = this.$(this.firstNode());
     const $cardContainer = bodyBoardComponent.$('.js-swimlanes');
 
-/*
-    // Incomplete fix about bug where opening card scrolls to wrong place
-    // https://github.com/wekan/wekan/issues/4572#issuecomment-1184149395
-    // TODO sometimes cardContainer is not available, maybe because it's not yet
-    // created?!
-    if (!$cardContainer) return;
-*/
+    /*
+        // Incomplete fix about bug where opening card scrolls to wrong place
+        // https://github.com/wekan/wekan/issues/4572#issuecomment-1184149395
+        // TODO sometimes cardContainer is not available, maybe because it's not yet
+        // created?!
+        if (!$cardContainer) return;
+    */
 
     const cardContainerScroll = $cardContainer.scrollLeft();
     const cardContainerWidth = $cardContainer.width();
@@ -306,7 +306,7 @@ BlazeComponent.extendComponent({
         $checklistsDom.data('sortable')
       ) {
         $checklistsDom.sortable('option', 'disabled', disabled);
-        if (Utils.isMiniScreenOrShowDesktopDragHandles()) {
+        if (Utils.isTouchScreenOrShowDesktopDragHandles()) {
           $checklistsDom.sortable({ handle: '.checklist-handle' });
         }
       }
@@ -793,8 +793,8 @@ const filterMembers = (filterTerm) => {
         user: Users.findOne(member.userId)
       }))
       .filter(({ user }) =>
-      (user.profile.fullname !== undefined && user.profile.fullname.toLowerCase().indexOf(filterTerm.toLowerCase()) !== -1)
-      || user.profile.fullname === undefined && user.profile.username !== undefined && user.profile.username.toLowerCase().indexOf(filterTerm.toLowerCase()) !== -1)
+        (user.profile.fullname !== undefined && user.profile.fullname.toLowerCase().indexOf(filterTerm.toLowerCase()) !== -1)
+        || user.profile.fullname === undefined && user.profile.username !== undefined && user.profile.username.toLowerCase().indexOf(filterTerm.toLowerCase()) !== -1)
       .map(({ member }) => member);
   }
   return members;
@@ -866,9 +866,9 @@ BlazeComponent.extendComponent({
    */
   setMoveAndCopyDialogOption(boardId) {
     this.moveAndCopyDialogOption = {
-      'boardId' : "",
-      'swimlaneId' : "",
-      'listId' : "",
+      'boardId': "",
+      'swimlaneId': "",
+      'listId': "",
     }
 
     let currentOptions = Meteor.user().getMoveAndCopyDialogOptions();
@@ -945,9 +945,9 @@ BlazeComponent.extendComponent({
           const swimlaneId = swimlaneSelect.options[swimlaneSelect.selectedIndex].value;
 
           const options = {
-            'boardId' : boardId,
-            'swimlaneId' : swimlaneId,
-            'listId' : listId,
+            'boardId': boardId,
+            'swimlaneId': swimlaneId,
+            'listId': listId,
           }
           Meteor.user().setMoveAndCopyDialogOption(this.currentBoardId, options);
         },
@@ -1728,16 +1728,14 @@ EscapeActions.register(
   () => {
     // if card description diverges from database due to editing
     // ask user whether changes should be applied
-    if(currentUser.profile.rescueCardDescription== true)
-    {
+    if (currentUser.profile.rescueCardDescription == true) {
       currentDescription = document.getElementsByClassName("editor js-new-description-input").item(0)
-      if (currentDescription?.value && !(currentDescription.value === Utils.getCurrentCard().getDescription()))
-      {
+      if (currentDescription?.value && !(currentDescription.value === Utils.getCurrentCard().getDescription())) {
         if (confirm(TAPi18n.__('rescue-card-description-dialogue'))) {
           Utils.getCurrentCard().setDescription(document.getElementsByClassName("editor js-new-description-input").item(0).value);
           // Save it!
           console.log(document.getElementsByClassName("editor js-new-description-input").item(0).value);
-          console.log("current description",Utils.getCurrentCard().getDescription());
+          console.log("current description", Utils.getCurrentCard().getDescription());
         } else {
           // Do nothing!
           console.log('Description changes were not saved to the database.');
@@ -1824,17 +1822,17 @@ Template.cardAssigneePopup.helpers({
     return user && user.isBoardAdmin() ? 'admin' : 'normal';
   },
 
-/*
-  presenceStatusClassName() {
-    const user = Users.findOne(this.userId);
-    const userPresence = presences.findOne({ userId: this.userId });
-    if (user && user.isInvitedTo(Session.get('currentBoard'))) return 'pending';
-    else if (!userPresence) return 'disconnected';
-    else if (Session.equals('currentBoard', userPresence.state.currentBoardId))
-      return 'active';
-    else return 'idle';
-  },
-*/
+  /*
+    presenceStatusClassName() {
+      const user = Users.findOne(this.userId);
+      const userPresence = presences.findOne({ userId: this.userId });
+      if (user && user.isInvitedTo(Session.get('currentBoard'))) return 'pending';
+      else if (!userPresence) return 'disconnected';
+      else if (Session.equals('currentBoard', userPresence.state.currentBoardId))
+        return 'active';
+      else return 'idle';
+    },
+  */
   isCardAssignee() {
     const card = Template.parentData();
     const cardAssignees = card.getAssignees();

+ 2 - 2
client/components/cards/checklists.jade

@@ -35,7 +35,7 @@ template(name="checklistDetail")
 
         if canModifyCard
           h2.title.js-open-inlined-form.is-editable
-            if isMiniScreenOrShowDesktopDragHandles
+            if isTouchScreenOrShowDesktopDragHandles
               span.fa.checklist-handle(class="fa-arrows" title="{{_ 'dragChecklist'}}")
             +viewer
               = checklist.title
@@ -104,7 +104,7 @@ template(name='checklistItemDetail')
     if canModifyCard
       .check-box-container
         .check-box.materialCheckBox(class="{{#if item.isFinished }}is-checked{{/if}}")
-      if isMiniScreenOrShowDesktopDragHandles
+      if isTouchScreenOrShowDesktopDragHandles
         span.fa.checklistitem-handle(class="fa-arrows" title="{{_ 'dragChecklistItem'}}")
       .item-title.js-open-inlined-form.is-editable(class="{{#if item.isFinished }}is-checked{{/if}}")
         +viewer

+ 18 - 19
client/components/cards/checklists.js

@@ -48,7 +48,7 @@ BlazeComponent.extendComponent({
     const self = this;
     self.itemsDom = this.$('.js-checklist-items');
     initSorting(self.itemsDom);
-    self.itemsDom.mousedown(function(evt) {
+    self.itemsDom.mousedown(function (evt) {
       evt.stopPropagation();
     });
 
@@ -61,7 +61,7 @@ BlazeComponent.extendComponent({
       const $itemsDom = $(self.itemsDom);
       if ($itemsDom.data('uiSortable') || $itemsDom.data('sortable')) {
         $(self.itemsDom).sortable('option', 'disabled', !userIsMember());
-        if (Utils.isMiniScreenOrShowDesktopDragHandles()) {
+        if (Utils.isTouchScreenOrShowDesktopDragHandles()) {
           $(self.itemsDom).sortable({
             handle: 'span.fa.checklistitem-handle',
           });
@@ -306,15 +306,15 @@ BlazeComponent.extendComponent({
   events() {
     return [
       {
-        'click .js-delete-checklist' : Popup.afterConfirm('checklistDelete', function () {
+        'click .js-delete-checklist': Popup.afterConfirm('checklistDelete', function () {
           Popup.back(2);
           const checklist = this.checklist;
           if (checklist && checklist._id) {
             Checklists.remove(checklist._id);
           }
         }),
-        'click .js-move-checklist' : Popup.open('moveChecklist'),
-        'click .js-copy-checklist' : Popup.open('copyChecklist'),
+        'click .js-move-checklist': Popup.open('moveChecklist'),
+        'click .js-copy-checklist': Popup.open('copyChecklist'),
       }
     ]
   }
@@ -407,9 +407,9 @@ class DialogWithBoardSwimlaneListAndCard extends BlazeComponent {
    */
   setChecklistDialogOption(boardId) {
     this.checklistDialogOption = {
-      'boardId' : "",
-      'swimlaneId' : "",
-      'listId' : "",
+      'boardId': "",
+      'swimlaneId': "",
+      'listId': "",
       'cardId': "",
     }
 
@@ -417,20 +417,19 @@ class DialogWithBoardSwimlaneListAndCard extends BlazeComponent {
     if (currentOptions && boardId && currentOptions[boardId]) {
       this.checklistDialogOption = currentOptions[boardId];
       if (this.checklistDialogOption.boardId &&
-          this.checklistDialogOption.swimlaneId &&
-          this.checklistDialogOption.listId
-      )
-      {
+        this.checklistDialogOption.swimlaneId &&
+        this.checklistDialogOption.listId
+      ) {
         this.selectedBoardId.set(this.checklistDialogOption.boardId)
         this.selectedSwimlaneId.set(this.checklistDialogOption.swimlaneId);
         this.selectedListId.set(this.checklistDialogOption.listId);
       }
     }
     this.getBoardData(this.selectedBoardId.get());
-    if (!this.selectedSwimlaneId.get() || !Swimlanes.findOne({_id: this.selectedSwimlaneId.get(), boardId: this.selectedBoardId.get()})) {
+    if (!this.selectedSwimlaneId.get() || !Swimlanes.findOne({ _id: this.selectedSwimlaneId.get(), boardId: this.selectedBoardId.get() })) {
       this.setFirstSwimlaneId();
     }
-    if (!this.selectedListId.get() || !Lists.findOne({_id: this.selectedListId.get(), boardId: this.selectedBoardId.get()})) {
+    if (!this.selectedListId.get() || !Lists.findOne({ _id: this.selectedListId.get(), boardId: this.selectedBoardId.get() })) {
       this.setFirstListId();
     }
   }
@@ -440,7 +439,7 @@ class DialogWithBoardSwimlaneListAndCard extends BlazeComponent {
       const board = Boards.findOne(this.selectedBoardId.get());
       const swimlaneId = board.swimlanes().fetch()[0]._id;
       this.selectedSwimlaneId.set(swimlaneId);
-    } catch (e) {}
+    } catch (e) { }
   }
   /** sets the first list id */
   setFirstListId() {
@@ -448,7 +447,7 @@ class DialogWithBoardSwimlaneListAndCard extends BlazeComponent {
       const board = Boards.findOne(this.selectedBoardId.get());
       const listId = board.lists().fetch()[0]._id;
       this.selectedListId.set(listId);
-    } catch (e) {}
+    } catch (e) { }
   }
 
   /** returns if the board id was the last confirmed one
@@ -561,9 +560,9 @@ class DialogWithBoardSwimlaneListAndCard extends BlazeComponent {
           const cardId = cardSelect.options[cardSelect.selectedIndex].value;
 
           const options = {
-            'boardId' : boardId,
-            'swimlaneId' : swimlaneId,
-            'listId' : listId,
+            'boardId': boardId,
+            'swimlaneId': swimlaneId,
+            'listId': listId,
             'cardId': cardId,
           }
           this.setDone(cardId, options);

+ 1 - 1
client/components/cards/labels.jade

@@ -29,7 +29,7 @@ template(name="cardLabelsPopup")
     each board.labels
       li.js-card-label-item
         a.card-label-edit-button.fa.fa-pencil.js-edit-label
-        if isMiniScreenOrShowDesktopDragHandles
+        if isTouchScreenOrShowDesktopDragHandles
           span.fa.label-handle(class="fa-arrows" title="{{_ 'dragLabel'}}")
         span.card-label.card-label-selectable.js-select-label.card-label-wrapper(class="card-label-{{color}}"
           class="{{# if isLabelSelected ../_id }}active{{/if}}")

+ 3 - 4
client/components/cards/labels.js

@@ -50,8 +50,7 @@ BlazeComponent.extendComponent({
       appendTo: '.edit-labels-pop-over',
       helper(element, currentItem) {
         let ret = currentItem.clone();
-        if (currentItem.closest('.popup-container-depth-0').size() == 0)
-        { // only set css transform at every sub-popup, not at the main popup
+        if (currentItem.closest('.popup-container-depth-0').size() == 0) { // only set css transform at every sub-popup, not at the main popup
           const content = currentItem.closest('.content')[0]
           const offsetLeft = content.offsetLeft;
           const offsetTop = $('.pop-over > .header').height() * -1;
@@ -76,7 +75,7 @@ BlazeComponent.extendComponent({
 
     // Disable drag-dropping if the current user is not a board member or is comment only
     this.autorun(() => {
-      if (Utils.isMiniScreenOrShowDesktopDragHandles()) {
+      if (Utils.isTouchScreenOrShowDesktopDragHandles()) {
         $labels.sortable({
           handle: '.label-handle',
         });
@@ -130,7 +129,7 @@ Template.createLabelPopup.events({
 });
 
 Template.editLabelPopup.events({
-  'click .js-delete-label': Popup.afterConfirm('deleteLabel', function() {
+  'click .js-delete-label': Popup.afterConfirm('deleteLabel', function () {
     const board = Boards.findOne(Session.get('currentBoard'));
     board.removeLabel(this._id);
     Popup.back(2);

+ 1 - 1
client/components/cards/minicard.jade

@@ -3,7 +3,7 @@ template(name="minicard")
     class="{{#if isLinkedCard}}linked-card{{/if}}"
     class="{{#if isLinkedBoard}}linked-board{{/if}}"
     class="{{#if colorClass}}minicard-{{colorClass}}{{/if}}")
-    if isMiniScreenOrShowDesktopDragHandles
+    if isTouchScreenOrShowDesktopDragHandles
       .handle
         .fa.fa-arrows
     if cover

+ 8 - 12
client/components/lists/list.js

@@ -96,7 +96,7 @@ BlazeComponent.extendComponent({
         $cards.sortable('cancel');
 
         if (MultiSelection.isActive()) {
-          Cards.find(MultiSelection.getMongoSelector(), {sort: ['sort']}).forEach((card, i) => {
+          Cards.find(MultiSelection.getMongoSelector(), { sort: ['sort'] }).forEach((card, i) => {
             const newSwimlaneId = targetSwimlaneId
               ? targetSwimlaneId
               : card.swimlaneId || defaultSwimlaneId;
@@ -119,35 +119,31 @@ BlazeComponent.extendComponent({
       },
       sort(event, ui) {
         const $boardCanvas = $('.board-canvas');
-        const  boardCanvas = $boardCanvas[0];
+        const boardCanvas = $boardCanvas[0];
 
-        if (event.pageX < 10)
-        { // scroll to the left
+        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
+        ) { // scroll to the right
           boardCanvas.scrollLeft += 15;
         }
         if (
           event.pageY > boardCanvas.offsetHeight - 10 &&
           event.pageY + boardCanvas.scrollTop < $boardCanvas.data('scrollTopMax') // don't scroll more than possible
-        )
-        { // scroll to the bottom
+        ) { // scroll to the bottom
           boardCanvas.scrollTop += 15;
         }
-        if (event.pageY < 10)
-        { // scroll to the top
+        if (event.pageY < 10) { // scroll to the top
           boardCanvas.scrollTop -= 15;
         }
       },
       activate(event, ui) {
         const $boardCanvas = $('.board-canvas');
-        const  boardCanvas = $boardCanvas[0];
+        const boardCanvas = $boardCanvas[0];
         // scrollTopMax and scrollLeftMax only available at Firefox (https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollTopMax)
         // https://www.it-swarm.com.de/de/javascript/so-erhalten-sie-den-maximalen-dokument-scrolltop-wert/1069126844/
         $boardCanvas.data('scrollTopMax', boardCanvas.scrollHeight - boardCanvas.clientTop);
@@ -157,7 +153,7 @@ BlazeComponent.extendComponent({
     });
 
     this.autorun(() => {
-      if (Utils.isMiniScreenOrShowDesktopDragHandles()) {
+      if (Utils.isTouchScreenOrShowDesktopDragHandles()) {
         $cards.sortable({
           handle: '.handle',
         });

+ 1 - 1
client/components/lists/listHeader.jade

@@ -44,7 +44,7 @@ template(name="listHeader")
               a.js-add-card.fa.fa-plus.list-header-plus-top(title="{{_ 'add-card-to-top-of-list'}}")
             a.fa.fa-navicon.js-open-list-menu(title="{{_ 'listActionPopup-title'}}")
           if currentUser.isBoardAdmin
-            if isShowDesktopDragHandles
+            if isTouchScreenOrShowDesktopDragHandles
               a.list-header-handle.handle.fa.fa-arrows.js-list-handle
 
 template(name="editListTitleForm")

+ 2 - 2
client/components/swimlanes/swimlaneHeader.jade

@@ -25,10 +25,10 @@ template(name="swimlaneFixedHeader")
       if currentUser.isBoardAdmin
         a.fa.fa-plus.js-open-add-swimlane-menu.swimlane-header-plus-icon(title="{{_ 'add-swimlane'}}")
         a.fa.fa-navicon.js-open-swimlane-menu(title="{{_ 'swimlaneActionPopup-title'}}")
-      unless isMiniScreen
+      unless isTouchScreen
         if isShowDesktopDragHandles
           a.swimlane-header-handle.handle.fa.fa-arrows.js-swimlane-header-handle
-      if isMiniScreen
+      if isTouchScreen
         a.swimlane-header-miniscreen-handle.handle.fa.fa-arrows.js-swimlane-header-handle
 
 template(name="editSwimlaneTitleForm")

+ 10 - 10
client/components/swimlanes/swimlanes.js

@@ -85,14 +85,14 @@ function initSortable(boardComponent, $listsDom) {
       const listDomElement = ui.item.get(0);
       const list = Blaze.getData(listDomElement);
 
-/*
-      Reverted incomplete change list width,
-      removed from below Lists.update:
-       https://github.com/wekan/wekan/issues/4558
-          $set: {
-            width: list._id.width(),
-            height: list._id.height(),
-*/
+      /*
+            Reverted incomplete change list width,
+            removed from below Lists.update:
+             https://github.com/wekan/wekan/issues/4558
+                $set: {
+                  width: list._id.width(),
+                  height: list._id.height(),
+      */
 
       Lists.update(list._id, {
         $set: {
@@ -114,7 +114,7 @@ function initSortable(boardComponent, $listsDom) {
   //}
 
   boardComponent.autorun(() => {
-    if (Utils.isMiniScreenOrShowDesktopDragHandles()) {
+    if (Utils.isTouchScreenOrShowDesktopDragHandles()) {
       $listsDom.sortable({
         handle: '.js-list-handle',
       });
@@ -200,7 +200,7 @@ BlazeComponent.extendComponent({
           // his mouse.
 
           const noDragInside = ['a', 'input', 'textarea', 'p'].concat(
-            Utils.isMiniScreenOrShowDesktopDragHandles()
+            Utils.isTouchScreenOrShowDesktopDragHandles()
               ? ['.js-list-handle', '.js-swimlane-header-handle']
               : ['.js-list-header'],
           );

+ 4 - 2
client/config/blazeHelpers.js

@@ -27,12 +27,14 @@ Blaze.registerHelper('concat', (...args) => args.slice(0, -1).join(''));
 
 Blaze.registerHelper('isMiniScreen', () => Utils.isMiniScreen());
 
+Blaze.registerHelper('isTouchScreen', () => Utils.isTouchScreen());
+
 Blaze.registerHelper('isShowDesktopDragHandles', () =>
   Utils.isShowDesktopDragHandles(),
 );
 
-Blaze.registerHelper('isMiniScreenOrShowDesktopDragHandles', () =>
-  Utils.isMiniScreenOrShowDesktopDragHandles(),
+Blaze.registerHelper('isTouchScreenOrShowDesktopDragHandles', () =>
+  Utils.isTouchScreenOrShowDesktopDragHandles(),
 );
 
 Blaze.registerHelper('moment', (...args) => {

+ 39 - 39
client/lib/tests/Utils.tests.js

@@ -5,20 +5,20 @@ import { Random } from 'meteor/random';
 import '../utils';
 
 
-describe('Utils', function() {
-  beforeEach(function() {
-    sinon.stub(Utils, 'reload').callsFake(() => {});
+describe('Utils', function () {
+  beforeEach(function () {
+    sinon.stub(Utils, 'reload').callsFake(() => { });
   });
 
-  afterEach(function() {
+  afterEach(function () {
     window.localStorage.removeItem(boardView);
     sinon.restore();
   });
 
   const boardView = 'boardView';
 
-  describe(Utils.setBoardView.name, function() {
-    it('sets the board view if the user exists', function(done) {
+  describe(Utils.setBoardView.name, function () {
+    it('sets the board view if the user exists', function (done) {
       const viewId = Random.id();
       const user = {
         setBoardView: (view) => {
@@ -32,14 +32,14 @@ describe('Utils', function() {
       expect(window.localStorage.getItem(boardView)).to.equal(viewId);
     });
 
-    it('sets a specific view if no user exists but a view is defined', function() {
+    it('sets a specific view if no user exists but a view is defined', function () {
       const views = [
         'board-view-swimlanes',
         'board-view-lists',
         'board-view-cal'
       ];
 
-      sinon.stub(Meteor, 'user').callsFake(() => {});
+      sinon.stub(Meteor, 'user').callsFake(() => { });
 
       views.forEach(viewName => {
         Utils.setBoardView(viewName);
@@ -47,15 +47,15 @@ describe('Utils', function() {
       });
     });
 
-    it('sets a default view if no user and no view are given', function() {
-      sinon.stub(Meteor, 'user').callsFake(() => {});
+    it('sets a default view if no user and no view are given', function () {
+      sinon.stub(Meteor, 'user').callsFake(() => { });
       Utils.setBoardView();
       expect(window.localStorage.getItem(boardView)).to.equal('board-view-swimlanes');
     });
   });
 
-  describe(Utils.unsetBoardView.name, function() {
-    it('removes the boardview from localStoage', function() {
+  describe(Utils.unsetBoardView.name, function () {
+    it('removes the boardview from localStoage', function () {
       window.localStorage.setItem(boardView, Random.id());
       window.localStorage.setItem('collapseSwimlane', Random.id());
 
@@ -66,8 +66,8 @@ describe('Utils', function() {
     });
   });
 
-  describe(Utils.boardView.name, function() {
-    it('returns the user\'s board view if a user exists', function() {
+  describe(Utils.boardView.name, function () {
+    it('returns the user\'s board view if a user exists', function () {
       const viewId = Random.id();
       const user = {};
       sinon.stub(Meteor, 'user').callsFake(() => user);
@@ -78,108 +78,108 @@ describe('Utils', function() {
 
       expect(Utils.boardView()).to.equal(boardView);
     });
-    it('returns the current defined view', function() {
+    it('returns the current defined view', function () {
       const views = [
         'board-view-swimlanes',
         'board-view-lists',
         'board-view-cal'
       ];
 
-      sinon.stub(Meteor, 'user').callsFake(() => {});
+      sinon.stub(Meteor, 'user').callsFake(() => { });
 
       views.forEach(viewName => {
         window.localStorage.setItem(boardView, viewName);
         expect(Utils.boardView()).to.equal(viewName);
       });
     });
-    it('returns a default if nothing is set', function() {
-      sinon.stub(Meteor, 'user').callsFake(() => {});
+    it('returns a default if nothing is set', function () {
+      sinon.stub(Meteor, 'user').callsFake(() => { });
       expect(Utils.boardView()).to.equal('board-view-swimlanes');
       expect(window.localStorage.getItem(boardView)).to.equal('board-view-swimlanes');
     });
   });
 
-  describe(Utils.myCardsSort.name, function() {
+  describe(Utils.myCardsSort.name, function () {
     it('has no tests yet');
   });
 
-  describe(Utils.myCardsSortToggle.name, function() {
+  describe(Utils.myCardsSortToggle.name, function () {
     it('has no tests yet');
   });
 
-  describe(Utils.setMyCardsSort.name, function() {
+  describe(Utils.setMyCardsSort.name, function () {
     it('has no tests yet');
   });
 
-  describe(Utils.archivedBoardIds.name, function() {
+  describe(Utils.archivedBoardIds.name, function () {
     it('has no tests yet');
   });
 
-  describe(Utils.dueCardsView.name, function() {
+  describe(Utils.dueCardsView.name, function () {
     it('has no tests yet');
   });
 
-  describe(Utils.setDueCardsView.name, function() {
+  describe(Utils.setDueCardsView.name, function () {
     it('has no tests yet');
   });
 
-  describe(Utils.goBoardId.name, function() {
+  describe(Utils.goBoardId.name, function () {
     it('has no tests yet');
   });
 
-  describe(Utils.goCardId.name, function() {
+  describe(Utils.goCardId.name, function () {
     it('has no tests yet');
   });
 
-  describe(Utils.processUploadedAttachment.name, function() {
+  describe(Utils.processUploadedAttachment.name, function () {
     it('has no tests yet');
   });
 
-  describe(Utils.shrinkImage.name, function() {
+  describe(Utils.shrinkImage.name, function () {
     it('has no tests yet');
   });
 
-  describe(Utils.capitalize.name, function() {
+  describe(Utils.capitalize.name, function () {
     it('has no tests yet');
   });
 
-  describe(Utils.isMiniScreen.name, function() {
+  describe(Utils.isMiniScreen.name, function () {
     it('has no tests yet');
   });
 
-  describe(Utils.isShowDesktopDragHandles.name, function() {
+  describe(Utils.isShowDesktopDragHandles.name, function () {
     it('has no tests yet');
   });
 
-  describe(Utils.isMiniScreenOrShowDesktopDragHandles.name, function() {
+  describe(Utils.isTouchScreenOrShowDesktopDragHandles.name, function () {
     it('has no tests yet');
   });
 
-  describe(Utils.calculateIndexData.name, function() {
+  describe(Utils.calculateIndexData.name, function () {
     it('has no tests yet');
   });
 
-  describe(Utils.calculateIndex.name, function() {
+  describe(Utils.calculateIndex.name, function () {
     it('has no tests yet');
   });
 
-  describe(Utils.manageCustomUI.name, function() {
+  describe(Utils.manageCustomUI.name, function () {
     it('has no tests yet');
   });
 
-  describe(Utils.setCustomUI.name, function() {
+  describe(Utils.setCustomUI.name, function () {
     it('has no tests yet');
   });
 
-  describe(Utils.setMatomo.name, function() {
+  describe(Utils.setMatomo.name, function () {
     it('has no tests yet');
   });
 
-  describe(Utils.manageMatomo.name, function() {
+  describe(Utils.manageMatomo.name, function () {
     it('has no tests yet');
   });
 
-  describe(Utils.getTriggerActionDesc.name, function() {
+  describe(Utils.getTriggerActionDesc.name, function () {
     it('has no tests yet');
   });
 });

+ 28 - 29
client/lib/utils.js

@@ -40,7 +40,7 @@ Utils = {
     const ret = Cards.findOne(cardId);
     return ret;
   },
-  reload () {
+  reload() {
     // we move all window.location.reload calls into this function
     // so we can disable it when running tests.
     // This is because we are not allowed to override location.reload but
@@ -201,14 +201,14 @@ Utils = {
       image = document.createElement('img');
     const maxSize = options.maxSize || 1024;
     const ratio = options.ratio || 1.0;
-    const next = function(result) {
+    const next = function (result) {
       image = null;
       canvas = null;
       if (typeof callback === 'function') {
         callback(result);
       }
     };
-    image.onload = function() {
+    image.onload = function () {
       let width = this.width,
         height = this.height;
       let changed = false;
@@ -237,7 +237,7 @@ Utils = {
         next(changed);
       }
     };
-    image.onerror = function() {
+    image.onerror = function () {
       next(false);
     };
     image.src = dataurl;
@@ -256,35 +256,34 @@ Utils = {
     // OLD WINDOW WIDTH DETECTION:
     this.windowResizeDep.depend();
     return $(window).width() <= 800;
+  },
+
+  isTouchScreen() {
 
     // 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;
+      hasTouchScreen = navigator.maxTouchPoints > 0;
     } else if ("msMaxTouchPoints" in navigator) {
-        hasTouchScreen = navigator.msMaxTouchPoints > 0;
+      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)
-            );
-        }
+      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;
+    return hasTouchScreen;
   },
 
   // returns if desktop drag handles are enabled
@@ -300,8 +299,8 @@ Utils = {
   },
 
   // returns if mini screen or desktop drag handles
-  isMiniScreenOrShowDesktopDragHandles() {
-    return this.isMiniScreen() || this.isShowDesktopDragHandles();
+  isTouchScreenOrShowDesktopDragHandles() {
+    return this.isTouchScreen() || this.isShowDesktopDragHandles();
   },
 
   calculateIndexData(prevData, nextData, nItems = 1) {
@@ -396,7 +395,7 @@ Utils = {
     window._paq.push(['trackPageView']);
     window._paq.push(['enableLinkTracking']);
 
-    (function() {
+    (function () {
       window._paq.push(['setTrackerUrl', `${data.address}piwik.php`]);
       window._paq.push(['setSiteId', data.siteId]);
 
@@ -500,8 +499,8 @@ Utils = {
   copyTextToClipboard(text) {
     let ret;
     if (navigator.clipboard) {
-      ret = navigator.clipboard.writeText(text).then(function() {
-      }, function(err) {
+      ret = navigator.clipboard.writeText(text).then(function () {
+      }, function (err) {
         console.error('Async: Could not copy text: ', err);
       });
     } else {