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.js191
1 files changed, 152 insertions, 39 deletions
diff --git a/src/lib/Menu.js b/src/lib/Menu.js
index c0c9d940d..d7398a126 100644
--- a/src/lib/Menu.js
+++ b/src/lib/Menu.js
@@ -3,12 +3,11 @@ import { observable, autorun } from 'mobx';
3import { defineMessages } from 'react-intl'; 3import { defineMessages } from 'react-intl';
4 4
5import { isMac, ctrlKey, cmdKey } from '../environment'; 5import { isMac, ctrlKey, cmdKey } from '../environment';
6import { GA_CATEGORY_WORKSPACES, workspaceStore } from '../features/workspaces/index'; 6import { workspaceStore } from '../features/workspaces/index';
7import { workspaceActions } from '../features/workspaces/actions'; 7import { workspaceActions } from '../features/workspaces/actions';
8import { gaEvent } from './analytics';
9import { announcementActions } from '../features/announcements/actions'; 8import { announcementActions } from '../features/announcements/actions';
10import { announcementsStore } from '../features/announcements'; 9import { announcementsStore } from '../features/announcements';
11import { GA_CATEGORY_TODOS, todosStore } from '../features/todos'; 10import { todosStore } from '../features/todos';
12import { todoActions } from '../features/todos/actions'; 11import { todoActions } from '../features/todos/actions';
13import { CUSTOM_WEBSITE_ID } from '../features/webControls/constants'; 12import { CUSTOM_WEBSITE_ID } from '../features/webControls/constants';
14 13
@@ -71,6 +70,18 @@ const menuItems = defineMessages({
71 id: 'menu.edit.emojiSymbols', 70 id: 'menu.edit.emojiSymbols',
72 defaultMessage: '!!!Emoji & Symbols', 71 defaultMessage: '!!!Emoji & Symbols',
73 }, 72 },
73 openQuickSwitch: {
74 id: 'menu.view.openQuickSwitch',
75 defaultMessage: '!!!Open Quick Switch',
76 },
77 back: {
78 id: 'menu.view.back',
79 defaultMessage: '!!!Back',
80 },
81 forward: {
82 id: 'menu.view.forward',
83 defaultMessage: '!!!Forward',
84 },
74 resetZoom: { 85 resetZoom: {
75 id: 'menu.view.resetZoom', 86 id: 'menu.view.resetZoom',
76 defaultMessage: '!!!Actual Size', 87 defaultMessage: '!!!Actual Size',
@@ -113,7 +124,11 @@ const menuItems = defineMessages({
113 }, 124 },
114 reloadFranz: { 125 reloadFranz: {
115 id: 'menu.view.reloadFranz', 126 id: 'menu.view.reloadFranz',
116 defaultMessage: '!!!Reload Franz', 127 defaultMessage: '!!!Reload Ferdi',
128 },
129 lockFerdi: {
130 id: 'menu.view.lockFerdi',
131 defaultMessage: '!!!Lock Ferdi',
117 }, 132 },
118 minimize: { 133 minimize: {
119 id: 'menu.window.minimize', 134 id: 'menu.window.minimize',
@@ -141,7 +156,7 @@ const menuItems = defineMessages({
141 }, 156 },
142 debugInfoCopiedHeadline: { 157 debugInfoCopiedHeadline: {
143 id: 'menu.help.debugInfoCopiedHeadline', 158 id: 'menu.help.debugInfoCopiedHeadline',
144 defaultMessage: '!!!Franz Debug Information', 159 defaultMessage: '!!!Ferdi Debug Information',
145 }, 160 },
146 debugInfoCopiedBody: { 161 debugInfoCopiedBody: {
147 id: 'menu.help.debugInfoCopiedBody', 162 id: 'menu.help.debugInfoCopiedBody',
@@ -177,7 +192,7 @@ const menuItems = defineMessages({
177 }, 192 },
178 about: { 193 about: {
179 id: 'menu.app.about', 194 id: 'menu.app.about',
180 defaultMessage: '!!!About Franz', 195 defaultMessage: '!!!About Ferdi',
181 }, 196 },
182 announcement: { 197 announcement: {
183 id: 'menu.app.announcement', 198 id: 'menu.app.announcement',
@@ -203,6 +218,10 @@ const menuItems = defineMessages({
203 id: 'menu.app.unhide', 218 id: 'menu.app.unhide',
204 defaultMessage: '!!!Unhide', 219 defaultMessage: '!!!Unhide',
205 }, 220 },
221 autohideMenuBar: {
222 id: 'menu.app.autohideMenuBar',
223 defaultMessage: '!!!Auto-hide menu bar',
224 },
206 quit: { 225 quit: {
207 id: 'menu.app.quit', 226 id: 'menu.app.quit',
208 defaultMessage: '!!!Quit', 227 defaultMessage: '!!!Quit',
@@ -270,7 +289,11 @@ const menuItems = defineMessages({
270}); 289});
271 290
272function getActiveWebview() { 291function getActiveWebview() {
273 return window.franz.stores.services.active.webview; 292 return window.ferdi.stores.services.active.webview;
293}
294
295function termsBase() {
296 return window.ferdi.stores.settings.all.app.server !== 'https://api.franzinfra.com' ? window.ferdi.stores.settings.all.app.server : 'https://meetfranz.com';
274} 297}
275 298
276const _templateFactory = intl => [ 299const _templateFactory = intl => [
@@ -329,6 +352,35 @@ const _templateFactory = intl => [
329 type: 'separator', 352 type: 'separator',
330 }, 353 },
331 { 354 {
355 label: intl.formatMessage(menuItems.openQuickSwitch),
356 accelerator: 'CmdOrCtrl+S',
357 click() {
358 window.ferdi.features.quickSwitch.state.isModalVisible = true;
359 },
360 },
361 {
362 type: 'separator',
363 },
364 {
365 label: intl.formatMessage(menuItems.back),
366 accelerator: 'CmdOrCtrl+Left',
367 click() {
368 const activeService = getActiveWebview();
369 activeService.goBack();
370 },
371 },
372 {
373 label: intl.formatMessage(menuItems.forward),
374 accelerator: 'CmdOrCtrl+Right',
375 click() {
376 const activeService = getActiveWebview();
377 activeService.goForward();
378 },
379 },
380 {
381 type: 'separator',
382 },
383 {
332 label: intl.formatMessage(menuItems.resetZoom), 384 label: intl.formatMessage(menuItems.resetZoom),
333 accelerator: 'Cmd+0', 385 accelerator: 'Cmd+0',
334 click() { 386 click() {
@@ -402,32 +454,32 @@ const _templateFactory = intl => [
402 submenu: [ 454 submenu: [
403 { 455 {
404 label: intl.formatMessage(menuItems.learnMore), 456 label: intl.formatMessage(menuItems.learnMore),
405 click() { shell.openExternal('https://meetfranz.com'); }, 457 click() { shell.openExternal('https://getferdi.com'); },
406 }, 458 },
407 { 459 {
408 label: intl.formatMessage(menuItems.announcement), 460 label: intl.formatMessage(menuItems.announcement),
409 click: () => { 461 click: () => {
410 announcementActions.show(); 462 announcementActions.show();
411 }, 463 },
412 visible: window.franz.stores.user.isLoggedIn && announcementsStore.areNewsAvailable, 464 visible: window.ferdi.stores.user.isLoggedIn && announcementsStore.areNewsAvailable,
413 }, 465 },
414 { 466 {
415 type: 'separator', 467 type: 'separator',
416 }, 468 },
417 { 469 {
418 label: intl.formatMessage(menuItems.support), 470 label: intl.formatMessage(menuItems.support),
419 click() { shell.openExternal('https://meetfranz.com/support'); }, 471 click() { shell.openExternal('https://getferdi.com/contact'); },
420 }, 472 },
421 { 473 {
422 type: 'separator', 474 type: 'separator',
423 }, 475 },
424 { 476 {
425 label: intl.formatMessage(menuItems.tos), 477 label: intl.formatMessage(menuItems.tos),
426 click() { shell.openExternal('https://meetfranz.com/terms'); }, 478 click() { shell.openExternal(`${termsBase()}/terms`); },
427 }, 479 },
428 { 480 {
429 label: intl.formatMessage(menuItems.privacy), 481 label: intl.formatMessage(menuItems.privacy),
430 click() { shell.openExternal('https://meetfranz.com/privacy'); }, 482 click() { shell.openExternal(`${termsBase()}/privacy`); },
431 }, 483 },
432 ], 484 ],
433 }, 485 },
@@ -435,7 +487,7 @@ const _templateFactory = intl => [
435 487
436const _titleBarTemplateFactory = intl => [ 488const _titleBarTemplateFactory = intl => [
437 { 489 {
438 label: intl.formatMessage(menuItems.edit), 490 label: `&${intl.formatMessage(menuItems.edit)}`,
439 submenu: [ 491 submenu: [
440 { 492 {
441 label: intl.formatMessage(menuItems.undo), 493 label: intl.formatMessage(menuItems.undo),
@@ -498,12 +550,41 @@ const _titleBarTemplateFactory = intl => [
498 ], 550 ],
499 }, 551 },
500 { 552 {
501 label: intl.formatMessage(menuItems.view), 553 label: `&${intl.formatMessage(menuItems.view)}`,
502 submenu: [ 554 submenu: [
503 { 555 {
504 type: 'separator', 556 type: 'separator',
505 }, 557 },
506 { 558 {
559 label: intl.formatMessage(menuItems.openQuickSwitch),
560 accelerator: 'CmdOrCtrl+S',
561 click() {
562 window.ferdi.features.quickSwitch.state.isModalVisible = true;
563 },
564 },
565 {
566 type: 'separator',
567 },
568 {
569 label: intl.formatMessage(menuItems.back),
570 accelerator: 'CmdOrCtrl+Left',
571 click() {
572 const activeService = getActiveWebview();
573 activeService.goBack();
574 },
575 },
576 {
577 label: intl.formatMessage(menuItems.forward),
578 accelerator: 'CmdOrCtrl+Right',
579 click() {
580 const activeService = getActiveWebview();
581 activeService.goForward();
582 },
583 },
584 {
585 type: 'separator',
586 },
587 {
507 label: intl.formatMessage(menuItems.resetZoom), 588 label: intl.formatMessage(menuItems.resetZoom),
508 accelerator: `${ctrlKey}+0`, 589 accelerator: `${ctrlKey}+0`,
509 click() { 590 click() {
@@ -544,14 +625,27 @@ const _titleBarTemplateFactory = intl => [
544 browserWindow.setFullScreen(!browserWindow.isFullScreen()); 625 browserWindow.setFullScreen(!browserWindow.isFullScreen());
545 }, 626 },
546 }, 627 },
628 {
629 label: intl.formatMessage(menuItems.autohideMenuBar),
630 type: 'checkbox',
631 checked: window.ferdi.stores.settings.app.autohideMenuBar,
632 click: () => {
633 window.ferdi.actions.settings.update({
634 type: 'app',
635 data: {
636 autohideMenuBar: !window.ferdi.stores.settings.app.autohideMenuBar,
637 },
638 });
639 },
640 },
547 ], 641 ],
548 }, 642 },
549 { 643 {
550 label: intl.formatMessage(menuItems.services), 644 label: `&${intl.formatMessage(menuItems.services)}`,
551 submenu: [], 645 submenu: [],
552 }, 646 },
553 { 647 {
554 label: intl.formatMessage(menuItems.workspaces), 648 label: `&${intl.formatMessage(menuItems.workspaces)}`,
555 submenu: [], 649 submenu: [],
556 visible: workspaceStore.isFeatureEnabled, 650 visible: workspaceStore.isFeatureEnabled,
557 }, 651 },
@@ -580,33 +674,33 @@ const _titleBarTemplateFactory = intl => [
580 ], 674 ],
581 }, 675 },
582 { 676 {
583 label: '?', 677 label: '&?',
584 submenu: [ 678 submenu: [
585 { 679 {
586 label: intl.formatMessage(menuItems.learnMore), 680 label: intl.formatMessage(menuItems.learnMore),
587 click() { shell.openExternal('https://meetfranz.com'); }, 681 click() { shell.openExternal('https://getferdi.com'); },
588 }, 682 },
589 { 683 {
590 label: intl.formatMessage(menuItems.changelog), 684 label: intl.formatMessage(menuItems.changelog),
591 click() { shell.openExternal('https://github.com/meetfranz/franz/blob/master/CHANGELOG.md'); }, 685 click() { shell.openExternal('https://github.com/getferdi/ferdi/blob/master/CHANGELOG.md'); },
592 }, 686 },
593 { 687 {
594 type: 'separator', 688 type: 'separator',
595 }, 689 },
596 { 690 {
597 label: intl.formatMessage(menuItems.support), 691 label: intl.formatMessage(menuItems.support),
598 click() { shell.openExternal('https://meetfranz.com/support'); }, 692 click() { shell.openExternal('https://getferdi.com/contact'); },
599 }, 693 },
600 { 694 {
601 type: 'separator', 695 type: 'separator',
602 }, 696 },
603 { 697 {
604 label: intl.formatMessage(menuItems.tos), 698 label: intl.formatMessage(menuItems.tos),
605 click() { shell.openExternal('https://meetfranz.com/terms'); }, 699 click() { shell.openExternal(`${termsBase()}/terms`); },
606 }, 700 },
607 { 701 {
608 label: intl.formatMessage(menuItems.privacy), 702 label: intl.formatMessage(menuItems.privacy),
609 click() { shell.openExternal('https://meetfranz.com/privacy'); }, 703 click() { shell.openExternal(`${termsBase()}/privacy`); },
610 }, 704 },
611 ], 705 ],
612 }, 706 },
@@ -637,13 +731,14 @@ export default class FranzMenu {
637 const serviceTpl = Object.assign([], this.serviceTpl()); 731 const serviceTpl = Object.assign([], this.serviceTpl());
638 732
639 // Don't initialize when window.franz is undefined or when we are on a payment window route 733 // Don't initialize when window.franz is undefined or when we are on a payment window route
640 if (window.franz === undefined || this.stores.router.location.pathname.startsWith('/payment/')) { 734 if (window.ferdi === undefined || this.stores.router.location.pathname.startsWith('/payment/')) {
641 console.log('skipping menu init'); 735 console.log('skipping menu init');
642 return; 736 return;
643 } 737 }
644 738
645 const { intl } = window.franz; 739 const { intl } = window.ferdi;
646 const tpl = isMac ? _templateFactory(intl) : _titleBarTemplateFactory(intl); 740 const tpl = isMac ? _templateFactory(intl) : _titleBarTemplateFactory(intl);
741 const { actions } = this;
647 742
648 tpl[1].submenu.push({ 743 tpl[1].submenu.push({
649 type: 'separator', 744 type: 'separator',
@@ -695,10 +790,33 @@ export default class FranzMenu {
695 click: () => { 790 click: () => {
696 window.location.reload(); 791 window.location.reload();
697 }, 792 },
793 }, {
794 type: 'separator',
795 }, {
796 label: intl.formatMessage(menuItems.lockFerdi),
797 accelerator: 'CmdOrCtrl+Shift+L',
798 enabled: this.stores.settings.app.lockingFeatureEnabled,
799 click() {
800 // Disable lock first - otherwise the application might not update correctly
801 actions.settings.update({
802 type: 'app',
803 data: {
804 locked: false,
805 },
806 });
807 setTimeout(() => {
808 actions.settings.update({
809 type: 'app',
810 data: {
811 locked: true,
812 },
813 });
814 }, 0);
815 },
698 }); 816 });
699 817
700 tpl.unshift({ 818 tpl.unshift({
701 label: isMac ? app.getName() : intl.formatMessage(menuItems.file), 819 label: isMac ? app.getName() : `&${intl.formatMessage(menuItems.file)}`,
702 submenu: [ 820 submenu: [
703 { 821 {
704 label: intl.formatMessage(menuItems.about), 822 label: intl.formatMessage(menuItems.about),
@@ -762,9 +880,9 @@ export default class FranzMenu {
762 click: () => { 880 click: () => {
763 dialog.showMessageBox({ 881 dialog.showMessageBox({
764 type: 'info', 882 type: 'info',
765 title: 'Franz', 883 title: 'Franz Ferdinand',
766 message: 'Franz', 884 message: 'Ferdi',
767 detail: `Version: ${remote.app.getVersion()}\nRelease: ${process.versions.electron} / ${process.platform} / ${process.arch}`, 885 detail: `Version: ${remote.app.getVersion()} (${process.arch})\nElectron: ${process.versions.electron}\nNode.js: ${process.version}\nPlatform: ${process.platform}`,
768 }); 886 });
769 }, 887 },
770 }; 888 };
@@ -816,7 +934,7 @@ export default class FranzMenu {
816 }, 934 },
817 ]; 935 ];
818 936
819 tpl[5].submenu.push({ 937 tpl[tpl.length - 1].submenu.push({
820 type: 'separator', 938 type: 'separator',
821 }, about); 939 }, about);
822 } 940 }
@@ -843,7 +961,7 @@ export default class FranzMenu {
843 } 961 }
844 962
845 serviceTpl() { 963 serviceTpl() {
846 const { intl } = window.franz; 964 const { intl } = window.ferdi;
847 const { user, services, settings } = this.stores; 965 const { user, services, settings } = this.stores;
848 if (!user.isLoggedIn) return []; 966 if (!user.isLoggedIn) return [];
849 const menu = []; 967 const menu = [];
@@ -903,7 +1021,7 @@ export default class FranzMenu {
903 1021
904 workspacesMenu() { 1022 workspacesMenu() {
905 const { workspaces, activeWorkspace, isWorkspaceDrawerOpen } = workspaceStore; 1023 const { workspaces, activeWorkspace, isWorkspaceDrawerOpen } = workspaceStore;
906 const { intl } = window.franz; 1024 const { intl } = window.ferdi;
907 const menu = []; 1025 const menu = [];
908 1026
909 // Add new workspace item: 1027 // Add new workspace item:
@@ -925,7 +1043,6 @@ export default class FranzMenu {
925 accelerator: `${cmdKey}+D`, 1043 accelerator: `${cmdKey}+D`,
926 click: () => { 1044 click: () => {
927 workspaceActions.toggleWorkspaceDrawer(); 1045 workspaceActions.toggleWorkspaceDrawer();
928 gaEvent(GA_CATEGORY_WORKSPACES, 'toggleDrawer', 'menu');
929 }, 1046 },
930 enabled: this.stores.user.isLoggedIn, 1047 enabled: this.stores.user.isLoggedIn,
931 }, { 1048 }, {
@@ -940,7 +1057,6 @@ export default class FranzMenu {
940 checked: !activeWorkspace, 1057 checked: !activeWorkspace,
941 click: () => { 1058 click: () => {
942 workspaceActions.deactivate(); 1059 workspaceActions.deactivate();
943 gaEvent(GA_CATEGORY_WORKSPACES, 'switch', 'menu');
944 }, 1060 },
945 }); 1061 });
946 1062
@@ -953,7 +1069,6 @@ export default class FranzMenu {
953 checked: activeWorkspace ? workspace.id === activeWorkspace.id : false, 1069 checked: activeWorkspace ? workspace.id === activeWorkspace.id : false,
954 click: () => { 1070 click: () => {
955 workspaceActions.activate({ workspace }); 1071 workspaceActions.activate({ workspace });
956 gaEvent(GA_CATEGORY_WORKSPACES, 'switch', 'menu');
957 }, 1072 },
958 })); 1073 }));
959 } 1074 }
@@ -963,7 +1078,7 @@ export default class FranzMenu {
963 1078
964 todosMenu() { 1079 todosMenu() {
965 const { isTodosPanelVisible, isFeatureEnabledByUser } = this.stores.todos; 1080 const { isTodosPanelVisible, isFeatureEnabledByUser } = this.stores.todos;
966 const { intl } = window.franz; 1081 const { intl } = window.ferdi;
967 const menu = []; 1082 const menu = [];
968 1083
969 const drawerLabel = isTodosPanelVisible ? menuItems.closeTodosDrawer : menuItems.openTodosDrawer; 1084 const drawerLabel = isTodosPanelVisible ? menuItems.closeTodosDrawer : menuItems.openTodosDrawer;
@@ -973,7 +1088,6 @@ export default class FranzMenu {
973 accelerator: `${cmdKey}+T`, 1088 accelerator: `${cmdKey}+T`,
974 click: () => { 1089 click: () => {
975 todoActions.toggleTodosPanel(); 1090 todoActions.toggleTodosPanel();
976 gaEvent(GA_CATEGORY_TODOS, 'toggleDrawer', 'menu');
977 }, 1091 },
978 enabled: this.stores.user.isLoggedIn && isFeatureEnabledByUser, 1092 enabled: this.stores.user.isLoggedIn && isFeatureEnabledByUser,
979 }); 1093 });
@@ -985,7 +1099,6 @@ export default class FranzMenu {
985 label: intl.formatMessage(menuItems.enableTodos), 1099 label: intl.formatMessage(menuItems.enableTodos),
986 click: () => { 1100 click: () => {
987 todoActions.toggleTodosFeatureVisibility(); 1101 todoActions.toggleTodosFeatureVisibility();
988 gaEvent(GA_CATEGORY_TODOS, 'enable', 'menu');
989 }, 1102 },
990 }); 1103 });
991 } 1104 }
@@ -995,7 +1108,7 @@ export default class FranzMenu {
995 1108
996 1109
997 debugMenu() { 1110 debugMenu() {
998 const { intl } = window.franz; 1111 const { intl } = window.ferdi;
999 1112
1000 return { 1113 return {
1001 label: intl.formatMessage(menuItems.debugInfo), 1114 label: intl.formatMessage(menuItems.debugInfo),
@@ -1021,7 +1134,7 @@ export default class FranzMenu {
1021 return service.name; 1134 return service.name;
1022 } 1135 }
1023 1136
1024 let name = service.recipe.name; 1137 let { name } = service.recipe;
1025 1138
1026 if (service.team) { 1139 if (service.team) {
1027 name = `${name} (${service.team})`; 1140 name = `${name} (${service.team})`;