shortcut.js 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. import { onUnmounted, onMounted } from 'vue';
  2. import Mousetrap from 'mousetrap';
  3. import { isObject } from '@/utils/helper';
  4. export const mapShortcuts = {
  5. 'page:dashboard': {
  6. id: 'page:dashboard',
  7. combo: 'option+1',
  8. },
  9. 'page:workflows': {
  10. id: 'page:workflows',
  11. combo: 'option+2',
  12. },
  13. 'page:collections': {
  14. id: 'page:collections',
  15. combo: 'option+3',
  16. },
  17. 'page:logs': {
  18. id: 'page:logs',
  19. combo: 'option+4',
  20. },
  21. 'page:settings': {
  22. id: 'page:settings',
  23. combo: 'option+5',
  24. },
  25. 'action:search': {
  26. id: 'action:search',
  27. combo: 'mod+shift+f',
  28. },
  29. 'action:new': {
  30. id: 'action:new',
  31. combo: 'mod+option+n',
  32. },
  33. 'editor:duplicate-block': {
  34. id: 'editor:duplicate-block',
  35. combo: 'mod+option+d',
  36. },
  37. 'editor:save': {
  38. id: 'editor:save',
  39. combo: 'mod+shift+s',
  40. },
  41. 'editor:execute-workflow': {
  42. id: 'editor:execute-workflow',
  43. combo: 'option+enter',
  44. },
  45. };
  46. const os = navigator.appVersion.indexOf('Win') !== -1 ? 'win' : 'mac';
  47. export function getReadableShortcut(str) {
  48. const list = {
  49. option: {
  50. win: 'alt',
  51. mac: 'option',
  52. },
  53. mod: {
  54. win: 'ctrl',
  55. mac: '⌘',
  56. },
  57. };
  58. const regex = new RegExp(Object.keys(list).join('|'), 'g');
  59. const replacedStr = str.replace(regex, (match) => {
  60. return list[match][os];
  61. });
  62. return replacedStr;
  63. }
  64. export function getShortcut(id, data) {
  65. const shortcut = mapShortcuts[id] || {};
  66. if (data) shortcut.data = data;
  67. if (!shortcut.readable) {
  68. shortcut.readable = getReadableShortcut(shortcut.combo);
  69. }
  70. return shortcut;
  71. }
  72. export function useShortcut(shortcuts, handler) {
  73. Mousetrap.prototype.stopCallback = () => false;
  74. const extractedShortcuts = {
  75. ids: {},
  76. keys: [],
  77. data: {},
  78. };
  79. const handleShortcut = (event, combo) => {
  80. const shortcutId = extractedShortcuts.ids[combo];
  81. const params = {
  82. event,
  83. ...extractedShortcuts.data[shortcutId],
  84. };
  85. if (typeof params.data === 'function') {
  86. params.data(params);
  87. } else {
  88. handler?.(params);
  89. }
  90. };
  91. const addShortcutData = ({ combo, id, readable, ...rest }) => {
  92. extractedShortcuts.ids[combo] = id;
  93. extractedShortcuts.keys.push(combo);
  94. extractedShortcuts.data[id] = { combo, id, readable, ...rest };
  95. };
  96. if (isObject(shortcuts)) {
  97. addShortcutData(getShortcut(shortcuts.id, shortcuts.data));
  98. } else if (typeof shortcuts === 'string') {
  99. addShortcutData(getShortcut(shortcuts));
  100. } else {
  101. shortcuts.forEach((item) => {
  102. const currentShortcut =
  103. typeof item === 'string' ? getShortcut(item) : item;
  104. addShortcutData(currentShortcut);
  105. });
  106. }
  107. onMounted(() => {
  108. Mousetrap.bind(extractedShortcuts.keys, handleShortcut);
  109. });
  110. onUnmounted(() => {
  111. Mousetrap.unbind(extractedShortcuts.keys);
  112. });
  113. return extractedShortcuts.data;
  114. }