aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib
diff options
context:
space:
mode:
authorLibravatar haraldox <hnaumann+github@gmail.com>2018-03-02 10:53:24 +0100
committerLibravatar haraldox <hnaumann+github@gmail.com>2018-03-02 10:53:24 +0100
commit662b55b0883255eeb4de9986a4e172cb6af4f0d8 (patch)
treeea177d1af31656d3321f739ac8a319ca5399cfd7 /src/lib
parentinternationalize validation messages (diff)
parentMerge branch 'feature/titlebar' of github.com:meetfranz/franz into feature/ti... (diff)
downloadferdium-app-662b55b0883255eeb4de9986a4e172cb6af4f0d8.tar.gz
ferdium-app-662b55b0883255eeb4de9986a4e172cb6af4f0d8.tar.zst
ferdium-app-662b55b0883255eeb4de9986a4e172cb6af4f0d8.zip
Merge branch 'feature/titlebar' into feature/i18n-universal
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/Menu.js330
1 files changed, 265 insertions, 65 deletions
diff --git a/src/lib/Menu.js b/src/lib/Menu.js
index 6962f22fe..50196af96 100644
--- a/src/lib/Menu.js
+++ b/src/lib/Menu.js
@@ -1,8 +1,8 @@
1import { remote, shell } from 'electron'; 1import { remote, shell } from 'electron';
2import { autorun, computed } from 'mobx'; 2import { observable, autorun, computed } from 'mobx';
3import { defineMessages } from 'react-intl'; 3import { defineMessages } from 'react-intl';
4 4
5import { isMac } from '../environment'; 5import { isMac, ctrlKey, cmdKey } from '../environment';
6 6
7const { app, Menu, dialog } = remote; 7const { app, Menu, dialog } = remote;
8 8
@@ -13,7 +13,11 @@ const menuItems = defineMessages({
13 }, 13 },
14}); 14});
15 15
16const _makeTemplate = intl => [ 16function getActiveWebview() {
17 return window.franz.stores.services.active.webview;
18}
19
20const _templateFactory = intl => [
17 { 21 {
18 label: intl.formatMessage(menuItems.edit), 22 label: intl.formatMessage(menuItems.edit),
19 submenu: [ 23 submenu: [
@@ -122,7 +126,162 @@ const _makeTemplate = intl => [
122 }, 126 },
123]; 127];
124 128
129const _titleBarTemplateFactory = intl => [
130 {
131 label: 'Edit',
132 submenu: [
133 {
134 label: 'Undo',
135 accelerator: `${ctrlKey}+Z`,
136 click() {
137 getActiveWebview().undo();
138 },
139 },
140 {
141 label: 'Redo',
142 accelerator: `${ctrlKey}+Y`,
143 click() {
144 getActiveWebview().redo();
145 },
146 },
147 {
148 type: 'separator',
149 },
150 {
151 label: 'Cut',
152 accelerator: `${ctrlKey}+X`,
153 click() {
154 getActiveWebview().cut();
155 },
156 },
157 {
158 label: 'Copy',
159 accelerator: `${ctrlKey}+C`,
160 click() {
161 getActiveWebview().copy();
162 },
163 },
164 {
165 label: 'Paste',
166 accelerator: `${ctrlKey}+V`,
167 click() {
168 getActiveWebview().paste();
169 },
170 },
171 {
172 label: 'Paste and Match Style',
173 accelerator: `${ctrlKey}+Shift+V`,
174 click() {
175 getActiveWebview().pasteAndMatchStyle();
176 },
177 },
178 {
179 label: 'Delete',
180 click() {
181 getActiveWebview().delete();
182 },
183 },
184 {
185 label: 'Select All',
186 accelerator: `${ctrlKey}+A`,
187 click() {
188 getActiveWebview().selectAll();
189 },
190 },
191 ],
192 },
193 {
194 label: 'View',
195 submenu: [
196 {
197 type: 'separator',
198 },
199 {
200 label: 'Reset Zoom',
201 accelerator: `${ctrlKey}+0`,
202 click() {
203 getActiveWebview().setZoomLevel(0);
204 },
205 },
206 {
207 label: 'Zoom in',
208 accelerator: `${ctrlKey}+=`,
209 click() {
210 getActiveWebview().getZoomLevel((zoomLevel) => {
211 getActiveWebview().setZoomLevel(zoomLevel === 5 ? zoomLevel : zoomLevel + 1);
212 });
213 },
214 },
215 {
216 label: 'Zoom out',
217 accelerator: `${ctrlKey}+-`,
218 click() {
219 getActiveWebview().getZoomLevel((zoomLevel) => {
220 getActiveWebview().setZoomLevel(zoomLevel === -5 ? zoomLevel : zoomLevel - 1);
221 });
222 },
223 },
224 ],
225 },
226 {
227 label: 'Services',
228 submenu: [],
229 },
230 {
231 label: 'Window',
232 submenu: [
233 {
234 label: 'Minimize',
235 accelerator: 'Alt+M',
236 click(menuItem, browserWindow) {
237 browserWindow.minimize();
238 },
239 },
240 {
241 label: 'Close',
242 accelerator: 'Alt+W',
243 click(menuItem, browserWindow) {
244 browserWindow.close();
245 },
246 },
247 ],
248 },
249 {
250 label: '?',
251 submenu: [
252 {
253 label: 'Learn More',
254 click() { shell.openExternal('http://meetfranz.com'); },
255 },
256 {
257 label: 'Changelog',
258 click() { shell.openExternal('https://github.com/meetfranz/franz/blob/master/CHANGELOG.md'); },
259 },
260 {
261 type: 'separator',
262 },
263 {
264 label: 'Support',
265 click() { shell.openExternal('http://meetfranz.com/support'); },
266 },
267 {
268 type: 'separator',
269 },
270 {
271 label: 'Terms of Service',
272 click() { shell.openExternal('https://meetfranz.com/terms'); },
273 },
274 {
275 label: 'Privacy Statement',
276 click() { shell.openExternal('https://meetfranz.com/privacy'); },
277 },
278 ],
279 },
280];
281
125export default class FranzMenu { 282export default class FranzMenu {
283 @observable currentTemplate = [];
284
126 constructor(stores, actions) { 285 constructor(stores, actions) {
127 this.stores = stores; 286 this.stores = stores;
128 this.actions = actions; 287 this.actions = actions;
@@ -134,6 +293,10 @@ export default class FranzMenu {
134 this._build(); 293 this._build();
135 } 294 }
136 295
296 get template() {
297 return this.currentTemplate.toJS();
298 }
299
137 _build() { 300 _build() {
138 // console.log(window.franz); 301 // console.log(window.franz);
139 const serviceTpl = Object.assign([], this.serviceTpl); // need to clone object so we don't modify computed (cached) object 302 const serviceTpl = Object.assign([], this.serviceTpl); // need to clone object so we don't modify computed (cached) object
@@ -142,13 +305,20 @@ export default class FranzMenu {
142 return; 305 return;
143 } 306 }
144 307
145 const tpl = _makeTemplate(window.franz.intl); 308 const intl = window.franz.intl;
309 const tpl = isMac ? _templateFactory(intl) : _titleBarTemplateFactory(intl);
146 310
147 tpl[1].submenu.push({ 311 tpl[1].submenu.push({
148 role: 'toggledevtools', 312 type: 'separator',
313 }, {
314 label: 'Toggle Developer Tools',
315 accelerator: `${cmdKey}+Alt+I`,
316 click: (menuItem, browserWindow) => {
317 browserWindow.webContents.toggleDevTools();
318 },
149 }, { 319 }, {
150 label: 'Toggle Service Developer Tools', 320 label: 'Open Service Developer Tools',
151 accelerator: 'CmdOrCtrl+Shift+Alt+i', 321 accelerator: `${cmdKey}+Shift+Alt+I`,
152 click: () => { 322 click: () => {
153 this.actions.service.openDevToolsForActiveService(); 323 this.actions.service.openDevToolsForActiveService();
154 }, 324 },
@@ -157,7 +327,7 @@ export default class FranzMenu {
157 tpl[1].submenu.unshift({ 327 tpl[1].submenu.unshift({
158 label: 'Reload Service', 328 label: 'Reload Service',
159 id: 'reloadService', 329 id: 'reloadService',
160 accelerator: 'CmdOrCtrl+R', 330 accelerator: `${cmdKey}+R`,
161 click: () => { 331 click: () => {
162 if (this.stores.user.isLoggedIn 332 if (this.stores.user.isLoggedIn
163 && this.stores.services.enabled.length > 0) { 333 && this.stores.services.enabled.length > 0) {
@@ -168,56 +338,69 @@ export default class FranzMenu {
168 }, 338 },
169 }, { 339 }, {
170 label: 'Reload Franz', 340 label: 'Reload Franz',
171 accelerator: 'CmdOrCtrl+Shift+R', 341 accelerator: `${cmdKey}+Shift+R`,
172 click: () => { 342 click: () => {
173 window.location.reload(); 343 window.location.reload();
174 }, 344 },
175 }); 345 });
176 346
177 if (isMac) { 347 tpl.unshift({
178 tpl.unshift({ 348 label: isMac ? app.getName() : 'File',
179 label: app.getName(), 349 submenu: [
180 submenu: [ 350 {
181 { 351 role: 'about',
182 role: 'about', 352 },
183 }, 353 {
184 { 354 type: 'separator',
185 type: 'separator', 355 },
186 }, 356 {
187 { 357 label: 'Settings',
188 label: 'Settings', 358 accelerator: 'CmdOrCtrl+,',
189 accelerator: 'CmdOrCtrl+,', 359 click: () => {
190 click: () => { 360 this.actions.ui.openSettings({ path: 'app' });
191 this.actions.ui.openSettings({ path: 'app' });
192 },
193 },
194 {
195 type: 'separator',
196 },
197 {
198 role: 'services',
199 submenu: [],
200 },
201 {
202 type: 'separator',
203 },
204 {
205 role: 'hide',
206 },
207 {
208 role: 'hideothers',
209 },
210 {
211 role: 'unhide',
212 },
213 {
214 type: 'separator',
215 },
216 {
217 role: 'quit',
218 }, 361 },
219 ], 362 },
220 }); 363 {
364 type: 'separator',
365 },
366 {
367 role: 'services',
368 submenu: [],
369 },
370 {
371 type: 'separator',
372 },
373 {
374 role: 'hide',
375 },
376 {
377 role: 'hideothers',
378 },
379 {
380 role: 'unhide',
381 },
382 {
383 type: 'separator',
384 },
385 {
386 role: 'quit',
387 },
388 ],
389 });
390
391 const about = {
392 label: 'About Franz',
393 click: () => {
394 dialog.showMessageBox({
395 type: 'info',
396 title: 'Franz',
397 message: 'Franz',
398 detail: `Version: ${remote.app.getVersion()}\nRelease: ${process.versions.electron} / ${process.platform} / ${process.arch}`,
399 });
400 },
401 };
402
403 if (isMac) {
221 // Edit menu. 404 // Edit menu.
222 tpl[1].submenu.push( 405 tpl[1].submenu.push(
223 { 406 {
@@ -235,23 +418,39 @@ export default class FranzMenu {
235 ], 418 ],
236 }, 419 },
237 ); 420 );
421
422 tpl[4].submenu.unshift(about, {
423 type: 'separator',
424 });
238 } else { 425 } else {
239 tpl[4].submenu.unshift({ 426 tpl[0].submenu = [
240 role: 'about', 427 {
241 click: () => { 428 label: 'Preferences...',
242 dialog.showMessageBox({ 429 accelerator: 'Ctrl+P',
243 type: 'info', 430 click: () => {
244 title: 'Franz', 431 this.actions.ui.openSettings({ path: 'app' });
245 message: 'Franz', 432 },
246 detail: `Version: ${remote.app.getVersion()}\nRelease: ${process.versions.electron} / ${process.platform} / ${process.arch}`,
247 });
248 }, 433 },
249 }); 434 {
435 type: 'separator',
436 },
437 {
438 label: 'Quit',
439 accelerator: 'Alt+F4',
440 click: () => {
441 app.quit();
442 },
443 },
444 ];
445
446 tpl[5].submenu.push({
447 type: 'separator',
448 }, about);
250 } 449 }
251 450
252 serviceTpl.unshift({ 451 serviceTpl.unshift({
253 label: 'Add new Service', 452 label: 'Add new Service',
254 accelerator: 'CmdOrCtrl+N', 453 accelerator: `${cmdKey}+N`,
255 click: () => { 454 click: () => {
256 this.actions.ui.openSettings({ path: 'recipes' }); 455 this.actions.ui.openSettings({ path: 'recipes' });
257 }, 456 },
@@ -260,9 +459,10 @@ export default class FranzMenu {
260 }); 459 });
261 460
262 if (serviceTpl.length > 0) { 461 if (serviceTpl.length > 0) {
263 tpl[isMac ? 3 : 2].submenu = serviceTpl; 462 tpl[3].submenu = serviceTpl;
264 } 463 }
265 464
465 this.currentTemplate = tpl;
266 const menu = Menu.buildFromTemplate(tpl); 466 const menu = Menu.buildFromTemplate(tpl);
267 Menu.setApplicationMenu(menu); 467 Menu.setApplicationMenu(menu);
268 } 468 }
@@ -273,7 +473,7 @@ export default class FranzMenu {
273 if (this.stores.user.isLoggedIn) { 473 if (this.stores.user.isLoggedIn) {
274 return services.map((service, i) => ({ 474 return services.map((service, i) => ({
275 label: this._getServiceName(service), 475 label: this._getServiceName(service),
276 accelerator: i <= 9 ? `CmdOrCtrl+${i + 1}` : null, 476 accelerator: i <= 9 ? `${cmdKey}+${i + 1}` : null,
277 type: 'radio', 477 type: 'radio',
278 checked: service.isActive, 478 checked: service.isActive,
279 click: () => { 479 click: () => {