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 32bd1644b..7e336c994 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';
13 12
14const { app, Menu, dialog } = remote; 13const { app, Menu, dialog } = remote;
@@ -70,6 +69,18 @@ const menuItems = defineMessages({
70 id: 'menu.edit.emojiSymbols', 69 id: 'menu.edit.emojiSymbols',
71 defaultMessage: '!!!Emoji & Symbols', 70 defaultMessage: '!!!Emoji & Symbols',
72 }, 71 },
72 openQuickSwitch: {
73 id: 'menu.view.openQuickSwitch',
74 defaultMessage: '!!!Open Quick Switch',
75 },
76 back: {
77 id: 'menu.view.back',
78 defaultMessage: '!!!Back',
79 },
80 forward: {
81 id: 'menu.view.forward',
82 defaultMessage: '!!!Forward',
83 },
73 resetZoom: { 84 resetZoom: {
74 id: 'menu.view.resetZoom', 85 id: 'menu.view.resetZoom',
75 defaultMessage: '!!!Actual Size', 86 defaultMessage: '!!!Actual Size',
@@ -112,7 +123,11 @@ const menuItems = defineMessages({
112 }, 123 },
113 reloadFranz: { 124 reloadFranz: {
114 id: 'menu.view.reloadFranz', 125 id: 'menu.view.reloadFranz',
115 defaultMessage: '!!!Reload Franz', 126 defaultMessage: '!!!Reload Ferdi',
127 },
128 lockFerdi: {
129 id: 'menu.view.lockFerdi',
130 defaultMessage: '!!!Lock Ferdi',
116 }, 131 },
117 minimize: { 132 minimize: {
118 id: 'menu.window.minimize', 133 id: 'menu.window.minimize',
@@ -140,7 +155,7 @@ const menuItems = defineMessages({
140 }, 155 },
141 debugInfoCopiedHeadline: { 156 debugInfoCopiedHeadline: {
142 id: 'menu.help.debugInfoCopiedHeadline', 157 id: 'menu.help.debugInfoCopiedHeadline',
143 defaultMessage: '!!!Franz Debug Information', 158 defaultMessage: '!!!Ferdi Debug Information',
144 }, 159 },
145 debugInfoCopiedBody: { 160 debugInfoCopiedBody: {
146 id: 'menu.help.debugInfoCopiedBody', 161 id: 'menu.help.debugInfoCopiedBody',
@@ -176,7 +191,7 @@ const menuItems = defineMessages({
176 }, 191 },
177 about: { 192 about: {
178 id: 'menu.app.about', 193 id: 'menu.app.about',
179 defaultMessage: '!!!About Franz', 194 defaultMessage: '!!!About Ferdi',
180 }, 195 },
181 announcement: { 196 announcement: {
182 id: 'menu.app.announcement', 197 id: 'menu.app.announcement',
@@ -202,6 +217,10 @@ const menuItems = defineMessages({
202 id: 'menu.app.unhide', 217 id: 'menu.app.unhide',
203 defaultMessage: '!!!Unhide', 218 defaultMessage: '!!!Unhide',
204 }, 219 },
220 autohideMenuBar: {
221 id: 'menu.app.autohideMenuBar',
222 defaultMessage: '!!!Auto-hide menu bar',
223 },
205 quit: { 224 quit: {
206 id: 'menu.app.quit', 225 id: 'menu.app.quit',
207 defaultMessage: '!!!Quit', 226 defaultMessage: '!!!Quit',
@@ -265,7 +284,11 @@ const menuItems = defineMessages({
265}); 284});
266 285
267function getActiveWebview() { 286function getActiveWebview() {
268 return window.franz.stores.services.active.webview; 287 return window.ferdi.stores.services.active.webview;
288}
289
290function termsBase() {
291 return window.ferdi.stores.settings.all.app.server !== 'https://api.franzinfra.com' ? window.ferdi.stores.settings.all.app.server : 'https://meetfranz.com';
269} 292}
270 293
271const _templateFactory = intl => [ 294const _templateFactory = intl => [
@@ -324,6 +347,35 @@ const _templateFactory = intl => [
324 type: 'separator', 347 type: 'separator',
325 }, 348 },
326 { 349 {
350 label: intl.formatMessage(menuItems.openQuickSwitch),
351 accelerator: 'CmdOrCtrl+S',
352 click() {
353 window.ferdi.features.quickSwitch.state.isModalVisible = true;
354 },
355 },
356 {
357 type: 'separator',
358 },
359 {
360 label: intl.formatMessage(menuItems.back),
361 accelerator: 'CmdOrCtrl+Left',
362 click() {
363 const activeService = getActiveWebview();
364 activeService.goBack();
365 },
366 },
367 {
368 label: intl.formatMessage(menuItems.forward),
369 accelerator: 'CmdOrCtrl+Right',
370 click() {
371 const activeService = getActiveWebview();
372 activeService.goForward();
373 },
374 },
375 {
376 type: 'separator',
377 },
378 {
327 label: intl.formatMessage(menuItems.resetZoom), 379 label: intl.formatMessage(menuItems.resetZoom),
328 accelerator: 'Cmd+0', 380 accelerator: 'Cmd+0',
329 click() { 381 click() {
@@ -397,32 +449,32 @@ const _templateFactory = intl => [
397 submenu: [ 449 submenu: [
398 { 450 {
399 label: intl.formatMessage(menuItems.learnMore), 451 label: intl.formatMessage(menuItems.learnMore),
400 click() { shell.openExternal('https://meetfranz.com'); }, 452 click() { shell.openExternal('https://getferdi.com'); },
401 }, 453 },
402 { 454 {
403 label: intl.formatMessage(menuItems.announcement), 455 label: intl.formatMessage(menuItems.announcement),
404 click: () => { 456 click: () => {
405 announcementActions.show(); 457 announcementActions.show();
406 }, 458 },
407 visible: window.franz.stores.user.isLoggedIn && announcementsStore.areNewsAvailable, 459 visible: window.ferdi.stores.user.isLoggedIn && announcementsStore.areNewsAvailable,
408 }, 460 },
409 { 461 {
410 type: 'separator', 462 type: 'separator',
411 }, 463 },
412 { 464 {
413 label: intl.formatMessage(menuItems.support), 465 label: intl.formatMessage(menuItems.support),
414 click() { shell.openExternal('https://meetfranz.com/support'); }, 466 click() { shell.openExternal('https://getferdi.com/contact'); },
415 }, 467 },
416 { 468 {
417 type: 'separator', 469 type: 'separator',
418 }, 470 },
419 { 471 {
420 label: intl.formatMessage(menuItems.tos), 472 label: intl.formatMessage(menuItems.tos),
421 click() { shell.openExternal('https://meetfranz.com/terms'); }, 473 click() { shell.openExternal(`${termsBase()}/terms`); },
422 }, 474 },
423 { 475 {
424 label: intl.formatMessage(menuItems.privacy), 476 label: intl.formatMessage(menuItems.privacy),
425 click() { shell.openExternal('https://meetfranz.com/privacy'); }, 477 click() { shell.openExternal(`${termsBase()}/privacy`); },
426 }, 478 },
427 ], 479 ],
428 }, 480 },
@@ -430,7 +482,7 @@ const _templateFactory = intl => [
430 482
431const _titleBarTemplateFactory = intl => [ 483const _titleBarTemplateFactory = intl => [
432 { 484 {
433 label: intl.formatMessage(menuItems.edit), 485 label: `&${intl.formatMessage(menuItems.edit)}`,
434 submenu: [ 486 submenu: [
435 { 487 {
436 label: intl.formatMessage(menuItems.undo), 488 label: intl.formatMessage(menuItems.undo),
@@ -493,12 +545,41 @@ const _titleBarTemplateFactory = intl => [
493 ], 545 ],
494 }, 546 },
495 { 547 {
496 label: intl.formatMessage(menuItems.view), 548 label: `&${intl.formatMessage(menuItems.view)}`,
497 submenu: [ 549 submenu: [
498 { 550 {
499 type: 'separator', 551 type: 'separator',
500 }, 552 },
501 { 553 {
554 label: intl.formatMessage(menuItems.openQuickSwitch),
555 accelerator: 'CmdOrCtrl+S',
556 click() {
557 window.ferdi.features.quickSwitch.state.isModalVisible = true;
558 },
559 },
560 {
561 type: 'separator',
562 },
563 {
564 label: intl.formatMessage(menuItems.back),
565 accelerator: 'CmdOrCtrl+Left',
566 click() {
567 const activeService = getActiveWebview();
568 activeService.goBack();
569 },
570 },
571 {
572 label: intl.formatMessage(menuItems.forward),
573 accelerator: 'CmdOrCtrl+Right',
574 click() {
575 const activeService = getActiveWebview();
576 activeService.goForward();
577 },
578 },
579 {
580 type: 'separator',
581 },
582 {
502 label: intl.formatMessage(menuItems.resetZoom), 583 label: intl.formatMessage(menuItems.resetZoom),
503 accelerator: `${ctrlKey}+0`, 584 accelerator: `${ctrlKey}+0`,
504 click() { 585 click() {
@@ -539,14 +620,27 @@ const _titleBarTemplateFactory = intl => [
539 browserWindow.setFullScreen(!browserWindow.isFullScreen()); 620 browserWindow.setFullScreen(!browserWindow.isFullScreen());
540 }, 621 },
541 }, 622 },
623 {
624 label: intl.formatMessage(menuItems.autohideMenuBar),
625 type: 'checkbox',
626 checked: window.ferdi.stores.settings.app.autohideMenuBar,
627 click: () => {
628 window.ferdi.actions.settings.update({
629 type: 'app',
630 data: {
631 autohideMenuBar: !window.ferdi.stores.settings.app.autohideMenuBar,
632 },
633 });
634 },
635 },
542 ], 636 ],
543 }, 637 },
544 { 638 {
545 label: intl.formatMessage(menuItems.services), 639 label: `&${intl.formatMessage(menuItems.services)}`,
546 submenu: [], 640 submenu: [],
547 }, 641 },
548 { 642 {
549 label: intl.formatMessage(menuItems.workspaces), 643 label: `&${intl.formatMessage(menuItems.workspaces)}`,
550 submenu: [], 644 submenu: [],
551 visible: workspaceStore.isFeatureEnabled, 645 visible: workspaceStore.isFeatureEnabled,
552 }, 646 },
@@ -575,33 +669,33 @@ const _titleBarTemplateFactory = intl => [
575 ], 669 ],
576 }, 670 },
577 { 671 {
578 label: '?', 672 label: '&?',
579 submenu: [ 673 submenu: [
580 { 674 {
581 label: intl.formatMessage(menuItems.learnMore), 675 label: intl.formatMessage(menuItems.learnMore),
582 click() { shell.openExternal('https://meetfranz.com'); }, 676 click() { shell.openExternal('https://getferdi.com'); },
583 }, 677 },
584 { 678 {
585 label: intl.formatMessage(menuItems.changelog), 679 label: intl.formatMessage(menuItems.changelog),
586 click() { shell.openExternal('https://github.com/meetfranz/franz/blob/master/CHANGELOG.md'); }, 680 click() { shell.openExternal('https://github.com/getferdi/ferdi/blob/master/CHANGELOG.md'); },
587 }, 681 },
588 { 682 {
589 type: 'separator', 683 type: 'separator',
590 }, 684 },
591 { 685 {
592 label: intl.formatMessage(menuItems.support), 686 label: intl.formatMessage(menuItems.support),
593 click() { shell.openExternal('https://meetfranz.com/support'); }, 687 click() { shell.openExternal('https://getferdi.com/contact'); },
594 }, 688 },
595 { 689 {
596 type: 'separator', 690 type: 'separator',
597 }, 691 },
598 { 692 {
599 label: intl.formatMessage(menuItems.tos), 693 label: intl.formatMessage(menuItems.tos),
600 click() { shell.openExternal('https://meetfranz.com/terms'); }, 694 click() { shell.openExternal(`${termsBase()}/terms`); },
601 }, 695 },
602 { 696 {
603 label: intl.formatMessage(menuItems.privacy), 697 label: intl.formatMessage(menuItems.privacy),
604 click() { shell.openExternal('https://meetfranz.com/privacy'); }, 698 click() { shell.openExternal(`${termsBase()}/privacy`); },
605 }, 699 },
606 ], 700 ],
607 }, 701 },
@@ -631,12 +725,13 @@ export default class FranzMenu {
631 // need to clone object so we don't modify computed (cached) object 725 // need to clone object so we don't modify computed (cached) object
632 const serviceTpl = Object.assign([], this.serviceTpl()); 726 const serviceTpl = Object.assign([], this.serviceTpl());
633 727
634 if (window.franz === undefined) { 728 if (window.ferdi === undefined) {
635 return; 729 return;
636 } 730 }
637 731
638 const { intl } = window.franz; 732 const { intl } = window.ferdi;
639 const tpl = isMac ? _templateFactory(intl) : _titleBarTemplateFactory(intl); 733 const tpl = isMac ? _templateFactory(intl) : _titleBarTemplateFactory(intl);
734 const { actions } = this;
640 735
641 tpl[1].submenu.push({ 736 tpl[1].submenu.push({
642 type: 'separator', 737 type: 'separator',
@@ -684,10 +779,33 @@ export default class FranzMenu {
684 click: () => { 779 click: () => {
685 window.location.reload(); 780 window.location.reload();
686 }, 781 },
782 }, {
783 type: 'separator',
784 }, {
785 label: intl.formatMessage(menuItems.lockFerdi),
786 accelerator: 'CmdOrCtrl+Shift+L',
787 enabled: this.stores.settings.app.lockingFeatureEnabled,
788 click() {
789 // Disable lock first - otherwise the application might not update correctly
790 actions.settings.update({
791 type: 'app',
792 data: {
793 locked: false,
794 },
795 });
796 setTimeout(() => {
797 actions.settings.update({
798 type: 'app',
799 data: {
800 locked: true,
801 },
802 });
803 }, 0);
804 },
687 }); 805 });
688 806
689 tpl.unshift({ 807 tpl.unshift({
690 label: isMac ? app.getName() : intl.formatMessage(menuItems.file), 808 label: isMac ? app.getName() : `&${intl.formatMessage(menuItems.file)}`,
691 submenu: [ 809 submenu: [
692 { 810 {
693 label: intl.formatMessage(menuItems.about), 811 label: intl.formatMessage(menuItems.about),
@@ -751,9 +869,9 @@ export default class FranzMenu {
751 click: () => { 869 click: () => {
752 dialog.showMessageBox({ 870 dialog.showMessageBox({
753 type: 'info', 871 type: 'info',
754 title: 'Franz', 872 title: 'Franz Ferdinand',
755 message: 'Franz', 873 message: 'Ferdi',
756 detail: `Version: ${remote.app.getVersion()}\nRelease: ${process.versions.electron} / ${process.platform} / ${process.arch}`, 874 detail: `Version: ${remote.app.getVersion()}\nElectron: ${process.versions.electron} / ${process.platform} / ${process.arch}`,
757 }); 875 });
758 }, 876 },
759 }; 877 };
@@ -805,7 +923,7 @@ export default class FranzMenu {
805 }, 923 },
806 ]; 924 ];
807 925
808 tpl[5].submenu.push({ 926 tpl[tpl.length - 1].submenu.push({
809 type: 'separator', 927 type: 'separator',
810 }, about); 928 }, about);
811 } 929 }
@@ -832,7 +950,7 @@ export default class FranzMenu {
832 } 950 }
833 951
834 serviceTpl() { 952 serviceTpl() {
835 const { intl } = window.franz; 953 const { intl } = window.ferdi;
836 const { user, services, settings } = this.stores; 954 const { user, services, settings } = this.stores;
837 if (!user.isLoggedIn) return []; 955 if (!user.isLoggedIn) return [];
838 const menu = []; 956 const menu = [];
@@ -882,7 +1000,7 @@ export default class FranzMenu {
882 1000
883 workspacesMenu() { 1001 workspacesMenu() {
884 const { workspaces, activeWorkspace, isWorkspaceDrawerOpen } = workspaceStore; 1002 const { workspaces, activeWorkspace, isWorkspaceDrawerOpen } = workspaceStore;
885 const { intl } = window.franz; 1003 const { intl } = window.ferdi;
886 const menu = []; 1004 const menu = [];
887 1005
888 // Add new workspace item: 1006 // Add new workspace item:
@@ -904,7 +1022,6 @@ export default class FranzMenu {
904 accelerator: `${cmdKey}+D`, 1022 accelerator: `${cmdKey}+D`,
905 click: () => { 1023 click: () => {
906 workspaceActions.toggleWorkspaceDrawer(); 1024 workspaceActions.toggleWorkspaceDrawer();
907 gaEvent(GA_CATEGORY_WORKSPACES, 'toggleDrawer', 'menu');
908 }, 1025 },
909 enabled: this.stores.user.isLoggedIn, 1026 enabled: this.stores.user.isLoggedIn,
910 }, { 1027 }, {
@@ -919,7 +1036,6 @@ export default class FranzMenu {
919 checked: !activeWorkspace, 1036 checked: !activeWorkspace,
920 click: () => { 1037 click: () => {
921 workspaceActions.deactivate(); 1038 workspaceActions.deactivate();
922 gaEvent(GA_CATEGORY_WORKSPACES, 'switch', 'menu');
923 }, 1039 },
924 }); 1040 });
925 1041
@@ -932,7 +1048,6 @@ export default class FranzMenu {
932 checked: activeWorkspace ? workspace.id === activeWorkspace.id : false, 1048 checked: activeWorkspace ? workspace.id === activeWorkspace.id : false,
933 click: () => { 1049 click: () => {
934 workspaceActions.activate({ workspace }); 1050 workspaceActions.activate({ workspace });
935 gaEvent(GA_CATEGORY_WORKSPACES, 'switch', 'menu');
936 }, 1051 },
937 })); 1052 }));
938 } 1053 }
@@ -942,7 +1057,7 @@ export default class FranzMenu {
942 1057
943 todosMenu() { 1058 todosMenu() {
944 const { isTodosPanelVisible, isFeatureEnabledByUser } = this.stores.todos; 1059 const { isTodosPanelVisible, isFeatureEnabledByUser } = this.stores.todos;
945 const { intl } = window.franz; 1060 const { intl } = window.ferdi;
946 const menu = []; 1061 const menu = [];
947 1062
948 const drawerLabel = isTodosPanelVisible ? menuItems.closeTodosDrawer : menuItems.openTodosDrawer; 1063 const drawerLabel = isTodosPanelVisible ? menuItems.closeTodosDrawer : menuItems.openTodosDrawer;
@@ -952,7 +1067,6 @@ export default class FranzMenu {
952 accelerator: `${cmdKey}+T`, 1067 accelerator: `${cmdKey}+T`,
953 click: () => { 1068 click: () => {
954 todoActions.toggleTodosPanel(); 1069 todoActions.toggleTodosPanel();
955 gaEvent(GA_CATEGORY_TODOS, 'toggleDrawer', 'menu');
956 }, 1070 },
957 enabled: this.stores.user.isLoggedIn && isFeatureEnabledByUser, 1071 enabled: this.stores.user.isLoggedIn && isFeatureEnabledByUser,
958 }); 1072 });
@@ -964,7 +1078,6 @@ export default class FranzMenu {
964 label: intl.formatMessage(menuItems.enableTodos), 1078 label: intl.formatMessage(menuItems.enableTodos),
965 click: () => { 1079 click: () => {
966 todoActions.toggleTodosFeatureVisibility(); 1080 todoActions.toggleTodosFeatureVisibility();
967 gaEvent(GA_CATEGORY_TODOS, 'enable', 'menu');
968 }, 1081 },
969 }); 1082 });
970 } 1083 }
@@ -974,7 +1087,7 @@ export default class FranzMenu {
974 1087
975 1088
976 debugMenu() { 1089 debugMenu() {
977 const { intl } = window.franz; 1090 const { intl } = window.ferdi;
978 1091
979 return { 1092 return {
980 label: intl.formatMessage(menuItems.debugInfo), 1093 label: intl.formatMessage(menuItems.debugInfo),
@@ -1000,7 +1113,7 @@ export default class FranzMenu {
1000 return service.name; 1113 return service.name;
1001 } 1114 }
1002 1115
1003 let name = service.recipe.name; 1116 let { name } = service.recipe;
1004 1117
1005 if (service.team) { 1118 if (service.team) {
1006 name = `${name} (${service.team})`; 1119 name = `${name} (${service.team})`;