app.js 6.5 KB
Newer Older
aaronchen2k2k's avatar
aaronchen2k2k 已提交
1
import {app, BrowserWindow, Menu, shell} from 'electron';
aaronchen2k2k's avatar
aaronchen2k2k 已提交
2
import main from "@electron/remote/main";
3

aaronchen2k2k's avatar
aaronchen2k2k 已提交
4
import {DEBUG} from './utils/consts';
aaronchen2k2k's avatar
aaronchen2k2k 已提交
5
import {IS_MAC_OSX} from './utils/env';
aaronchen2k2k's avatar
i118  
aaronchen2k2k 已提交
6
import Lang, {initLang} from './core/lang';
aaronchen2k2k's avatar
aaronchen2k2k 已提交
7
import {logInfo, logErr} from './utils/log';
aaronchen2k2k's avatar
aaronchen2k2k 已提交
8 9
import {startUIService} from "./core/ui";
import {startZtfServer, killZtfServer} from "./core/ztf";
10 11

export default class ZtfApp {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
12
    constructor() {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
13
        this._windows = new Map();
14

aaronchen2k2k's avatar
aaronchen2k2k 已提交
15 16 17 18 19
        startZtfServer().then((ztfServerUrl)=> {
            logInfo(`>> ztf server started successfully on : ${ztfServerUrl}`);
            this.bindElectronEvents();
        }).catch((err) => {
            logErr('>> ztf server started failed, err: ' + error);
aaronchen2k2k's avatar
aaronchen2k2k 已提交
20
            process.exit(1);
aaronchen2k2k's avatar
aaronchen2k2k 已提交
21
            return;
aaronchen2k2k's avatar
aaronchen2k2k 已提交
22
        })
23 24 25
    }

    showAndFocus() {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
26
        logInfo(`>> ztf app: AppWindow[${this.name}]: show and focus`);
27 28 29 30 31 32 33 34 35 36 37

        const {browserWindow} = this;
        if (browserWindow.isMinimized()) {
            browserWindow.restore();
        } else {
            browserWindow.setOpacity(1);
            browserWindow.show();
        }
        browserWindow.focus();
    }

aaronchen2k2k's avatar
i118  
aaronchen2k2k 已提交
38
    async createWindow() {
39 40
        process.env['ELECTRON_DISABLE_SECURITY_WARNINGS'] = 'true';

aaronchen2k2k's avatar
aaronchen2k2k 已提交
41 42
        const remoteMain = require('@electron/remote/main')
        remoteMain.initialize()
43

aaronchen2k2k's avatar
i118  
aaronchen2k2k 已提交
44
        const mainWin = new BrowserWindow({
45 46 47
            show: false,
            webPreferences: {nodeIntegration: true, contextIsolation: false}
        })
aaronchen2k2k's avatar
aaronchen2k2k 已提交
48
        remoteMain.enable(mainWin.webContents)
49

aaronchen2k2k's avatar
i118  
aaronchen2k2k 已提交
50 51
        mainWin.maximize()
        mainWin.show()
52

aaronchen2k2k's avatar
i118  
aaronchen2k2k 已提交
53
        this._windows.set('main', mainWin.l);
aaronchen2k2k's avatar
aaronchen2k2k 已提交
54

aaronchen2k2k's avatar
aaronchen2k2k 已提交
55
        const url = await startUIService()
aaronchen2k2k's avatar
i118  
aaronchen2k2k 已提交
56
        await mainWin.loadURL(url);
aaronchen2k2k's avatar
aaronchen2k2k 已提交
57 58 59 60

        if (DEBUG) {
            mainWin.webContents.openDevTools({mode: 'bottom'});
        }
61 62
    };

aaronchen2k2k's avatar
aaronchen2k2k 已提交
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
    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();
    }

aaronchen2k2k's avatar
i118  
aaronchen2k2k 已提交
82
    async ready() {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
83
        logInfo('>> ztf app ready.');
aaronchen2k2k's avatar
i118  
aaronchen2k2k 已提交
84 85

        initLang()
aaronchen2k2k's avatar
aaronchen2k2k 已提交
86 87 88 89 90 91 92 93
        this.openOrCreateWindow();
        this.buildAppMenu();
    }

    quit() {
        killZtfServer();
    }

94 95
    bindElectronEvents() {
        app.on('window-all-closed', () => {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
96
            logInfo(`>> event: window-all-closed`)
97 98 99 100
            app.quit();
        });

        app.on('quit', () => {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
101
            logInfo(`>> event: quit`)
aaronchen2k2k's avatar
aaronchen2k2k 已提交
102
            this.quit();
103 104 105
        });

        app.on('activate', () => {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
106
            logInfo('>> event: activate');
107 108 109

            // 在 OS X 系统上,可能存在所有应用窗口关闭了,但是程序还没关闭,此时如果收到激活应用请求需要
            // 重新打开应用窗口并创建应用菜单
aaronchen2k2k's avatar
aaronchen2k2k 已提交
110 111
            this.openOrCreateWindow();
            this.buildAppMenu();
112 113 114
        });
    }

