first commit

This commit is contained in:
编码猿
2024-09-27 01:11:00 +08:00
commit ebaaceaa05
122 changed files with 11359 additions and 0 deletions

1
src/module/.pydio Normal file
View File

@@ -0,0 +1 @@
7c8cbb72-6167-4b36-a68b-5f918f18acf2

View File

@@ -0,0 +1 @@
9142ae4e-fbb4-4e6b-b1de-8bc5fbe9de1b

View File

@@ -0,0 +1,20 @@
import { ipcMain } from "electron";
import utils from "../utils/utils";
import { Config } from "../../config/index";
class FileUpload {
/**
* 文件选择的进程处理
*/
upload() {
ipcMain.on('openFile', async (event, arg) => {
// 决定用哪套配置去选择文件
// @ts-ignore
let params = arg == "html" ? Config.FileType.HtmlFileConfig : Config.FileType.PugFileConfig
// 使用系统自带文件选择对话框选中文件,获取选中文件路径
event.returnValue = await utils.OpenDialog(params)
})
}
}
export default new FileUpload();

View File

@@ -0,0 +1,64 @@
import { ipcMain } from "electron";
import utils from "../utils/utils";
import { Config } from "../../config/index";
import { app, BrowserWindow } from "electron";
import SettingWindow from "../../module/ipcMain/SettingWindow";
import MyTouchBar from "../touchbar/action";
import CreatedMenu from "../menu/menu";
import FileIpc from "./FileUpload";
import ThemeChange from "./ThemeChange";
import LoginStart from "./LoginStart";
import WindowAction from "./WindowAction";
class IndexWindow {
public IndexWin: any;
/**
* 创建主页窗口
* @param welcomeWindow
*/
createdWindow(welcomeWindow: any) {
ipcMain.on('openIndexWindow', async (event, arg) => {
this.IndexWin = new BrowserWindow(Config.WindowsConfig);
this.IndexWin.loadFile(Config.StartUpPage);
// 在打开主页前关闭欢迎页,
// 注册各种Ipc
welcomeWindow.close();
this.RegistrationProcess();
this.IndexWin.once('ready-to-show', () => {
this.IndexWin.show()
});
event.returnValue = "success"
})
}
/**
* 注册首页需要的一些Ipc
* @constructor
*/
public RegistrationProcess(): void {
WindowAction.action(this.IndexWin);
// 文件上传主进程
FileIpc.upload();
// 菜单进程
CreatedMenu.buildFromTemplate(this.IndexWin.webContents);
// touchbar进场
this.IndexWin.setTouchBar(MyTouchBar.getMyTouchBarItem(this.IndexWin.webContents));
/**
* 设置页面
*/
// 文件下载监听
utils.downFile(this.IndexWin)
// 创建设置页面
SettingWindow.createdWindow(this.IndexWin);
// 下载新版 ipc
SettingWindow.downVersion(this.IndexWin);
// 订阅macOS的原生的主题切换通知
ThemeChange.MacOsThemeChange();
// 开机自启
LoginStart.openLoginStart();
}
}
export default new IndexWindow();

View File

@@ -0,0 +1,30 @@
import { app, BrowserWindow, ipcMain } from "electron";
import path from "path";
class LoginStart {
openLoginStart() {
ipcMain.on('settingLoginStart', async (event, arg) => {
const appFolder = path.dirname(process.execPath)
const updateExe = path.resolve(appFolder, '..', 'PugToHtml.app')
const exeName = path.basename(process.execPath)
app.setLoginItemSettings({
openAtLogin: arg,
path: updateExe,
args: [
'--processStart', `"${exeName}"`,
'--process-start-args', `"--hidden"`
]
});
event.returnValue = "success"
})
}
}
export default new LoginStart();

View File

@@ -0,0 +1,87 @@
import { ipcMain } from "electron";
import utils from "../utils/utils";
import { Config } from "../../config/index";
import { app, BrowserWindow } from "electron";
import Net from "../../module/net/net";
class SettingWindow {
public SettingWin: any;
constructor() {
this.closedSetting();
this.check();
this.getVersion();
}
createdWindow(parentWindow: any) {
ipcMain.on('openWindow', async (event, arg) => {
// @ts-ignore
Config.SettingWindow.parent = parentWindow;
this.SettingWin = new BrowserWindow(Config.SettingWindow);
// @ts-ignore
this.SettingWin.loadFile(Config.SettingPage);
this.SettingWin.once('ready-to-show', () => {
this.SettingWin.show()
});
// setting.webContents.openDevTools();
event.returnValue = "success"
})
}
/**
* 下载最新版 被点击
* @param indexWindow
*/
downVersion(indexWindow: any) {
ipcMain.on('downVersion', async (event, arg) => {
let SavePath = await utils.SaveDialog(this.SettingWin, {
title: '下载提示',
message: '请选择软件的保存路径',
filters: [
{ name: 'All', extensions: ['*'] },
],
properties: ['openDirectory']
});
if(!SavePath.canceled) {
Config.TemporarySavePath = SavePath.filePath;
indexWindow.webContents.downloadURL(arg);
}
event.returnValue = "success";
})
}
/**
* 检测更新 被点击
*/
check() {
ipcMain.on('update', async (event, arg) => {
event.returnValue = await Net.get(`${Config.UpdateUrl}${Config.currentVersion}`)
})
}
/**
* 获取客户端默认版本号
*/
getVersion () {
ipcMain.on("getVersion", async (event, arg) => {
event.returnValue = Config.currentVersion;
})
}
/**
* 关闭设置页面
*/
closedSetting() {
ipcMain.on('closedWindow', async (event) => {
this.SettingWin.close();
event.returnValue = "success"
})
}
}
export default new SettingWindow();

