提交 835aa506 编写于 作者: aaronchen2k2k's avatar aaronchen2k2k

improve electron nodejs codes

上级 f5f6d766
......@@ -2,7 +2,7 @@
"name": "ztf",
"productName": "ztf",
"version": "1.0.0",
"description": "My Electron application description",
"description": "ztf",
"main": ".webpack/main",
"scripts": {
"start": "NODE_ENV=development electron-forge start",
......@@ -17,10 +17,10 @@
},
"keywords": [],
"author": {
"name": "Hao Sun",
"email": "sunhao@easycorp.ltd"
"name": "Aaron Chen",
"email": "chenqi@easycorp.ltd"
},
"license": "MIT",
"license": "GPL3",
"config": {
"forge": "./forge.config.js"
},
......
import {app, BrowserWindow} from 'electron';
import {app, BrowserWindow, Menu, shell} from 'electron';
import Lang from './utils/lang';
import {IS_MAC_OSX, setEntryPath} from './utils/env';
import {logInfo} from './utils/log';
import {getUIServerUrl, killZtfServer} from "./service";
import {logInfo, logErr} from './utils/log';
import {getUIServerUrl, startZtfServer, killZtfServer} from "./service";
export default class ZtfApp {
constructor(entryPath) {
setEntryPath(entryPath);
this._windows = new Map();
this.lang = Lang;
setEntryPath(entryPath);
this.bindElectronEvents();
logInfo(`>> ZtfApp: created, entry path is "${entryPath}".`);
}
ready() {
logInfo('>> ZtfApp: ready.');
this.openOrCreateWindow();
// this.buildAppMenu();
startZtfServer()
}
openOrCreateWindow() {
const {lastFocusedAppWin} = this;
if (lastFocusedAppWin) {
lastFocusedAppWin.showAndFocus();
} else {
this.createWindow();
async startZtfServer() {
try {
const ztfServerUrl = await startZtfServer();
logInfo(`>> ZTF Server started successfully: ${ztfServerUrl}`);
} catch (error) {
logErr('>> Start ztf server failed: ' + error);
process.exit(1);
return;
}
}
......@@ -57,12 +54,43 @@ export default class ZtfApp {
mainWindow.maximize()
mainWindow.show()
this._windows.set('main', mainWindow);
getUIServerUrl().then((url) => {
mainWindow.loadURL(url);
mainWindow.webContents.openDevTools({mode: 'bottom'});
})
};
openOrCreateWindow() {
const mainWin = this._windows.get('main');
if (mainWin) {
this.showAndFocus(mainWin)
} else {
this.createWindow();
}
}
showAndFocus(mainWin) {
if (mainWin.isMinimized()) {
mainWin.restore();
} else {
mainWin.setOpacity(1);
mainWin.show();
}
mainWin.focus();
}
ready() {
logInfo('>> ZtfApp: ready.');
this.openOrCreateWindow();
this.buildAppMenu();
}
quit() {
killZtfServer();
}
bindElectronEvents() {
app.on('window-all-closed', () => {
logInfo(`>> Event window-all-closed`)
......@@ -71,7 +99,7 @@ export default class ZtfApp {
app.on('quit', () => {
logInfo(`>> Event quit`)
killZtfServer();
this.quit();
});
app.on('activate', () => {
......@@ -79,152 +107,114 @@ export default class ZtfApp {
// 在 OS X 系统上,可能存在所有应用窗口关闭了,但是程序还没关闭,此时如果收到激活应用请求需要
// 重新打开应用窗口并创建应用菜单
this.createWindow();
// this.buildAppMenu();
this.openOrCreateWindow();
this.buildAppMenu();
});
}
// buildAppMenu() {
// if (!IS_MAC_OSX) {
// return;
// }
//
// const template = [{
// label: Lang.string('app.title', Config.pkg.displayName),
// submenu: [{
// label: Lang.string('menu.about'),
// selector: 'orderFrontStandardAboutPanel:'
// }, {
// type: 'separator'
// }, {
// label: 'Services',
// submenu: []
// }, {
// type: 'separator'
// }, {
// label: Lang.string('menu.hideCurrentWindow'),
// accelerator: 'Command+H',
// selector: 'hide:'
// }, {
// label: Lang.string('menu.hideOtherWindows'),
// accelerator: 'Command+Shift+H',
// selector: 'hideOtherApplications:'
// }, {
// label: Lang.string('menu.showAllWindows'),
// selector: 'unhideAllApplications:'
// }, {
// type: 'separator'
// }, {
// label: Lang.string('menu.quit'),
// accelerator: 'Command+Q',
// click: () => {
// this.quit();
// }
// }]
// },
// {
// label: Lang.string('menu.edit'),
// submenu: [{
// label: Lang.string('menu.undo'),
// accelerator: 'Command+Z',
// selector: 'undo:'
// }, {
// label: Lang.string('menu.redo'),
// accelerator: 'Shift+Command+Z',
// selector: 'redo:'
// }, {
// type: 'separator'
// }, {
// label: Lang.string('menu.cut'),
// accelerator: 'Command+X',
// selector: 'cut:'
// }, {
// label: Lang.string('menu.copy'),
// accelerator: 'Command+C',
// selector: 'copy:'
// }, {
// label: Lang.string('menu.paste'),
// accelerator: 'Command+V',
// selector: 'paste:'
// }, {
// label: Lang.string('menu.selectAll'),
// accelerator: 'Command+A',
// selector: 'selectAll:'
// }]
// },
// {
// label: Lang.string('menu.view'),
// submenu: (DEBUG) ? [{
// label: Lang.string('menu.reload'),
// accelerator: 'Command+R',
// click: () => {
// this.getLastFocusedWindow({includeChildWindow: true}).browserWindow.webContents.reload();
// }
// }, {
// label: Lang.string('menu.toggleFullscreen'),
// accelerator: 'Ctrl+Command+F',
// click: () => {
// const lastWindow = this.getLastFocusedWindow();
// lastWindow.browserWindow.setFullScreen(!lastWindow.browserWindow.isFullScreen());
// }
// }, {
// label: Lang.string('menu.toggleDeveloperTool'),
// accelerator: 'Alt+Command+I',
// click: () => {
// this.lastFocusedAppWin.browserWindow.toggleDevTools();
// }
// }] : [{
// label: Lang.string('menu.toggleFullscreen'),
// accelerator: 'Ctrl+Command+F',
// click: () => {
// const lastWindow = this.getLastFocusedWindow();
// lastWindow.browserWindow.setFullScreen(!lastWindow.browserWindow.isFullScreen());
// }
// }]
// },
// {
// label: Lang.string('menu.window'),
// submenu: [{
// label: Lang.string('menu.createNewWindow'),
// accelerator: 'Command+N',
// click: () => {
// this.createMainWindow();
// }
// }, {
// label: Lang.string('menu.minimize'),
// accelerator: 'Command+M',
// selector: 'performMiniaturize:'
// }, {
// label: Lang.string('menu.close'),
// accelerator: 'Command+W',
// selector: 'performClose:'
// }, {
// type: 'separator'
// }, {
// label: Lang.string('menu.bringAllToFront'),
// selector: 'arrangeInFront:'
// }]
// },
// {
// label: Lang.string('menu.help'),
// submenu: [{
// label: Lang.string('menu.website'),
// click: () => {
// shell.openExternal(Lang.string('app.homepage', Config.pkg.homepage));
// }
// }, {
// label: Lang.string('menu.community'),
// click() {
// shell.openExternal('https://www.xuanim.com/forum/');
// }
// }]
// }];
//
// const menu = Menu.buildFromTemplate(template);
// Menu.setApplicationMenu(menu);
//
// if (DEBUG) {
// console.log('>> XuanxuanApp: build application menu.');
// }
// }
get windows() {
return this._windows;
}
buildAppMenu() {
if (!IS_MAC_OSX) {
return;
}
const template = [
{
label: 'ZTF',
submenu: [
{
label: '关于',
selector: 'orderFrontStandardAboutPanel:'
}, {
label: '退出',
accelerator: 'Command+Q',
click: () => {
this.quit();
}
}
]
},
{
label: '编辑',
submenu: [{
label: '撤销',
accelerator: 'Command+Z',
selector: 'undo:'
}, {
label: '重做',
accelerator: 'Shift+Command+Z',
selector: 'redo:'
}, {
type: 'separator'
}, {
label: '剪切',
accelerator: 'Command+X',
selector: 'cut:'
}, {
label: '复制',
accelerator: 'Command+C',
selector: 'copy:'
}, {
label: '黏贴',
accelerator: 'Command+V',
selector: 'paste:'
}, {
label: '选择所有',
accelerator: 'Command+A',
selector: 'selectAll:'
}]
},
{
label: '查看',
submenu: [
{
label: '切换全屏',
accelerator: 'Ctrl+Command+F',
click: () => {
const mainWin = this._windows.get('main');
mainWin.browserWindow.setFullScreen(!mainWin.browserWindow.isFullScreen());
}
}
]
},
{
label: '窗口',
submenu: [
{
label: '最小化',
accelerator: 'Command+M',
selector: 'performMiniaturize:'
},
{
label: '关闭',
accelerator: 'Command+W',
selector: 'performClose:'
},
{
type: 'separator'
},
{
label: '全部置于顶层',
selector: 'arrangeInFront:'
}
]
},
{
label: '帮助',
submenu: [{
label: '网站',
click: () => {
shell.openExternal('http://ztf.im');
}
}]
}];
const menu = Menu.buildFromTemplate(template);
Menu.setApplicationMenu(menu);
logInfo('>> ZtfApp: build application menu.');
}
}
\ No newline at end of file
......@@ -41,8 +41,10 @@ export function startZtfServer() {
}
return new Promise((resolve, reject) => {
const cwd = process.env.SERVER_CWD_PATH || path.dirname(serverExePath);
logInfo(`>> Starting ZTF Server from exe path with command "${serverExePath} -p ${portServer}" in "${cwd}"...`);
const cmd = spawn(serverExePath, ['-p', portServer, "-uuid", uuid], {
logInfo(`>> Starting ZTF Server from exe path with command ` +
`"${serverExePath} -p ${portServer} -uuid ${uuid}" in "${cwd}"...`);
const cmd = spawn(serverExePath, ['-p', portServer, '-uuid', uuid], {
cwd,
shell: true,
});
......@@ -235,8 +237,9 @@ export function killZtfServer() {
if (!isWin) {
logInfo(`>> no windows`);
cmd = `ps -ef | grep ${uuid} | grep -v "\-\-%s" | grep -v "grep" | awk '{print $2}' | xargs kill -9`
cmd = `ps -ef | grep ${uuid} | grep -v "grep" | awk '{print $2}' | xargs kill -9`
logInfo(`kill cmd : ${cmd}`);
const cp = require('child_process');
cp.exec(cmd, function (error, stdout, stderr) {
logInfo(`stdout: ${stdout}; stderr: ${stderr}; error: ${error}`);
......
export const portClient = 55231
export const portServer = 55232
export const uuid = 'ZTF@1CF17A46-B136-4AEB-96B4-F21C8200EF5A~'
......
import TextMap from './text-map';
import {formatString} from './string';
/**
* 语言访问辅助类
*/
export default class LangHelper extends TextMap {
/**
* 创建一个语言访问辅助类对象
* @param {?String} name 语言名称
* @param {?Map<String, String>} langData 语言文本表对象
* @memberof LangHelper
*/
constructor(name, langData) {
super(langData);
this._name = name;
}
/**
* 变更语言名称和语言数据
* @param {String} name 语言名称
* @param {Map<String, String>} langData 语言文本表对象
* @return {void}
* @memberof LangHelper
*/
change(name, langData) {
this._data = langData;
this._name = name;
}
/**
* 获取语言名称
*
* @readonly
* @memberof LangHelper
* @type {String}
*/
get name() {
return this._name;
}
/**
* 获取错误信息对应的语言文本
*
* @param {string|Error} err 错误信息或错误对象本身
* @return {string} 语言文本
*/
error(err) {
if (!err) {
if (DEBUG) {
console.collapse('LANG.error', 'redBg', '<Unknown Error>', 'redPale');
console.error(err);
console.groupEnd();
}
return '<Unknown Error>';
}
if (typeof err === 'string') {
return this.string(err.startsWith('error.') ? err : `error.${err}`, err);
}
if (Array.isArray(err)) {
return err.map(this.error).join(';');
}
let message = '';
if (err.code) {
message += this.string(`error.${err.code}`, `${err.message || ''}[${err.code}]`);
} else if (err.message) {
message = this.string(`error.${err.message}`, err.message);
}
if (message) {
let formatParams = err.formats || err.extras;
if (formatParams) {
if (typeof formatParams === 'object' && !Array.isArray(formatParams)) {
message = formatString(message, formatParams);
} else {
if (!Array.isArray(formatParams)) {
formatParams = [formatParams];
}
message = formatString(message, ...formatParams);
}
}
}
return message;
}
}
import LangHelper from './lang-helper';
/**
* 语言访问辅助对象
* @type {LangHelper}
*/
const langHelper = new LangHelper();
export default langHelper;
......@@ -7,4 +7,6 @@ if (require('electron-squirrel-startup')) { // eslint-disable-line global-requir
}
const ztfApp = new ZtfApp(__dirname);
app.on('ready', ztfApp.ready);
app.on('ready', () => {
ztfApp.ready()
});
......@@ -19,6 +19,7 @@ npm install --save-dev electron-packager
cd ui && yarn build --dest ../client/ui && cd ..
go-bindata -o=res/res.go -pkg=res res/...
make compile_win64
cd client && npm run package-win64 && cd ..
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册