update dependencies
This commit is contained in:
1 parent
3de6903594
commit
d251c7914e
22 files changed
+3717
-390
No files matched your search
Vendored
+16
-15
@@ -1,23 +1,24 @@
|
||||
import fs from 'node:fs'
|
||||
import path from 'node:path'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import { createRequire } from 'node:module'
|
||||
import { spawn } from 'node:child_process'
|
||||
import { spawn } from "node:child_process";
|
||||
import fs from "node:fs";
|
||||
import { createRequire } from "node:module";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
const pkg = createRequire(import.meta.url)('../package.json')
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
||||
const pkg = createRequire(import.meta.url)("../package.json");
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
// write .debug.env
|
||||
const envContent = Object.entries(pkg.debug.env).map(([key, val]) => `${key}=${val}`)
|
||||
fs.writeFileSync(path.join(__dirname, '.debug.env'), envContent.join('\n'))
|
||||
const envContent = Object.entries(pkg.debug.env).map(([key, val]) => `${key}=${val}`);
|
||||
fs.writeFileSync(path.join(__dirname, ".debug.env"), envContent.join("\n"));
|
||||
|
||||
// bootstrap
|
||||
spawn(
|
||||
// TODO: terminate `npm run dev` when Debug exits.
|
||||
process.platform === 'win32' ? 'npm.cmd' : 'npm',
|
||||
['run', 'dev'],
|
||||
process.platform === "win32" ? "npm.cmd" : "npm",
|
||||
["run", "dev"],
|
||||
{
|
||||
stdio: 'inherit',
|
||||
env: Object.assign(process.env, { VSCODE_DEBUG: 'true' }),
|
||||
},
|
||||
)
|
||||
stdio: "inherit",
|
||||
shell: true,
|
||||
env: Object.assign(process.env, { VSCODE_DEBUG: "true" }),
|
||||
}
|
||||
);
|
||||
Vendored
+10
-3
@@ -7,7 +7,10 @@
|
||||
{
|
||||
"name": "Debug App",
|
||||
"preLaunchTask": "Before Debug",
|
||||
"configurations": ["Debug Main Process", "Debug Renderer Process"],
|
||||
"configurations": [
|
||||
"Debug Main Process",
|
||||
"Debug Renderer Process"
|
||||
],
|
||||
"presentation": {
|
||||
"hidden": false,
|
||||
"group": "",
|
||||
@@ -25,7 +28,11 @@
|
||||
"windows": {
|
||||
"runtimeExecutable": "${workspaceRoot}/node_modules/.bin/electron.cmd"
|
||||
},
|
||||
"runtimeArgs": ["--no-sandbox", "--remote-debugging-port=9229", "."],
|
||||
"runtimeArgs": [
|
||||
"--no-sandbox",
|
||||
"--remote-debugging-port=9229",
|
||||
"."
|
||||
],
|
||||
"envFile": "${workspaceFolder}/.vscode/.debug.env",
|
||||
"console": "integratedTerminal"
|
||||
},
|
||||
@@ -42,6 +49,6 @@
|
||||
// Skip files in host(VITE_DEV_SERVER_URL)
|
||||
"http://127.0.0.1:7777/**"
|
||||
]
|
||||
}
|
||||
},
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
{
|
||||
"$schema": "https://raw.githubusercontent.com/electron-userland/electron-builder/master/packages/app-builder-lib/scheme.json",
|
||||
"appId": "behavior3editor",
|
||||
"productName": "Behavior3 Editor",
|
||||
"asar": true,
|
||||
"directories": {
|
||||
"output": "release/${version}"
|
||||
},
|
||||
"files": ["dist-electron", "dist"],
|
||||
"mac": {
|
||||
"artifactName": "behavior3editor_${version}.${ext}",
|
||||
"target": ["dmg", "zip"]
|
||||
},
|
||||
"win": {
|
||||
"target": [
|
||||
{
|
||||
"target": "nsis",
|
||||
"arch": ["x64"]
|
||||
}
|
||||
],
|
||||
"artifactName": "behavior3editor_${version}.${ext}"
|
||||
},
|
||||
"nsis": {
|
||||
"oneClick": false,
|
||||
"perMachine": false,
|
||||
"allowToChangeInstallationDirectory": true,
|
||||
"deleteAppDataOnUninstall": false
|
||||
},
|
||||
"publish": {
|
||||
"provider": "generic",
|
||||
"channel": "latest",
|
||||
"url": "https://github.com/electron-vite/electron-vite-react/releases/download/v0.9.9/"
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
/**
|
||||
* @see https://www.electron.build/configuration/configuration
|
||||
*/
|
||||
{
|
||||
appId: "behavior3editor",
|
||||
productName: "Behavior3 Editor",
|
||||
asar: true,
|
||||
directories: {
|
||||
output: "release/${version}",
|
||||
},
|
||||
files: ["dist-electron", "dist"],
|
||||
mac: {
|
||||
artifactName: "behavior3editor_${version}.${ext}",
|
||||
target: ["dmg", "zip"],
|
||||
},
|
||||
win: {
|
||||
target: [
|
||||
{
|
||||
target: "nsis",
|
||||
arch: ["x64"],
|
||||
// arch: ["x64", "ia32"],
|
||||
},
|
||||
],
|
||||
artifactName: "behavior3editor_${version}.${ext}",
|
||||
},
|
||||
nsis: {
|
||||
oneClick: false,
|
||||
perMachine: false,
|
||||
allowToChangeInstallationDirectory: true,
|
||||
deleteAppDataOnUninstall: false,
|
||||
},
|
||||
publish: {
|
||||
provider: "generic",
|
||||
channel: "latest",
|
||||
url: "https://github.com/electron-vite/electron-vite-react/releases/download/v0.9.9/",
|
||||
},
|
||||
}
|
||||
Vendored
+15
-3
@@ -3,9 +3,21 @@
|
||||
declare namespace NodeJS {
|
||||
interface ProcessEnv {
|
||||
VSCODE_DEBUG?: 'true'
|
||||
DIST_ELECTRON: string
|
||||
DIST: string
|
||||
/**
|
||||
* The built directory structure
|
||||
*
|
||||
* ```tree
|
||||
* ├─┬ dist-electron
|
||||
* │ ├─┬ main
|
||||
* │ │ └── index.js > Electron-Main
|
||||
* │ └─┬ preload
|
||||
* │ └── index.mjs > Preload-Scripts
|
||||
* ├─┬ dist
|
||||
* │ └── index.html > Electron-Renderer
|
||||
* ```
|
||||
*/
|
||||
APP_ROOT: string
|
||||
/** /dist/ or /public/ */
|
||||
PUBLIC: string
|
||||
VITE_PUBLIC: string
|
||||
}
|
||||
}
|
||||
+29
-26
@@ -1,11 +1,16 @@
|
||||
import { app, BrowserWindow, ipcMain, shell } from "electron";
|
||||
import * as fs from "node:fs";
|
||||
import { release } from "node:os";
|
||||
import path, { join } from "node:path";
|
||||
import { createRequire } from "node:module";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
import { argv } from "node:process";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import * as b3util from "../../src/misc/b3util";
|
||||
import Path from "../../src/misc/path";
|
||||
|
||||
const require = createRequire(import.meta.url);
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
// Check command line arguments
|
||||
let buildProject: string | undefined;
|
||||
let buildOutput: string | undefined;
|
||||
@@ -93,18 +98,22 @@ if (buildOutput || buildProject || buildHelp) {
|
||||
// │ ├─┬ main
|
||||
// │ │ └── index.js > Electron-Main
|
||||
// │ └─┬ preload
|
||||
// │ └── index.js > Preload-Scripts
|
||||
// │ └── index.mjs > Preload-Scripts
|
||||
// ├─┬ dist
|
||||
// │ └── index.html > Electron-Renderer
|
||||
//
|
||||
process.env.DIST_ELECTRON = join(__dirname, "../../");
|
||||
process.env.DIST = join(process.env.DIST_ELECTRON, "../dist");
|
||||
process.env.PUBLIC = process.env.VITE_DEV_SERVER_URL
|
||||
? join(process.env.DIST_ELECTRON, "../public")
|
||||
: process.env.DIST;
|
||||
process.env.APP_ROOT = path.join(__dirname, "../..");
|
||||
|
||||
export const MAIN_DIST = path.join(process.env.APP_ROOT, "dist-electron");
|
||||
export const RENDERER_DIST = path.join(process.env.APP_ROOT, "dist");
|
||||
export const VITE_DEV_SERVER_URL = process.env.VITE_DEV_SERVER_URL;
|
||||
|
||||
process.env.VITE_PUBLIC = VITE_DEV_SERVER_URL
|
||||
? path.join(process.env.APP_ROOT, "public")
|
||||
: RENDERER_DIST;
|
||||
|
||||
// Disable GPU Acceleration for Windows 7
|
||||
if (release().startsWith("6.1")) app.disableHardwareAcceleration();
|
||||
if (os.release().startsWith("6.1")) app.disableHardwareAcceleration();
|
||||
|
||||
// Set application name for Windows 10+ notifications
|
||||
if (process.platform === "win32") app.setAppUserModelId(app.getName());
|
||||
@@ -114,24 +123,19 @@ if (!app.requestSingleInstanceLock()) {
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
// Remove electron security warnings
|
||||
// This warning only shows in development mode
|
||||
// Read more on https://www.electronjs.org/docs/latest/tutorial/security
|
||||
// process.env['ELECTRON_DISABLE_SECURITY_WARNINGS'] = 'true'
|
||||
|
||||
interface Workspace {
|
||||
projectPath?: string;
|
||||
window: BrowserWindow;
|
||||
}
|
||||
|
||||
const preload = "../preload/index.js";
|
||||
const url = process.env.VITE_DEV_SERVER_URL;
|
||||
const indexHtml = join(process.env.DIST, "index.html");
|
||||
const preload = path.join(__dirname, "../preload/index.mjs");
|
||||
const indexHtml = path.join(RENDERER_DIST, "index.html");
|
||||
const windows: Workspace[] = [];
|
||||
|
||||
async function createWindow(projectPath?: string) {
|
||||
const win = new BrowserWindow({
|
||||
title: "Behaviour3 Editor",
|
||||
icon: Path.join(process.env.VITE_PUBLIC, "favicon.ico"),
|
||||
frame: false,
|
||||
width: 1280,
|
||||
height: 800,
|
||||
@@ -147,7 +151,6 @@ async function createWindow(projectPath?: string) {
|
||||
: { color: "#0d1117", height: 35, symbolColor: "#7d8590" },
|
||||
backgroundColor: "#0d1117",
|
||||
trafficLightPosition: { x: 10, y: 10 },
|
||||
icon: join(process.env.PUBLIC, "favicon.ico"),
|
||||
webPreferences: {
|
||||
preload,
|
||||
// Warning: Enable nodeIntegration and disable contextIsolation is not secure in production
|
||||
@@ -164,9 +167,9 @@ async function createWindow(projectPath?: string) {
|
||||
|
||||
win.maximizable = true;
|
||||
|
||||
if (process.env.VITE_DEV_SERVER_URL) {
|
||||
// electron-vite-vue#298
|
||||
win.loadURL(url);
|
||||
if (VITE_DEV_SERVER_URL) {
|
||||
// #298
|
||||
win.loadURL(VITE_DEV_SERVER_URL);
|
||||
// Open devTool if the app is not packaged
|
||||
win.webContents.openDevTools();
|
||||
} else {
|
||||
@@ -174,6 +177,7 @@ async function createWindow(projectPath?: string) {
|
||||
win.loadFile(indexHtml);
|
||||
}
|
||||
|
||||
// Test actively push message to the Electron-Renderer
|
||||
win.webContents.on("did-finish-load", () => {
|
||||
win.webContents.setZoomFactor(1);
|
||||
if (workspace.projectPath) {
|
||||
@@ -209,7 +213,7 @@ async function createWindow(projectPath?: string) {
|
||||
|
||||
require("@electron/remote/main").enable(win.webContents);
|
||||
|
||||
// Apply electron-updater
|
||||
// Auto update
|
||||
// update(win);
|
||||
}
|
||||
|
||||
@@ -228,7 +232,6 @@ app.on("second-instance", () => {
|
||||
|
||||
app.on("activate", () => {
|
||||
const allWindows = BrowserWindow.getAllWindows();
|
||||
|
||||
if (allWindows.length) {
|
||||
allWindows[0].focus();
|
||||
} else {
|
||||
@@ -237,7 +240,7 @@ app.on("activate", () => {
|
||||
});
|
||||
|
||||
// New window example arg: new windows url
|
||||
ipcMain.handle("open-win", (event, arg: string | undefined) => {
|
||||
ipcMain.handle("open-win", (event, arg) => {
|
||||
if (arg) {
|
||||
let workspace = windows.find((v) => v.projectPath === arg);
|
||||
if (workspace) {
|
||||
@@ -256,12 +259,12 @@ ipcMain.handle("open-win", (event, arg: string | undefined) => {
|
||||
createWindow(arg);
|
||||
});
|
||||
|
||||
ipcMain.handle("trashItem", (_, arg: string) => {
|
||||
ipcMain.handle("trashItem", (_, arg) => {
|
||||
arg = arg.replace(/\//g, path.sep);
|
||||
shell.trashItem(arg).catch((e) => console.error(e));
|
||||
});
|
||||
|
||||
ipcMain.handle("showItemInFolder", (_, arg: string) => {
|
||||
ipcMain.handle("showItemInFolder", (_, arg) => {
|
||||
arg = arg.replace(/\//g, path.sep);
|
||||
shell.showItemInFolder(arg);
|
||||
});
|
||||
+41
-41
@@ -1,76 +1,76 @@
|
||||
import { app, ipcMain } from "electron";
|
||||
import { type ProgressInfo, type UpdateDownloadedEvent, autoUpdater } from "electron-updater";
|
||||
import { app, ipcMain } from 'electron'
|
||||
import { createRequire } from 'node:module'
|
||||
import type {
|
||||
ProgressInfo,
|
||||
UpdateDownloadedEvent,
|
||||
UpdateInfo,
|
||||
} from 'electron-updater'
|
||||
|
||||
const { autoUpdater } = createRequire(import.meta.url)('electron-updater');
|
||||
|
||||
export function update(win: Electron.BrowserWindow) {
|
||||
|
||||
// When set to false, the update download will be triggered through the API
|
||||
autoUpdater.autoDownload = false;
|
||||
autoUpdater.disableWebInstaller = false;
|
||||
autoUpdater.allowDowngrade = false;
|
||||
autoUpdater.autoDownload = false
|
||||
autoUpdater.disableWebInstaller = false
|
||||
autoUpdater.allowDowngrade = false
|
||||
|
||||
// start check
|
||||
autoUpdater.on("checking-for-update", function () {});
|
||||
autoUpdater.on('checking-for-update', function () { })
|
||||
// update available
|
||||
autoUpdater.on("update-available", (arg) => {
|
||||
win.webContents.send("update-can-available", {
|
||||
update: true,
|
||||
version: app.getVersion(),
|
||||
newVersion: arg?.version,
|
||||
});
|
||||
});
|
||||
autoUpdater.on('update-available', (arg: UpdateInfo) => {
|
||||
win.webContents.send('update-can-available', { update: true, version: app.getVersion(), newVersion: arg?.version })
|
||||
})
|
||||
// update not available
|
||||
autoUpdater.on("update-not-available", (arg) => {
|
||||
win.webContents.send("update-can-available", {
|
||||
update: false,
|
||||
version: app.getVersion(),
|
||||
newVersion: arg?.version,
|
||||
});
|
||||
});
|
||||
autoUpdater.on('update-not-available', (arg: UpdateInfo) => {
|
||||
win.webContents.send('update-can-available', { update: false, version: app.getVersion(), newVersion: arg?.version })
|
||||
})
|
||||
|
||||
// Checking for updates
|
||||
ipcMain.handle("check-update", async () => {
|
||||
ipcMain.handle('check-update', async () => {
|
||||
if (!app.isPackaged) {
|
||||
const error = new Error("The update feature is only available after the package.");
|
||||
return { message: error.message, error };
|
||||
const error = new Error('The update feature is only available after the package.')
|
||||
return { message: error.message, error }
|
||||
}
|
||||
|
||||
try {
|
||||
return await autoUpdater.checkForUpdatesAndNotify();
|
||||
return await autoUpdater.checkForUpdatesAndNotify()
|
||||
} catch (error) {
|
||||
return { message: "Network error", error };
|
||||
return { message: 'Network error', error }
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
// Start downloading and feedback on progress
|
||||
ipcMain.handle("start-download", (event) => {
|
||||
ipcMain.handle('start-download', (event: Electron.IpcMainInvokeEvent) => {
|
||||
startDownload(
|
||||
(error, progressInfo) => {
|
||||
if (error) {
|
||||
// feedback download error message
|
||||
event.sender.send("update-error", { message: error.message, error });
|
||||
event.sender.send('update-error', { message: error.message, error })
|
||||
} else {
|
||||
// feedback update progress message
|
||||
event.sender.send("download-progress", progressInfo);
|
||||
event.sender.send('download-progress', progressInfo)
|
||||
}
|
||||
},
|
||||
() => {
|
||||
// feedback update downloaded message
|
||||
event.sender.send("update-downloaded");
|
||||
event.sender.send('update-downloaded')
|
||||
}
|
||||
);
|
||||
});
|
||||
)
|
||||
})
|
||||
|
||||
// Install now
|
||||
ipcMain.handle("quit-and-install", () => {
|
||||
autoUpdater.quitAndInstall(false, true);
|
||||
});
|
||||
ipcMain.handle('quit-and-install', () => {
|
||||
autoUpdater.quitAndInstall(false, true)
|
||||
})
|
||||
}
|
||||
|
||||
function startDownload(
|
||||
callback: (error: Error | null, info: ProgressInfo) => void,
|
||||
complete: (event: UpdateDownloadedEvent) => void
|
||||
callback: (error: Error | null, info: ProgressInfo | null) => void,
|
||||
complete: (event: UpdateDownloadedEvent) => void,
|
||||
) {
|
||||
autoUpdater.on("download-progress", (info) => callback(null, info));
|
||||
autoUpdater.on("error", (error) => callback(error, null!));
|
||||
autoUpdater.on("update-downloaded", complete);
|
||||
autoUpdater.downloadUpdate();
|
||||
autoUpdater.on('download-progress', (info: ProgressInfo) => callback(null, info))
|
||||
autoUpdater.on('error', (error: Error) => callback(error, null))
|
||||
autoUpdater.on('update-downloaded', complete)
|
||||
autoUpdater.downloadUpdate()
|
||||
}
|
||||
@@ -1,3 +1,28 @@
|
||||
// --------- Expose some API to the Renderer process ---------
|
||||
// contextBridge.exposeInMainWorld("ipcRenderer", {
|
||||
// on(...args: Parameters<typeof ipcRenderer.on>) {
|
||||
// const [channel, listener] = args;
|
||||
// return ipcRenderer.on(channel, (event, ...args) => listener(event, ...args));
|
||||
// },
|
||||
// off(...args: Parameters<typeof ipcRenderer.off>) {
|
||||
// const [channel, ...omit] = args;
|
||||
// return ipcRenderer.off(channel, ...omit);
|
||||
// },
|
||||
// send(...args: Parameters<typeof ipcRenderer.send>) {
|
||||
// const [channel, ...omit] = args;
|
||||
// return ipcRenderer.send(channel, ...omit);
|
||||
// },
|
||||
// invoke(...args: Parameters<typeof ipcRenderer.invoke>) {
|
||||
// const [channel, ...omit] = args;
|
||||
// return ipcRenderer.invoke(channel, ...omit);
|
||||
// },
|
||||
|
||||
// // You can expose other APTs you need here.
|
||||
// // ...
|
||||
// });
|
||||
// contextBridge.exposeInMainWorld("process", process);
|
||||
|
||||
// --------- Preload scripts loading ---------
|
||||
function domReady(condition: DocumentReadyState[] = ["complete", "interactive"]) {
|
||||
return new Promise((resolve) => {
|
||||
if (condition.includes(document.readyState)) {
|
||||
@@ -70,8 +95,8 @@ function useLoading() {
|
||||
|
||||
return {
|
||||
appendLoading() {
|
||||
safeDOM.append(document.head, oStyle);
|
||||
safeDOM.append(document.body, oDiv);
|
||||
// safeDOM.append(document.head, oStyle);
|
||||
// safeDOM.append(document.body, oDiv);
|
||||
},
|
||||
removeLoading() {
|
||||
safeDOM.remove(document.head, oStyle);
|
||||
|
||||
Generated
+3365
-153
File diff suppressed because it is too large.
Load diff
+36
-32
@@ -1,51 +1,30 @@
|
||||
{
|
||||
"name": "behavior3editor",
|
||||
"version": "1.7.0",
|
||||
"main": "dist-electron/electron/main/index.js",
|
||||
"main": "dist-electron/main/index.js",
|
||||
"description": "行为树编辑器",
|
||||
"author": "zhandouxiaojiji & codetypes",
|
||||
"license": "MIT",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"debug": {
|
||||
"env": {
|
||||
"VITE_DEV_SERVER_URL": "http://127.0.0.1:7777/"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"tsc-check:": "tsc --noEmit",
|
||||
"postinstall": "tsx pre-commit.ts",
|
||||
"dev": "vite",
|
||||
"build": "tsc && vite build && electron-builder",
|
||||
"tsc-check:": "tsc --noEmit",
|
||||
"postinstall": "copy-files-from-to"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+ssh://git@github.com/zhandouxiaojiji/behavior3editor.git"
|
||||
"preview": "vite preview",
|
||||
"pretest": "vite build --mode=test",
|
||||
"test": "vitest run"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/zhandouxiaojiji/behavior3editor/issues"
|
||||
},
|
||||
"homepage": "https://github.com/zhandouxiaojiji/behavior3editor#readme",
|
||||
"devDependencies": {
|
||||
"@stylistic/eslint-plugin-js": "^1.8.1",
|
||||
"@types/react": "^18.3.3",
|
||||
"@types/react-dom": "^18.3.0",
|
||||
"@typescript-eslint/eslint-plugin": "^7.18.0",
|
||||
"@typescript-eslint/parser": "^7.18.0",
|
||||
"@vitejs/plugin-react": "^4.3.4",
|
||||
"copy-files-from-to": "^3.11.0",
|
||||
"electron": "^30.3.1",
|
||||
"electron-builder": "^24.13.3",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-plugin-react-refresh": "^0.4.9",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"sass": "^1.77.8",
|
||||
"typescript": "^5.5.4",
|
||||
"vite": "^6.2.0",
|
||||
"vite-electron-plugin": "^0.8.3",
|
||||
"vite-plugin-electron": "^0.28.7",
|
||||
"vite-plugin-electron-renderer": "^0.14.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"@ant-design/icons": "^5.4.0",
|
||||
"@antv/g6": "^4.8.24",
|
||||
@@ -55,7 +34,7 @@
|
||||
"ahooks": "^3.8.0",
|
||||
"antd": "^5.20.0",
|
||||
"electron-localshortcut": "^3.2.1",
|
||||
"electron-updater": "^6.3.2",
|
||||
"electron-updater": "^6.3.9",
|
||||
"i18next": "^23.12.2",
|
||||
"i18next-browser-languagedetector": "^7.2.1",
|
||||
"i18next-http-backend": "^2.5.2",
|
||||
@@ -67,10 +46,35 @@
|
||||
"ts-key-enum": "^2.0.12",
|
||||
"use-force-update": "^1.0.11",
|
||||
"usehooks-ts": "^3.1.0",
|
||||
"zustand": "^4.5.4"
|
||||
"zustand": "^5.0.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.18.0 || >=16.0.0"
|
||||
"devDependencies": {
|
||||
"@playwright/test": "^1.48.2",
|
||||
"@stylistic/eslint-plugin-js": "^1.8.1",
|
||||
"@types/react": "^18.3.12",
|
||||
"@types/react-dom": "^18.3.1",
|
||||
"@typescript-eslint/eslint-plugin": "^7.18.0",
|
||||
"@typescript-eslint/parser": "^7.18.0",
|
||||
"@vitejs/plugin-react": "^4.3.4",
|
||||
"autoprefixer": "^10.4.20",
|
||||
"copy-files-from-to": "^3.11.0",
|
||||
"electron": "^33.2.0",
|
||||
"electron-builder": "^24.13.3",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-plugin-react-refresh": "^0.4.9",
|
||||
"postcss": "^8.4.49",
|
||||
"postcss-import": "^16.1.0",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"sass": "^1.77.8",
|
||||
"tailwindcss": "^3.4.15",
|
||||
"tsx": "^4.19.3",
|
||||
"typescript": "^5.8.2",
|
||||
"vite": "^6.2.0",
|
||||
"vite-electron-plugin": "^0.8.3",
|
||||
"vite-plugin-electron": "^0.29.0",
|
||||
"vite-plugin-electron-renderer": "^0.14.6",
|
||||
"vitest": "^2.1.5"
|
||||
},
|
||||
"copyFilesSettings": {
|
||||
"whenFileExists": "overwrite"
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
module.exports = {
|
||||
plugins: {
|
||||
'postcss-import': {},
|
||||
'tailwindcss/nesting': {},
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
},
|
||||
}
|
||||
-18
@@ -1,18 +0,0 @@
|
||||
#!/bin/sh
|
||||
echo -e "\nValidating Javascript:\n"
|
||||
# Check for eslint
|
||||
which tsc &> /dev/null
|
||||
if [[ "$?" == 1 ]]; then
|
||||
echo -e "\t\033[41mPlease install tsc\033[0m"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
tsc --noEmit
|
||||
|
||||
if [[ "$?" == 0 ]]; then
|
||||
echo -e "\033[42mCOMMIT SUCCEEDED\033[0m\n"
|
||||
exit 0
|
||||
else
|
||||
echo -e "\033[41mCOMMIT FAILED:\033[0m Your commit contains files that should pass ESLint but do not. Please fix the ESLint errors and try again.\n"
|
||||
exit 1
|
||||
fi
|
||||
@@ -0,0 +1,24 @@
|
||||
import * as fs from "node:fs";
|
||||
|
||||
const hooks = `
|
||||
#!/bin/sh
|
||||
echo -e "\nValidating Javascript:\n"
|
||||
# Check for eslint
|
||||
which tsc &> /dev/null
|
||||
if [[ "$?" == 1 ]]; then
|
||||
echo -e "\t\x1b[41mPlease install tsc\x1b[0m"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
tsc --noEmit
|
||||
|
||||
if [[ "$?" == 0 ]]; then
|
||||
echo -e "\x1b[42mCOMMIT SUCCEEDED\x1b[0m\n"
|
||||
exit 0
|
||||
else
|
||||
echo -e "\x1b[41mCOMMIT FAILED:\x1b[0m Your commit contains files that should pass ESLint but do not. Please fix the ESLint errors and try again.\n"
|
||||
exit 1
|
||||
fi
|
||||
`;
|
||||
fs.writeFileSync(".git/hooks/pre-commit", hooks);
|
||||
fs.chmodSync(".git/hooks/pre-commit", 0o755);
|
||||
@@ -10,7 +10,7 @@
|
||||
"cancel": "取消",
|
||||
"copy": "复制",
|
||||
"console": "控制台",
|
||||
"cut": "替换",
|
||||
"cut": "剪切",
|
||||
"createProject": "新建项目",
|
||||
"delete": "删除",
|
||||
"deleteNode": "删除节点",
|
||||
|
||||
@@ -35,7 +35,6 @@ import {
|
||||
isNodeArgArray,
|
||||
isNodeArgOptional,
|
||||
isValidVariableName,
|
||||
nodeDefs,
|
||||
} from "../misc/b3util";
|
||||
import { Hotkey, isMacos } from "../misc/keys";
|
||||
import { mergeClassNames } from "../misc/util";
|
||||
@@ -121,7 +120,7 @@ const NodeInspector: FC = () => {
|
||||
// set form values
|
||||
useEffect(() => {
|
||||
const data = workspace.editingNode.data;
|
||||
const def = nodeDefs.get(workspace.editingNode.data.name);
|
||||
const def = workspace.nodeDefs.get(workspace.editingNode.data.name);
|
||||
form.resetFields();
|
||||
form.setFieldValue("id", data.id);
|
||||
form.setFieldValue("name", data.name);
|
||||
@@ -237,7 +236,7 @@ const NodeInspector: FC = () => {
|
||||
}, [workspace.allFiles, workspace.fileTree]);
|
||||
|
||||
const editingNode = workspace.editingNode;
|
||||
const def = nodeDefs.get(editingNode.data.name);
|
||||
const def = workspace.nodeDefs.get(editingNode.data.name);
|
||||
const disabled = !editingNode.editable;
|
||||
|
||||
// update value
|
||||
|
||||
+15
-13
@@ -12,7 +12,7 @@ import { useSetting } from "../contexts/setting-context";
|
||||
import { useWorkspace } from "../contexts/workspace-context";
|
||||
import * as b3util from "../misc/b3util";
|
||||
import i18n from "../misc/i18n";
|
||||
import { Hotkey, isMacos, sendInputEvent } from "../misc/keys";
|
||||
import { Hotkey, isMacos } from "../misc/keys";
|
||||
|
||||
const MenuItemLabel: FC<FlexProps> = (itemProps) => {
|
||||
return (
|
||||
@@ -175,9 +175,9 @@ export const Menu: FC<LayoutProps> = () => {
|
||||
id: "menu.edit.undo",
|
||||
label: t("undo"),
|
||||
enabled: enabled,
|
||||
accelerator: Hotkey.Undo,
|
||||
accelerator: Hotkey.Undo.replaceAll(".", "+"),
|
||||
click: () => {
|
||||
sendInputEvent(Hotkey.Undo);
|
||||
// sendInputEvent(Hotkey.Undo);
|
||||
getFocusedWebContents()?.undo();
|
||||
},
|
||||
},
|
||||
@@ -185,9 +185,9 @@ export const Menu: FC<LayoutProps> = () => {
|
||||
id: "menu.edit.redo",
|
||||
label: t("redo"),
|
||||
enabled: enabled,
|
||||
accelerator: Hotkey.Redo,
|
||||
accelerator: Hotkey.Redo.replaceAll(".", "+"),
|
||||
click: () => {
|
||||
sendInputEvent(Hotkey.Redo);
|
||||
// sendInputEvent(Hotkey.Redo);
|
||||
getFocusedWebContents()?.redo();
|
||||
},
|
||||
},
|
||||
@@ -196,9 +196,9 @@ export const Menu: FC<LayoutProps> = () => {
|
||||
id: "menu.edit.copy",
|
||||
label: t("copy"),
|
||||
enabled: enabled,
|
||||
accelerator: Hotkey.Copy,
|
||||
accelerator: Hotkey.Copy.replaceAll(".", "+"),
|
||||
click: () => {
|
||||
sendInputEvent(Hotkey.Copy);
|
||||
// sendInputEvent(Hotkey.Copy);
|
||||
getFocusedWebContents()?.copy();
|
||||
},
|
||||
},
|
||||
@@ -206,9 +206,9 @@ export const Menu: FC<LayoutProps> = () => {
|
||||
id: "menu.edit.paste",
|
||||
label: t("paste"),
|
||||
enabled: enabled,
|
||||
accelerator: Hotkey.Paste,
|
||||
accelerator: Hotkey.Paste.replaceAll(".", "+"),
|
||||
click: () => {
|
||||
sendInputEvent(Hotkey.Paste);
|
||||
// sendInputEvent(Hotkey.Paste);
|
||||
getFocusedWebContents()?.paste();
|
||||
},
|
||||
},
|
||||
@@ -216,7 +216,7 @@ export const Menu: FC<LayoutProps> = () => {
|
||||
id: "menu.edit.cut",
|
||||
label: t("cut"),
|
||||
enabled: enabled,
|
||||
accelerator: Hotkey.Cut,
|
||||
accelerator: Hotkey.Cut.replaceAll(".", "+"),
|
||||
click: () => {
|
||||
getFocusedWebContents()?.cut();
|
||||
},
|
||||
@@ -225,7 +225,7 @@ export const Menu: FC<LayoutProps> = () => {
|
||||
id: "menu.edit.selectAll",
|
||||
label: t("selectAll"),
|
||||
enabled: enabled,
|
||||
accelerator: Hotkey.SelectAll,
|
||||
accelerator: Hotkey.SelectAll.replaceAll(".", "+"),
|
||||
click: () => {
|
||||
getFocusedWebContents()?.selectAll();
|
||||
},
|
||||
@@ -235,16 +235,18 @@ export const Menu: FC<LayoutProps> = () => {
|
||||
id: "menu.edit.insertNode",
|
||||
label: t("insertNode"),
|
||||
enabled: enabled,
|
||||
accelerator: Hotkey.Enter.replaceAll(".", "+"),
|
||||
click: () => {
|
||||
workspace.editing?.dispatch("insert");
|
||||
// workspace.editing?.dispatch("insert");
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "menu.edit.deleteNode",
|
||||
label: t("deleteNode"),
|
||||
enabled: enabled,
|
||||
accelerator: Hotkey.Backspace.replaceAll(".", "+"),
|
||||
click: () => {
|
||||
workspace.editing?.dispatch("delete");
|
||||
// workspace.editing?.dispatch("delete");
|
||||
},
|
||||
},
|
||||
],
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import G6 from "@antv/g6";
|
||||
import { useWorkspace } from "../contexts/workspace-context";
|
||||
import { TreeGraphData, getNodeType } from "../misc/b3type";
|
||||
import { checkTreeData, nodeDefs, workdir } from "../misc/b3util";
|
||||
import { checkTreeData, getNodeDefs } from "../misc/b3util";
|
||||
import i18n from "../misc/i18n";
|
||||
import { isMacos } from "../misc/keys";
|
||||
|
||||
@@ -141,6 +142,7 @@ G6.registerNode(
|
||||
},
|
||||
draw(cfg, group) {
|
||||
const data = cfg as TreeGraphData;
|
||||
const nodeDefs = getNodeDefs();
|
||||
const nodeDef = nodeDefs.get(data.name);
|
||||
let classify = getNodeType(nodeDef);
|
||||
let color = nodeDef.color || NODE_COLORS[classify] || NODE_COLORS["Other"];
|
||||
@@ -257,7 +259,9 @@ G6.registerNode(
|
||||
});
|
||||
|
||||
// icon
|
||||
const img = nodeDef.icon ? `file:///${workdir}/${nodeDef.icon}` : `./icons/${classify}.svg`;
|
||||
const img = nodeDef.icon
|
||||
? `file:///${useWorkspace.getState().workdir}/${nodeDef.icon}`
|
||||
: `./icons/${classify}.svg`;
|
||||
addShape("image", {
|
||||
attrs: {
|
||||
x: 5,
|
||||
|
||||
@@ -155,7 +155,7 @@ export type WorkspaceStore = {
|
||||
loadTrees: () => void;
|
||||
|
||||
loadNodeDefs: () => void;
|
||||
nodeDefs: Map<string, NodeDef>;
|
||||
nodeDefs: b3util.NodeDefs;
|
||||
|
||||
// edit node
|
||||
editingNode?: EditNode | null;
|
||||
@@ -609,11 +609,11 @@ export const useWorkspace = create<WorkspaceStore>((set, get) => ({
|
||||
}
|
||||
},
|
||||
|
||||
nodeDefs: new Map(),
|
||||
nodeDefs: new b3util.NodeDefs(),
|
||||
loadNodeDefs: () => {
|
||||
const workspace = get();
|
||||
b3util.initWorkdir(workspace.workdir, message.error.bind(message));
|
||||
set({ nodeDefs: b3util.nodeDefs });
|
||||
set({ nodeDefs: b3util.getNodeDefs() });
|
||||
workspace.editing?.dispatch("refresh");
|
||||
},
|
||||
|
||||
|
||||
+12
-6
@@ -16,8 +16,15 @@ import {
|
||||
import Path from "./path";
|
||||
import { readJson } from "./util";
|
||||
|
||||
export let workdir: string = "";
|
||||
export class NodeDefs extends Map<string, NodeDef> {
|
||||
get(key: string): NodeDef {
|
||||
return super.get(key) ?? unknownNodeDef;
|
||||
}
|
||||
}
|
||||
|
||||
let workdir: string = "";
|
||||
let alertError: (msg: string, duration?: number) => void = () => {};
|
||||
let nodeDefs: NodeDefs = new NodeDefs();
|
||||
|
||||
const unknownNodeDef: NodeDef = {
|
||||
name: "unknown",
|
||||
@@ -25,16 +32,15 @@ const unknownNodeDef: NodeDef = {
|
||||
type: "Action",
|
||||
};
|
||||
|
||||
export const nodeDefs = new (class extends Map<string, NodeDef> {
|
||||
get(key: string): NodeDef {
|
||||
return super.get(key) ?? unknownNodeDef;
|
||||
}
|
||||
})();
|
||||
export const getNodeDefs = () => {
|
||||
return nodeDefs;
|
||||
};
|
||||
|
||||
export const initWorkdir = (path: string, handler: typeof alertError) => {
|
||||
workdir = path;
|
||||
alertError = handler;
|
||||
const nodeDefData = readJson(`${workdir}/node-config.b3-setting`) as NodeDef[];
|
||||
nodeDefs = new NodeDefs();
|
||||
for (const v of nodeDefData) {
|
||||
nodeDefs.set(v.name, v);
|
||||
}
|
||||
|
||||
Vendored
+5
@@ -1 +1,6 @@
|
||||
/// <reference types="vite/client" />
|
||||
|
||||
interface Window {
|
||||
// expose in the `electron/preload/index.ts`
|
||||
ipcRenderer: import("electron").IpcRenderer;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
export default {
|
||||
content: [
|
||||
'./index.html',
|
||||
'./src/**/*.{js,ts,jsx,tsx}',
|
||||
],
|
||||
theme: {
|
||||
extend: {},
|
||||
},
|
||||
corePlugins: {
|
||||
preflight: false,
|
||||
},
|
||||
plugins: [],
|
||||
}
|
||||
+54
-32
@@ -1,59 +1,81 @@
|
||||
import react from "@vitejs/plugin-react";
|
||||
import { rmSync } from "node:fs";
|
||||
import path from "node:path";
|
||||
import { defineConfig } from "vite";
|
||||
import electron from "vite-electron-plugin";
|
||||
import { customStart, loadViteEnv } from "vite-electron-plugin/plugin";
|
||||
import renderer from "vite-plugin-electron-renderer";
|
||||
import electron from "vite-plugin-electron/simple";
|
||||
import pkg from "./package.json";
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig(({ command }) => {
|
||||
rmSync("dist-electron", { recursive: true, force: true });
|
||||
|
||||
const sourcemap = true; //command === "serve" || !!process.env.VSCODE_DEBUG;
|
||||
const isServe = command === "serve";
|
||||
const isBuild = false; //command === "build";
|
||||
const sourcemap = true; //isServe || !!process.env.VSCODE_DEBUG;
|
||||
|
||||
return {
|
||||
resolve: {
|
||||
alias: {
|
||||
"@": path.join(__dirname, "src"),
|
||||
},
|
||||
},
|
||||
build: {
|
||||
sourcemap: true,
|
||||
sourcemap,
|
||||
},
|
||||
plugins: [
|
||||
react(),
|
||||
electron({
|
||||
include: [
|
||||
"electron",
|
||||
"src/misc/b3type.ts",
|
||||
"src/misc/b3util.ts",
|
||||
"src/misc/path.ts",
|
||||
"src/misc/util.ts",
|
||||
],
|
||||
transformOptions: {
|
||||
sourcemap,
|
||||
main: {
|
||||
// Shortcut of `build.lib.entry`
|
||||
entry: "electron/main/index.ts",
|
||||
onstart(args) {
|
||||
if (process.env.VSCODE_DEBUG) {
|
||||
console.log(/* For `.vscode/.debug.script.mjs` */ "[startup] Electron App");
|
||||
} else {
|
||||
args.startup();
|
||||
}
|
||||
},
|
||||
plugins: [
|
||||
...(!!process.env.VSCODE_DEBUG
|
||||
? [
|
||||
// Will start Electron via VSCode Debug
|
||||
customStart(() =>
|
||||
console.log(/* For `.vscode/.debug.script.mjs` */ "[startup] Electron App")
|
||||
),
|
||||
]
|
||||
: []),
|
||||
// Allow use `import.meta.env.VITE_SOME_KEY` in Electron-Main
|
||||
loadViteEnv(),
|
||||
],
|
||||
vite: {
|
||||
build: {
|
||||
sourcemap,
|
||||
minify: isBuild,
|
||||
outDir: "dist-electron/main",
|
||||
rollupOptions: {
|
||||
external: Object.keys("dependencies" in pkg ? pkg.dependencies : {}),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
preload: {
|
||||
// Shortcut of `build.rollupOptions.input`.
|
||||
// Preload scripts may contain Web assets, so use the `build.rollupOptions.input` instead `build.lib.entry`.
|
||||
input: "electron/preload/index.ts",
|
||||
vite: {
|
||||
build: {
|
||||
sourcemap: sourcemap ? "inline" : undefined, // #332
|
||||
minify: isBuild,
|
||||
outDir: "dist-electron/preload",
|
||||
rollupOptions: {
|
||||
external: Object.keys("dependencies" in pkg ? pkg.dependencies : {}),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
// Ployfill the Electron and Node.js API for Renderer process.
|
||||
// If you want use Node.js in Renderer process, the `nodeIntegration` needs to be enabled in the Main process.
|
||||
// See 👉 https://github.com/electron-vite/vite-plugin-electron-renderer
|
||||
renderer: {},
|
||||
}),
|
||||
// Use Node.js API in the Renderer-process
|
||||
renderer(),
|
||||
],
|
||||
server: !!process.env.VSCODE_DEBUG
|
||||
? (() => {
|
||||
server:
|
||||
process.env.VSCODE_DEBUG &&
|
||||
(() => {
|
||||
const url = new URL(pkg.debug.env.VITE_DEV_SERVER_URL);
|
||||
return {
|
||||
host: url.hostname,
|
||||
port: +url.port,
|
||||
};
|
||||
})()
|
||||
: undefined,
|
||||
})(),
|
||||
clearScreen: false,
|
||||
};
|
||||
});
|
||||
Reference in new issue
Block a user