diff options
author | muhamedsalih-tw <104364298+muhamedsalih-tw@users.noreply.github.com> | 2022-11-06 10:36:51 +0530 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-11-06 05:06:51 +0000 |
commit | e7dbea5bc6d7e6b121dbc94b21b759a29f16e0c0 (patch) | |
tree | 958d6dad84687352af27c19c50bdcac345bc3a79 /src/lib | |
parent | 6.2.1-nightly.39 [skip ci] (diff) | |
download | ferdium-app-e7dbea5bc6d7e6b121dbc94b21b759a29f16e0c0.tar.gz ferdium-app-e7dbea5bc6d7e6b121dbc94b21b759a29f16e0c0.tar.zst ferdium-app-e7dbea5bc6d7e6b121dbc94b21b759a29f16e0c0.zip |
Transform tray & menu files to typescript (#740)
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/DBus.ts | 13 | ||||
-rw-r--r-- | src/lib/Menu.ts (renamed from src/lib/Menu.js) | 633 | ||||
-rw-r--r-- | src/lib/Tray.ts (renamed from src/lib/Tray.js) | 130 |
3 files changed, 410 insertions, 366 deletions
diff --git a/src/lib/DBus.ts b/src/lib/DBus.ts index b1febc2d1..bbff405c4 100644 --- a/src/lib/DBus.ts +++ b/src/lib/DBus.ts | |||
@@ -1,17 +1,20 @@ | |||
1 | import { MessageBus, sessionBus } from 'dbus-next'; | 1 | import { MessageBus, sessionBus } from 'dbus-next'; |
2 | import { isLinux } from '../environment'; | 2 | import { isLinux } from '../environment'; |
3 | import TrayIcon from './Tray'; | ||
3 | 4 | ||
4 | export default class DBus { | 5 | export default class DBus { |
5 | bus: MessageBus | null = null; | 6 | bus: MessageBus | null = null; |
6 | 7 | ||
7 | trayIcon: any; | 8 | trayIcon: TrayIcon; |
8 | 9 | ||
9 | constructor(trayIcon: any) { | 10 | constructor(trayIcon: TrayIcon) { |
10 | this.trayIcon = trayIcon; | 11 | this.trayIcon = trayIcon; |
11 | } | 12 | } |
12 | 13 | ||
13 | start() { | 14 | start() { |
14 | if (!isLinux || this.bus) return; | 15 | if (!isLinux || this.bus) { |
16 | return; | ||
17 | } | ||
15 | 18 | ||
16 | try { | 19 | try { |
17 | this.bus = sessionBus(); | 20 | this.bus = sessionBus(); |
@@ -47,7 +50,9 @@ export default class DBus { | |||
47 | } | 50 | } |
48 | 51 | ||
49 | stop() { | 52 | stop() { |
50 | if (!this.bus) return; | 53 | if (!this.bus) { |
54 | return; | ||
55 | } | ||
51 | 56 | ||
52 | this.bus.disconnect(); | 57 | this.bus.disconnect(); |
53 | this.bus = null; | 58 | this.bus = null; |
diff --git a/src/lib/Menu.js b/src/lib/Menu.ts index 52b6be18a..c206ea55d 100644 --- a/src/lib/Menu.js +++ b/src/lib/Menu.ts | |||
@@ -1,4 +1,4 @@ | |||
1 | import { clipboard } from 'electron'; | 1 | import { clipboard, MenuItemConstructorOptions } from 'electron'; |
2 | import { | 2 | import { |
3 | app, | 3 | app, |
4 | Menu, | 4 | Menu, |
@@ -8,7 +8,7 @@ import { | |||
8 | getCurrentWindow, | 8 | getCurrentWindow, |
9 | } from '@electron/remote'; | 9 | } from '@electron/remote'; |
10 | import { autorun, action, makeObservable, observable } from 'mobx'; | 10 | import { autorun, action, makeObservable, observable } from 'mobx'; |
11 | import { defineMessages } from 'react-intl'; | 11 | import { defineMessages, IntlShape } from 'react-intl'; |
12 | import osName from 'os-name'; | 12 | import osName from 'os-name'; |
13 | import { fromJS } from 'immutable'; | 13 | import { fromJS } from 'immutable'; |
14 | import semver from 'semver'; | 14 | import semver from 'semver'; |
@@ -42,9 +42,11 @@ import { importExportURL, serverBase, serverName } from '../api/apiBase'; | |||
42 | import { openExternalUrl } from '../helpers/url-helpers'; | 42 | import { openExternalUrl } from '../helpers/url-helpers'; |
43 | import globalMessages from '../i18n/globalMessages'; | 43 | import globalMessages from '../i18n/globalMessages'; |
44 | import { onAuthGoToReleaseNotes } from '../helpers/update-helpers'; | 44 | import { onAuthGoToReleaseNotes } from '../helpers/update-helpers'; |
45 | |||
46 | // @ts-expect-error Cannot find module '../buildInfo.json' or its corresponding type declarations. | 45 | // @ts-expect-error Cannot find module '../buildInfo.json' or its corresponding type declarations. |
47 | import * as buildInfo from '../buildInfo.json'; | 46 | import { timestamp, gitHashShort, gitBranch } from '../buildInfo.json'; |
47 | import Service from '../models/Service'; | ||
48 | import { StoresProps } from '../@types/ferdium-components.types'; | ||
49 | import { RealStores } from '../stores'; | ||
48 | 50 | ||
49 | const menuItems = defineMessages({ | 51 | const menuItems = defineMessages({ |
50 | edit: { | 52 | edit: { |
@@ -349,11 +351,11 @@ const menuItems = defineMessages({ | |||
349 | }, | 351 | }, |
350 | }); | 352 | }); |
351 | 353 | ||
352 | function getActiveService() { | 354 | function getActiveService(): Service | undefined { |
353 | return window['ferdium'].stores.services.active; | 355 | return window['ferdium'].stores.services.active; |
354 | } | 356 | } |
355 | 357 | ||
356 | function _toggleFullScreen() { | 358 | function toggleFullScreen(): void { |
357 | const mainWindow = getCurrentWindow(); | 359 | const mainWindow = getCurrentWindow(); |
358 | 360 | ||
359 | if (!mainWindow) return; | 361 | if (!mainWindow) return; |
@@ -365,314 +367,337 @@ function _toggleFullScreen() { | |||
365 | } | 367 | } |
366 | } | 368 | } |
367 | 369 | ||
368 | const _titleBarTemplateFactory = (intl, locked) => [ | 370 | function titleBarTemplateFactory( |
369 | { | 371 | intl: IntlShape, |
370 | label: intl.formatMessage(menuItems.edit), | 372 | locked: boolean, |
371 | accelerator: `${altKey()}+E`, | 373 | ): MenuItemConstructorOptions[] { |
372 | submenu: [ | 374 | return [ |
373 | { | 375 | { |
374 | label: intl.formatMessage(menuItems.undo), | 376 | label: intl.formatMessage(menuItems.edit), |
375 | role: 'undo', | 377 | accelerator: `${altKey()}+E`, |
376 | }, | 378 | submenu: [ |
377 | { | 379 | { |
378 | label: intl.formatMessage(menuItems.redo), | 380 | label: intl.formatMessage(menuItems.undo), |
379 | role: 'redo', | 381 | role: 'undo', |
380 | }, | ||
381 | { | ||
382 | type: 'separator', | ||
383 | }, | ||
384 | { | ||
385 | label: intl.formatMessage(menuItems.cut), | ||
386 | accelerator: `${cmdOrCtrlShortcutKey()}+X`, | ||
387 | role: 'cut', | ||
388 | }, | ||
389 | { | ||
390 | label: intl.formatMessage(menuItems.copy), | ||
391 | accelerator: `${cmdOrCtrlShortcutKey()}+C`, | ||
392 | role: 'copy', | ||
393 | }, | ||
394 | { | ||
395 | label: intl.formatMessage(menuItems.paste), | ||
396 | accelerator: `${cmdOrCtrlShortcutKey()}+V`, | ||
397 | role: 'paste', | ||
398 | }, | ||
399 | { | ||
400 | label: intl.formatMessage(menuItems.pasteAndMatchStyle), | ||
401 | accelerator: `${cmdOrCtrlShortcutKey()}+${shiftKey()}+V`, // Override the accelerator since this adds new key combo in macos | ||
402 | role: 'pasteAndMatchStyle', | ||
403 | }, | ||
404 | { | ||
405 | label: intl.formatMessage(menuItems.delete), | ||
406 | role: 'delete', | ||
407 | }, | ||
408 | { | ||
409 | label: intl.formatMessage(menuItems.selectAll), | ||
410 | accelerator: `${cmdOrCtrlShortcutKey()}+A`, | ||
411 | role: 'selectall', | ||
412 | }, | ||
413 | ], | ||
414 | }, | ||
415 | { | ||
416 | label: intl.formatMessage(menuItems.view), | ||
417 | accelerator: `${altKey()}+V`, | ||
418 | visible: !locked, | ||
419 | submenu: [ | ||
420 | { | ||
421 | type: 'separator', | ||
422 | }, | ||
423 | { | ||
424 | label: intl.formatMessage(menuItems.openQuickSwitch), | ||
425 | accelerator: `${cmdOrCtrlShortcutKey()}+S`, | ||
426 | click() { | ||
427 | window['ferdium'].features.quickSwitch.state.isModalVisible = true; | ||
428 | }, | 382 | }, |
429 | }, | 383 | { |
430 | { | 384 | label: intl.formatMessage(menuItems.redo), |
431 | type: 'separator', | 385 | role: 'redo', |
432 | }, | 386 | }, |
433 | { | 387 | { |
434 | label: intl.formatMessage(menuItems.findInPage), | 388 | type: 'separator', |
435 | accelerator: `${cmdOrCtrlShortcutKey()}+F`, | 389 | }, |
436 | click() { | 390 | { |
437 | const service = getActiveService(); | 391 | label: intl.formatMessage(menuItems.cut), |
438 | // Check if there is a service active | 392 | accelerator: `${cmdOrCtrlShortcutKey()}+X`, |
439 | if (service) { | 393 | role: 'cut', |
440 | // Focus webview so find in page popup gets focused | 394 | }, |
441 | service.webview.focus(); | 395 | { |
442 | 396 | label: intl.formatMessage(menuItems.copy), | |
397 | accelerator: `${cmdOrCtrlShortcutKey()}+C`, | ||
398 | role: 'copy', | ||
399 | }, | ||
400 | { | ||
401 | label: intl.formatMessage(menuItems.paste), | ||
402 | accelerator: `${cmdOrCtrlShortcutKey()}+V`, | ||
403 | role: 'paste', | ||
404 | }, | ||
405 | { | ||
406 | label: intl.formatMessage(menuItems.pasteAndMatchStyle), | ||
407 | accelerator: `${cmdOrCtrlShortcutKey()}+${shiftKey()}+V`, // Override the accelerator since this adds new key combo in macos | ||
408 | role: 'pasteAndMatchStyle', | ||
409 | }, | ||
410 | { | ||
411 | label: intl.formatMessage(menuItems.delete), | ||
412 | role: 'delete', | ||
413 | }, | ||
414 | { | ||
415 | label: intl.formatMessage(menuItems.selectAll), | ||
416 | accelerator: `${cmdOrCtrlShortcutKey()}+A`, | ||
417 | role: 'selectAll', | ||
418 | }, | ||
419 | ], | ||
420 | }, | ||
421 | { | ||
422 | label: intl.formatMessage(menuItems.view), | ||
423 | accelerator: `${altKey()}+V`, | ||
424 | visible: !locked, | ||
425 | submenu: [ | ||
426 | { | ||
427 | type: 'separator', | ||
428 | }, | ||
429 | { | ||
430 | label: intl.formatMessage(menuItems.openQuickSwitch), | ||
431 | accelerator: `${cmdOrCtrlShortcutKey()}+S`, | ||
432 | click() { | ||
433 | window['ferdium'].features.quickSwitch.state.isModalVisible = true; | ||
434 | }, | ||
435 | }, | ||
436 | { | ||
437 | type: 'separator', | ||
438 | }, | ||
439 | { | ||
440 | label: intl.formatMessage(menuItems.findInPage), | ||
441 | accelerator: `${cmdOrCtrlShortcutKey()}+F`, | ||
442 | click() { | ||
443 | const activeService = getActiveService(); | ||
444 | if (!activeService) { | ||
445 | return; | ||
446 | } | ||
447 | activeService.webview.focus(); | ||
443 | window['ferdium'].actions.service.sendIPCMessage({ | 448 | window['ferdium'].actions.service.sendIPCMessage({ |
444 | serviceId: service.id, | 449 | serviceId: activeService.id, |
445 | channel: 'find-in-page', | 450 | channel: 'find-in-page', |
446 | args: {}, | 451 | args: {}, |
447 | }); | 452 | }); |
448 | } | 453 | }, |
449 | }, | 454 | }, |
450 | }, | 455 | { |
451 | { | 456 | type: 'separator', |
452 | type: 'separator', | ||
453 | }, | ||
454 | { | ||
455 | label: intl.formatMessage(menuItems.back), | ||
456 | accelerator: `${!isMac ? altKey() : cmdOrCtrlShortcutKey()}+Left`, | ||
457 | click() { | ||
458 | getActiveService().webview.goBack(); | ||
459 | }, | 457 | }, |
460 | }, | 458 | { |
461 | { | 459 | label: intl.formatMessage(menuItems.back), |
462 | label: intl.formatMessage(menuItems.forward), | 460 | accelerator: `${!isMac ? altKey() : cmdOrCtrlShortcutKey()}+Left`, |
463 | accelerator: `${!isMac ? altKey() : cmdOrCtrlShortcutKey()}+Right`, | 461 | click() { |
464 | click() { | 462 | const activeService = getActiveService(); |
465 | getActiveService().webview.goForward(); | 463 | if (!activeService) { |
464 | return; | ||
465 | } | ||
466 | activeService.webview.goBack(); | ||
467 | }, | ||
466 | }, | 468 | }, |
467 | }, | 469 | { |
468 | { | 470 | label: intl.formatMessage(menuItems.forward), |
469 | type: 'separator', | 471 | accelerator: `${!isMac ? altKey() : cmdOrCtrlShortcutKey()}+Right`, |
470 | }, | 472 | click() { |
471 | { | 473 | const activeService = getActiveService(); |
472 | label: intl.formatMessage(menuItems.resetZoom), | 474 | if (!activeService) { |
473 | accelerator: `${cmdOrCtrlShortcutKey()}+0`, | 475 | return; |
474 | click() { | 476 | } |
475 | getActiveService().webview.setZoomLevel(0); | 477 | activeService.webview.goForward(); |
478 | }, | ||
476 | }, | 479 | }, |
477 | }, | 480 | { |
478 | { | 481 | type: 'separator', |
479 | label: intl.formatMessage(menuItems.zoomIn), | ||
480 | accelerator: `${cmdOrCtrlShortcutKey()}+plus`, | ||
481 | click() { | ||
482 | const activeService = getActiveService().webview; | ||
483 | const level = activeService.getZoomLevel(); | ||
484 | |||
485 | activeService.setZoomLevel(level + 0.5); | ||
486 | }, | 482 | }, |
487 | }, | 483 | { |
488 | { | 484 | label: intl.formatMessage(menuItems.resetZoom), |
489 | label: intl.formatMessage(menuItems.zoomOut), | 485 | accelerator: `${cmdOrCtrlShortcutKey()}+0`, |
490 | accelerator: `${cmdOrCtrlShortcutKey()}+-`, | 486 | click() { |
491 | click() { | 487 | const activeService = getActiveService(); |
492 | const activeService = getActiveService().webview; | 488 | if (!activeService) { |
493 | const level = activeService.getZoomLevel(); | 489 | return; |
494 | 490 | } | |
495 | activeService.setZoomLevel(level - 0.5); | 491 | activeService.webview.setZoomLevel(0); |
492 | }, | ||
496 | }, | 493 | }, |
497 | }, | 494 | { |
498 | { | 495 | label: intl.formatMessage(menuItems.zoomIn), |
499 | type: 'separator', | 496 | accelerator: `${cmdOrCtrlShortcutKey()}+plus`, |
500 | }, | 497 | click() { |
501 | { | 498 | const activeService = getActiveService(); |
502 | label: intl.formatMessage(menuItems.toggleFullScreen), | 499 | if (!activeService) { |
503 | click: () => { | 500 | return; |
504 | _toggleFullScreen(); | 501 | } |
502 | const { webview } = activeService; | ||
503 | const level = webview.getZoomLevel(); | ||
504 | webview.setZoomLevel(level + 0.5); | ||
505 | }, | ||
505 | }, | 506 | }, |
506 | accelerator: toggleFullScreenKey(), | 507 | { |
507 | }, | 508 | label: intl.formatMessage(menuItems.zoomOut), |
508 | { | 509 | accelerator: `${cmdOrCtrlShortcutKey()}+-`, |
509 | label: intl.formatMessage(menuItems.toggleNavigationBar), | 510 | click() { |
510 | accelerator: `${cmdOrCtrlShortcutKey()}+B`, | 511 | const activeService = getActiveService(); |
511 | role: 'toggleNavigationBar', | 512 | if (!activeService) { |
512 | type: 'checkbox', | 513 | return; |
513 | checked: | 514 | } |
514 | window['ferdium'].stores.settings.app.navigationBarManualActive, | 515 | const { webview } = activeService; |
515 | click: () => { | 516 | const level = webview.getZoomLevel(); |
516 | window['ferdium'].actions.settings.update({ | 517 | webview.setZoomLevel(level - 0.5); |
517 | type: 'app', | 518 | }, |
518 | data: { | ||
519 | navigationBarManualActive: | ||
520 | !window['ferdium'].stores.settings.app | ||
521 | .navigationBarManualActive, | ||
522 | }, | ||
523 | }); | ||
524 | }, | 519 | }, |
525 | }, | 520 | { |
526 | { | 521 | type: 'separator', |
527 | label: intl.formatMessage(menuItems.splitModeToggle), | ||
528 | accelerator: `${splitModeToggleShortcutKey()}`, | ||
529 | role: 'splitModeToggle', | ||
530 | type: 'checkbox', | ||
531 | checked: window['ferdium'].stores.settings.app.splitMode, | ||
532 | click: () => { | ||
533 | window['ferdium'].actions.settings.update({ | ||
534 | type: 'app', | ||
535 | data: { | ||
536 | splitMode: !window['ferdium'].stores.settings.app.splitMode, | ||
537 | }, | ||
538 | }); | ||
539 | }, | 522 | }, |
540 | }, | 523 | { |
541 | { | 524 | label: intl.formatMessage(menuItems.toggleFullScreen), |
542 | label: intl.formatMessage(menuItems.toggleDarkMode), | 525 | click: () => { |
543 | type: 'checkbox', | 526 | toggleFullScreen(); |
544 | accelerator: `${cmdOrCtrlShortcutKey()}+${shiftKey()}+D`, | 527 | }, |
545 | checked: window['ferdium'].stores.settings.app.darkMode, | 528 | accelerator: toggleFullScreenKey(), |
546 | click: () => { | ||
547 | window['ferdium'].actions.settings.update({ | ||
548 | type: 'app', | ||
549 | data: { | ||
550 | darkMode: !window['ferdium'].stores.settings.app.darkMode, | ||
551 | }, | ||
552 | }); | ||
553 | }, | 529 | }, |
554 | }, | 530 | { |
555 | ], | 531 | label: intl.formatMessage(menuItems.toggleNavigationBar), |
556 | }, | 532 | accelerator: `${cmdOrCtrlShortcutKey()}+B`, |
557 | { | 533 | // role: 'toggleNavigationBar', |
558 | label: intl.formatMessage(menuItems.services), | 534 | type: 'checkbox', |
559 | accelerator: `${altKey()}+S`, | 535 | checked: |
560 | visible: !locked, | 536 | window['ferdium'].stores.settings.app.navigationBarManualActive, |
561 | submenu: [], | 537 | click: () => { |
562 | }, | 538 | window['ferdium'].actions.settings.update({ |
563 | { | 539 | type: 'app', |
564 | label: intl.formatMessage(menuItems.workspaces), | 540 | data: { |
565 | accelerator: `${altKey()}+W`, | 541 | navigationBarManualActive: |
566 | submenu: [], | 542 | !window['ferdium'].stores.settings.app |
567 | visible: !locked, | 543 | .navigationBarManualActive, |
568 | }, | 544 | }, |
569 | { | 545 | }); |
570 | label: intl.formatMessage(menuItems.todos), | 546 | }, |
571 | submenu: [], | ||
572 | visible: !locked, | ||
573 | }, | ||
574 | { | ||
575 | label: intl.formatMessage(menuItems.window), | ||
576 | role: 'window', | ||
577 | submenu: [ | ||
578 | { | ||
579 | label: intl.formatMessage(menuItems.minimize), | ||
580 | role: 'minimize', | ||
581 | }, | ||
582 | { | ||
583 | label: intl.formatMessage(menuItems.close), | ||
584 | role: 'close', | ||
585 | }, | ||
586 | ], | ||
587 | }, | ||
588 | { | ||
589 | label: intl.formatMessage(menuItems.help), | ||
590 | accelerator: `${altKey()}+H`, | ||
591 | role: 'help', | ||
592 | submenu: [ | ||
593 | { | ||
594 | label: intl.formatMessage(menuItems.learnMore), | ||
595 | click() { | ||
596 | openExternalUrl(LIVE_API_FERDIUM_WEBSITE, true); | ||
597 | }, | 547 | }, |
598 | }, | 548 | { |
599 | { | 549 | label: intl.formatMessage(menuItems.splitModeToggle), |
600 | label: intl.formatMessage(menuItems.changelog), | 550 | accelerator: `${splitModeToggleShortcutKey()}`, |
601 | click() { | 551 | // role: 'splitModeToggle', |
602 | window.location.href = onAuthGoToReleaseNotes(window.location.href); | 552 | type: 'checkbox', |
553 | checked: window['ferdium'].stores.settings.app.splitMode, | ||
554 | click: () => { | ||
555 | window['ferdium'].actions.settings.update({ | ||
556 | type: 'app', | ||
557 | data: { | ||
558 | splitMode: !window['ferdium'].stores.settings.app.splitMode, | ||
559 | }, | ||
560 | }); | ||
561 | }, | ||
603 | }, | 562 | }, |
604 | }, | 563 | { |
605 | { | 564 | label: intl.formatMessage(menuItems.toggleDarkMode), |
606 | label: intl.formatMessage(menuItems.importExportData), | 565 | type: 'checkbox', |
607 | click() { | 566 | accelerator: `${cmdOrCtrlShortcutKey()}+${shiftKey()}+D`, |
608 | openExternalUrl(importExportURL(), true); | 567 | checked: window['ferdium'].stores.settings.app.darkMode, |
568 | click: () => { | ||
569 | window['ferdium'].actions.settings.update({ | ||
570 | type: 'app', | ||
571 | data: { | ||
572 | darkMode: !window['ferdium'].stores.settings.app.darkMode, | ||
573 | }, | ||
574 | }); | ||
575 | }, | ||
609 | }, | 576 | }, |
610 | enabled: !locked, | 577 | ], |
611 | }, | 578 | }, |
612 | { | 579 | { |
613 | type: 'separator', | 580 | label: intl.formatMessage(menuItems.services), |
614 | }, | 581 | accelerator: `${altKey()}+S`, |
615 | { | 582 | visible: !locked, |
616 | label: intl.formatMessage(menuItems.support), | 583 | submenu: [], |
617 | click() { | 584 | }, |
618 | openExternalUrl(`${LIVE_API_FERDIUM_WEBSITE}/contact`, true); | 585 | { |
586 | label: intl.formatMessage(menuItems.workspaces), | ||
587 | accelerator: `${altKey()}+W`, | ||
588 | submenu: [], | ||
589 | visible: !locked, | ||
590 | }, | ||
591 | { | ||
592 | label: intl.formatMessage(menuItems.todos), | ||
593 | submenu: [], | ||
594 | visible: !locked, | ||
595 | }, | ||
596 | { | ||
597 | label: intl.formatMessage(menuItems.window), | ||
598 | role: 'window', | ||
599 | submenu: [ | ||
600 | { | ||
601 | label: intl.formatMessage(menuItems.minimize), | ||
602 | role: 'minimize', | ||
619 | }, | 603 | }, |
620 | }, | 604 | { |
621 | { | 605 | label: intl.formatMessage(menuItems.close), |
622 | type: 'separator', | 606 | role: 'close', |
623 | }, | ||
624 | { | ||
625 | label: intl.formatMessage(menuItems.tos), | ||
626 | click() { | ||
627 | openExternalUrl(`${serverBase()}/terms`, true); | ||
628 | }, | 607 | }, |
629 | }, | 608 | ], |
630 | { | 609 | }, |
631 | label: intl.formatMessage(menuItems.privacy), | 610 | { |
632 | click() { | 611 | label: intl.formatMessage(menuItems.help), |
633 | openExternalUrl(`${serverBase()}/privacy`, true); | 612 | accelerator: `${altKey()}+H`, |
613 | role: 'help', | ||
614 | submenu: [ | ||
615 | { | ||
616 | label: intl.formatMessage(menuItems.learnMore), | ||
617 | click() { | ||
618 | openExternalUrl(LIVE_API_FERDIUM_WEBSITE, true); | ||
619 | }, | ||
634 | }, | 620 | }, |
635 | }, | 621 | { |
636 | ], | 622 | label: intl.formatMessage(menuItems.changelog), |
637 | }, | 623 | click() { |
638 | ]; | 624 | window.location.href = onAuthGoToReleaseNotes(window.location.href); |
625 | }, | ||
626 | }, | ||
627 | { | ||
628 | label: intl.formatMessage(menuItems.importExportData), | ||
629 | click() { | ||
630 | openExternalUrl(importExportURL(), true); | ||
631 | }, | ||
632 | enabled: !locked, | ||
633 | }, | ||
634 | { | ||
635 | type: 'separator', | ||
636 | }, | ||
637 | { | ||
638 | label: intl.formatMessage(menuItems.support), | ||
639 | click() { | ||
640 | openExternalUrl(`${LIVE_API_FERDIUM_WEBSITE}/contact`, true); | ||
641 | }, | ||
642 | }, | ||
643 | { | ||
644 | type: 'separator', | ||
645 | }, | ||
646 | { | ||
647 | label: intl.formatMessage(menuItems.tos), | ||
648 | click() { | ||
649 | openExternalUrl(`${serverBase()}/terms`, true); | ||
650 | }, | ||
651 | }, | ||
652 | { | ||
653 | label: intl.formatMessage(menuItems.privacy), | ||
654 | click() { | ||
655 | openExternalUrl(`${serverBase()}/privacy`, true); | ||
656 | }, | ||
657 | }, | ||
658 | ], | ||
659 | }, | ||
660 | ]; | ||
661 | } | ||
639 | 662 | ||
640 | class FranzMenu { | 663 | class FranzMenu implements StoresProps { |
641 | @observable currentTemplate = []; | 664 | @observable currentTemplate: MenuItemConstructorOptions[]; |
642 | 665 | ||
643 | constructor(stores, actions) { | 666 | actions: any; |
667 | |||
668 | stores: RealStores; | ||
669 | |||
670 | constructor(stores: RealStores, actions: any) { | ||
644 | this.stores = stores; | 671 | this.stores = stores; |
645 | this.actions = actions; | 672 | this.actions = actions; |
673 | this.currentTemplate = []; | ||
646 | 674 | ||
647 | makeObservable(this); | 675 | makeObservable(this); |
648 | 676 | ||
649 | setTimeout(() => { | 677 | setTimeout(() => autorun(this._build.bind(this)), 10); |
650 | autorun(this._build.bind(this)); | ||
651 | }, 10); | ||
652 | } | 678 | } |
653 | 679 | ||
654 | @action _setCurrentTemplate(tpl) { | 680 | @action _setCurrentTemplate(tpl: MenuItemConstructorOptions[]): void { |
655 | this.currentTemplate = tpl; | 681 | this.currentTemplate = tpl; |
656 | } | 682 | } |
657 | 683 | ||
658 | rebuild() { | 684 | rebuild(): void { |
659 | this._build(); | 685 | this._build(); |
660 | } | 686 | } |
661 | 687 | ||
662 | get template() { | 688 | get template(): any { |
663 | return fromJS(this.currentTemplate).toJS(); | 689 | return fromJS(this.currentTemplate).toJS(); |
664 | } | 690 | } |
665 | 691 | ||
666 | getOsName() { | 692 | getOsName(): string { |
667 | let osNameParse = osName(); | 693 | let osNameParse = osName(); |
668 | const isWin11 = semver.satisfies(os.release(), '>=10.0.22000'); | 694 | const isWin11 = semver.satisfies(os.release(), '>=10.0.22000'); |
669 | |||
670 | osNameParse = isWindows && isWin11 ? 'Windows 11' : osNameParse; | 695 | osNameParse = isWindows && isWin11 ? 'Windows 11' : osNameParse; |
671 | 696 | ||
672 | return osNameParse; | 697 | return osNameParse; |
673 | } | 698 | } |
674 | 699 | ||
675 | _build() { | 700 | _build(): void { |
676 | // need to clone object so we don't modify computed (cached) object | 701 | // need to clone object so we don't modify computed (cached) object |
677 | const serviceTpl = Object.assign([], this.serviceTpl()); | 702 | const serviceTpl = Object.assign([], this.serviceTpl()); |
678 | 703 | ||
@@ -687,11 +712,11 @@ class FranzMenu { | |||
687 | this.stores.settings.app.locked && | 712 | this.stores.settings.app.locked && |
688 | this.stores.settings.app.lockingFeatureEnabled && | 713 | this.stores.settings.app.lockingFeatureEnabled && |
689 | this.stores.user.isLoggedIn; | 714 | this.stores.user.isLoggedIn; |
690 | const tpl = _titleBarTemplateFactory(intl, locked); | ||
691 | const { actions } = this; | 715 | const { actions } = this; |
716 | const tpl = titleBarTemplateFactory(intl, locked); | ||
692 | 717 | ||
693 | if (!isMac) { | 718 | if (!isMac) { |
694 | tpl[1].submenu.push({ | 719 | (tpl[1].submenu as MenuItemConstructorOptions[]).push({ |
695 | label: intl.formatMessage(menuItems.autohideMenuBar), | 720 | label: intl.formatMessage(menuItems.autohideMenuBar), |
696 | type: 'checkbox', | 721 | type: 'checkbox', |
697 | checked: window['ferdium'].stores.settings.app.autohideMenuBar, | 722 | checked: window['ferdium'].stores.settings.app.autohideMenuBar, |
@@ -708,7 +733,7 @@ class FranzMenu { | |||
708 | } | 733 | } |
709 | 734 | ||
710 | if (!locked) { | 735 | if (!locked) { |
711 | tpl[1].submenu.push( | 736 | (tpl[1].submenu as MenuItemConstructorOptions[]).push( |
712 | { | 737 | { |
713 | type: 'separator', | 738 | type: 'separator', |
714 | }, | 739 | }, |
@@ -740,7 +765,7 @@ class FranzMenu { | |||
740 | ); | 765 | ); |
741 | 766 | ||
742 | if (this.stores.todos.isFeatureEnabledByUser) { | 767 | if (this.stores.todos.isFeatureEnabledByUser) { |
743 | tpl[1].submenu.push({ | 768 | (tpl[1].submenu as MenuItemConstructorOptions[]).push({ |
744 | label: intl.formatMessage(menuItems.toggleTodosDevTools), | 769 | label: intl.formatMessage(menuItems.toggleTodosDevTools), |
745 | accelerator: `${cmdOrCtrlShortcutKey()}+${shiftKey()}+${altKey()}+O`, | 770 | accelerator: `${cmdOrCtrlShortcutKey()}+${shiftKey()}+${altKey()}+O`, |
746 | click: () => { | 771 | click: () => { |
@@ -750,7 +775,7 @@ class FranzMenu { | |||
750 | }); | 775 | }); |
751 | } | 776 | } |
752 | 777 | ||
753 | tpl[1].submenu.unshift( | 778 | (tpl[1].submenu as MenuItemConstructorOptions[]).unshift( |
754 | { | 779 | { |
755 | label: intl.formatMessage(menuItems.reloadService), | 780 | label: intl.formatMessage(menuItems.reloadService), |
756 | accelerator: `${cmdOrCtrlShortcutKey()}+R`, | 781 | accelerator: `${cmdOrCtrlShortcutKey()}+R`, |
@@ -759,8 +784,8 @@ class FranzMenu { | |||
759 | this.stores.user.isLoggedIn && | 784 | this.stores.user.isLoggedIn && |
760 | this.stores.services.enabled.length > 0 | 785 | this.stores.services.enabled.length > 0 |
761 | ) { | 786 | ) { |
762 | if (getActiveService().recipe.id === CUSTOM_WEBSITE_RECIPE_ID) { | 787 | if (getActiveService()?.recipe.id === CUSTOM_WEBSITE_RECIPE_ID) { |
763 | getActiveService().webview.reload(); | 788 | getActiveService()?.webview.reload(); |
764 | } else { | 789 | } else { |
765 | this.actions.service.reloadActive(); | 790 | this.actions.service.reloadActive(); |
766 | } | 791 | } |
@@ -816,7 +841,7 @@ class FranzMenu { | |||
816 | systemPreferences.canPromptTouchID() | 841 | systemPreferences.canPromptTouchID() |
817 | : false; | 842 | : false; |
818 | 843 | ||
819 | tpl[0].submenu.unshift( | 844 | (tpl[0].submenu as MenuItemConstructorOptions[]).unshift( |
820 | { | 845 | { |
821 | label: intl.formatMessage(menuItems.touchId), | 846 | label: intl.formatMessage(menuItems.touchId), |
822 | accelerator: `${lockFerdiumShortcutKey()}`, | 847 | accelerator: `${lockFerdiumShortcutKey()}`, |
@@ -909,9 +934,9 @@ class FranzMenu { | |||
909 | `Node.js: ${nodeVersion}`, | 934 | `Node.js: ${nodeVersion}`, |
910 | `Platform: ${this.getOsName()}`, | 935 | `Platform: ${this.getOsName()}`, |
911 | `Arch: ${osArch}`, | 936 | `Arch: ${osArch}`, |
912 | `Build date: ${new Date(Number(buildInfo.timestamp))}`, | 937 | `Build date: ${new Date(Number(timestamp))}`, |
913 | `Git SHA: ${buildInfo.gitHashShort}`, | 938 | `Git SHA: ${gitHashShort}`, |
914 | `Git branch: ${buildInfo.gitBranch}`, | 939 | `Git branch: ${gitBranch}`, |
915 | ].join('\n'); | 940 | ].join('\n'); |
916 | 941 | ||
917 | const about = { | 942 | const about = { |
@@ -940,7 +965,7 @@ class FranzMenu { | |||
940 | 965 | ||
941 | if (isMac) { | 966 | if (isMac) { |
942 | // Edit menu. | 967 | // Edit menu. |
943 | tpl[1].submenu.push( | 968 | (tpl[1].submenu as MenuItemConstructorOptions[]).push( |
944 | { | 969 | { |
945 | type: 'separator', | 970 | type: 'separator', |
946 | }, | 971 | }, |
@@ -949,17 +974,17 @@ class FranzMenu { | |||
949 | submenu: [ | 974 | submenu: [ |
950 | { | 975 | { |
951 | label: intl.formatMessage(menuItems.startSpeaking), | 976 | label: intl.formatMessage(menuItems.startSpeaking), |
952 | role: 'startspeaking', | 977 | role: 'startSpeaking', |
953 | }, | 978 | }, |
954 | { | 979 | { |
955 | label: intl.formatMessage(menuItems.stopSpeaking), | 980 | label: intl.formatMessage(menuItems.stopSpeaking), |
956 | role: 'stopspeaking', | 981 | role: 'stopSpeaking', |
957 | }, | 982 | }, |
958 | ], | 983 | ], |
959 | }, | 984 | }, |
960 | ); | 985 | ); |
961 | 986 | ||
962 | tpl[0].submenu.unshift(about, { | 987 | (tpl[0].submenu as MenuItemConstructorOptions[]).unshift(about, { |
963 | type: 'separator', | 988 | type: 'separator', |
964 | }); | 989 | }); |
965 | } else { | 990 | } else { |
@@ -985,7 +1010,7 @@ class FranzMenu { | |||
985 | }, | 1010 | }, |
986 | ]; | 1011 | ]; |
987 | 1012 | ||
988 | tpl[tpl.length - 1].submenu.push( | 1013 | (tpl[tpl.length - 1].submenu as MenuItemConstructorOptions[]).push( |
989 | { | 1014 | { |
990 | type: 'separator', | 1015 | type: 'separator', |
991 | }, | 1016 | }, |
@@ -1002,7 +1027,7 @@ class FranzMenu { | |||
1002 | 1027 | ||
1003 | tpl[5].submenu = this.todosMenu(); | 1028 | tpl[5].submenu = this.todosMenu(); |
1004 | 1029 | ||
1005 | tpl[tpl.length - 1].submenu.push( | 1030 | (tpl[tpl.length - 1].submenu as MenuItemConstructorOptions[]).push( |
1006 | { | 1031 | { |
1007 | type: 'separator', | 1032 | type: 'separator', |
1008 | }, | 1033 | }, |
@@ -1014,13 +1039,15 @@ class FranzMenu { | |||
1014 | Menu.setApplicationMenu(menu); | 1039 | Menu.setApplicationMenu(menu); |
1015 | } | 1040 | } |
1016 | 1041 | ||
1017 | serviceTpl() { | 1042 | serviceTpl(): MenuItemConstructorOptions[] { |
1018 | const { intl } = window['ferdium']; | 1043 | const { intl } = window['ferdium']; |
1019 | const { user, services, settings } = this.stores; | 1044 | const { user, services, settings } = this.stores; |
1020 | if (!user.isLoggedIn) return []; | 1045 | if (!user.isLoggedIn) { |
1021 | const menu = []; | 1046 | return []; |
1022 | const cmdAltShortcutsVisibile = !isLinux; | 1047 | } |
1023 | 1048 | ||
1049 | const cmdAltShortcutsVisibile = !isLinux; | ||
1050 | const menu: MenuItemConstructorOptions[] = []; | ||
1024 | menu.push( | 1051 | menu.push( |
1025 | { | 1052 | { |
1026 | label: intl.formatMessage(menuItems.addNewService), | 1053 | label: intl.formatMessage(menuItems.addNewService), |
@@ -1075,7 +1102,7 @@ class FranzMenu { | |||
1075 | for (const [i, service] of services.allDisplayed.entries()) { | 1102 | for (const [i, service] of services.allDisplayed.entries()) { |
1076 | menu.push({ | 1103 | menu.push({ |
1077 | label: this._getServiceName(service), | 1104 | label: this._getServiceName(service), |
1078 | accelerator: i < 9 ? `${cmdOrCtrlShortcutKey()}+${i + 1}` : null, | 1105 | accelerator: i < 9 ? `${cmdOrCtrlShortcutKey()}+${i + 1}` : undefined, |
1079 | type: 'radio', | 1106 | type: 'radio', |
1080 | checked: service.isActive, | 1107 | checked: service.isActive, |
1081 | click: () => { | 1108 | click: () => { |
@@ -1108,12 +1135,12 @@ class FranzMenu { | |||
1108 | return menu; | 1135 | return menu; |
1109 | } | 1136 | } |
1110 | 1137 | ||
1111 | workspacesMenu() { | 1138 | workspacesMenu(): MenuItemConstructorOptions[] { |
1112 | const { workspaces, activeWorkspace, isWorkspaceDrawerOpen } = | 1139 | const { workspaces, activeWorkspace, isWorkspaceDrawerOpen } = |
1113 | workspaceStore; | 1140 | workspaceStore; |
1114 | const { intl } = window['ferdium']; | 1141 | const { intl } = window['ferdium']; |
1115 | const menu = []; | ||
1116 | 1142 | ||
1143 | const menu: MenuItemConstructorOptions[] = []; | ||
1117 | // Add new workspace item: | 1144 | // Add new workspace item: |
1118 | menu.push({ | 1145 | menu.push({ |
1119 | label: intl.formatMessage(menuItems.addNewWorkspace), | 1146 | label: intl.formatMessage(menuItems.addNewWorkspace), |
@@ -1159,7 +1186,7 @@ class FranzMenu { | |||
1159 | menu.push({ | 1186 | menu.push({ |
1160 | label: workspace.name, | 1187 | label: workspace.name, |
1161 | accelerator: | 1188 | accelerator: |
1162 | i < 9 ? `${cmdOrCtrlShortcutKey()}+${altKey()}+${i + 1}` : null, | 1189 | i < 9 ? `${cmdOrCtrlShortcutKey()}+${altKey()}+${i + 1}` : undefined, |
1163 | type: 'radio', | 1190 | type: 'radio', |
1164 | checked: activeWorkspace ? workspace.id === activeWorkspace.id : false, | 1191 | checked: activeWorkspace ? workspace.id === activeWorkspace.id : false, |
1165 | click: () => { | 1192 | click: () => { |
@@ -1171,11 +1198,11 @@ class FranzMenu { | |||
1171 | return menu; | 1198 | return menu; |
1172 | } | 1199 | } |
1173 | 1200 | ||
1174 | todosMenu() { | 1201 | todosMenu(): MenuItemConstructorOptions[] { |
1175 | const { isTodosPanelVisible, isFeatureEnabledByUser } = this.stores.todos; | 1202 | const { isTodosPanelVisible, isFeatureEnabledByUser } = this.stores.todos; |
1176 | const { intl } = window['ferdium']; | 1203 | const { intl } = window['ferdium']; |
1177 | const menu = []; | ||
1178 | 1204 | ||
1205 | const menu: MenuItemConstructorOptions[] = []; | ||
1179 | menu.push({ | 1206 | menu.push({ |
1180 | label: intl.formatMessage( | 1207 | label: intl.formatMessage( |
1181 | isFeatureEnabledByUser ? menuItems.disableTodos : menuItems.enableTodos, | 1208 | isFeatureEnabledByUser ? menuItems.disableTodos : menuItems.enableTodos, |
@@ -1209,7 +1236,7 @@ class FranzMenu { | |||
1209 | return menu; | 1236 | return menu; |
1210 | } | 1237 | } |
1211 | 1238 | ||
1212 | debugMenu() { | 1239 | debugMenu(): MenuItemConstructorOptions[] { |
1213 | const { intl } = window['ferdium']; | 1240 | const { intl } = window['ferdium']; |
1214 | 1241 | ||
1215 | return [ | 1242 | return [ |
@@ -1233,9 +1260,8 @@ class FranzMenu { | |||
1233 | { | 1260 | { |
1234 | label: intl.formatMessage(menuItems.publishDebugInfo), | 1261 | label: intl.formatMessage(menuItems.publishDebugInfo), |
1235 | click: () => { | 1262 | click: () => { |
1236 | window[ | 1263 | window['ferdium'].features.publishDebugInfo.state.isModalVisible = |
1237 | 'ferdium' | 1264 | true; |
1238 | ].features.publishDebugInfo.state.isModalVisible = true; | ||
1239 | }, | 1265 | }, |
1240 | }, | 1266 | }, |
1241 | ]; | 1267 | ]; |
@@ -1246,15 +1272,14 @@ class FranzMenu { | |||
1246 | return service.name; | 1272 | return service.name; |
1247 | } | 1273 | } |
1248 | 1274 | ||
1249 | let { name } = service.recipe; | 1275 | let { name: serviceName } = service.recipe; |
1250 | |||
1251 | if (service.team) { | 1276 | if (service.team) { |
1252 | name = `${name} (${service.team})`; | 1277 | serviceName = `${serviceName} (${service.team})`; |
1253 | } else if (service.customUrl) { | 1278 | } else if (service.customUrl) { |
1254 | name = `${name} (${service.customUrl})`; | 1279 | serviceName = `${serviceName} (${service.customUrl})`; |
1255 | } | 1280 | } |
1256 | 1281 | ||
1257 | return name; | 1282 | return serviceName; |
1258 | } | 1283 | } |
1259 | } | 1284 | } |
1260 | 1285 | ||
diff --git a/src/lib/Tray.js b/src/lib/Tray.ts index fffdec64d..8e489edde 100644 --- a/src/lib/Tray.js +++ b/src/lib/Tray.ts | |||
@@ -7,6 +7,7 @@ import { | |||
7 | Tray, | 7 | Tray, |
8 | ipcMain, | 8 | ipcMain, |
9 | BrowserWindow, | 9 | BrowserWindow, |
10 | NativeImage, | ||
10 | } from 'electron'; | 11 | } from 'electron'; |
11 | import { join } from 'path'; | 12 | import { join } from 'path'; |
12 | import macosVersion from 'macos-version'; | 13 | import macosVersion from 'macos-version'; |
@@ -19,56 +20,30 @@ const INDICATOR_TRAY_INDIRECT = 'tray-indirect'; | |||
19 | 20 | ||
20 | // TODO: Need to support i18n for a lot of the hard-coded strings in this file | 21 | // TODO: Need to support i18n for a lot of the hard-coded strings in this file |
21 | export default class TrayIcon { | 22 | export default class TrayIcon { |
22 | trayIcon = null; | 23 | trayIcon: Tray | null = null; |
23 | 24 | ||
24 | indicator = 0; | 25 | indicator: string | number = 0; |
25 | 26 | ||
26 | themeChangeSubscriberId = null; | 27 | themeChangeSubscriberId: number | null = null; |
27 | 28 | ||
28 | trayMenu = null; | 29 | trayMenu: Menu | null = null; |
29 | 30 | ||
30 | visible = false; | 31 | visible = false; |
31 | 32 | ||
32 | isAppMuted = false; | 33 | isAppMuted = false; |
33 | 34 | ||
34 | mainWindow = null; | 35 | mainWindow: BrowserWindow | null = null; |
35 | |||
36 | trayMenuTemplate = tray => [ | ||
37 | { | ||
38 | label: | ||
39 | tray.mainWindow.isVisible() && tray.mainWindow.isFocused() | ||
40 | ? 'Hide Ferdium' | ||
41 | : 'Show Ferdium', | ||
42 | click() { | ||
43 | tray._toggleWindow(); | ||
44 | }, | ||
45 | }, | ||
46 | { | ||
47 | label: tray.isAppMuted | ||
48 | ? 'Enable Notifications && Audio' | ||
49 | : 'Disable Notifications && Audio', | ||
50 | click() { | ||
51 | if (!tray.mainWindow) return; | ||
52 | tray.mainWindow.webContents.send('muteApp'); | ||
53 | }, | ||
54 | }, | ||
55 | { | ||
56 | label: 'Quit Ferdium', | ||
57 | click() { | ||
58 | app.quit(); | ||
59 | }, | ||
60 | }, | ||
61 | ]; | ||
62 | 36 | ||
63 | constructor() { | 37 | constructor() { |
64 | ipcMain.on('initialAppSettings', (event, appSettings) => { | 38 | ipcMain.on('initialAppSettings', (_, appSettings) => { |
65 | this._updateTrayMenu(appSettings); | 39 | this._updateTrayMenu(appSettings); |
66 | }); | 40 | }); |
67 | ipcMain.on('updateAppSettings', (event, appSettings) => { | 41 | ipcMain.on('updateAppSettings', (_, appSettings) => { |
68 | this._updateTrayMenu(appSettings); | 42 | this._updateTrayMenu(appSettings); |
69 | }); | 43 | }); |
70 | 44 | ||
71 | this.mainWindow = BrowserWindow.getAllWindows()[0]; | 45 | const [firstWindow] = BrowserWindow.getAllWindows(); |
46 | this.mainWindow = firstWindow; | ||
72 | 47 | ||
73 | // listen to window events to be able to set correct string | 48 | // listen to window events to be able to set correct string |
74 | // to tray menu ('Hide Ferdium' / 'Show Ferdium') | 49 | // to tray menu ('Hide Ferdium' / 'Show Ferdium') |
@@ -92,7 +67,36 @@ export default class TrayIcon { | |||
92 | }); | 67 | }); |
93 | } | 68 | } |
94 | 69 | ||
95 | _updateTrayMenu(appSettings) { | 70 | trayMenuTemplate(tray) { |
71 | return [ | ||
72 | { | ||
73 | label: | ||
74 | tray.mainWindow.isVisible() && tray.mainWindow.isFocused() | ||
75 | ? 'Hide Ferdium' | ||
76 | : 'Show Ferdium', | ||
77 | click() { | ||
78 | tray._toggleWindow(); | ||
79 | }, | ||
80 | }, | ||
81 | { | ||
82 | label: tray.isAppMuted | ||
83 | ? 'Enable Notifications && Audio' | ||
84 | : 'Disable Notifications && Audio', | ||
85 | click() { | ||
86 | if (!tray.mainWindow) return; | ||
87 | tray.mainWindow.webContents.send('muteApp'); | ||
88 | }, | ||
89 | }, | ||
90 | { | ||
91 | label: 'Quit Ferdium', | ||
92 | click() { | ||
93 | app.quit(); | ||
94 | }, | ||
95 | }, | ||
96 | ]; | ||
97 | } | ||
98 | |||
99 | _updateTrayMenu(appSettings): void { | ||
96 | if (!this.trayIcon) return; | 100 | if (!this.trayIcon) return; |
97 | 101 | ||
98 | if (appSettings && appSettings.type === 'app') { | 102 | if (appSettings && appSettings.type === 'app') { |
@@ -105,13 +109,15 @@ export default class TrayIcon { | |||
105 | } | 109 | } |
106 | } | 110 | } |
107 | 111 | ||
108 | show() { | 112 | show(): void { |
109 | this.visible = true; | 113 | this.visible = true; |
110 | this._show(); | 114 | this._show(); |
111 | } | 115 | } |
112 | 116 | ||
113 | _show() { | 117 | _show(): void { |
114 | if (this.trayIcon) return; | 118 | if (this.trayIcon) { |
119 | return; | ||
120 | } | ||
115 | 121 | ||
116 | this.trayIcon = new Tray(this._getAsset('tray', INDICATOR_TRAY_PLAIN)); | 122 | this.trayIcon = new Tray(this._getAsset('tray', INDICATOR_TRAY_PLAIN)); |
117 | this.trayIcon.setToolTip('Ferdium'); | 123 | this.trayIcon.setToolTip('Ferdium'); |
@@ -127,7 +133,9 @@ export default class TrayIcon { | |||
127 | 133 | ||
128 | if (isMac || isWindows) { | 134 | if (isMac || isWindows) { |
129 | this.trayIcon.on('right-click', () => { | 135 | this.trayIcon.on('right-click', () => { |
130 | this.trayIcon.popUpContextMenu(this.trayMenu); | 136 | if (this.trayIcon && this.trayMenu) { |
137 | this.trayIcon.popUpContextMenu(this.trayMenu); | ||
138 | } | ||
131 | }); | 139 | }); |
132 | } | 140 | } |
133 | 141 | ||
@@ -141,9 +149,11 @@ export default class TrayIcon { | |||
141 | } | 149 | } |
142 | } | 150 | } |
143 | 151 | ||
144 | _toggleWindow() { | 152 | _toggleWindow(): void { |
145 | const mainWindow = BrowserWindow.getAllWindows()[0]; | 153 | const [mainWindow] = BrowserWindow.getAllWindows(); |
146 | if (!mainWindow) return; | 154 | if (!mainWindow) { |
155 | return; | ||
156 | } | ||
147 | 157 | ||
148 | if (mainWindow.isMinimized()) { | 158 | if (mainWindow.isMinimized()) { |
149 | mainWindow.restore(); | 159 | mainWindow.restore(); |
@@ -161,12 +171,12 @@ export default class TrayIcon { | |||
161 | } | 171 | } |
162 | } | 172 | } |
163 | 173 | ||
164 | hide() { | 174 | hide(): void { |
165 | this.visible = false; | 175 | this.visible = false; |
166 | this._hide(); | 176 | this._hide(); |
167 | } | 177 | } |
168 | 178 | ||
169 | _hide() { | 179 | _hide(): void { |
170 | if (!this.trayIcon) return; | 180 | if (!this.trayIcon) return; |
171 | 181 | ||
172 | this.trayIcon.destroy(); | 182 | this.trayIcon.destroy(); |
@@ -178,7 +188,7 @@ export default class TrayIcon { | |||
178 | } | 188 | } |
179 | } | 189 | } |
180 | 190 | ||
181 | recreateIfVisible() { | 191 | recreateIfVisible(): void { |
182 | if (this.visible) { | 192 | if (this.visible) { |
183 | this._hide(); | 193 | this._hide(); |
184 | setTimeout(() => { | 194 | setTimeout(() => { |
@@ -189,23 +199,26 @@ export default class TrayIcon { | |||
189 | } | 199 | } |
190 | } | 200 | } |
191 | 201 | ||
192 | setIndicator(indicator) { | 202 | setIndicator(indicator: string | number): void { |
193 | this.indicator = indicator; | 203 | this.indicator = indicator; |
194 | this._refreshIcon(); | 204 | this._refreshIcon(); |
195 | } | 205 | } |
196 | 206 | ||
197 | _getAssetFromIndicator(indicator) { | 207 | _getAssetFromIndicator(indicator: string | number): string { |
208 | let assetFromIndicator = INDICATOR_TRAY_PLAIN; | ||
198 | if (indicator === '•') { | 209 | if (indicator === '•') { |
199 | return INDICATOR_TRAY_INDIRECT; | 210 | assetFromIndicator = INDICATOR_TRAY_INDIRECT; |
200 | } | 211 | } |
201 | if (indicator !== 0) { | 212 | if (indicator !== 0) { |
202 | return INDICATOR_TRAY_UNREAD; | 213 | assetFromIndicator = INDICATOR_TRAY_UNREAD; |
203 | } | 214 | } |
204 | return INDICATOR_TRAY_PLAIN; | 215 | return assetFromIndicator; |
205 | } | 216 | } |
206 | 217 | ||
207 | _refreshIcon() { | 218 | _refreshIcon(): void { |
208 | if (!this.trayIcon) return; | 219 | if (!this.trayIcon) { |
220 | return; | ||
221 | } | ||
209 | 222 | ||
210 | this.trayIcon.setImage( | 223 | this.trayIcon.setImage( |
211 | this._getAsset('tray', this._getAssetFromIndicator(this.indicator)), | 224 | this._getAsset('tray', this._getAssetFromIndicator(this.indicator)), |
@@ -221,13 +234,14 @@ export default class TrayIcon { | |||
221 | } | 234 | } |
222 | } | 235 | } |
223 | 236 | ||
224 | _getAsset(type, asset) { | 237 | _getAsset(type, asset): NativeImage { |
225 | let { platform } = process; | 238 | const { platform } = process; |
239 | let platformPath: string = platform; | ||
226 | 240 | ||
227 | if (isMac && macosVersion.isGreaterThanOrEqualTo('11')) { | 241 | if (isMac && macosVersion.isGreaterThanOrEqualTo('11')) { |
228 | platform = `${platform}-20`; | 242 | platformPath = `${platform}-20`; |
229 | } else if (isMac && nativeTheme.shouldUseDarkColors) { | 243 | } else if (isMac && nativeTheme.shouldUseDarkColors) { |
230 | platform = `${platform}-dark`; | 244 | platformPath = `${platform}-dark`; |
231 | } | 245 | } |
232 | 246 | ||
233 | const trayImg = nativeImage.createFromPath( | 247 | const trayImg = nativeImage.createFromPath( |
@@ -237,7 +251,7 @@ export default class TrayIcon { | |||
237 | 'assets', | 251 | 'assets', |
238 | 'images', | 252 | 'images', |
239 | type, | 253 | type, |
240 | platform, | 254 | platformPath, |
241 | `${asset}.${FILE_EXTENSION}`, | 255 | `${asset}.${FILE_EXTENSION}`, |
242 | ), | 256 | ), |
243 | ); | 257 | ); |