Skip to content

Commit

Permalink
chore: 初回ファイルの取得をbackendの関数として表現するようにする (#2524)
Browse files Browse the repository at this point in the history
Co-authored-by: Hiroshiba Kazuyuki <[email protected]>
Co-authored-by: Hiroshiba <[email protected]>
  • Loading branch information
3 people authored Feb 15, 2025
1 parent f44a29b commit 41d6666
Show file tree
Hide file tree
Showing 11 changed files with 84 additions and 64 deletions.
9 changes: 6 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ pnpm run electron:serve

# ビルド時に近い環境で実行
pnpm run electron:serve --mode production

# 引数を指定して実行
pnpm run electron:serve -- ...
```

音声合成エンジンのリポジトリはこちらです <https://github.com/VOICEVOX/voicevox_engine>
Expand Down Expand Up @@ -128,7 +131,7 @@ fork したリポジトリで Actions を ON にし、workflow_dispatch で`buil
pnpm run test:unit
pnpm run test-watch:unit # 監視モード
pnpm run test-ui:unit # VitestのUIを表示
pnpm run test:unit -- --update # スナップショットの更新
pnpm run test:unit --update # スナップショットの更新
```

> [!NOTE]
Expand All @@ -148,7 +151,7 @@ Electron の機能が不要な、UI や音声合成などの End to End テス
```bash
pnpm run test:browser-e2e
pnpm run test-watch:browser-e2e # 監視モード
pnpm run test-watch:browser-e2e -- --headed # テスト中の UI を表示
pnpm run test-watch:browser-e2e --headed # テスト中の UI を表示
pnpm run test-ui:browser-e2e # Playwright の UI を表示
```

Expand Down Expand Up @@ -216,7 +219,7 @@ pnpm run test-ui:storybook-vrt # Playwright の UI を表示
ローカル PC の OS に対応したもののみが更新されます。

```bash
pnpm run test:browser-e2e -- --update-snapshots
pnpm run test:browser-e2e --update-snapshots
```

### Electron End to End テスト
Expand Down
3 changes: 3 additions & 0 deletions src/backend/browser/sandbox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ export const api: Sandbox = {
// NOTE: ブラウザ版ではサポートされていません
return Promise.resolve({});
},
getInitialProjectFilePath() {
return Promise.resolve(undefined);
},
showSaveDirectoryDialog(obj: { title: string }) {
return showOpenDirectoryDialogImpl(obj);
},
Expand Down
67 changes: 42 additions & 25 deletions src/backend/electron/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ import {
EngineId,
TextAsset,
} from "@/type/preload";
import { isMac } from "@/helpers/platform";
import { isMac, isProduction } from "@/helpers/platform";
import { createLogger } from "@/helpers/log";

type SingleInstanceLockData = {
Expand Down Expand Up @@ -245,7 +245,25 @@ function checkMultiEngineEnabled(): boolean {
return enabled;
}

let filePathOnMac: string | undefined = undefined;
/** コマンドライン引数を取得する */
function getArgv(): string[] {
// 製品版でmacOS以外の場合、引数はargv[1]以降をそのまま
if (isProduction) {
if (!isMac) {
return process.argv.slice(1);
}
}
// 開発版の場合、引数は`--`がある場合は`--`以降、無い場合は引数なしとして扱う
else {
const index = process.argv.indexOf("--");
if (index !== -1) {
return process.argv.slice(index + 1);
}
}
return [];
}

let initialFilePath: string | undefined = getArgv()[0]; // TODO: カプセル化する

const menuTemplateForMac: Electron.MenuItemConstructorOptions[] = [
{
Expand Down Expand Up @@ -355,6 +373,12 @@ registerIpcMainHandle<IpcMainHandle>({
return engineInfoManager.altPortInfos;
},

GET_INITIAL_PROJECT_FILE_PATH: async () => {
if (initialFilePath && initialFilePath.endsWith(".vvproj")) {
return initialFilePath;
}
},

/**
* 保存先になるディレクトリを選ぶダイアログを表示する。
*/
Expand Down Expand Up @@ -689,7 +713,7 @@ app.once("will-finish-launching", () => {
// macOS only
app.once("open-file", (event, filePath) => {
event.preventDefault();
filePathOnMac = filePath;
initialFilePath = filePath;
});
});

Expand Down Expand Up @@ -817,45 +841,38 @@ void app.whenReady().then(async () => {
);
}

// runEngineAllの前にVVPPを読み込む
let filePath: string | undefined;
if (process.platform === "darwin") {
filePath = filePathOnMac;
} else {
if (process.argv.length > 1) {
filePath = process.argv[1];
}
}

// 多重起動防止
// TODO: readyを待たずにもっと早く実行すべき
if (
!isDevelopment &&
!isTest &&
!app.requestSingleInstanceLock({
filePath,
} as SingleInstanceLockData)
filePath: initialFilePath,
} satisfies SingleInstanceLockData)
) {
log.info("VOICEVOX already running. Cancelling launch.");
log.info(`File path sent: ${filePath}`);
log.info(`File path sent: ${initialFilePath}`);
appState.willQuit = true;
app.quit();
return;
}

if (filePath && isVvppFile(filePath)) {
log.info(`vvpp file install: ${filePath}`);
// FIXME: GUI側に合流させる
if (checkMultiEngineEnabled()) {
await engineAndVvppController.installVvppEngineWithWarning({
vvppPath: filePath,
reloadNeeded: false,
});
if (initialFilePath) {
log.info(`Initial file path provided: ${initialFilePath}`);
if (isVvppFile(initialFilePath)) {
log.info(`vvpp file install: ${initialFilePath}`);
// FIXME: GUI側に合流させる
if (checkMultiEngineEnabled()) {
await engineAndVvppController.installVvppEngineWithWarning({
vvppPath: initialFilePath,
reloadNeeded: false,
});
}
}
}

await engineAndVvppController.launchEngines();
await windowManager.createWindow(filePath);
await windowManager.createWindow();
});

// 他のプロセスが起動したとき、`requestSingleInstanceLock`経由で`rawData`が送信される。
Expand Down
34 changes: 3 additions & 31 deletions src/backend/electron/manager/windowManager.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import fs from "fs";
import path from "path";
import {
BrowserWindow,
Expand All @@ -13,7 +12,6 @@ import windowStateKeeper from "electron-window-state";
import { getConfigManager } from "../electronConfig";
import { getEngineAndVvppController } from "../engineAndVvppController";
import { ipcMainSendProxy } from "../ipc";
import { isMac } from "@/helpers/platform";
import { themes } from "@/domain/theme";
import { createLogger } from "@/helpers/log";

Expand Down Expand Up @@ -57,7 +55,7 @@ class WindowManager {
return this._win;
}

public async createWindow(filePathOnMac: string | undefined) {
public async createWindow() {
if (this.win != undefined) {
throw new Error("Window has already been created");
}
Expand Down Expand Up @@ -88,27 +86,6 @@ class WindowManager {
icon: path.join(this.staticDir, "icon.png"),
});

let projectFilePath = "";
if (isMac) {
if (filePathOnMac) {
if (filePathOnMac.endsWith(".vvproj")) {
projectFilePath = filePathOnMac;
}
filePathOnMac = undefined;
}
} else {
if (process.argv.length >= 2) {
const filePath = process.argv[1];
if (
fs.existsSync(filePath) &&
fs.statSync(filePath).isFile() &&
filePath.endsWith(".vvproj")
) {
projectFilePath = filePath;
}
}
}

win.on("maximize", () => {
ipcMainSendProxy.DETECT_MAXIMIZED(win);
});
Expand Down Expand Up @@ -149,21 +126,17 @@ class WindowManager {
mainWindowState.manage(win);
this._win = win;

await this.load({ projectFilePath });
await this.load({});

if (this.isDevelopment && !this.isTest) win.webContents.openDevTools();
}

/**
* 画面の読み込みを開始する。
* @param obj.isMultiEngineOffMode マルチエンジンオフモードにするかどうか。無指定時はfalse扱いになる。
* @param obj.projectFilePath 初期化時に読み込むプロジェクトファイル。無指定時は何も読み込まない。
* @returns ロードの完了を待つPromise。
*/
public async load(obj: {
isMultiEngineOffMode?: boolean;
projectFilePath?: string;
}) {
public async load(obj: { isMultiEngineOffMode?: boolean }) {
const win = this.getWindow();
const firstUrl =
import.meta.env.VITE_DEV_SERVER_URL ?? "app://./index.html";
Expand All @@ -172,7 +145,6 @@ class WindowManager {
"isMultiEngineOffMode",
(obj?.isMultiEngineOffMode ?? false).toString(),
);
url.searchParams.append("projectFilePath", obj?.projectFilePath ?? "");
await win.loadURL(url.toString());
}

Expand Down
4 changes: 4 additions & 0 deletions src/backend/electron/preload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ const api: Sandbox = {
return await ipcRendererInvokeProxy.GET_ALT_PORT_INFOS();
},

getInitialProjectFilePath: async () => {
return await ipcRendererInvokeProxy.GET_INITIAL_PROJECT_FILE_PATH();
},

showSaveDirectoryDialog: ({ title }) => {
return ipcRendererInvokeProxy.SHOW_SAVE_DIRECTORY_DIALOG({ title });
},
Expand Down
6 changes: 2 additions & 4 deletions src/components/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -114,9 +114,6 @@ onMounted(async () => {
await store.actions.INIT_VUEX();
// プロジェクトファイルのパスを取得
const projectFilePath = urlParams.get("projectFilePath");
// ショートカットキーの設定を登録
const hotkeySettings = store.state.hotkeySettings;
hotkeyManager.load(structuredClone(toRaw(hotkeySettings)));
Expand Down Expand Up @@ -163,7 +160,8 @@ onMounted(async () => {
});
// プロジェクトファイルが指定されていればロード
if (typeof projectFilePath === "string" && projectFilePath !== "") {
const projectFilePath = await store.actions.GET_INITIAL_PROJECT_FILE_PATH();
if (projectFilePath != undefined) {
isProjectFileLoaded.value = await store.actions.LOAD_PROJECT_FILE({
type: "path",
filePath: projectFilePath,
Expand Down
6 changes: 6 additions & 0 deletions src/store/project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,12 @@ export const projectStore = createPartialStore<ProjectStoreTypes>({
}),
},

GET_INITIAL_PROJECT_FILE_PATH: {
action: async () => {
return await window.backend.getInitialProjectFilePath();
},
},

IS_EDITED: {
getter(state, getters) {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
Expand Down
4 changes: 4 additions & 0 deletions src/store/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1859,6 +1859,10 @@ export type ProjectStoreTypes = {
}): "saved" | "discarded" | "canceled";
};

GET_INITIAL_PROJECT_FILE_PATH: {
action(): Promise<string | undefined>;
};

IS_EDITED: {
getter: boolean;
};
Expand Down
5 changes: 5 additions & 0 deletions src/type/ipc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ export type IpcIHData = {
return: AltPortInfos;
};

GET_INITIAL_PROJECT_FILE_PATH: {
args: [];
return: string | undefined;
};

SHOW_SAVE_DIRECTORY_DIALOG: {
args: [obj: { title: string }];
return?: string;
Expand Down
1 change: 1 addition & 0 deletions src/type/preload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ export interface Sandbox {
getAppInfos(): Promise<AppInfos>;
getTextAsset<K extends keyof TextAsset>(textType: K): Promise<TextAsset[K]>;
getAltPortInfos(): Promise<AltPortInfos>;
getInitialProjectFilePath(): Promise<string | undefined>;
showSaveDirectoryDialog(obj: { title: string }): Promise<string | undefined>;
showVvppOpenDialog(obj: {
title: string;
Expand Down
9 changes: 8 additions & 1 deletion vite.config.mts
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,14 @@ export default defineConfig((options) => {
onstart: ({ startup }) => {
console.log("main process build is complete.");
if (!skipLaunchElectron) {
void startup([".", "--no-sandbox"]);
// ここのprocess.argvは以下のような形で渡ってくる:
// ["node", ".../vite.js", (...vite用の引数...), "--", その他引数...]
const args: string[] = [".", "--no-sandbox"];
const doubleDashIndex = process.argv.indexOf("--");
if (doubleDashIndex !== -1) {
args.push("--", ...process.argv.slice(doubleDashIndex + 1));
}
void startup(args);
}
},
vite: {
Expand Down

0 comments on commit 41d6666

Please sign in to comment.