mirror of
https://github.com/HighCapable/YukiHookAPI-ProjectBuilder.git
synced 2025-09-06 10:45:38 +08:00
Initial commit
This commit is contained in:
384
src/app-space.js
Normal file
384
src/app-space.js
Normal file
@@ -0,0 +1,384 @@
|
||||
/*
|
||||
* 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};
|
Reference in New Issue
Block a user