feat: add tray

This commit is contained in:
Dr_rOot
2019-03-20 23:18:30 +08:00
parent b01e006073
commit 1bdd17a80a
20 changed files with 159 additions and 25 deletions
+9 -1
View File
@@ -13,6 +13,7 @@ import ProtocolManager from './core/ProtocolManager'
import WindowManager from './ui/WindowManager'
import MenuManager from './ui/MenuManager'
import TouchBarManager from './ui/TouchBarManager'
import TrayManager from './ui/TrayManager'
export default class Application extends EventEmitter {
constructor () {
@@ -43,6 +44,8 @@ export default class Application extends EventEmitter {
this.touchBarManager = new TouchBarManager()
this.trayManager = new TrayManager()
this.energyManager = new EnergyManager()
this.initUpdaterManager()
@@ -248,7 +251,12 @@ export default class Application extends EventEmitter {
})
this.on('application:change-locale', (locale) => {
this.menuManager.setup(locale)
logger.info('[Motrix] application:change-locale===>', locale)
this.localeManager.changeLanguageByLocale(locale)
.then(() => {
this.menuManager.setup(locale)
this.trayManager.setup(locale)
})
})
this.on('application:open-file', (event) => {
+11
View File
@@ -0,0 +1,11 @@
[
{ "id": "task.new-task", "command": "application:new-task", "command-after": "application:show,index" },
{ "id": "task.new-bt-task", "command": "application:new-bt-task", "command-arg": "torrent", "command-after": "application:show,index" },
{ "id": "task.open-file", "command": "application:open-file", "command-before": "application:show,index" },
{ "type": "separator" },
{ "id": "app.show", "command": "application:show", "command-arg": "index" },
{ "id": "help.manual", "command": "help:manual" },
{ "type": "separator" },
{ "id": "app.preferences", "command": "application:preferences", "command-before": "application:show,index" },
{ "id": "app.quit", "role": "quit" }
]
+21 -20
View File
@@ -6,29 +6,24 @@ import {
updateStates
} from '../utils/menu'
import keymap from '@shared/keymap'
import { getI18n } from '@/ui/Locale'
export default class MenuManager extends EventEmitter {
constructor (options) {
super()
this.options = options
this.i18n = getI18n()
this.keymap = keymap
this.template = []
this.menu = null
this.items = {}
this.load()
this.setup()
}
load (locale = 'en-US') {
let template = null
try {
template = require(`../menus/${locale}/${process.platform}.json`)
if (!template) {
template = require(`../menus/en-US/${process.platform}.json`)
}
} catch (err) {
template = require(`../menus/en-US/${process.platform}.json`)
}
load () {
let template = require(`../menus/${process.platform}.json`)
this.template = template['menu']
}
@@ -38,15 +33,21 @@ export default class MenuManager extends EventEmitter {
keystrokesByCommand[this.keymap[item]] = item
}
const tpl = translateTemplate(this.template, keystrokesByCommand)
this.menu = Menu.buildFromTemplate(tpl)
// Deepclone the menu template to refresh menu
const template = JSON.parse(JSON.stringify(this.template))
const tpl = translateTemplate(template, keystrokesByCommand, this.i18n)
const menu = Menu.buildFromTemplate(tpl)
return menu
}
setup (locale) {
this.load(locale)
this.build()
Menu.setApplicationMenu(this.menu)
this.items = flattenMenuItems(this.menu)
setup () {
const menu = this.build()
Menu.setApplicationMenu(menu)
this.items = flattenMenuItems(menu)
}
rebuild () {
this.setup()
}
updateStates (visibleStates, enabledStates, checkedStates) {
+98 -1
View File
@@ -1,3 +1,100 @@
export default class TrayManager {
import { EventEmitter } from 'events'
import { join } from 'path'
import { Tray, Menu } from 'electron'
import is from 'electron-is'
import { translateTemplate } from '../utils/menu'
import { getI18n } from '@/ui/Locale'
let tray = null
export default class TrayManager extends EventEmitter {
constructor (options = {}) {
super()
this.i18n = getI18n()
this.menu = null
this.load()
this.init()
this.setup()
this.handleEvents()
}
load () {
this.template = require(`../menus/tray.json`)
if (is.windows()) {
this.normalIcon = join(__static, './mo-tray-colorful-normal.ico')
this.activeIcon = join(__static, './mo-tray-colorful-active.ico')
} else if (is.macOS()) {
this.normalIcon = join(__static, './mo-tray-normal.png')
this.activeIcon = join(__static, './mo-tray-active.png')
} else {
this.normalIcon = join(__static, './mo-tray-colorful-normal.png')
this.activeIcon = join(__static, './mo-tray-colorful-active.png')
}
}
build () {
const keystrokesByCommand = {}
for (let item in this.keymap) {
keystrokesByCommand[this.keymap[item]] = item
}
// Deepclone the menu template to refresh menu
const template = JSON.parse(JSON.stringify(this.template))
const tpl = translateTemplate(template, keystrokesByCommand, this.i18n)
this.menu = Menu.buildFromTemplate(tpl)
}
setup () {
this.build()
/**
* Linux requires setContextMenu to be called
* in order for the context menu to populate correctly
*/
if (process.platform === 'linux') {
tray.setContextMenu(this.menu)
}
}
init () {
tray = new Tray(this.normalIcon)
tray.setToolTip('Motrix')
}
handleEvents () {
tray.on('click', this.handleTrayClick)
tray.on('double-click', this.handleTrayDbClick)
tray.on('right-click', this.handleTrayRightClick)
tray.on('drop-files', this.handleTrayDropFile)
}
handleTrayClick = (event) => {
event.preventDefault()
global.application.toggle()
}
handleTrayDbClick = (event) => {
event.preventDefault()
global.application.show()
}
handleTrayRightClick = (event) => {
event.preventDefault()
tray.popUpContextMenu(this.menu)
}
handleTrayDropFile = (event, files) => {
global.application.show()
global.application.handleFile(files[0])
}
updateStatus (status) {
const icon = status === 'active' ? this.activeIcon : this.normalIcon
tray.setImage(icon)
}
}
+13 -3
View File
@@ -71,19 +71,29 @@ function findById (template, id) {
return null
}
export function translateTemplate (template, keystrokesByCommand) {
export function translateTemplate (template, keystrokesByCommand, i18n) {
for (let i in template) {
let item = template[i]
if (item.command) {
item.accelerator = acceleratorForCommand(item.command, keystrokesByCommand)
}
// If label is specified, label is used as the key of i18n.t(key),
// which mainly solves the inaccurate translation of item.id.
if (i18n) {
if (item.label) {
item.label = i18n.t(item.label)
} else if (item.id) {
item.label = i18n.t(item.id)
}
}
item.click = () => {
console.log('click sendCommand', item)
handleCommand(item)
}
if (item.submenu) {
translateTemplate(item.submenu, keystrokesByCommand)
translateTemplate(item.submenu, keystrokesByCommand, i18n)
}
}
return template
+1
View File
@@ -16,6 +16,7 @@ export default {
'hide': 'Motrix verbergen',
'hide-others': 'Andere verbergen',
'unhide': 'Alles anzeigen',
'show': 'Motrix anzeigen',
'quit': 'Motrix beenden',
'under-development-message': 'Entschuldigung, diese Funktion befindet sich in der Entwicklung...',
'yes': 'Ja',
+1
View File
@@ -16,6 +16,7 @@ export default {
'hide': 'Hide Motrix',
'hide-others': 'Hide Others',
'unhide': 'Show All',
'show': 'Show Motrix',
'quit': 'Quit Motrix',
'under-development-message': 'Sorry, this feature is under development...',
'yes': 'Yes',
+1
View File
@@ -16,6 +16,7 @@ export default {
'hide': 'Cacher Motrix',
'hide-others': 'Cacher les autres',
'unhide': 'Tout montrer',
'show': 'Montrer Motrix',
'quit': 'Quitter Motrix',
'under-development-message': 'Désolé, cette fonctionnalité est en cours de développement...',
'yes': 'Oui',
+1
View File
@@ -16,6 +16,7 @@ export default {
'hide': 'Ocultar Motrix',
'hide-others': 'Ocultar Outros',
'unhide': 'Exibir Todos',
'show': 'Exibir Motrix',
'quit': 'Sair do Motrix',
'under-development-message': 'Desculpe, essa funcionalidade está em desenvolvimento...',
'yes': 'Sim',
+1
View File
@@ -16,6 +16,7 @@ export default {
'hide': 'Motrix\'i gizle',
'hide-others': 'Diğerlerini gizle',
'unhide': 'Hepsini Göster',
'show': 'Motrix\'i Göster',
'quit': 'Motrix\'ten çık',
'under-development-message': 'Üzgünüz, bu özellik geliştirme aşamasında...',
'yes': 'Evet',
+1
View File
@@ -16,6 +16,7 @@ export default {
'hide': '隐藏 Motrix',
'hide-others': '隐藏其他',
'unhide': '显示全部',
'show': '显示 Motrix',
'quit': '退出 Motrix',
'under-development-message': '该功能开发中...',
'yes': '是',
+1
View File
@@ -16,6 +16,7 @@ export default {
'hide': '隱藏 Motrix',
'hide-others': '隱藏其它',
'unhide': '全部顯示',
'show': '顯示 Motrix',
'quit': '結束 Motrix',
'under-development-message': '該功能開發中...',
'yes': '是',
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 140 B

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 183 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 137 B

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 175 B