View File

@@ -0,0 +1,23 @@
import { systemPreferences, nativeTheme} from "electron"
import {Config} from "@/config";
import { ipcMain } from "electron";
class ThemeChange {
MacOsThemeChange(): void {
ipcMain.on('getCurrentTheme', async (event, arg) => {
event.returnValue = nativeTheme.shouldUseDarkColors
});
// systemPreferences.subscribeNotification(
// 'AppleInterfaceThemeChangedNotification',
// function theThemeHasChanged () {
// console.log("主题切换的时候自动触发: ", nativeTheme.shouldUseDarkColors);
// webContents.send('updateAppTheme', nativeTheme.shouldUseDarkColors)
// }
// );
}
}
export default new ThemeChange()

View File

@@ -0,0 +1,23 @@
import { app, ipcMain} from "electron";
class WindowAction {
/**
* 自定义窗口关闭,最小化,最大化
* @param win
*/
action(win: any) {
ipcMain.on('min', e=> win.minimize());
ipcMain.on('max', e=> {
if (win.isMaximized()) {
win.unmaximize()
} else {
win.maximize()
}
});
ipcMain.on('close', e=> win.close());
}
}
export default new WindowAction();

1
src/module/menu/.pydio Normal file
View File

@@ -0,0 +1 @@
1d19ec12-3481-4e0f-87c5-e95b004cfe00

115
src/module/menu/menu.ts Normal file
View File

@@ -0,0 +1,115 @@
import utils from "../utils/utils";
import { Config} from "../../config";
import {app, Menu, shell} from "electron";
export class CreatedMenu {
private webContents: any;
private templateMenu = [
{
label: app.name,
submenu: [
{ label: `关于 ${app.name}`, role: 'about' },
{ type: 'separator' },
{ label: '服务', role: 'services' },
{ type: 'separator' },
{ label: `隐藏 ${app.name}`, role: 'hide' },
{ role: 'hideothers' },
{ label: '隐藏其他', role: 'unhide' },
{ type: 'separator' },
{ label: `退出${app.name}`, role: 'quit' }
]
},
{
label: '文件',
submenu: [
{
label: '打开Html文件',
role: 'open',
click: async () => {
// @ts-ignore
this.webContents.send('TouchBarHtmlFileChoice', await utils.OpenDialog(Config.FileType.HtmlFileConfig))
}
},
{
label: '打开Pug/Jade文件',
role: 'open',
click: async () => {
// @ts-ignore
this.webContents.send('TouchBarPugFileChoice', await utils.OpenDialog(Config.FileType.PugFileConfig))
}
}
]
},
{
label: '编辑',
submenu: [
{ label: '撤销', role: 'undo' },
{ label: '恢复', role: 'redo' },
{type: 'separator' },
{ label: '剪切', role: 'cut' },
{ label: '复制', role: 'copy' },
{ label: '粘贴', role: 'paste' },
{type: 'separator' },
{ label: '粘贴保留样式', role: 'pasteAndMatchStyle' },
{ label: '删除', role: 'delete' },
{ label: '全选', role: 'selectAll' },
{ type: 'separator' },
{
label: '听写',
submenu: [
{ label: '开始听写', role: 'startspeaking' },
{ label: '停止听写', role: 'stopspeaking' }
]
}
]
},
{
label: '视图',
submenu: [
{ label: '刷新', role: 'reload' },
{ label: '重置', role: 'resetzoom' },
{ label: '放大', role: 'zoomin' },
{ label: '缩小', role: 'zoomout' },
{ type: 'separator' },
{ label: '全屏', role: 'togglefullscreen' },
{ label: '切换开发人员工具', role: 'toggledevtools' },
]
},
{
label: '窗口',
submenu: [
{ label: '最小化', role: 'minimize' },
{ label: '最大化',role: 'zoom' },
{ label: '关闭', role: 'close' }
]
},
{
label: '帮助',
role: 'help',
submenu: [
{
label: '了解更多',
click: async () => {
await shell.openExternal('https://electronjs.org')
}
},
{
label: 'GitHub主页',
click: async () => {
await shell.openExternal(Config.Github)
}
}
]
}
]
buildFromTemplate(webContents: any) {
this.webContents = webContents;
// @ts-ignore
const successMenu = Menu.buildFromTemplate(this.templateMenu)
Config.isMac ? Menu.setApplicationMenu(successMenu) : Menu.setApplicationMenu(null)
}
}
export default new CreatedMenu();

1
src/module/net/.pydio Normal file
View File

