diff options
Diffstat (limited to 'src/lib/Menu.js')
-rw-r--r-- | src/lib/Menu.js | 441 |
1 files changed, 102 insertions, 339 deletions
diff --git a/src/lib/Menu.js b/src/lib/Menu.js index c60536f0c..e4056e536 100644 --- a/src/lib/Menu.js +++ b/src/lib/Menu.js | |||
@@ -6,7 +6,7 @@ import { autorun, observable } from 'mobx'; | |||
6 | import { defineMessages } from 'react-intl'; | 6 | import { defineMessages } from 'react-intl'; |
7 | import { CUSTOM_WEBSITE_RECIPE_ID, GITHUB_FERDI_URL, LIVE_API_FERDI_WEBSITE } from '../config'; | 7 | import { CUSTOM_WEBSITE_RECIPE_ID, GITHUB_FERDI_URL, LIVE_API_FERDI_WEBSITE } from '../config'; |
8 | import { | 8 | import { |
9 | cmdKey, ctrlKey, isLinux, isMac, aboutAppDetails, termsBase, | 9 | shortcutKey, altKey, shiftKey, settingsShortcutKey, isLinux, isMac, aboutAppDetails, lockFerdiShortcutKey, todosToggleShortcutKey, workspaceToggleShortcutKey, addNewServiceShortcutKey, muteFerdiShortcutKey, |
10 | } from '../environment'; | 10 | } from '../environment'; |
11 | import { announcementsStore } from '../features/announcements'; | 11 | import { announcementsStore } from '../features/announcements'; |
12 | import { announcementActions } from '../features/announcements/actions'; | 12 | import { announcementActions } from '../features/announcements/actions'; |
@@ -14,6 +14,7 @@ import { todosStore } from '../features/todos'; | |||
14 | import { todoActions } from '../features/todos/actions'; | 14 | import { todoActions } from '../features/todos/actions'; |
15 | import { workspaceActions } from '../features/workspaces/actions'; | 15 | import { workspaceActions } from '../features/workspaces/actions'; |
16 | import { workspaceStore } from '../features/workspaces/index'; | 16 | import { workspaceStore } from '../features/workspaces/index'; |
17 | import apiBase, { termsBase } from '../api/apiBase'; | ||
17 | 18 | ||
18 | const menuItems = defineMessages({ | 19 | const menuItems = defineMessages({ |
19 | edit: { | 20 | edit: { |
@@ -100,14 +101,6 @@ const menuItems = defineMessages({ | |||
100 | id: 'menu.view.zoomOut', | 101 | id: 'menu.view.zoomOut', |
101 | defaultMessage: '!!!Zoom Out', | 102 | defaultMessage: '!!!Zoom Out', |
102 | }, | 103 | }, |
103 | enterFullScreen: { | ||
104 | id: 'menu.view.enterFullScreen', | ||
105 | defaultMessage: '!!!Enter Full Screen', | ||
106 | }, | ||
107 | exitFullScreen: { | ||
108 | id: 'menu.view.exitFullScreen', | ||
109 | defaultMessage: '!!!Exit Full Screen', | ||
110 | }, | ||
111 | toggleFullScreen: { | 104 | toggleFullScreen: { |
112 | id: 'menu.view.toggleFullScreen', | 105 | id: 'menu.view.toggleFullScreen', |
113 | defaultMessage: '!!!Toggle Full Screen', | 106 | defaultMessage: '!!!Toggle Full Screen', |
@@ -132,8 +125,8 @@ const menuItems = defineMessages({ | |||
132 | id: 'menu.view.reloadService', | 125 | id: 'menu.view.reloadService', |
133 | defaultMessage: '!!!Reload Service', | 126 | defaultMessage: '!!!Reload Service', |
134 | }, | 127 | }, |
135 | reloadFranz: { | 128 | reloadFerdi: { |
136 | id: 'menu.view.reloadFranz', | 129 | id: 'menu.view.reloadFerdi', |
137 | defaultMessage: '!!!Reload Ferdi', | 130 | defaultMessage: '!!!Reload Ferdi', |
138 | }, | 131 | }, |
139 | lockFerdi: { | 132 | lockFerdi: { |
@@ -160,6 +153,10 @@ const menuItems = defineMessages({ | |||
160 | id: 'menu.help.changelog', | 153 | id: 'menu.help.changelog', |
161 | defaultMessage: '!!!Changelog', | 154 | defaultMessage: '!!!Changelog', |
162 | }, | 155 | }, |
156 | importExportData: { | ||
157 | id: 'menu.help.importExportData', | ||
158 | defaultMessage: '!!!Import/Export Configuration Data', | ||
159 | }, | ||
163 | support: { | 160 | support: { |
164 | id: 'menu.help.support', | 161 | id: 'menu.help.support', |
165 | defaultMessage: '!!!Support', | 162 | defaultMessage: '!!!Support', |
@@ -318,9 +315,10 @@ function getActiveWebview() { | |||
318 | return window.ferdi.stores.services.active.webview; | 315 | return window.ferdi.stores.services.active.webview; |
319 | } | 316 | } |
320 | 317 | ||
321 | const _templateFactory = (intl, locked) => [ | 318 | const _titleBarTemplateFactory = (intl, locked) => [ |
322 | { | 319 | { |
323 | label: intl.formatMessage(menuItems.edit), | 320 | label: intl.formatMessage(menuItems.edit), |
321 | accelerator: `${altKey}+E`, | ||
324 | submenu: [ | 322 | submenu: [ |
325 | { | 323 | { |
326 | label: intl.formatMessage(menuItems.undo), | 324 | label: intl.formatMessage(menuItems.undo), |
@@ -335,23 +333,23 @@ const _templateFactory = (intl, locked) => [ | |||
335 | }, | 333 | }, |
336 | { | 334 | { |
337 | label: intl.formatMessage(menuItems.cut), | 335 | label: intl.formatMessage(menuItems.cut), |
338 | accelerator: 'Cmd+X', | 336 | accelerator: `${shortcutKey()}+X`, |
339 | selector: 'cut:', | 337 | role: 'cut', |
340 | }, | 338 | }, |
341 | { | 339 | { |
342 | label: intl.formatMessage(menuItems.copy), | 340 | label: intl.formatMessage(menuItems.copy), |
343 | accelerator: 'Cmd+C', | 341 | accelerator: `${shortcutKey()}+C`, |
344 | selector: 'copy:', | 342 | role: 'copy', |
345 | }, | 343 | }, |
346 | { | 344 | { |
347 | label: intl.formatMessage(menuItems.paste), | 345 | label: intl.formatMessage(menuItems.paste), |
348 | accelerator: 'Cmd+V', | 346 | accelerator: `${shortcutKey()}+V`, |
349 | selector: 'paste:', | 347 | role: 'paste', |
350 | }, | 348 | }, |
351 | { | 349 | { |
352 | label: intl.formatMessage(menuItems.pasteAndMatchStyle), | 350 | label: intl.formatMessage(menuItems.pasteAndMatchStyle), |
353 | accelerator: 'Cmd+Shift+V', | 351 | accelerator: `${shortcutKey()}+${shiftKey}+V`, // Override the accelerator since this adds new key combo in macos |
354 | selector: 'pasteAndMatchStyle:', | 352 | role: 'pasteAndMatchStyle', |
355 | click() { | 353 | click() { |
356 | getActiveWebview().pasteAndMatchStyle(); | 354 | getActiveWebview().pasteAndMatchStyle(); |
357 | }, | 355 | }, |
@@ -362,13 +360,14 @@ const _templateFactory = (intl, locked) => [ | |||
362 | }, | 360 | }, |
363 | { | 361 | { |
364 | label: intl.formatMessage(menuItems.selectAll), | 362 | label: intl.formatMessage(menuItems.selectAll), |
365 | accelerator: 'Cmd+A', | 363 | accelerator: `${shortcutKey()}+A`, |
366 | selector: 'selectAll:', | 364 | role: 'selectall', |
367 | }, | 365 | }, |
368 | ], | 366 | ], |
369 | }, | 367 | }, |
370 | { | 368 | { |
371 | label: intl.formatMessage(menuItems.view), | 369 | label: intl.formatMessage(menuItems.view), |
370 | accelerator: `${altKey}+V`, | ||
372 | visible: !locked, | 371 | visible: !locked, |
373 | submenu: [ | 372 | submenu: [ |
374 | { | 373 | { |
@@ -376,7 +375,7 @@ const _templateFactory = (intl, locked) => [ | |||
376 | }, | 375 | }, |
377 | { | 376 | { |
378 | label: intl.formatMessage(menuItems.openQuickSwitch), | 377 | label: intl.formatMessage(menuItems.openQuickSwitch), |
379 | accelerator: 'CmdOrCtrl+S', | 378 | accelerator: `${shortcutKey()}+S`, |
380 | click() { | 379 | click() { |
381 | window.ferdi.features.quickSwitch.state.isModalVisible = true; | 380 | window.ferdi.features.quickSwitch.state.isModalVisible = true; |
382 | }, | 381 | }, |
@@ -386,7 +385,7 @@ const _templateFactory = (intl, locked) => [ | |||
386 | }, | 385 | }, |
387 | { | 386 | { |
388 | label: intl.formatMessage(menuItems.findInPage), | 387 | label: intl.formatMessage(menuItems.findInPage), |
389 | accelerator: 'CmdOrCtrl+F', | 388 | accelerator: `${shortcutKey()}+F`, |
390 | click() { | 389 | click() { |
391 | // Check if there is a service active | 390 | // Check if there is a service active |
392 | if (!window.ferdi.stores.services.active) return; | 391 | if (!window.ferdi.stores.services.active) return; |
@@ -407,18 +406,16 @@ const _templateFactory = (intl, locked) => [ | |||
407 | }, | 406 | }, |
408 | { | 407 | { |
409 | label: intl.formatMessage(menuItems.back), | 408 | label: intl.formatMessage(menuItems.back), |
410 | accelerator: 'CmdOrCtrl+Left', | 409 | accelerator: `${shortcutKey()}+Left`, |
411 | click() { | 410 | click() { |
412 | const activeService = getActiveWebview(); | 411 | getActiveWebview().goBack(); |
413 | activeService.goBack(); | ||
414 | }, | 412 | }, |
415 | }, | 413 | }, |
416 | { | 414 | { |
417 | label: intl.formatMessage(menuItems.forward), | 415 | label: intl.formatMessage(menuItems.forward), |
418 | accelerator: 'CmdOrCtrl+Right', | 416 | accelerator: `${shortcutKey()}+Right`, |
419 | click() { | 417 | click() { |
420 | const activeService = getActiveWebview(); | 418 | getActiveWebview().goForward(); |
421 | activeService.goForward(); | ||
422 | }, | 419 | }, |
423 | }, | 420 | }, |
424 | { | 421 | { |
@@ -426,14 +423,16 @@ const _templateFactory = (intl, locked) => [ | |||
426 | }, | 423 | }, |
427 | { | 424 | { |
428 | label: intl.formatMessage(menuItems.resetZoom), | 425 | label: intl.formatMessage(menuItems.resetZoom), |
429 | accelerator: 'Cmd+0', | 426 | accelerator: `${shortcutKey()}+0`, |
427 | role: 'resetZoom', | ||
430 | click() { | 428 | click() { |
431 | getActiveWebview().setZoomLevel(0); | 429 | getActiveWebview().setZoomLevel(0); |
432 | }, | 430 | }, |
433 | }, | 431 | }, |
434 | { | 432 | { |
435 | label: intl.formatMessage(menuItems.zoomIn), | 433 | label: intl.formatMessage(menuItems.zoomIn), |
436 | accelerator: 'Cmd+plus', | 434 | accelerator: `${shortcutKey()}+plus`, |
435 | role: 'zoomIn', | ||
437 | click() { | 436 | click() { |
438 | const activeService = getActiveWebview(); | 437 | const activeService = getActiveWebview(); |
439 | const level = activeService.getZoomLevel(); | 438 | const level = activeService.getZoomLevel(); |
@@ -444,7 +443,8 @@ const _templateFactory = (intl, locked) => [ | |||
444 | }, | 443 | }, |
445 | { | 444 | { |
446 | label: intl.formatMessage(menuItems.zoomOut), | 445 | label: intl.formatMessage(menuItems.zoomOut), |
447 | accelerator: 'Cmd+-', | 446 | accelerator: `${shortcutKey()}+-`, |
447 | role: 'zoomOut', | ||
448 | click() { | 448 | click() { |
449 | const activeService = getActiveWebview(); | 449 | const activeService = getActiveWebview(); |
450 | const level = activeService.getZoomLevel(); | 450 | const level = activeService.getZoomLevel(); |
@@ -457,15 +457,13 @@ const _templateFactory = (intl, locked) => [ | |||
457 | type: 'separator', | 457 | type: 'separator', |
458 | }, | 458 | }, |
459 | { | 459 | { |
460 | label: app.mainWindow.isFullScreen() // label doesn't work, gets overridden by Electron | 460 | label: intl.formatMessage(menuItems.toggleFullScreen), |
461 | ? intl.formatMessage(menuItems.exitFullScreen) | 461 | role: 'toggleFullScreen', |
462 | : intl.formatMessage(menuItems.enterFullScreen), | ||
463 | role: 'togglefullscreen', | ||
464 | }, | 462 | }, |
465 | { | 463 | { |
466 | label: intl.formatMessage(menuItems.toggleDarkMode), | 464 | label: intl.formatMessage(menuItems.toggleDarkMode), |
467 | type: 'checkbox', | 465 | type: 'checkbox', |
468 | accelerator: `${cmdKey}+Shift+D`, | 466 | accelerator: `${shortcutKey()}+${shiftKey}+D`, |
469 | checked: window.ferdi.stores.settings.app.darkMode, | 467 | checked: window.ferdi.stores.settings.app.darkMode, |
470 | click: () => { | 468 | click: () => { |
471 | window.ferdi.actions.settings.update({ | 469 | window.ferdi.actions.settings.update({ |
@@ -480,11 +478,13 @@ const _templateFactory = (intl, locked) => [ | |||
480 | }, | 478 | }, |
481 | { | 479 | { |
482 | label: intl.formatMessage(menuItems.services), | 480 | label: intl.formatMessage(menuItems.services), |
481 | accelerator: `${altKey}+S`, | ||
483 | visible: !locked, | 482 | visible: !locked, |
484 | submenu: [], | 483 | submenu: [], |
485 | }, | 484 | }, |
486 | { | 485 | { |
487 | label: intl.formatMessage(menuItems.workspaces), | 486 | label: intl.formatMessage(menuItems.workspaces), |
487 | accelerator: `${altKey}+W`, | ||
488 | submenu: [], | 488 | submenu: [], |
489 | visible: !locked && workspaceStore.isFeatureEnabled, | 489 | visible: !locked && workspaceStore.isFeatureEnabled, |
490 | }, | 490 | }, |
@@ -509,6 +509,7 @@ const _templateFactory = (intl, locked) => [ | |||
509 | }, | 509 | }, |
510 | { | 510 | { |
511 | label: intl.formatMessage(menuItems.help), | 511 | label: intl.formatMessage(menuItems.help), |
512 | accelerator: `${altKey}+H`, | ||
512 | role: 'help', | 513 | role: 'help', |
513 | submenu: [ | 514 | submenu: [ |
514 | { | 515 | { |
@@ -516,274 +517,23 @@ const _templateFactory = (intl, locked) => [ | |||
516 | click() { shell.openExternal(LIVE_API_FERDI_WEBSITE); }, | 517 | click() { shell.openExternal(LIVE_API_FERDI_WEBSITE); }, |
517 | }, | 518 | }, |
518 | { | 519 | { |
519 | label: intl.formatMessage(menuItems.announcement), | 520 | label: intl.formatMessage(menuItems.changelog), |
520 | click: () => { | 521 | click() { shell.openExternal(`${GITHUB_FERDI_URL}/ferdi/blob/master/CHANGELOG.md`); }, |
521 | announcementActions.show(); | ||
522 | }, | ||
523 | visible: !locked && window.ferdi.stores.user.isLoggedIn && announcementsStore.areNewsAvailable, | ||
524 | }, | ||
525 | { | ||
526 | type: 'separator', | ||
527 | }, | ||
528 | { | ||
529 | label: intl.formatMessage(menuItems.support), | ||
530 | click() { shell.openExternal(`${LIVE_API_FERDI_WEBSITE}/contact`); }, | ||
531 | }, | ||
532 | { | ||
533 | type: 'separator', | ||
534 | }, | ||
535 | { | ||
536 | label: intl.formatMessage(menuItems.tos), | ||
537 | click() { shell.openExternal(`${termsBase()}/terms`); }, | ||
538 | }, | ||
539 | { | ||
540 | label: intl.formatMessage(menuItems.privacy), | ||
541 | click() { shell.openExternal(`${termsBase()}/privacy`); }, | ||
542 | }, | ||
543 | ], | ||
544 | }, | ||
545 | ]; | ||
546 | |||
547 | const _titleBarTemplateFactory = (intl, locked) => [ | ||
548 | { | ||
549 | label: intl.formatMessage(menuItems.edit), | ||
550 | accelerator: 'Alt+E', | ||
551 | submenu: [ | ||
552 | { | ||
553 | label: intl.formatMessage(menuItems.undo), | ||
554 | accelerator: `${ctrlKey}+Z`, | ||
555 | click() { | ||
556 | getActiveWebview().undo(); | ||
557 | }, | ||
558 | }, | ||
559 | { | ||
560 | label: intl.formatMessage(menuItems.redo), | ||
561 | accelerator: `${ctrlKey}+Y`, | ||
562 | click() { | ||
563 | getActiveWebview().redo(); | ||
564 | }, | ||
565 | }, | ||
566 | { | ||
567 | type: 'separator', | ||
568 | }, | ||
569 | { | ||
570 | label: intl.formatMessage(menuItems.cut), | ||
571 | accelerator: `${ctrlKey}+X`, | ||
572 | click() { | ||
573 | getActiveWebview().cut(); | ||
574 | }, | ||
575 | }, | ||
576 | { | ||
577 | label: intl.formatMessage(menuItems.copy), | ||
578 | accelerator: `${ctrlKey}+C`, | ||
579 | click() { | ||
580 | getActiveWebview().copy(); | ||
581 | }, | ||
582 | }, | ||
583 | { | ||
584 | label: intl.formatMessage(menuItems.paste), | ||
585 | accelerator: `${ctrlKey}+V`, | ||
586 | click() { | ||
587 | getActiveWebview().paste(); | ||
588 | }, | ||
589 | }, | ||
590 | { | ||
591 | label: intl.formatMessage(menuItems.pasteAndMatchStyle), | ||
592 | accelerator: `${ctrlKey}+Shift+V`, | ||
593 | click() { | ||
594 | getActiveWebview().pasteAndMatchStyle(); | ||
595 | }, | ||
596 | }, | ||
597 | { | ||
598 | label: intl.formatMessage(menuItems.delete), | ||
599 | click() { | ||
600 | getActiveWebview().delete(); | ||
601 | }, | ||
602 | }, | ||
603 | { | ||
604 | label: intl.formatMessage(menuItems.selectAll), | ||
605 | accelerator: `${ctrlKey}+A`, | ||
606 | click() { | ||
607 | getActiveWebview().selectAll(); | ||
608 | }, | ||
609 | }, | ||
610 | ], | ||
611 | }, | ||
612 | { | ||
613 | label: intl.formatMessage(menuItems.view), | ||
614 | accelerator: 'Alt+V', | ||
615 | visible: !locked, | ||
616 | submenu: [ | ||
617 | { | ||
618 | type: 'separator', | ||
619 | }, | ||
620 | { | ||
621 | label: intl.formatMessage(menuItems.openQuickSwitch), | ||
622 | accelerator: 'CmdOrCtrl+S', | ||
623 | click() { | ||
624 | window.ferdi.features.quickSwitch.state.isModalVisible = true; | ||
625 | }, | ||
626 | }, | ||
627 | { | ||
628 | type: 'separator', | ||
629 | }, | ||
630 | { | ||
631 | label: intl.formatMessage(menuItems.findInPage), | ||
632 | accelerator: 'CmdOrCtrl+F', | ||
633 | click() { | ||
634 | // Check if there is a service active | ||
635 | if (!window.ferdi.stores.services.active) return; | ||
636 | |||
637 | // Focus webview so find in page popup gets focused | ||
638 | window.ferdi.stores.services.active.webview.focus(); | ||
639 | |||
640 | const currentService = window.ferdi.stores.services.active.id; | ||
641 | window.ferdi.actions.service.sendIPCMessage({ | ||
642 | serviceId: currentService, | ||
643 | channel: 'find-in-page', | ||
644 | args: {}, | ||
645 | }); | ||
646 | }, | ||
647 | }, | ||
648 | { | ||
649 | type: 'separator', | ||
650 | }, | ||
651 | { | ||
652 | label: intl.formatMessage(menuItems.back), | ||
653 | accelerator: 'CmdOrCtrl+Left', | ||
654 | click() { | ||
655 | const activeService = getActiveWebview(); | ||
656 | activeService.goBack(); | ||
657 | }, | ||
658 | }, | ||
659 | { | ||
660 | label: intl.formatMessage(menuItems.forward), | ||
661 | accelerator: 'CmdOrCtrl+Right', | ||
662 | click() { | ||
663 | const activeService = getActiveWebview(); | ||
664 | activeService.goForward(); | ||
665 | }, | ||
666 | }, | ||
667 | { | ||
668 | type: 'separator', | ||
669 | }, | ||
670 | { | ||
671 | label: intl.formatMessage(menuItems.resetZoom), | ||
672 | accelerator: `${ctrlKey}+0`, | ||
673 | click() { | ||
674 | getActiveWebview().setZoomLevel(0); | ||
675 | }, | ||
676 | }, | ||
677 | { | ||
678 | label: intl.formatMessage(menuItems.zoomIn), | ||
679 | accelerator: `${ctrlKey}+=`, | ||
680 | click() { | ||
681 | const activeService = getActiveWebview(); | ||
682 | const level = activeService.getZoomLevel(); | ||
683 | |||
684 | // level 9 =~ +300% and setZoomLevel wouldnt zoom in further | ||
685 | if (level < 9) activeService.setZoomLevel(level + 1); | ||
686 | }, | ||
687 | }, | 522 | }, |
688 | { | 523 | { |
689 | label: intl.formatMessage(menuItems.zoomOut), | 524 | label: intl.formatMessage(menuItems.importExportData), |
690 | accelerator: `${ctrlKey}+-`, | 525 | click() { shell.openExternal(apiBase(false)); }, |
691 | click() { | 526 | enabled: !locked, |
692 | const activeService = getActiveWebview(); | ||
693 | const level = activeService.getZoomLevel(); | ||
694 | |||
695 | // level -9 =~ -50% and setZoomLevel wouldnt zoom out further | ||
696 | if (level > -9) activeService.setZoomLevel(level - 1); | ||
697 | }, | ||
698 | }, | 527 | }, |
699 | { | 528 | { |
700 | type: 'separator', | 529 | type: 'separator', |
701 | }, | 530 | }, |
702 | { | 531 | { |
703 | label: app.mainWindow.isFullScreen() // label doesn't work, gets overridden by Electron | 532 | label: intl.formatMessage(menuItems.announcement), |
704 | ? intl.formatMessage(menuItems.exitFullScreen) | ||
705 | : intl.formatMessage(menuItems.enterFullScreen), | ||
706 | accelerator: 'F11', | ||
707 | click(menuItem, browserWindow) { | ||
708 | browserWindow.setFullScreen(!browserWindow.isFullScreen()); | ||
709 | }, | ||
710 | }, | ||
711 | { | ||
712 | label: intl.formatMessage(menuItems.toggleDarkMode), | ||
713 | type: 'checkbox', | ||
714 | accelerator: `${cmdKey}+Shift+D`, | ||
715 | checked: window.ferdi.stores.settings.app.darkMode, | ||
716 | click: () => { | ||
717 | window.ferdi.actions.settings.update({ | ||
718 | type: 'app', | ||
719 | data: { | ||
720 | darkMode: !window.ferdi.stores.settings.app.darkMode, | ||
721 | }, | ||
722 | }); | ||
723 | }, | ||
724 | }, | ||
725 | { | ||
726 | label: intl.formatMessage(menuItems.autohideMenuBar), | ||
727 | type: 'checkbox', | ||
728 | checked: window.ferdi.stores.settings.app.autohideMenuBar, | ||
729 | click: () => { | 533 | click: () => { |
730 | window.ferdi.actions.settings.update({ | 534 | announcementActions.show(); |
731 | type: 'app', | ||
732 | data: { | ||
733 | autohideMenuBar: !window.ferdi.stores.settings.app.autohideMenuBar, | ||
734 | }, | ||
735 | }); | ||
736 | }, | ||
737 | }, | ||
738 | ], | ||
739 | }, | ||
740 | { | ||
741 | label: intl.formatMessage(menuItems.services), | ||
742 | accelerator: 'Alt+S', | ||
743 | visible: !locked, | ||
744 | submenu: [], | ||
745 | }, | ||
746 | { | ||
747 | label: intl.formatMessage(menuItems.workspaces), | ||
748 | accelerator: 'Alt+W', | ||
749 | submenu: [], | ||
750 | visible: !locked && workspaceStore.isFeatureEnabled, | ||
751 | }, | ||
752 | { | ||
753 | label: intl.formatMessage(menuItems.todos), | ||
754 | submenu: [], | ||
755 | visible: !locked && todosStore.isFeatureEnabled, | ||
756 | }, | ||
757 | { | ||
758 | label: intl.formatMessage(menuItems.window), | ||
759 | submenu: [ | ||
760 | { | ||
761 | label: intl.formatMessage(menuItems.minimize), | ||
762 | accelerator: 'Ctrl+M', | ||
763 | click(menuItem, browserWindow) { | ||
764 | browserWindow.minimize(); | ||
765 | }, | 535 | }, |
766 | }, | 536 | enabled: !locked && window.ferdi.stores.user.isLoggedIn && announcementsStore.areNewsAvailable, |
767 | { | ||
768 | label: intl.formatMessage(menuItems.close), | ||
769 | accelerator: 'Ctrl+W', | ||
770 | click(menuItem, browserWindow) { | ||
771 | browserWindow.close(); | ||
772 | }, | ||
773 | }, | ||
774 | ], | ||
775 | }, | ||
776 | { | ||
777 | label: '?', | ||
778 | accelerator: 'Alt+?', | ||
779 | submenu: [ | ||
780 | { | ||
781 | label: intl.formatMessage(menuItems.learnMore), | ||
782 | click() { shell.openExternal(LIVE_API_FERDI_WEBSITE); }, | ||
783 | }, | ||
784 | { | ||
785 | label: intl.formatMessage(menuItems.changelog), | ||
786 | click() { shell.openExternal(`${GITHUB_FERDI_URL}/ferdi/blob/master/CHANGELOG.md`); }, | ||
787 | }, | 537 | }, |
788 | { | 538 | { |
789 | type: 'separator', | 539 | type: 'separator', |
@@ -831,30 +581,44 @@ export default class FranzMenu { | |||
831 | // need to clone object so we don't modify computed (cached) object | 581 | // need to clone object so we don't modify computed (cached) object |
832 | const serviceTpl = Object.assign([], this.serviceTpl()); | 582 | const serviceTpl = Object.assign([], this.serviceTpl()); |
833 | 583 | ||
834 | // Don't initialize when window.franz is undefined or when we are on a payment window route | 584 | // Don't initialize when window.ferdi is undefined |
835 | if (window.ferdi === undefined || this.stores.router.location.pathname.startsWith('/payment/')) { | 585 | if (window.ferdi === undefined) { |
836 | console.log('skipping menu init'); | 586 | console.log('skipping menu init'); |
837 | return; | 587 | return; |
838 | } | 588 | } |
839 | 589 | ||
840 | const { intl } = window.ferdi; | 590 | const { intl } = window.ferdi; |
841 | const tpl = isMac | 591 | const tpl = _titleBarTemplateFactory(intl, this.stores.settings.app.locked); |
842 | ? _templateFactory(intl, this.stores.settings.app.locked) | ||
843 | : _titleBarTemplateFactory(intl, this.stores.settings.app.locked); | ||
844 | const { actions } = this; | 592 | const { actions } = this; |
845 | 593 | ||
594 | if (!isMac) { | ||
595 | tpl[1].submenu.push({ | ||
596 | label: intl.formatMessage(menuItems.autohideMenuBar), | ||
597 | type: 'checkbox', | ||
598 | checked: window.ferdi.stores.settings.app.autohideMenuBar, | ||
599 | click: () => { | ||
600 | window.ferdi.actions.settings.update({ | ||
601 | type: 'app', | ||
602 | data: { | ||
603 | autohideMenuBar: !window.ferdi.stores.settings.app.autohideMenuBar, | ||
604 | }, | ||
605 | }); | ||
606 | }, | ||
607 | }); | ||
608 | } | ||
609 | |||
846 | if (!this.stores.settings.app.locked) { | 610 | if (!this.stores.settings.app.locked) { |
847 | tpl[1].submenu.push({ | 611 | tpl[1].submenu.push({ |
848 | type: 'separator', | 612 | type: 'separator', |
849 | }, { | 613 | }, { |
850 | label: intl.formatMessage(menuItems.toggleDevTools), | 614 | label: intl.formatMessage(menuItems.toggleDevTools), |
851 | accelerator: `${cmdKey}+Alt+I`, | 615 | accelerator: `${shortcutKey()}+${altKey}+I`, |
852 | click: (menuItem, browserWindow) => { | 616 | click: (menuItem, browserWindow) => { |
853 | browserWindow.webContents.toggleDevTools(); | 617 | browserWindow.webContents.toggleDevTools(); |
854 | }, | 618 | }, |
855 | }, { | 619 | }, { |
856 | label: intl.formatMessage(menuItems.toggleServiceDevTools), | 620 | label: intl.formatMessage(menuItems.toggleServiceDevTools), |
857 | accelerator: `${cmdKey}+Shift+Alt+I`, | 621 | accelerator: `${shortcutKey()}+${shiftKey}+${altKey}+I`, |
858 | click: () => { | 622 | click: () => { |
859 | this.actions.service.openDevToolsForActiveService(); | 623 | this.actions.service.openDevToolsForActiveService(); |
860 | }, | 624 | }, |
@@ -864,7 +628,7 @@ export default class FranzMenu { | |||
864 | if (this.stores.features.features.isTodosEnabled) { | 628 | if (this.stores.features.features.isTodosEnabled) { |
865 | tpl[1].submenu.push({ | 629 | tpl[1].submenu.push({ |
866 | label: intl.formatMessage(menuItems.toggleTodosDevTools), | 630 | label: intl.formatMessage(menuItems.toggleTodosDevTools), |
867 | accelerator: `${cmdKey}+Shift+Alt+O`, | 631 | accelerator: `${shortcutKey()}+${shiftKey}+${altKey}+O`, |
868 | click: () => { | 632 | click: () => { |
869 | const webview = document.querySelector('#todos-panel webview'); | 633 | const webview = document.querySelector('#todos-panel webview'); |
870 | if (webview) this.actions.todos.openDevTools(); | 634 | if (webview) this.actions.todos.openDevTools(); |
@@ -875,7 +639,7 @@ export default class FranzMenu { | |||
875 | tpl[1].submenu.unshift({ | 639 | tpl[1].submenu.unshift({ |
876 | label: intl.formatMessage(menuItems.reloadService), | 640 | label: intl.formatMessage(menuItems.reloadService), |
877 | id: 'reloadService', // TODO: needed? | 641 | id: 'reloadService', // TODO: needed? |
878 | accelerator: `${cmdKey}+R`, | 642 | accelerator: `${shortcutKey()}+R`, |
879 | click: () => { | 643 | click: () => { |
880 | if (this.stores.user.isLoggedIn | 644 | if (this.stores.user.isLoggedIn |
881 | && this.stores.services.enabled.length > 0) { | 645 | && this.stores.services.enabled.length > 0) { |
@@ -889,14 +653,14 @@ export default class FranzMenu { | |||
889 | } | 653 | } |
890 | }, | 654 | }, |
891 | }, { | 655 | }, { |
892 | label: intl.formatMessage(menuItems.reloadFranz), | 656 | label: intl.formatMessage(menuItems.reloadFerdi), |
893 | accelerator: `${cmdKey}+Shift+R`, | 657 | accelerator: `${shortcutKey()}+${shiftKey}+R`, |
894 | click: () => { | 658 | click: () => { |
895 | window.location.reload(); | 659 | window.location.reload(); |
896 | }, | 660 | }, |
897 | }, { | 661 | }, { |
898 | label: intl.formatMessage(menuItems.reloadTodos), | 662 | label: intl.formatMessage(menuItems.reloadTodos), |
899 | accelerator: `${cmdKey}+Shift+Alt+R`, | 663 | accelerator: `${shortcutKey()}+${shiftKey}+${altKey}+R`, |
900 | click: () => { | 664 | click: () => { |
901 | this.actions.todos.reload(); | 665 | this.actions.todos.reload(); |
902 | }, | 666 | }, |
@@ -904,7 +668,7 @@ export default class FranzMenu { | |||
904 | type: 'separator', | 668 | type: 'separator', |
905 | }, { | 669 | }, { |
906 | label: intl.formatMessage(menuItems.lockFerdi), | 670 | label: intl.formatMessage(menuItems.lockFerdi), |
907 | accelerator: 'CmdOrCtrl+Shift+L', | 671 | accelerator: `${lockFerdiShortcutKey()}`, |
908 | enabled: this.stores.user.isLoggedIn && this.stores.settings.app.lockingFeatureEnabled, | 672 | enabled: this.stores.user.isLoggedIn && this.stores.settings.app.lockingFeatureEnabled, |
909 | click() { | 673 | click() { |
910 | actions.settings.update({ | 674 | actions.settings.update({ |
@@ -932,7 +696,7 @@ export default class FranzMenu { | |||
932 | 696 | ||
933 | tpl[0].submenu.unshift({ | 697 | tpl[0].submenu.unshift({ |
934 | label: intl.formatMessage(menuItems.touchId), | 698 | label: intl.formatMessage(menuItems.touchId), |
935 | accelerator: 'CmdOrCtrl+Shift+L', | 699 | accelerator: `${lockFerdiShortcutKey()}`, |
936 | visible: touchIdEnabled, | 700 | visible: touchIdEnabled, |
937 | click() { | 701 | click() { |
938 | systemPreferences.promptTouchID(intl.formatMessage(menuItems.touchIdPrompt)).then(() => { | 702 | systemPreferences.promptTouchID(intl.formatMessage(menuItems.touchIdPrompt)).then(() => { |
@@ -952,7 +716,7 @@ export default class FranzMenu { | |||
952 | 716 | ||
953 | tpl.unshift({ | 717 | tpl.unshift({ |
954 | label: isMac ? app.name : intl.formatMessage(menuItems.file), | 718 | label: isMac ? app.name : intl.formatMessage(menuItems.file), |
955 | accelerator: 'Alt+F', | 719 | accelerator: `${altKey}+F`, |
956 | submenu: [ | 720 | submenu: [ |
957 | { | 721 | { |
958 | label: intl.formatMessage(menuItems.about), | 722 | label: intl.formatMessage(menuItems.about), |
@@ -963,7 +727,7 @@ export default class FranzMenu { | |||
963 | }, | 727 | }, |
964 | { | 728 | { |
965 | label: intl.formatMessage(menuItems.settings), | 729 | label: intl.formatMessage(menuItems.settings), |
966 | accelerator: 'CmdOrCtrl+,', | 730 | accelerator: `${settingsShortcutKey()}`, |
967 | click: () => { | 731 | click: () => { |
968 | this.actions.ui.openSettings({ path: 'app' }); | 732 | this.actions.ui.openSettings({ path: 'app' }); |
969 | }, | 733 | }, |
@@ -995,7 +759,7 @@ export default class FranzMenu { | |||
995 | }, | 759 | }, |
996 | { | 760 | { |
997 | label: intl.formatMessage(menuItems.hideOthers), | 761 | label: intl.formatMessage(menuItems.hideOthers), |
998 | role: 'hideothers', | 762 | role: 'hideOthers', |
999 | }, | 763 | }, |
1000 | { | 764 | { |
1001 | label: intl.formatMessage(menuItems.unhide), | 765 | label: intl.formatMessage(menuItems.unhide), |
@@ -1016,6 +780,7 @@ export default class FranzMenu { | |||
1016 | 780 | ||
1017 | const about = { | 781 | const about = { |
1018 | label: intl.formatMessage(menuItems.about), | 782 | label: intl.formatMessage(menuItems.about), |
783 | role: 'about', | ||
1019 | click: () => { | 784 | click: () => { |
1020 | dialog.showMessageBox({ | 785 | dialog.showMessageBox({ |
1021 | type: 'info', | 786 | type: 'info', |
@@ -1054,7 +819,7 @@ export default class FranzMenu { | |||
1054 | tpl[0].submenu = [ | 819 | tpl[0].submenu = [ |
1055 | { | 820 | { |
1056 | label: intl.formatMessage(menuItems.settings), | 821 | label: intl.formatMessage(menuItems.settings), |
1057 | accelerator: 'Ctrl+P', | 822 | accelerator: `${settingsShortcutKey()}`, |
1058 | click: () => { | 823 | click: () => { |
1059 | this.actions.ui.openSettings({ path: 'app' }); | 824 | this.actions.ui.openSettings({ path: 'app' }); |
1060 | }, | 825 | }, |
@@ -1067,7 +832,7 @@ export default class FranzMenu { | |||
1067 | { | 832 | { |
1068 | label: intl.formatMessage(menuItems.quit), | 833 | label: intl.formatMessage(menuItems.quit), |
1069 | role: 'quit', | 834 | role: 'quit', |
1070 | accelerator: 'Ctrl+Q', | 835 | accelerator: `${shortcutKey()}+Q`, |
1071 | click() { | 836 | click() { |
1072 | app.quit(); | 837 | app.quit(); |
1073 | }, | 838 | }, |
@@ -1110,7 +875,7 @@ export default class FranzMenu { | |||
1110 | 875 | ||
1111 | menu.push({ | 876 | menu.push({ |
1112 | label: intl.formatMessage(menuItems.addNewService), | 877 | label: intl.formatMessage(menuItems.addNewService), |
1113 | accelerator: `${cmdKey}+N`, | 878 | accelerator: `${addNewServiceShortcutKey()}`, |
1114 | click: () => { | 879 | click: () => { |
1115 | this.actions.ui.openSettings({ path: 'recipes' }); | 880 | this.actions.ui.openSettings({ path: 'recipes' }); |
1116 | }, | 881 | }, |
@@ -1118,29 +883,29 @@ export default class FranzMenu { | |||
1118 | type: 'separator', | 883 | type: 'separator', |
1119 | }, { | 884 | }, { |
1120 | label: intl.formatMessage(menuItems.activateNextService), | 885 | label: intl.formatMessage(menuItems.activateNextService), |
1121 | accelerator: `${cmdKey}+tab`, | 886 | accelerator: `${shortcutKey()}+tab`, |
1122 | click: () => this.actions.service.setActiveNext(), | 887 | click: () => this.actions.service.setActiveNext(), |
1123 | visible: !cmdAltShortcutsVisibile, | 888 | visible: !cmdAltShortcutsVisibile, |
1124 | }, { | 889 | }, { |
1125 | label: intl.formatMessage(menuItems.activateNextService), | 890 | label: intl.formatMessage(menuItems.activateNextService), |
1126 | accelerator: `${cmdKey}+alt+right`, | 891 | accelerator: `${shortcutKey()}+${altKey}+right`, |
1127 | click: () => this.actions.service.setActiveNext(), | 892 | click: () => this.actions.service.setActiveNext(), |
1128 | visible: cmdAltShortcutsVisibile, | 893 | visible: cmdAltShortcutsVisibile, |
1129 | }, { | 894 | }, { |
1130 | label: intl.formatMessage(menuItems.activatePreviousService), | 895 | label: intl.formatMessage(menuItems.activatePreviousService), |
1131 | accelerator: `${cmdKey}+shift+tab`, | 896 | accelerator: `${shortcutKey()}+${shiftKey}+tab`, |
1132 | click: () => this.actions.service.setActivePrev(), | 897 | click: () => this.actions.service.setActivePrev(), |
1133 | visible: !cmdAltShortcutsVisibile, | 898 | visible: !cmdAltShortcutsVisibile, |
1134 | }, { | 899 | }, { |
1135 | label: intl.formatMessage(menuItems.activatePreviousService), | 900 | label: intl.formatMessage(menuItems.activatePreviousService), |
1136 | accelerator: `${cmdKey}+alt+left`, | 901 | accelerator: `${shortcutKey()}+${altKey}+left`, |
1137 | click: () => this.actions.service.setActivePrev(), | 902 | click: () => this.actions.service.setActivePrev(), |
1138 | visible: cmdAltShortcutsVisibile, | 903 | visible: cmdAltShortcutsVisibile, |
1139 | }, { | 904 | }, { |
1140 | label: intl.formatMessage( | 905 | label: intl.formatMessage( |
1141 | settings.all.app.isAppMuted ? menuItems.unmuteApp : menuItems.muteApp, | 906 | settings.all.app.isAppMuted ? menuItems.unmuteApp : menuItems.muteApp, |
1142 | ).replace('&', '&&'), | 907 | ).replace('&', '&&'), |
1143 | accelerator: `${cmdKey}+shift+m`, | 908 | accelerator: `${muteFerdiShortcutKey()}`, |
1144 | click: () => this.actions.app.toggleMuteApp(), | 909 | click: () => this.actions.app.toggleMuteApp(), |
1145 | }, { | 910 | }, { |
1146 | type: 'separator', | 911 | type: 'separator', |
@@ -1148,7 +913,7 @@ export default class FranzMenu { | |||
1148 | 913 | ||
1149 | services.allDisplayed.forEach((service, i) => (menu.push({ | 914 | services.allDisplayed.forEach((service, i) => (menu.push({ |
1150 | label: this._getServiceName(service), | 915 | label: this._getServiceName(service), |
1151 | accelerator: i < 9 ? `${cmdKey}+${i + 1}` : null, | 916 | accelerator: i < 9 ? `${shortcutKey()}+${i + 1}` : null, |
1152 | type: 'radio', | 917 | type: 'radio', |
1153 | checked: service.isActive, | 918 | checked: service.isActive, |
1154 | click: () => { | 919 | click: () => { |
@@ -1165,7 +930,7 @@ export default class FranzMenu { | |||
1165 | type: 'separator', | 930 | type: 'separator', |
1166 | }, { | 931 | }, { |
1167 | label: intl.formatMessage(menuItems.serviceGoHome), | 932 | label: intl.formatMessage(menuItems.serviceGoHome), |
1168 | accelerator: `${cmdKey}+shift+H`, | 933 | accelerator: `${shortcutKey()}+${shiftKey}+H`, |
1169 | click: () => this.actions.service.reloadActive(), | 934 | click: () => this.actions.service.reloadActive(), |
1170 | }); | 935 | }); |
1171 | } | 936 | } |
@@ -1181,7 +946,7 @@ export default class FranzMenu { | |||
1181 | // Add new workspace item: | 946 | // Add new workspace item: |
1182 | menu.push({ | 947 | menu.push({ |
1183 | label: intl.formatMessage(menuItems.addNewWorkspace), | 948 | label: intl.formatMessage(menuItems.addNewWorkspace), |
1184 | accelerator: `${cmdKey}+Shift+N`, | 949 | accelerator: `${shortcutKey()}+${shiftKey}+N`, |
1185 | click: () => { | 950 | click: () => { |
1186 | workspaceActions.openWorkspaceSettings(); | 951 | workspaceActions.openWorkspaceSettings(); |
1187 | }, | 952 | }, |
@@ -1195,7 +960,7 @@ export default class FranzMenu { | |||
1195 | ); | 960 | ); |
1196 | menu.push({ | 961 | menu.push({ |
1197 | label: intl.formatMessage(drawerLabel), | 962 | label: intl.formatMessage(drawerLabel), |
1198 | accelerator: `${cmdKey}+D`, | 963 | accelerator: `${workspaceToggleShortcutKey()}`, |
1199 | click: () => { | 964 | click: () => { |
1200 | workspaceActions.toggleWorkspaceDrawer(); | 965 | workspaceActions.toggleWorkspaceDrawer(); |
1201 | }, | 966 | }, |
@@ -1210,7 +975,7 @@ export default class FranzMenu { | |||
1210 | // Default workspace | 975 | // Default workspace |
1211 | menu.push({ | 976 | menu.push({ |
1212 | label: intl.formatMessage(menuItems.defaultWorkspace), | 977 | label: intl.formatMessage(menuItems.defaultWorkspace), |
1213 | accelerator: `${cmdKey}+Alt+0`, | 978 | accelerator: `${shortcutKey()}+${altKey}+0`, |
1214 | type: 'radio', | 979 | type: 'radio', |
1215 | checked: !activeWorkspace, | 980 | checked: !activeWorkspace, |
1216 | click: () => { | 981 | click: () => { |
@@ -1219,17 +984,15 @@ export default class FranzMenu { | |||
1219 | }); | 984 | }); |
1220 | 985 | ||
1221 | // Workspace items | 986 | // Workspace items |
1222 | if (this.stores.user.isPremium) { | 987 | workspaces.forEach((workspace, i) => menu.push({ |
1223 | workspaces.forEach((workspace, i) => menu.push({ | 988 | label: workspace.name, |
1224 | label: workspace.name, | 989 | accelerator: i < 9 ? `${shortcutKey()}+${altKey}+${i + 1}` : null, |
1225 | accelerator: i < 9 ? `${cmdKey}+Alt+${i + 1}` : null, | 990 | type: 'radio', |
1226 | type: 'radio', | 991 | checked: activeWorkspace ? workspace.id === activeWorkspace.id : false, |
1227 | checked: activeWorkspace ? workspace.id === activeWorkspace.id : false, | 992 | click: () => { |
1228 | click: () => { | 993 | workspaceActions.activate({ workspace }); |
1229 | workspaceActions.activate({ workspace }); | 994 | }, |
1230 | }, | 995 | })); |
1231 | })); | ||
1232 | } | ||
1233 | 996 | ||
1234 | return menu; | 997 | return menu; |
1235 | } | 998 | } |
@@ -1243,7 +1006,7 @@ export default class FranzMenu { | |||
1243 | 1006 | ||
1244 | menu.push({ | 1007 | menu.push({ |
1245 | label: intl.formatMessage(drawerLabel), | 1008 | label: intl.formatMessage(drawerLabel), |
1246 | accelerator: `${cmdKey}+T`, | 1009 | accelerator: `${todosToggleShortcutKey()}`, |
1247 | click: () => { | 1010 | click: () => { |
1248 | todoActions.toggleTodosPanel(); | 1011 | todoActions.toggleTodosPanel(); |
1249 | }, | 1012 | }, |