Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: WindowManagerを追加 #2455

Merged
merged 13 commits into from
Jan 2, 2025
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 6 additions & 15 deletions src/backend/electron/engineAndVvppController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import path from "path";
import fs from "fs";
import { ReadableStream } from "node:stream/web";
import log from "electron-log/main";
import { dialog, MessageBoxSyncOptions } from "electron";
import { dialog } from "electron";

import { getConfigManager } from "./electronConfig";
import { getEngineInfoManager } from "./manager/engineInfoManager";
Expand Down Expand Up @@ -79,33 +79,24 @@ export class EngineAndVvppController {
reloadCallback?: () => void; // 再読み込みが必要な場合のコールバック
}) {
// FIXME: dialog表示関数をDI可能にする。
Hiroshiba marked this conversation as resolved.
Show resolved Hide resolved
const win = getWindowManager().win;
const option: MessageBoxSyncOptions = {
const windowManager = getWindowManager();
const result = windowManager.showMessageBoxSync({
type: "warning",
title: "エンジン追加の確認",
message: `この操作はコンピュータに損害を与える可能性があります。エンジンの配布元が信頼できない場合は追加しないでください。`,
buttons: ["追加", "キャンセル"],
noLink: true,
cancelId: 1,
};
let result: number;
if (win != undefined) {
result = dialog.showMessageBoxSync(win, option);
} else {
result = dialog.showMessageBoxSync(option);
}
});
if (result == 1) {
return;
}

await this.installVvppEngine(vvppPath);

if (reloadNeeded) {
if (win == undefined) {
throw new Error("win == undefined");
}
void dialog
.showMessageBox(win, {
void windowManager
.showMessageBox({
type: "info",
title: "再読み込みが必要です",
message:
Expand Down
69 changes: 26 additions & 43 deletions src/backend/electron/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,7 @@ import path from "path";

import fs from "fs";
import { pathToFileURL } from "url";
import {
app,
dialog,
Menu,
MessageBoxSyncOptions,
nativeTheme,
net,
protocol,
shell,
} from "electron";
import { app, dialog, Menu, nativeTheme, net, protocol, shell } from "electron";
import installExtension, { VUEJS_DEVTOOLS } from "electron-devtools-installer";

import log from "electron-log/main";
Expand Down Expand Up @@ -240,19 +231,13 @@ function openEngineDirectory(engineId: EngineId) {
function checkMultiEngineEnabled(): boolean {
const enabled = configManager.get("enableMultiEngine");
if (!enabled) {
const win = windowManager.win;
const option: MessageBoxSyncOptions = {
windowManager.showMessageBoxSync({
type: "info",
title: "マルチエンジン機能が無効です",
message: `マルチエンジン機能が無効です。vvppファイルを使用するには設定からマルチエンジン機能を有効にしてください。`,
buttons: ["OK"],
noLink: true,
};
if (win != undefined) {
dialog.showMessageBoxSync(win, option);
} else {
dialog.showMessageBoxSync(option);
}
});
}
return enabled;
}
Expand Down Expand Up @@ -314,17 +299,14 @@ const retryShowSaveDialogWhileSafeDir = async <
*/
const showWarningDialog = async () => {
const productName = app.getName().toUpperCase();
const warningResult = await dialog.showMessageBox(
windowManager.getWindow(),
{
message: `指定された保存先は${productName}により自動的に削除される可能性があります。\n他の場所に保存することをおすすめします。`,
type: "warning",
buttons: ["保存場所を変更", "無視して保存"],
defaultId: 0,
title: "警告",
cancelId: 0,
},
);
const warningResult = await windowManager.showMessageBox({
message: `指定された保存先は${productName}により自動的に削除される可能性があります。\n他の場所に保存することをおすすめします。`,
type: "warning",
buttons: ["保存場所を変更", "無視して保存"],
defaultId: 0,
title: "警告",
cancelId: 0,
});
return warningResult.response === 0 ? "retry" : "forceSave";
};

Expand Down Expand Up @@ -375,7 +357,7 @@ registerIpcMainHandle<IpcMainHandle>({
*/
SHOW_SAVE_DIRECTORY_DIALOG: async (_, { title }) => {
const result = await retryShowSaveDialogWhileSafeDir(() =>
dialog.showOpenDialog(windowManager.getWindow(), {
windowManager.showOpenDialog({
title,
properties: [
"openDirectory",
Expand All @@ -391,7 +373,7 @@ registerIpcMainHandle<IpcMainHandle>({
},

SHOW_VVPP_OPEN_DIALOG: async (_, { title, defaultPath }) => {
const result = await dialog.showOpenDialog(windowManager.getWindow(), {
const result = await windowManager.showOpenDialog({
title,
defaultPath,
filters: [
Expand All @@ -407,7 +389,7 @@ registerIpcMainHandle<IpcMainHandle>({
* 保存先として選ぶ場合は SHOW_SAVE_DIRECTORY_DIALOG を使うべき。
*/
SHOW_OPEN_DIRECTORY_DIALOG: async (_, { title }) => {
const result = await dialog.showOpenDialog(windowManager.getWindow(), {
const result = await windowManager.showOpenDialog({
title,
properties: [
"openDirectory",
Expand All @@ -423,7 +405,7 @@ registerIpcMainHandle<IpcMainHandle>({

SHOW_PROJECT_SAVE_DIALOG: async (_, { title, defaultPath }) => {
const result = await retryShowSaveDialogWhileSafeDir(() =>
dialog.showSaveDialog(windowManager.getWindow(), {
windowManager.showSaveDialog({
title,
defaultPath,
filters: [{ name: "VOICEVOX Project file", extensions: ["vvproj"] }],
Expand All @@ -437,7 +419,7 @@ registerIpcMainHandle<IpcMainHandle>({
},

SHOW_PROJECT_LOAD_DIALOG: async (_, { title }) => {
const result = await dialog.showOpenDialog(windowManager.getWindow(), {
const result = await windowManager.showOpenDialog({
title,
filters: [{ name: "VOICEVOX Project file", extensions: ["vvproj"] }],
properties: ["openFile", "createDirectory", "treatPackageAsDirectory"],
Expand All @@ -449,23 +431,23 @@ registerIpcMainHandle<IpcMainHandle>({
},

SHOW_WARNING_DIALOG: (_, { title, message }) => {
return dialog.showMessageBox(windowManager.getWindow(), {
return windowManager.showMessageBox({
type: "warning",
title,
message,
});
},

SHOW_ERROR_DIALOG: (_, { title, message }) => {
return dialog.showMessageBox(windowManager.getWindow(), {
return windowManager.showMessageBox({
type: "error",
title,
message,
});
},

SHOW_IMPORT_FILE_DIALOG: (_, { title, name, extensions }) => {
return dialog.showOpenDialogSync(windowManager.getWindow(), {
return windowManager.showOpenDialogSync({
title,
filters: [{ name: name ?? "Text", extensions: extensions ?? ["txt"] }],
properties: ["openFile", "createDirectory", "treatPackageAsDirectory"],
Expand All @@ -477,7 +459,7 @@ registerIpcMainHandle<IpcMainHandle>({
{ title, defaultPath, extensionName, extensions },
) => {
const result = await retryShowSaveDialogWhileSafeDir(() =>
dialog.showSaveDialog(windowManager.getWindow(), {
windowManager.showSaveDialog({
title,
defaultPath,
filters: [{ name: extensionName, extensions: extensions }],
Expand All @@ -492,15 +474,15 @@ registerIpcMainHandle<IpcMainHandle>({
},

IS_MAXIMIZED_WINDOW: () => {
return windowManager.getWindow().isMaximized();
return windowManager.isMaximized();
},

CLOSE_WINDOW: () => {
appState.willQuit = true;
windowManager.getWindow().destroy();
windowManager.destroyWindow();
},
MINIMIZE_WINDOW: () => {
windowManager.getWindow().minimize();
windowManager.minimize();
},
TOGGLE_MAXIMIZE_WINDOW: () => {
windowManager.toggleMaximizeWindow();
Expand Down Expand Up @@ -552,7 +534,7 @@ registerIpcMainHandle<IpcMainHandle>({
},

ON_VUEX_READY: () => {
windowManager.getWindow().show();
windowManager.show();
},

CHECK_FILE_EXISTS: (_, { file }) => {
Expand Down Expand Up @@ -877,7 +859,8 @@ app.on("second-instance", async (_event, _argv, _workDir, rawData) => {
const data = rawData as SingleInstanceLockData;
const win = windowManager.win;
if (win == undefined) {
// 起動中または終了中に来た場合は諦める
// TODO: 起動中の場合Windowが作られるまで待つ
Hiroshiba marked this conversation as resolved.
Show resolved Hide resolved
log.warn("A 'second-instance' event was emitted but there is no window.");
return;
}
if (!data.filePath) {
Expand Down
56 changes: 55 additions & 1 deletion src/backend/electron/manager/windowManager.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
import fs from "fs";
import path from "path";
import { BrowserWindow } from "electron";
import {
BrowserWindow,
dialog,
MessageBoxOptions,
MessageBoxSyncOptions,
OpenDialogOptions,
OpenDialogSyncOptions,
SaveDialogOptions,
} from "electron";
import log from "electron-log/main";
import windowStateKeeper from "electron-window-state";
import { getConfigManager } from "../electronConfig";
Expand Down Expand Up @@ -245,6 +253,52 @@ class WindowManager {
const win = this.getWindow();
win.webContents.setZoomFactor(1);
}

public destroyWindow() {
this.getWindow().destroy();
}

public show() {
this.getWindow().show();
}

public minimize() {
this.getWindow().minimize();
}

public isMaximized() {
return this.getWindow().isMaximized();
}

public showOpenDialogSync(options: OpenDialogSyncOptions) {
return this._win == undefined
? dialog.showOpenDialogSync(options)
: dialog.showOpenDialogSync(this.getWindow(), options);
}

public showOpenDialog(options: OpenDialogOptions) {
return this._win == undefined
? dialog.showOpenDialog(options)
: dialog.showOpenDialog(this.getWindow(), options);
}

public showSaveDialog(options: SaveDialogOptions) {
return this._win == undefined
? dialog.showSaveDialog(options)
: dialog.showSaveDialog(this.getWindow(), options);
}

public showMessageBoxSync(options: MessageBoxSyncOptions) {
return this._win == undefined
? dialog.showMessageBoxSync(options)
: dialog.showMessageBoxSync(this.getWindow(), options);
}

public showMessageBox(options: MessageBoxOptions) {
return this._win == undefined
? dialog.showMessageBox(options)
: dialog.showMessageBox(this.getWindow(), options);
}
}

let windowManager: WindowManager | undefined;
Expand Down
Loading