@@ -0,0 +1 @@
d2c2d259-d7d0-434f-a815-33788aba5037

32
src/module/net/net.ts Normal file
View File

@@ -0,0 +1,32 @@
import { net } from "electron";
import utils from "../utils/utils";
class Net {
get(Url: string): Promise<any> {
const request = net.request({
method: 'GET',
url: Url
});
return new Promise((resolve, reject) => {
request.on('response', (response) => {
response.on('data', (chunk) => {
resolve(chunk.toString())
});
response.on('error', (error: any) => {
utils.showErrorBox({ title: 'error', content: JSON.stringify(error)});
});
response.on('end', () => {
console.log('No more data in response.')
});
});
request.end();
})
}
}
export default new Net();

View File

@@ -0,0 +1 @@
8ff0f184-659e-4a7b-a9c1-7ff24d6bdd15

View File

@@ -0,0 +1,52 @@
import { app, BrowserWindow, TouchBar, dialog, shell } from "electron";
const { TouchBarLabel, TouchBarButton,TouchBarSpacer } = TouchBar;
import utils from "../utils/utils";
import { Config } from "../../config";
// 主要负责创建 TouchBar 的类
class MyTouchBar {
constructor() {
this.setTouchBarButton()
}
// @ts-ignore
setTouchBarButton(title?: string, callback?: any): TouchBarButton {
return new TouchBarButton({
label: title,
backgroundColor: '#3a3a3c',
click: () => callback()
});
}
/**
* touchbar 触控栏按钮
* @param webContents 主进程传递过来的 webContents
* touchbar上按钮被点击后会调用webContents推送主进程数据到渲染进程
*/
getMyTouchBarItem(webContents: any): TouchBar {
return new TouchBar({
items: [
new TouchBarSpacer({ size: 'small' }),
this.setTouchBarButton("打开HTML文件", async () => {
// @ts-ignore
webContents.send('TouchBarHtmlFileChoice', await utils.OpenDialog(Config.FileType.HtmlFileConfig))
}),
new TouchBarSpacer({ size: 'small' }),
this.setTouchBarButton("打开Pug文件", async () => {
// @ts-ignore
webContents.send('TouchBarPugFileChoice', await utils.OpenDialog(Config.FileType.PugFileConfig))
}),
new TouchBarSpacer({ size: 'small' }),
this.setTouchBarButton("字体设置", function () {
dialog.showErrorBox("字体设置", "内容")
}),
new TouchBarSpacer({ size: 'small' }),
this.setTouchBarButton("关于作者", async () => {
await shell.openExternal(Config.Github)
})
]
});
}
}
export default new MyTouchBar();

1
src/module/utils/.pydio Normal file
View File

@@ -0,0 +1 @@
7bd4b7f8-8e63-4c3c-a494-2a124df7deb0

83
src/module/utils/utils.ts Normal file
View File

@@ -0,0 +1,83 @@
import { dialog, Notification } from "electron";
import { readFile } from "fs";
import { Config } from "../../config/index";
import { join } from "path";
class utils {
/**
* 打开弹窗获取用户选中文件路径
* 并调用 ReadFile 方法获取文件内容
* @param params Object 弹窗的参数配置
* @constructor
*/
async OpenDialog(params: Object): Promise<String>{
return await this.ReadFile((await dialog.showOpenDialog(params)).filePaths[0]);
}
async SaveDialog(parent: any,params: Object): Promise<any> {
return await dialog.showSaveDialog(params);
}
async showErrorBox(params: { title: string, content: string }): Promise<void> {
await dialog.showErrorBox(params.title, params.content);
}
/**
* 读取指定路径的文件内容
* @param path string 路径地址
*/
async ReadFile(path: string): Promise<any> {
if(path != undefined ) {
return new Promise((resolve,reject)=>{
readFile(path, 'utf-8', function (err, data) {
if (err) {
reject(err)
}
resolve(data.toString());
});
})
} else {
this.showErrorBox({ title: '错误', content: '您未选择任何文件,请选择!' })
}
}
downFile(windows: any): void {
windows.webContents.session.on('will-download', (event: any, item: any, webContents: any) => {
item.setSavePath(`${Config.TemporarySavePath}/${item.getFilename()}`);
item.on('updated', (event: any, state: any) => {
if (state === 'interrupted') {
console.log('下载被中断,但可以继续')
} else if (state === 'progressing') {
// 显示进度条
windows.setProgressBar(item.getReceivedBytes() / item.getTotalBytes())
if (item.isPaused()) {
console.log('下载已暂停')
} else {
}
}
});
item.once('done', (event: any, state: any) => {
if (state === 'completed') {
// 下载成功后显示通知
let not = new Notification({
title: '下载提示',
body: `文件 ${item.getFilename()} 已成功下载,请及时安装!!`,
silent: true,
icon: join(__dirname,'../../view/assets/img/pic.png'),
sound: join(__dirname, '../../view/assets/audio/Ping.aiff')
});
not.show();
windows.setProgressBar(-1);
} else {
console.log(`下载失败: ${state}`)
}
})
})
}
}
export default new utils();