From fef6a0bc2968ecf85be9185370402162dac40163 Mon Sep 17 00:00:00 2001 From: 2sky <2skydev@gmail.com> Date: Tue, 10 Oct 2023 00:18:05 +0900 Subject: [PATCH 1/2] =?UTF-8?q?=F0=9F=90=9B=20fix:=20i18n=20lng=20fallback?= =?UTF-8?q?=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/modules/electron/electron.service.ts | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/main/modules/electron/electron.service.ts b/src/main/modules/electron/electron.service.ts index 625e2f2..fc5eac0 100644 --- a/src/main/modules/electron/electron.service.ts +++ b/src/main/modules/electron/electron.service.ts @@ -443,13 +443,6 @@ export const generatedIpcOnContext = {` } private async initI18Next() { - const systemLocale = app.getSystemLocale().replace('-', '_') - const savedLanguage = this.configService.get('general.language') - - if (!savedLanguage) { - this.configService.set('general.language', systemLocale) - } - const fileNames = await readdir(`${this.RESOURCES_PATH}/locales`) const files = await Promise.all( @@ -458,7 +451,7 @@ export const generatedIpcOnContext = {` ), ) - const resources = files.reduce((resources, file, index) => { + const resources: Record = files.reduce((resources, file, index) => { const json = jsoncParse(file) const locale = fileNames[index].replace('.json', '') @@ -474,10 +467,19 @@ export const generatedIpcOnContext = {` return resources }, {}) + const systemLocale = app.getSystemLocale().replace('-', '_') + const configLocale = this.configService.get('general.language') + + const inputLocale = configLocale ?? systemLocale + const outputLocale = resources[inputLocale] ? inputLocale : 'en_US' + await i18next.init({ - lng: savedLanguage ?? systemLocale, - fallbackLng: 'ko_KR', + lng: outputLocale, resources, }) + + if (!configLocale) { + this.configService.set('general.language', outputLocale) + } } } From d0df1e31c4cdbe6b904d7775f9f02a6c904179ad Mon Sep 17 00:00:00 2001 From: 2sky <2skydev@gmail.com> Date: Tue, 10 Oct 2023 02:03:38 +0900 Subject: [PATCH 2/2] =?UTF-8?q?=F0=9F=90=9B=20fix:=20=EB=A7=88=EC=9D=B4?= =?UTF-8?q?=EA=B7=B8=EB=A0=88=EC=9D=B4=EC=85=98=20=EB=8F=99=EC=9E=91=20?= =?UTF-8?q?=EB=B0=A9=EC=8B=9D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../modules/migration/migration.module.ts | 113 ++++++++++++++---- src/main/modules/migration/migration.store.ts | 6 +- 2 files changed, 95 insertions(+), 24 deletions(-) diff --git a/src/main/modules/migration/migration.module.ts b/src/main/modules/migration/migration.module.ts index 4d00e09..228f325 100644 --- a/src/main/modules/migration/migration.module.ts +++ b/src/main/modules/migration/migration.module.ts @@ -3,7 +3,8 @@ import log from 'electron-log' import { Module } from '@nestjs/common' import AutoLaunch from 'auto-launch' -import { gt, valid } from 'semver' +import { omit } from 'lodash' +import { lte, valid } from 'semver' import { configStore } from '@main/modules/config/config.store' import { migrationStore } from '@main/modules/migration/migration.store' @@ -11,24 +12,64 @@ import { migrationStore } from '@main/modules/migration/migration.store' @Module({}) export class MigrationModule { public static async forRootAsync() { - let currentVersion = `v${app.getVersion()}` + const currentVersion = `v${app.getVersion()}` + const initialInstallationVersion = migrationStore.get('initialInstallationVersion') + const isInitialInstallation = + !initialInstallationVersion && + !Object.keys(omit(migrationStore.store, ['migratedVersions', 'initialInstallationVersion'])) + .length - // 개발 모드에서는 가장 최신 버전으로 마이그레이션 - if (!app.isPackaged) { - const versions = Object.getOwnPropertyNames(this).filter(propertyName => valid(propertyName)) - const latestVersion = versions.find(version => gt(version, currentVersion)) - currentVersion = latestVersion || currentVersion - } + let migratedVersions = migrationStore.get('migratedVersions') + let executedMigrationVersions = migrationStore.get('executedMigrationVersions') + + // 마이그레이션 스토어가 비어있는 경우 + if (!migratedVersions || !executedMigrationVersions) { + migratedVersions = [] + executedMigrationVersions = [] - if (!migrationStore.get(currentVersion)) { - if (this[currentVersion]) { - await this[currentVersion]() - log.info(`[Migration Module] Migrated to ${currentVersion}`) - } else { - log.info(`[Migration Module] Migration for ${currentVersion} not found`) + migrationStore.store = { + initialInstallationVersion: currentVersion, + migratedVersions, + executedMigrationVersions, } + } + + // 선언된 모든 마이그레이션 불러오기 + const migrationVersions = Object.getOwnPropertyNames(this).filter(propertyName => + valid(propertyName), + ) + + if (isInitialInstallation) { + // 초기 설치라면 현재 모든 마이그레이션을 실행할 필요가 없으므로 실행된 것으로 간주 + migrationStore.set('migratedVersions', migrationVersions) + } else { + // 초기 설치가 아니라면 마이그레이션 실행 + const executableMigrationVersions = migrationVersions.filter(version => { + const isExecutable = !migratedVersions!.includes(version) + + // 개발 모드라면 버전 비교 없이 실행 + if (!app.isPackaged) return isExecutable - migrationStore.set(currentVersion, true) + // 프로덕션 모드라면 하위 및 같은 버전만 실행 + return isExecutable && lte(version, currentVersion) + }) + + // 실행 가능한 마이그레이션이 있다면 실행 + if (executableMigrationVersions.length) { + for (const version of executableMigrationVersions) { + try { + await this[version]() + log.info(`[Migration Module] Migrated to ${currentVersion}`) + } catch (error) { + log.error(`[Migration Module] ${currentVersion}`, error) + } + } + + migratedVersions.push(...executableMigrationVersions) + executedMigrationVersions.push(...executableMigrationVersions) + migrationStore.set('migratedVersions', migratedVersions) + migrationStore.set('executedMigrationVersions', executedMigrationVersions) + } } return { @@ -37,7 +78,9 @@ export class MigrationModule { } public static async 'v0.0.5'() { - configStore.set('general.openWindowWhenLeagueClientLaunch', true) + if (configStore.get('general.openWindowWhenLeagueClientLaunch') === undefined) { + configStore.set('general.openWindowWhenLeagueClientLaunch', true) + } if (configStore.get('general.autoLaunch')) { const ladaAutoLauncher = new AutoLaunch({ @@ -52,24 +95,48 @@ export class MigrationModule { } public static async 'v0.0.11'() { - configStore.set('game.useCurrentPositionChampionData', true) + if (configStore.get('game.useCurrentPositionChampionData') === undefined) { + configStore.set('game.useCurrentPositionChampionData', true) + } } public static async 'v0.0.16'() { - configStore.set('general.zoom', 1.0) + if (configStore.get('general.zoom') === undefined) { + configStore.set('general.zoom', 1.0) + } } public static async 'v0.0.17'() { - configStore.set('game.statsProvider', 'LOL.PS') - configStore.set('game.autoRuneSetting', true) + if (configStore.get('game.statsProvider') === undefined) { + configStore.set('game.statsProvider', 'LOL.PS') + } + + if (configStore.get('game.autoRuneSetting') === undefined) { + configStore.set('game.autoRuneSetting', true) + } } public static async 'v0.0.18'() { - configStore.set('game.autoSummonerSpellSetting', true) - configStore.set('game.flashKey', 'F') + if (configStore.get('game.autoSummonerSpellSetting') === undefined) { + configStore.set('game.autoSummonerSpellSetting', true) + } + + if (configStore.get('game.flashKey') === undefined) { + configStore.set('game.flashKey', 'F') + } } public static async 'v0.0.19'() { - configStore.set('general.language', null) + if (configStore.get('general.language') === undefined) { + configStore.set('general.language', null) + } + } + + public static async 'v0.0.22'() { + const language = configStore.get('general.language') as string | undefined | null + + if (language && !['en_US', 'ko_KR'].includes(language)) { + configStore.set('general.language', null) + } } } diff --git a/src/main/modules/migration/migration.store.ts b/src/main/modules/migration/migration.store.ts index 4f886fd..a0a215d 100644 --- a/src/main/modules/migration/migration.store.ts +++ b/src/main/modules/migration/migration.store.ts @@ -1,6 +1,10 @@ import Store from 'electron-store' -export type MigrationStoreValues = Record +export interface MigrationStoreValues { + initialInstallationVersion?: string + migratedVersions?: string[] + executedMigrationVersions?: string[] +} export const migrationStore = new Store({ name: 'migration',