keyboard.js 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. // XXX There is no reason to define these shortcuts globally, they should be
  2. // attached to a template (most of them will go in the `board` template).
  3. function getHoveredCardId() {
  4. const card = $('.js-minicard:hover').get(0);
  5. if (!card) return null;
  6. return Blaze.getData(card)._id;
  7. }
  8. function getSelectedCardId() {
  9. return Session.get('selectedCard') || getHoveredCardId();
  10. }
  11. Mousetrap.bind('?', () => {
  12. FlowRouter.go('shortcuts');
  13. });
  14. Mousetrap.bind('w', () => {
  15. if (Sidebar.isOpen() && Sidebar.getView() === 'home') {
  16. Sidebar.toggle();
  17. } else {
  18. Sidebar.setView();
  19. }
  20. });
  21. Mousetrap.bind('q', () => {
  22. const currentBoardId = Session.get('currentBoard');
  23. const currentUserId = Meteor.userId();
  24. if (currentBoardId && currentUserId) {
  25. Filter.members.toggle(currentUserId);
  26. }
  27. });
  28. Mousetrap.bind('x', () => {
  29. if (Filter.isActive()) {
  30. Filter.reset();
  31. }
  32. });
  33. Mousetrap.bind('f', () => {
  34. if (Sidebar.isOpen() && Sidebar.getView() === 'filter') {
  35. Sidebar.toggle();
  36. } else {
  37. Sidebar.setView('filter');
  38. }
  39. });
  40. Mousetrap.bind(['down', 'up'], (evt, key) => {
  41. if (!Session.get('currentCard')) {
  42. return;
  43. }
  44. const nextFunc = key === 'down' ? 'next' : 'prev';
  45. const nextCard = $('.js-minicard.is-selected')
  46. [nextFunc]('.js-minicard')
  47. .get(0);
  48. if (nextCard) {
  49. const nextCardId = Blaze.getData(nextCard)._id;
  50. Utils.goCardId(nextCardId);
  51. }
  52. });
  53. Mousetrap.bind('space', evt => {
  54. const cardId = getSelectedCardId();
  55. if (!cardId) {
  56. return;
  57. }
  58. const currentUserId = Meteor.userId();
  59. if (currentUserId === null) {
  60. return;
  61. }
  62. if (Meteor.user().isBoardMember()) {
  63. const card = Cards.findOne(cardId);
  64. card.toggleMember(currentUserId);
  65. // We should prevent scrolling in card when spacebar is clicked
  66. // This should do it according to Mousetrap docs, but it doesn't
  67. evt.preventDefault();
  68. }
  69. });
  70. Mousetrap.bind('c', evt => {
  71. const cardId = getSelectedCardId();
  72. if (!cardId) {
  73. return;
  74. }
  75. const currentUserId = Meteor.userId();
  76. if (currentUserId === null) {
  77. return;
  78. }
  79. if (
  80. Meteor.user().isBoardMember() &&
  81. !Meteor.user().isCommentOnly() &&
  82. !Meteor.user().isWorker()
  83. ) {
  84. const card = Cards.findOne(cardId);
  85. card.archive();
  86. // We should prevent scrolling in card when spacebar is clicked
  87. // This should do it according to Mousetrap docs, but it doesn't
  88. evt.preventDefault();
  89. }
  90. });
  91. Template.keyboardShortcuts.helpers({
  92. mapping: [
  93. {
  94. keys: ['w'],
  95. action: 'shortcut-toggle-sidebar',
  96. },
  97. {
  98. keys: ['q'],
  99. action: 'shortcut-filter-my-cards',
  100. },
  101. {
  102. keys: ['f'],
  103. action: 'shortcut-toggle-filterbar',
  104. },
  105. {
  106. keys: ['x'],
  107. action: 'shortcut-clear-filters',
  108. },
  109. {
  110. keys: ['?'],
  111. action: 'shortcut-show-shortcuts',
  112. },
  113. {
  114. keys: ['ESC'],
  115. action: 'shortcut-close-dialog',
  116. },
  117. {
  118. keys: ['@'],
  119. action: 'shortcut-autocomplete-members',
  120. },
  121. {
  122. keys: ['SPACE'],
  123. action: 'shortcut-assign-self',
  124. },
  125. {
  126. keys: ['c'],
  127. action: 'archive-card',
  128. },
  129. ],
  130. });