diff --git a/src/background.ts b/src/background.ts index c73d12d1e7..6cb427ee62 100644 --- a/src/background.ts +++ b/src/background.ts @@ -967,30 +967,82 @@ app.once("will-finish-launching", () => { app.on("ready", async () => { await configManager.initialize().catch(async (e) => { log.error(e); - await dialog - .showMessageBox({ - type: "error", - title: "設定ファイルの読み込みエラー", - message: `設定ファイルの読み込みに失敗しました。${app.getPath( - "userData" - )} にある config.json の名前を変えることで解決することがあります(ただし設定がすべてリセットされます)。設定ファイルがあるフォルダを開きますか?`, - buttons: ["いいえ", "はい"], - noLink: true, - cancelId: 0, - }) - .then(async ({ response }) => { - if (response === 1) { - await shell.openPath(app.getPath("userData")); - // 直後にexitするとフォルダが開かないため - await new Promise((resolve) => { - setTimeout(resolve, 500); - }); - } - }) - .finally(async () => { - await configManager.ensureSaved(); - app.exit(1); + + const appExit = async () => { + await configManager?.ensureSaved(); + app.exit(1); + }; + const openConfigFolderAndExit = async () => { + await shell.openPath(app.getPath("userData")); + // 直後にexitするとフォルダが開かないため + await new Promise((resolve) => { + setTimeout(resolve, 500); }); + await appExit(); + }; + const resetConfig = async () => { + configManager.reset(); + await configManager.ensureSaved(); + }; + + // 実利用時はconfigファイル削除で解決する可能性があることを案内して終了 + if (!isDevelopment) { + await dialog + .showMessageBox({ + type: "error", + title: "設定ファイルの読み込みエラー", + message: `設定ファイルの読み込みに失敗しました。${app.getPath( + "userData" + )} にある config.json の名前を変えることで解決することがあります(ただし設定がすべてリセットされます)。設定ファイルがあるフォルダを開きますか?`, + buttons: ["いいえ", "はい"], + noLink: true, + cancelId: 0, + }) + .then(async ({ response }) => { + switch (response) { + case 0: + await appExit(); + break; + case 1: + await openConfigFolderAndExit(); + break; + default: + throw new Error(`Unknown response: ${response}`); + } + }); + } + + // 開発時はconfigをリセットして起動を続行するかも問う + else { + await dialog + .showMessageBox({ + type: "error", + title: "設定ファイルの読み込みエラー(開発者向け案内)", + message: `設定ファイルの読み込みに失敗しました。設定ファイルの名前を変更するか、設定をリセットしてください。`, + buttons: [ + "何もせず終了", + "設定ファイルのフォルダを開いて終了", + "設定をリセットして続行", + ], + noLink: true, + cancelId: 0, + }) + .then(async ({ response }) => { + switch (response) { + case 0: + await appExit(); + break; + case 1: + await openConfigFolderAndExit(); + break; + case 2: + await resetConfig(); + break; + default: + throw new Error(`Unknown response: ${response}`); + } + }); + } }); if (isDevelopment && !isTest) { diff --git a/src/shared/ConfigManager.ts b/src/shared/ConfigManager.ts index fd5e61a095..0995c27556 100644 --- a/src/shared/ConfigManager.ts +++ b/src/shared/ConfigManager.ts @@ -129,6 +129,11 @@ export abstract class BaseConfigManager { protected abstract getAppVersion(): string; + public reset() { + this.config = this.getDefaultConfig(); + this._save(); + } + public async initialize(): Promise { if (await this.exists()) { const data = await this.load(); @@ -139,10 +144,10 @@ export abstract class BaseConfigManager { } } this.config = this.migrateHotkeySettings(configSchema.parse(data)); + this._save(); } else { - this.config = this.getDefaultConfig(); + this.reset(); } - this._save(); await this.ensureSaved(); return this;