mirror of
https://github.com/HighCapable/YukiHookAPI-ProjectBuilder.git
synced 2025-09-04 09:45:36 +08:00
384 lines
14 KiB
JavaScript
384 lines
14 KiB
JavaScript
/*
|
|
* YukiHookAPI Project Builder - A Xposed Project Builder by YukiHookAPI.
|
|
* Copyright (C) 2019-2022 HighCapable
|
|
* https://github.com/fankes/YukiHookAPI-ProjectBuilder
|
|
*
|
|
* This software is non-free but opensource software: you can redistribute it
|
|
* and/or modify it under the terms of the GNU Affero General Public License
|
|
* as published by the Free Software Foundation; either
|
|
* version 3 of the License, or any later version.
|
|
*
|
|
* This software is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Affero General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Affero General Public License
|
|
* and eula along with this software. If not, see
|
|
* <https://www.gnu.org/licenses/>
|
|
*
|
|
* This file is Created by fankes on 2022/7/21.
|
|
*/
|
|
|
|
const {app, ipcMain, dialog, BrowserWindow, Menu, MenuItem} = require('electron');
|
|
const {locale} = require('./libs/locale');
|
|
const {fileSystem} = require('./libs/file-system');
|
|
const {store} = require('./libs/store');
|
|
const {system} = require("./libs/system");
|
|
|
|
/** 主窗口 */
|
|
let mainWindow = null;
|
|
|
|
/**
|
|
* 应用程序初始化命名空间
|
|
*/
|
|
const appSpace = {
|
|
/** 开始装载窗口 */
|
|
loadFrame: () => {
|
|
appSpace.createWindow();
|
|
appSpace.createMenu();
|
|
},
|
|
/** 创建窗口 */
|
|
createWindow: () => {
|
|
mainWindow = new BrowserWindow({
|
|
title: locale.i18n.windowTitle,
|
|
width: 1000,
|
|
height: 1050,
|
|
resizable: false,
|
|
maximizable: false,
|
|
show: false,
|
|
webPreferences: {
|
|
nodeIntegration: true,
|
|
contextIsolation: false
|
|
}
|
|
});
|
|
mainWindow.loadFile('src/content/index.html').then(() => {
|
|
appWindow.webContents.methods.page.init(localeConfig.currentLocale(), app.getVersion());
|
|
});
|
|
mainWindow.once('ready-to-show', () => {
|
|
mainWindow.show();
|
|
});
|
|
},
|
|
/** 创建菜单 */
|
|
createMenu: () => {
|
|
const menu = new Menu();
|
|
const separatorItem = new MenuItem({type: 'separator'});
|
|
const aboutChildItem = new MenuItem({
|
|
label: locale.i18n.about,
|
|
accelerator: system.isMacOS ? 'command+a' : 'ctrl+a',
|
|
click: () => {
|
|
appWindow.webContents.methods.page.showAbout(app.getName(), app.getVersion());
|
|
}
|
|
});
|
|
const checkUpdateChildItem = new MenuItem({
|
|
label: locale.i18n.checkUpdate,
|
|
click: () => {
|
|
appWindow.webContents.methods.page.checkForUpdates();
|
|
}
|
|
});
|
|
const projectAddressChildItem = new MenuItem({
|
|
label: locale.i18n.projectAddress,
|
|
accelerator: system.isMacOS ? 'command+w' : 'ctrl+w',
|
|
click: () => {
|
|
system.openBrowser('https://github.com/fankes/YukiHookAPI');
|
|
}
|
|
});
|
|
const helpDocumentationChildItem = new MenuItem({
|
|
label: locale.i18n.helpDocumentation,
|
|
accelerator: system.isMacOS ? 'command+h' : 'ctrl+h',
|
|
click: () => {
|
|
system.openBrowser('https://fankes.github.io/YukiHookAPI');
|
|
}
|
|
});
|
|
const openSourceChildItem = new MenuItem({
|
|
label: locale.i18n.openSource,
|
|
accelerator: system.isMacOS ? 'command+o' : 'ctrl+o',
|
|
click: () => {
|
|
appWindow.webContents.methods.page.showOpenSource();
|
|
}
|
|
});
|
|
const laguageSubChildItems = [];
|
|
laguageSubChildItems.push(new MenuItem({
|
|
type: 'radio',
|
|
label: locale.i18n.followSystem,
|
|
checked: localeConfig.isFollowSystem,
|
|
click: () => {
|
|
localeConfig.changeLocale();
|
|
}
|
|
}));
|
|
for (const la in locale.languageSupports)
|
|
laguageSubChildItems.push(new MenuItem({
|
|
type: 'radio',
|
|
label: locale.languageSupports[la],
|
|
checked: la === locale.name && !localeConfig.isFollowSystem,
|
|
click: () => {
|
|
localeConfig.changeLocale(la);
|
|
}
|
|
}));
|
|
const languageChildItem = new MenuItem({
|
|
label: locale.i18n.language + ' (Language)',
|
|
submenu: laguageSubChildItems
|
|
});
|
|
const quitChildItem = new MenuItem({
|
|
label: locale.i18n.quit,
|
|
accelerator: system.isMacOS ? 'command+q' : 'ctrl+q',
|
|
click: () => {
|
|
app.quit();
|
|
}
|
|
});
|
|
const runBuildChildItem = new MenuItem({
|
|
label: locale.i18n.runBuild,
|
|
accelerator: system.isMacOS ? 'command+b' : 'ctrl+b',
|
|
click: () => {
|
|
appWindow.webContents.methods.build.checking();
|
|
}
|
|
});
|
|
const newTemplateChildItem = new MenuItem({
|
|
label: locale.i18n.newTemplate,
|
|
accelerator: system.isMacOS ? 'command+n' : 'ctrl+n',
|
|
click: () => {
|
|
appWindow.webContents.methods.configTemplate.createNew();
|
|
}
|
|
});
|
|
const templateSubChildItems = [];
|
|
const clearAllTemplateChildItem = new MenuItem({
|
|
label: locale.i18n.clearAllTemplate,
|
|
accelerator: system.isMacOS ? 'command+d' : 'ctrl+d',
|
|
click: () => {
|
|
appWindow.webContents.methods.configTemplate.clearAll();
|
|
}
|
|
});
|
|
const templates = store.get('config-templates', []);
|
|
if (templates.length > 0) {
|
|
templates.forEach((value) => {
|
|
templateSubChildItems.push(new MenuItem({
|
|
label: value.name,
|
|
click: () => {
|
|
appWindow.webContents.methods.configTemplate.load(value);
|
|
}
|
|
}));
|
|
});
|
|
templateSubChildItems.push(separatorItem);
|
|
templateSubChildItems.push(clearAllTemplateChildItem);
|
|
} else templateSubChildItems.push(new MenuItem({
|
|
label: locale.i18n.nothing,
|
|
enabled: false
|
|
}));
|
|
const savedTemplateChildItem = new MenuItem({
|
|
label: locale.i18n.savedTemplate,
|
|
submenu: templateSubChildItems
|
|
});
|
|
const configTemplateChildItem = new MenuItem({
|
|
label: locale.i18n.configTemplate,
|
|
submenu: [newTemplateChildItem, savedTemplateChildItem]
|
|
});
|
|
const resetCurrentConfigChildItem = new MenuItem({
|
|
label: locale.i18n.resetCurrentConfig,
|
|
accelerator: system.isMacOS ? 'command+r' : 'ctrl+r',
|
|
click: () => {
|
|
appWindow.webContents.methods.page.restore();
|
|
}
|
|
});
|
|
const fileMainItem = new MenuItem({
|
|
label: system.isMacOS ? app.name : locale.i18n.file,
|
|
submenu: system.isMacOS ? [aboutChildItem, separatorItem, checkUpdateChildItem, separatorItem,
|
|
projectAddressChildItem, helpDocumentationChildItem, separatorItem, openSourceChildItem, separatorItem,
|
|
languageChildItem, separatorItem, quitChildItem] : [languageChildItem, separatorItem, quitChildItem]
|
|
});
|
|
const projectMainItem = new MenuItem({
|
|
label: locale.i18n.project,
|
|
submenu: [runBuildChildItem, separatorItem, configTemplateChildItem, resetCurrentConfigChildItem]
|
|
});
|
|
const helpMainItem = new MenuItem({
|
|
label: (locale.i18n.help),
|
|
submenu: [aboutChildItem, separatorItem, checkUpdateChildItem, separatorItem,
|
|
projectAddressChildItem, helpDocumentationChildItem, separatorItem, openSourceChildItem]
|
|
});
|
|
menu.append(fileMainItem);
|
|
menu.append(projectMainItem);
|
|
if (!system.isMacOS) menu.append(helpMainItem);
|
|
Menu.setApplicationMenu(menu);
|
|
},
|
|
/**
|
|
* 注册 ipc 监听
|
|
* @param option 回调选项
|
|
*/
|
|
registerIpcListener: (option) => {
|
|
ipcMain.on('run-packaging-project', (_, configs) => {
|
|
option['run-packaging-project'](configs);
|
|
});
|
|
ipcMain.on('open-complete-project', () => {
|
|
option['open-complete-project']();
|
|
});
|
|
ipcMain.on('save-config-template', (_, configs) => {
|
|
const templates = store.get('config-templates', []);
|
|
templates.push(configs);
|
|
store.set('config-templates', templates);
|
|
appSpace.createMenu();
|
|
});
|
|
ipcMain.on('clear-all-config-template', () => {
|
|
store.set('config-templates', []);
|
|
appSpace.createMenu();
|
|
});
|
|
ipcMain.on('reload-current-page', () => {
|
|
setTimeout(() => {
|
|
mainWindow.reload();
|
|
appWindow.webContents.methods.page.init(localeConfig.currentLocale(), app.getVersion());
|
|
}, 150);
|
|
});
|
|
ipcMain.on('relaunch-app', () => {
|
|
mainWindow.close();
|
|
app.relaunch();
|
|
});
|
|
ipcMain.on('open-system-browser', (_, url) => {
|
|
system.openBrowser(url);
|
|
});
|
|
}
|
|
};
|
|
|
|
/**
|
|
* 应用程序配置命名空间
|
|
*/
|
|
const appConfig = {
|
|
/**
|
|
* 项目根路径
|
|
* @return string
|
|
*/
|
|
sourcePath: app.isPackaged ? app.getAppPath() : '.',
|
|
/**
|
|
* 项目外部路径
|
|
* @return string
|
|
*/
|
|
dataPath: fileSystem.path(app.getPath('appData'), 'YukiHookAPI'),
|
|
/** 创建应用数据目录 */
|
|
createDataDir: () => {
|
|
const dataPath = appConfig.dataPath;
|
|
if (!fileSystem.exists(dataPath)) fileSystem.mkdir(dataPath);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* 语言区域配置命名空间
|
|
*/
|
|
const localeConfig = {
|
|
/**
|
|
* 语言是否跟随系统
|
|
* @return boolean
|
|
*/
|
|
isFollowSystem: store.get('locale-follow-system', true),
|
|
/**
|
|
* 当前存储的语言名称
|
|
* @return string
|
|
*/
|
|
storeLocaleName: store.get('store-locale-name', locale.default),
|
|
/**
|
|
* 获取当前语言区域名称
|
|
* @return string
|
|
*/
|
|
currentLocale: () => {
|
|
return localeConfig.isFollowSystem ? app.getLocale() : localeConfig.storeLocaleName;
|
|
},
|
|
/**
|
|
* 修改语言
|
|
* @param name 语言名称
|
|
*/
|
|
changeLocale: (name = 'default') => {
|
|
if (name === 'default') {
|
|
store.set('locale-follow-system', true);
|
|
store.set('store-locale-name', locale.default);
|
|
} else {
|
|
store.set('locale-follow-system', false);
|
|
store.set('store-locale-name', name);
|
|
}
|
|
appWindow.webContents.methods.page.relaunch();
|
|
}
|
|
};
|
|
|
|
/**
|
|
* 应用程序窗口命名空间
|
|
*/
|
|
const appWindow = {
|
|
/**
|
|
* 打开目录
|
|
* @param option 选项
|
|
* @param callback 回调结果
|
|
* @param onError 回调错误
|
|
*/
|
|
showOpenDirectory: (option, callback, onError) => {
|
|
dialog.showOpenDialog(mainWindow, {
|
|
properties: ['openDirectory'],
|
|
title: option['title'],
|
|
message: option['message'],
|
|
buttonLabel: option['buttonLabel']
|
|
}).then(result => {
|
|
callback(result);
|
|
}).catch((e) => {
|
|
onError(e);
|
|
});
|
|
},
|
|
/** 窗口内网页交互调用桥 */
|
|
webContents: {
|
|
/**
|
|
* 执行内部 JS
|
|
* @param code 执行代码
|
|
*/
|
|
execJs: (code) => {
|
|
mainWindow.webContents.executeJavaScript(code).then(() => null);
|
|
},
|
|
methods: {
|
|
configTemplate: {
|
|
load: (configs) => {
|
|
appWindow.webContents.execJs('configTemplate.load(\'' + encodeURI(JSON.stringify(configs)) + '\')');
|
|
},
|
|
createNew: () => {
|
|
appWindow.webContents.execJs('configTemplate.createNew()');
|
|
},
|
|
clearAll: () => {
|
|
appWindow.webContents.execJs('configTemplate.clearAll()');
|
|
}
|
|
},
|
|
page: {
|
|
init: (localeName, appVersion) => {
|
|
appWindow.webContents.execJs('page.init(\'' + localeName + '\',\'' + appVersion + '\')');
|
|
},
|
|
snack: (message) => {
|
|
appWindow.webContents.execJs('page.snack(\'' + message + '\')');
|
|
},
|
|
showAbout: (name, version) => {
|
|
appWindow.webContents.execJs('page.showAbout(\'' + name + '\',\'' + version + '\')');
|
|
},
|
|
showOpenSource: () => {
|
|
appWindow.webContents.execJs('page.showOpenSource()');
|
|
},
|
|
checkForUpdates: () => {
|
|
appWindow.webContents.execJs('page.checkForUpdates()');
|
|
},
|
|
restore: () => {
|
|
appWindow.webContents.execJs('page.restore()');
|
|
},
|
|
relaunch: () => {
|
|
appWindow.webContents.execJs('page.relaunch()');
|
|
}
|
|
},
|
|
build: {
|
|
checking: () => {
|
|
appWindow.webContents.execJs('build.checking()');
|
|
},
|
|
changeStatus: (msg) => {
|
|
appWindow.webContents.execJs('build.changeStatus(\'' + msg + '\')');
|
|
},
|
|
complete: (msg) => {
|
|
appWindow.webContents.execJs('build.complete(\'' + msg + '\')');
|
|
},
|
|
failure: (msg) => {
|
|
appWindow.webContents.execJs('build.failure(\'' + msg + '\')');
|
|
},
|
|
cancel: () => {
|
|
appWindow.webContents.execJs('build.cancel()');
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
module.exports = {appSpace, appWindow, appConfig, localeConfig}; |