diff --git a/electron/main/index.ts b/electron/main/index.ts index 2b9c2b5..d161377 100644 --- a/electron/main/index.ts +++ b/electron/main/index.ts @@ -109,6 +109,7 @@ if (!app.requestSingleInstanceLock()) { interface Workspace { projectPath?: string; + files: { path: string; active: boolean }[]; window: BrowserWindow; } @@ -146,7 +147,7 @@ async function createWindow(projectPath?: string) { }, }); - const workspace = { projectPath, window: win }; + const workspace = { projectPath, window: win, files: [] }; windows.push(workspace); win.maximizable = true; @@ -164,9 +165,6 @@ async function createWindow(projectPath?: string) { // Test actively push message to the Electron-Renderer win.webContents.on("did-finish-load", () => { win.webContents.setZoomFactor(1); - if (workspace.projectPath) { - win?.webContents.send("open-project", workspace.projectPath); - } const nextWin = BrowserWindow.getAllWindows().at(-1); if (nextWin) { @@ -224,7 +222,7 @@ app.on("activate", () => { }); // New window example arg: new windows url -ipcMain.handle("open-win", (event, arg) => { +ipcMain.handle("open-win", (e, arg) => { if (arg) { let workspace = windows.find((v) => v.projectPath === arg); if (workspace) { @@ -232,7 +230,7 @@ ipcMain.handle("open-win", (event, arg) => { return; } - workspace = windows.find((v) => v.window.webContents.id === event.sender.id); + workspace = windows.find((v) => v.window.webContents.id === e.sender.id); if (workspace && !workspace.projectPath) { workspace.projectPath = arg; workspace.window.webContents.send("open-project", arg); @@ -243,12 +241,39 @@ ipcMain.handle("open-win", (event, arg) => { createWindow(arg); }); -ipcMain.handle("trashItem", (_, arg) => { +ipcMain.handle("ready-to-show", (e) => { + const workspace = windows.find((v) => v.window.webContents.id === e.sender.id); + if (workspace && workspace.projectPath) { + workspace.window.webContents.send("open-project", workspace.projectPath, workspace.files); + } +}); + +ipcMain.handle("open-file", (e, path: string) => { + const workspace = windows.find((v) => v.window.webContents.id === e.sender.id); + if (workspace) { + const entry = workspace.files.find((v) => v.path === path); + workspace.files.forEach((v) => (v.active = false)); + if (entry) { + entry.active = true; + } else { + workspace.files.push({ path, active: true }); + } + } +}); + +ipcMain.handle("close-file", (e, path: string) => { + const workspace = windows.find((v) => v.window.webContents.id === e.sender.id); + if (workspace) { + workspace.files = workspace.files.filter((v) => v.path !== path); + } +}); + +ipcMain.handle("trash-item", (_, arg) => { arg = arg.replace(/\//g, path.sep); shell.trashItem(arg).catch((e) => console.error(e)); }); -ipcMain.handle("showItemInFolder", (_, arg) => { +ipcMain.handle("show-item-in-folder", (_, arg) => { arg = arg.replace(/\//g, path.sep); shell.showItemInFolder(arg); }); diff --git a/src/components/editor.tsx b/src/components/editor.tsx index 0c8c0a9..dee4fb6 100644 --- a/src/components/editor.tsx +++ b/src/components/editor.tsx @@ -351,7 +351,13 @@ export const Editor: FC = ({ onChange, data: editor, ...props }) => } }); } - }, [editorSize, workspace.editing, graph, t]); + }, [editorSize, workspace.editing, graph]); + + useEffect(() => { + if (graph) { + graph.refresh(); + } + }, [t]); return (
{ if (path === workspace.editing?.path) { workspace.close(path); } - ipcRenderer.invoke("trashItem", path); + ipcRenderer.invoke("trash-item", path); }} > {i18n.t("moveToTrash")} @@ -526,7 +526,7 @@ const alertDeleteFolder = (path: string) => { workspace.close(editor.path); } }); - ipcRenderer.invoke("trashItem", path); + ipcRenderer.invoke("trash-item", path); alert.destroy(); }} > @@ -812,7 +812,7 @@ export const Explorer: FC = () => { break; } case "revealFile": - ipcRenderer.invoke("showItemInFolder", node.path); + ipcRenderer.invoke("show-item-in-folder", node.path); break; case "rename": { if (b3util.isTreeFile(node.path)) { diff --git a/src/components/menu.tsx b/src/components/menu.tsx index 1d7386b..e3ec4e5 100644 --- a/src/components/menu.tsx +++ b/src/components/menu.tsx @@ -29,8 +29,8 @@ const getFocusedWebContents = () => { return BrowserWindow.getFocusedWindow()?.webContents; }; -ipcRenderer.on("open-project", (_, dir) => { - useWorkspace.getState().init(dir); +ipcRenderer.on("open-project", (_, dir, files) => { + useWorkspace.getState().init(dir, files); }); ipcRenderer.on("refresh-app-men", () => { diff --git a/src/components/register-node.ts b/src/components/register-node.ts index 530c413..da7fce7 100644 --- a/src/components/register-node.ts +++ b/src/components/register-node.ts @@ -50,7 +50,7 @@ const calcTextWith = (text: string, fontSize?: string) => { const metrics = ctx.measureText(text); width = metrics.width; // width = width - (isMacos ? 1.6 : 0.8); - width *= isMacos ? 0.88 : 0.95; + width *= isMacos ? 0.88 : 0.98; textWidthMap.set(key, width); } } diff --git a/src/components/setup.tsx b/src/components/setup.tsx index d600a02..97dcf11 100644 --- a/src/components/setup.tsx +++ b/src/components/setup.tsx @@ -1,3 +1,4 @@ +import { ipcRenderer } from "electron"; import { FC } from "react"; import { useSetting } from "../contexts/setting-context"; import { message, setGlobalHooks } from "../misc/hooks"; @@ -5,6 +6,7 @@ import { message, setGlobalHooks } from "../misc/hooks"; export const Setup: FC = () => { if (!message) { useSetting().load(); + ipcRenderer.invoke("ready-to-show"); } setGlobalHooks(); return
; diff --git a/src/contexts/workspace-context.ts b/src/contexts/workspace-context.ts index 88a5657..889cf24 100644 --- a/src/contexts/workspace-context.ts +++ b/src/contexts/workspace-context.ts @@ -113,7 +113,7 @@ export interface WorkspaceModel { } export type WorkspaceStore = { - init: (project: string) => void; + init: (project: string, files?: { path: string; active: boolean }[]) => void; createProject: () => void; openProject: (project?: string) => void; batchProject: () => void; @@ -225,7 +225,7 @@ export const useWorkspace = create((set, get) => ({ path: "", settings: {}, - init: (path) => { + init: (path, files) => { const workspace = get(); if (!workspace.workdir) { try { @@ -236,6 +236,20 @@ export const useWorkspace = create((set, get) => ({ workspace.loadNodeDefs(); workspace.watch(); useSetting.getState().appendRecent(path); + if (files?.length) { + for (const entry of files) { + try { + const editor = new EditorStore(entry.path); + workspace.editors.push(editor); + if (entry.active) { + workspace.open(editor.path); + } + } catch (error) { + console.error(error); + message.error(`invalid file: ${path}`); + } + } + } } catch (error) { console.error(error); if (!fs.existsSync(path)) { @@ -505,6 +519,7 @@ export const useWorkspace = create((set, get) => ({ if (editor) { workspace.onEditingTree(editor); } + ipcRenderer.invoke("open-file", path); }, close: (path) => { @@ -523,6 +538,7 @@ export const useWorkspace = create((set, get) => ({ set({ editingNode: undefined, editingTree: undefined }); } set({ editing: editting, editors: editors }); + ipcRenderer.invoke("close-file", path); }, find: (path) => {