aaronchen2k2k's avatar
aaronchen2k2k 已提交
115 116 117 118 119
    get windows() {
        return this._windows;
    }

    buildAppMenu() {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
120
        logInfo('>> ztf app: build application menu.');
aaronchen2k2k's avatar
i118  
aaronchen2k2k 已提交
121

aaronchen2k2k's avatar
aaronchen2k2k 已提交
122 123 124 125 126 127 128 129 130
        if (!IS_MAC_OSX) {
            return;
        }

        const template = [
            {
                label: 'ZTF',
                submenu: [
                    {
aaronchen2k2k's avatar
i118  
aaronchen2k2k 已提交
131
                        label: Lang.string('app.about'),
aaronchen2k2k's avatar
aaronchen2k2k 已提交
132 133
                        selector: 'orderFrontStandardAboutPanel:'
                    }, {
aaronchen2k2k's avatar
i118  
aaronchen2k2k 已提交
134
                        label: Lang.string('app.exit'),
aaronchen2k2k's avatar
aaronchen2k2k 已提交
135 136
                        accelerator: 'Command+Q',
                        click: () => {
aaronchen2k2k's avatar
i118  
aaronchen2k2k 已提交
137
                            app.quit();
aaronchen2k2k's avatar
aaronchen2k2k 已提交
138 139 140 141 142
                        }
                    }
                ]
            },
            {
aaronchen2k2k's avatar
i118  
aaronchen2k2k 已提交
143
                label: Lang.string('app.edit'),
aaronchen2k2k's avatar
aaronchen2k2k 已提交
144
                submenu: [{
aaronchen2k2k's avatar
i118  
aaronchen2k2k 已提交
145
                    label: Lang.string('app.undo'),
aaronchen2k2k's avatar
aaronchen2k2k 已提交
146 147 148
                    accelerator: 'Command+Z',
                    selector: 'undo:'
                }, {
aaronchen2k2k's avatar
i118  
aaronchen2k2k 已提交
149
                    label: Lang.string('app.redo'),
aaronchen2k2k's avatar
aaronchen2k2k 已提交
150 151 152 153 154
                    accelerator: 'Shift+Command+Z',
                    selector: 'redo:'
                }, {
                    type: 'separator'
                }, {
aaronchen2k2k's avatar
i118  
aaronchen2k2k 已提交
155
                    label: Lang.string('app.cut'),
aaronchen2k2k's avatar
aaronchen2k2k 已提交
156 157 158
                    accelerator: 'Command+X',
                    selector: 'cut:'
                }, {
aaronchen2k2k's avatar
i118  
aaronchen2k2k 已提交
159
                    label: Lang.string('app.copy'),
aaronchen2k2k's avatar
aaronchen2k2k 已提交
160 161 162
                    accelerator: 'Command+C',
                    selector: 'copy:'
                }, {
aaronchen2k2k's avatar
i118  
aaronchen2k2k 已提交
163
                    label: Lang.string('app.paste'),
aaronchen2k2k's avatar
aaronchen2k2k 已提交
164 165 166
                    accelerator: 'Command+V',
                    selector: 'paste:'
                }, {
aaronchen2k2k's avatar
i118  
aaronchen2k2k 已提交
167
                    label: Lang.string('app.select_all'),
aaronchen2k2k's avatar
aaronchen2k2k 已提交
168 169 170 171 172
                    accelerator: 'Command+A',
                    selector: 'selectAll:'
                }]
            },
            {
aaronchen2k2k's avatar
i118  
aaronchen2k2k 已提交
173
                label: Lang.string('app.view'),
aaronchen2k2k's avatar
aaronchen2k2k 已提交
174 175
                submenu:  [
                    {
aaronchen2k2k's avatar
i118  
aaronchen2k2k 已提交
176
                        label: Lang.string('app.switch_to_full_screen'),
aaronchen2k2k's avatar
aaronchen2k2k 已提交
177 178 179 180 181 182 183 184 185
                        accelerator: 'Ctrl+Command+F',
                        click: () => {
                            const mainWin = this._windows.get('main');
                            mainWin.browserWindow.setFullScreen(!mainWin.browserWindow.isFullScreen());
                        }
                    }
                ]
            },
            {
aaronchen2k2k's avatar
i118  
aaronchen2k2k 已提交
186
                label: Lang.string('app.window'),
aaronchen2k2k's avatar
aaronchen2k2k 已提交
187 188
                submenu: [
                    {
aaronchen2k2k's avatar
i118  
aaronchen2k2k 已提交
189
                        label: Lang.string('app.minimize'),
aaronchen2k2k's avatar
aaronchen2k2k 已提交
190 191 192 193
                        accelerator: 'Command+M',
                        selector: 'performMiniaturize:'
                    },
                    {
aaronchen2k2k's avatar
i118  
aaronchen2k2k 已提交
194
                        label: Lang.string('app.close'),
aaronchen2k2k's avatar
aaronchen2k2k 已提交
195 196 197 198 199 200 201
                        accelerator: 'Command+W',
                        selector: 'performClose:'
                    },
                    {
                        type: 'separator'
                    },
                    {
aaronchen2k2k's avatar
i118  
aaronchen2k2k 已提交
202
                        label: Lang.string('app.bring_all_to_front'),
aaronchen2k2k's avatar
aaronchen2k2k 已提交
203 204 205 206 207
                        selector: 'arrangeInFront:'
                    }
                ]
            },
            {
aaronchen2k2k's avatar
i118  
aaronchen2k2k 已提交
208
                label: Lang.string('app.help'),
aaronchen2k2k's avatar
aaronchen2k2k 已提交
209
                submenu: [{
aaronchen2k2k's avatar
i118  
aaronchen2k2k 已提交
210
                    label: Lang.string('app.website'),
aaronchen2k2k's avatar
aaronchen2k2k 已提交
211 212 213 214 215 216 217 218 219
                    click: () => {
                        shell.openExternal('http://ztf.im');
                    }
                }]
            }];

        const menu = Menu.buildFromTemplate(template);
        Menu.setApplicationMenu(menu);
    }
220
}