aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/Menu.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/Menu.js')
-rw-r--r--src/lib/Menu.js177
1 files changed, 96 insertions, 81 deletions
diff --git a/src/lib/Menu.js b/src/lib/Menu.js
index f2669a106..91e7c981a 100644
--- a/src/lib/Menu.js
+++ b/src/lib/Menu.js
@@ -1,15 +1,15 @@
1import { remote, shell, clipboard } from 'electron'; 1import { clipboard, remote, shell } from 'electron';
2import { observable, autorun } from 'mobx'; 2import { autorun, observable } from 'mobx';
3import { defineMessages } from 'react-intl'; 3import { defineMessages } from 'react-intl';
4 4import { cmdKey, ctrlKey, isMac } from '../environment';
5import { isMac, ctrlKey, cmdKey } from '../environment';
6import { workspaceStore } from '../features/workspaces/index';
7import { workspaceActions } from '../features/workspaces/actions';
8import { announcementActions } from '../features/announcements/actions';
9import { announcementsStore } from '../features/announcements'; 5import { announcementsStore } from '../features/announcements';
6import { announcementActions } from '../features/announcements/actions';
10import { todosStore } from '../features/todos'; 7import { todosStore } from '../features/todos';
11import { todoActions } from '../features/todos/actions'; 8import { todoActions } from '../features/todos/actions';
12import { CUSTOM_WEBSITE_ID } from '../features/webControls/constants'; 9import { CUSTOM_WEBSITE_ID } from '../features/webControls/constants';
10import { workspaceActions } from '../features/workspaces/actions';
11import { workspaceStore } from '../features/workspaces/index';
12
13 13
14const { app, Menu, dialog } = remote; 14const { app, Menu, dialog } = remote;
15 15
@@ -300,7 +300,7 @@ function termsBase() {
300 return window.ferdi.stores.settings.all.app.server !== 'https://api.franzinfra.com' ? window.ferdi.stores.settings.all.app.server : 'https://meetfranz.com'; 300 return window.ferdi.stores.settings.all.app.server !== 'https://api.franzinfra.com' ? window.ferdi.stores.settings.all.app.server : 'https://meetfranz.com';
301} 301}
302 302
303const _templateFactory = intl => [ 303const _templateFactory = (intl, locked) => [
304 { 304 {
305 label: intl.formatMessage(menuItems.edit), 305 label: intl.formatMessage(menuItems.edit),
306 submenu: [ 306 submenu: [
@@ -351,6 +351,7 @@ const _templateFactory = intl => [
351 }, 351 },
352 { 352 {
353 label: intl.formatMessage(menuItems.view), 353 label: intl.formatMessage(menuItems.view),
354 visible: !locked,
354 submenu: [ 355 submenu: [
355 { 356 {
356 type: 'separator', 357 type: 'separator',
@@ -426,17 +427,18 @@ const _templateFactory = intl => [
426 }, 427 },
427 { 428 {
428 label: intl.formatMessage(menuItems.services), 429 label: intl.formatMessage(menuItems.services),
430 visible: !locked,
429 submenu: [], 431 submenu: [],
430 }, 432 },
431 { 433 {
432 label: intl.formatMessage(menuItems.workspaces), 434 label: intl.formatMessage(menuItems.workspaces),
433 submenu: [], 435 submenu: [],
434 visible: workspaceStore.isFeatureEnabled, 436 visible: !locked && workspaceStore.isFeatureEnabled,
435 }, 437 },
436 { 438 {
437 label: intl.formatMessage(menuItems.todos), 439 label: intl.formatMessage(menuItems.todos),
438 submenu: [], 440 submenu: [],
439 visible: todosStore.isFeatureEnabled, 441 visible: !locked && todosStore.isFeatureEnabled,
440 }, 442 },
441 { 443 {
442 label: intl.formatMessage(menuItems.window), 444 label: intl.formatMessage(menuItems.window),
@@ -465,7 +467,7 @@ const _templateFactory = intl => [
465 click: () => { 467 click: () => {
466 announcementActions.show(); 468 announcementActions.show();
467 }, 469 },
468 visible: window.ferdi.stores.user.isLoggedIn && announcementsStore.areNewsAvailable, 470 visible: !locked && window.ferdi.stores.user.isLoggedIn && announcementsStore.areNewsAvailable,
469 }, 471 },
470 { 472 {
471 type: 'separator', 473 type: 'separator',
@@ -489,7 +491,7 @@ const _templateFactory = intl => [
489 }, 491 },
490]; 492];
491 493
492const _titleBarTemplateFactory = intl => [ 494const _titleBarTemplateFactory = (intl, locked) => [
493 { 495 {
494 label: intl.formatMessage(menuItems.edit), 496 label: intl.formatMessage(menuItems.edit),
495 accelerator: 'Alt+E', 497 accelerator: 'Alt+E',
@@ -557,6 +559,7 @@ const _titleBarTemplateFactory = intl => [
557 { 559 {
558 label: intl.formatMessage(menuItems.view), 560 label: intl.formatMessage(menuItems.view),
559 accelerator: 'Alt+V', 561 accelerator: 'Alt+V',
562 visible: !locked,
560 submenu: [ 563 submenu: [
561 { 564 {
562 type: 'separator', 565 type: 'separator',
@@ -649,18 +652,19 @@ const _titleBarTemplateFactory = intl => [
649 { 652 {
650 label: intl.formatMessage(menuItems.services), 653 label: intl.formatMessage(menuItems.services),
651 accelerator: 'Alt+S', 654 accelerator: 'Alt+S',
655 visible: !locked,
652 submenu: [], 656 submenu: [],
653 }, 657 },
654 { 658 {
655 label: intl.formatMessage(menuItems.workspaces), 659 label: intl.formatMessage(menuItems.workspaces),
656 accelerator: 'Alt+W', 660 accelerator: 'Alt+W',
657 submenu: [], 661 submenu: [],
658 visible: workspaceStore.isFeatureEnabled, 662 visible: !locked && workspaceStore.isFeatureEnabled,
659 }, 663 },
660 { 664 {
661 label: intl.formatMessage(menuItems.todos), 665 label: intl.formatMessage(menuItems.todos),
662 submenu: [], 666 submenu: [],
663 visible: todosStore.isFeatureEnabled, 667 visible: !locked && todosStore.isFeatureEnabled,
664 }, 668 },
665 { 669 {
666 label: intl.formatMessage(menuItems.window), 670 label: intl.formatMessage(menuItems.window),
@@ -746,83 +750,90 @@ export default class FranzMenu {
746 } 750 }
747 751
748 const { intl } = window.ferdi; 752 const { intl } = window.ferdi;
749 const tpl = isMac ? _templateFactory(intl) : _titleBarTemplateFactory(intl); 753 const tpl = isMac
754 ? _templateFactory(intl, this.stores.settings.app.locked)
755 : _titleBarTemplateFactory(intl, this.stores.settings.app.locked);
750 const { actions } = this; 756 const { actions } = this;
751 757
752 tpl[1].submenu.push({ 758 if (this.stores.settings.app.locked) {
753 type: 'separator',
754 }, {
755 label: intl.formatMessage(menuItems.toggleDevTools),
756 accelerator: `${cmdKey}+Alt+I`,
757 click: (menuItem, browserWindow) => {
758 browserWindow.webContents.toggleDevTools();
759 },
760 }, {
761 label: intl.formatMessage(menuItems.toggleServiceDevTools),
762 accelerator: `${cmdKey}+Shift+Alt+I`,
763 click: () => {
764 this.actions.service.openDevToolsForActiveService();
765 },
766 enabled: this.stores.user.isLoggedIn && this.stores.services.enabled.length > 0,
767 });
768
769 if (this.stores.features.features.isTodosEnabled) {
770 tpl[1].submenu.push({ 759 tpl[1].submenu.push({
771 label: intl.formatMessage(menuItems.toggleTodosDevTools), 760 type: 'separator',
772 accelerator: `${cmdKey}+Shift+Alt+O`, 761 }, {
762 label: intl.formatMessage(menuItems.toggleDevTools),
763 accelerator: `${cmdKey}+Alt+I`,
764 click: (menuItem, browserWindow) => {
765 browserWindow.webContents.toggleDevTools();
766 },
767 }, {
768 label: intl.formatMessage(menuItems.toggleServiceDevTools),
769 accelerator: `${cmdKey}+Shift+Alt+I`,
773 click: () => { 770 click: () => {
774 const webview = document.querySelector('webview[partition="persist:todos"]'); 771 this.actions.service.openDevToolsForActiveService();
775 if (webview) webview.openDevTools();
776 }, 772 },
773 enabled: this.stores.user.isLoggedIn && this.stores.services.enabled.length > 0,
777 }); 774 });
778 }
779 775
780 tpl[1].submenu.unshift({ 776 if (this.stores.features.features.isTodosEnabled) {
781 label: intl.formatMessage(menuItems.reloadService), 777 tpl[1].submenu.push({
782 id: 'reloadService', // TODO: needed? 778 label: intl.formatMessage(menuItems.toggleTodosDevTools),
783 accelerator: `${cmdKey}+R`, 779 accelerator: `${cmdKey}+Shift+Alt+O`,
784 click: () => { 780 click: () => {
785 if (this.stores.user.isLoggedIn 781 const webview = document.querySelector('webview[partition="persist:todos"]');
786 && this.stores.services.enabled.length > 0) { 782 if (webview) webview.openDevTools();
787 if (this.stores.services.active.recipe.id === CUSTOM_WEBSITE_ID) { 783 },
788 this.stores.services.active.webview.reload(); 784 });
785 }
786
787 tpl[1].submenu.unshift({
788 label: intl.formatMessage(menuItems.reloadService),
789 id: 'reloadService', // TODO: needed?
790 accelerator: `${cmdKey}+R`,
791 click: () => {
792 if (this.stores.user.isLoggedIn
793 && this.stores.services.enabled.length > 0) {
794 if (this.stores.services.active.recipe.id === CUSTOM_WEBSITE_ID) {
795 this.stores.services.active.webview.reload();
796 } else {
797 this.actions.service.reloadActive();
798 }
789 } else { 799 } else {
790 this.actions.service.reloadActive(); 800 window.location.reload();
791 } 801 }
792 } else { 802 },
803 }, {
804 label: intl.formatMessage(menuItems.reloadFranz),
805 accelerator: `${cmdKey}+Shift+R`,
806 click: () => {
793 window.location.reload(); 807 window.location.reload();
794 } 808 },
795 }, 809 }, {
796 }, { 810 type: 'separator',
797 label: intl.formatMessage(menuItems.reloadFranz), 811 }, {
798 accelerator: `${cmdKey}+Shift+R`, 812 label: intl.formatMessage(menuItems.lockFerdi),
799 click: () => { 813 accelerator: 'CmdOrCtrl+Shift+L',
800 window.location.reload(); 814 enabled: this.stores.user.isLoggedIn && this.stores.settings.app.lockingFeatureEnabled,
801 }, 815 click() {
802 }, {
803 type: 'separator',
804 }, {
805 label: intl.formatMessage(menuItems.lockFerdi),
806 accelerator: 'CmdOrCtrl+Shift+L',
807 enabled: this.stores.user.isLoggedIn && this.stores.settings.app.lockingFeatureEnabled,
808 click() {
809 // Disable lock first - otherwise the application might not update correctly
810 actions.settings.update({
811 type: 'app',
812 data: {
813 locked: false,
814 },
815 });
816 setTimeout(() => {
817 actions.settings.update({ 816 actions.settings.update({
818 type: 'app', 817 type: 'app',
819 data: { 818 data: {
820 locked: true, 819 locked: true,
821 }, 820 },
822 }); 821 });
823 }, 0); 822 }
824 }, 823 });
825 }); 824
825 if (serviceTpl.length > 0) {
826 tpl[3].submenu = serviceTpl;
827 }
828
829 if (workspaceStore.isFeatureEnabled) {
830 tpl[4].submenu = this.workspacesMenu();
831 }
832
833 if (todosStore.isFeatureEnabled) {
834 tpl[5].submenu = this.todosMenu();
835 }
836 }
826 837
827 tpl.unshift({ 838 tpl.unshift({
828 label: isMac ? app.name : intl.formatMessage(menuItems.file), 839 label: isMac ? app.name : intl.formatMessage(menuItems.file),
@@ -842,15 +853,18 @@ export default class FranzMenu {
842 this.actions.ui.openSettings({ path: 'app' }); 853 this.actions.ui.openSettings({ path: 'app' });
843 }, 854 },
844 enabled: this.stores.user.isLoggedIn, 855 enabled: this.stores.user.isLoggedIn,
856 visible: !this.stores.settings.app.locked,
845 }, 857 },
846 { 858 {
847 label: intl.formatMessage(menuItems.checkForUpdates), 859 label: intl.formatMessage(menuItems.checkForUpdates),
860 visible: !this.stores.settings.app.locked,
848 click: () => { 861 click: () => {
849 this.actions.app.checkForUpdates(); 862 this.actions.app.checkForUpdates();
850 }, 863 },
851 }, 864 },
852 { 865 {
853 type: 'separator', 866 type: 'separator',
867 visible: !this.stores.settings.app.locked,
854 }, 868 },
855 { 869 {
856 label: intl.formatMessage(menuItems.services), 870 label: intl.formatMessage(menuItems.services),
@@ -930,6 +944,7 @@ export default class FranzMenu {
930 this.actions.ui.openSettings({ path: 'app' }); 944 this.actions.ui.openSettings({ path: 'app' });
931 }, 945 },
932 enabled: this.stores.user.isLoggedIn, 946 enabled: this.stores.user.isLoggedIn,
947 visible: !this.stores.settings.locked,
933 }, 948 },
934 { 949 {
935 type: 'separator', 950 type: 'separator',
@@ -961,14 +976,14 @@ export default class FranzMenu {
961 tpl[5].submenu = this.todosMenu(); 976 tpl[5].submenu = this.todosMenu();
962 } 977 }
963 978
964 tpl[tpl.length - 1].submenu.push({ 979 if (!this.stores.settings.app.locked) {
965 type: 'separator', 980 tpl[tpl.length - 1].submenu.push({
966 }, ...this.debugMenu()); 981 type: 'separator',
967 982 }, ...this.debugMenu());
983 }
968 this.currentTemplate = tpl; 984 this.currentTemplate = tpl;
969 const menu = Menu.buildFromTemplate(tpl); 985 const menu = Menu.buildFromTemplate(tpl);
970 const lockedMenu = Menu.buildFromTemplate([]); 986 Menu.setApplicationMenu(menu);
971 Menu.setApplicationMenu(this.stores.user.isLoggedIn && this.stores.settings.app.locked ? lockedMenu : menu);
972 } 987 }
973 988
974 serviceTpl() { 989 serviceTpl() {