From 788bea0016f9eabfe32edd3b889c6e11332112ea Mon Sep 17 00:00:00 2001 From: Jakob Scheid Date: Fri, 7 Aug 2026 00:50:13 +0200 Subject: [PATCH] refactor(i18n): move currentLanguage utility to correct location Moved src/utils/currentLanguage.js to src/features/i18n/utils/navigatorLanguage.js and updated it to only parse the navigator language. --- .../utils/__tests__/navigatorLanguage.test.js | 51 ++++++++++++++++ .../i18n/utils/navigatorLanguage.js} | 4 +- src/i18n.js | 3 +- src/main.js | 4 +- src/utils/__tests__/currentLanguage.test.js | 61 ------------------- 5 files changed, 54 insertions(+), 69 deletions(-) create mode 100644 src/features/i18n/utils/__tests__/navigatorLanguage.test.js rename src/{utils/currentLanguage.js => features/i18n/utils/navigatorLanguage.js} (83%) delete mode 100644 src/utils/__tests__/currentLanguage.test.js diff --git a/src/features/i18n/utils/__tests__/navigatorLanguage.test.js b/src/features/i18n/utils/__tests__/navigatorLanguage.test.js new file mode 100644 index 0000000..78b91f4 --- /dev/null +++ b/src/features/i18n/utils/__tests__/navigatorLanguage.test.js @@ -0,0 +1,51 @@ +/* +Copyright 2026 Seekra + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import { getNavigatorLanguage } from '../navigatorLanguage'; +import { describe, expect, test } from 'vitest'; + +describe('navigatorLanguage', () => { + test.for([ + { navigatorLanguage: 'en', expected: 'en'}, + { navigatorLanguage: 'de', expected: 'de'}, + { navigatorLanguage: 'fr', expected: 'fr'}, + + { navigatorLanguage: 'en-US', expected: 'en'}, + { navigatorLanguage: 'en-AU', expected: 'en'}, + { navigatorLanguage: 'de-DE', expected: 'de'}, + { navigatorLanguage: 'fr-FR', expected: 'fr'}, + + { navigatorLanguage: 'en-us', expected: 'en'}, + { navigatorLanguage: 'en-au', expected: 'en'}, + { navigatorLanguage: 'de-de', expected: 'de'}, + { navigatorLanguage: 'fr-fr', expected: 'fr'}, + + { navigatorLanguage: 'zh-Hans-CN', expected: 'zh'}, + { navigatorLanguage: 'zh-Hant-TW', expected: 'zh'}, + { navigatorLanguage: 'uz-Latn-UZ', expected: 'uz'}, + + { navigatorLanguage: 'en-US-u-ca-gregory', expected: 'en'}, + { navigatorLanguage: 'de-DE-u-co-phonebk', expected: 'de'}, + { navigatorLanguage: 'zh-Hant-TW-u-co-phonebk', expected: 'zh'} + ])('returns language $expected with navigator language $navigatorLanguage', ({ navigatorLanguage, expected }) => { + Object.defineProperty(navigator, 'language', { + value: navigatorLanguage, + configurable: true + }); + + expect(getNavigatorLanguage()).toBe(expected); + }); +}); diff --git a/src/utils/currentLanguage.js b/src/features/i18n/utils/navigatorLanguage.js similarity index 83% rename from src/utils/currentLanguage.js rename to src/features/i18n/utils/navigatorLanguage.js index 4d568e6..adddf26 100644 --- a/src/utils/currentLanguage.js +++ b/src/features/i18n/utils/navigatorLanguage.js @@ -14,9 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -export default function getCurrentLanguage () { - const saved = localStorage.getItem('locale'); - if (saved) return saved; +export const getNavigatorLanguage = function getNavigatorLanguage () { const locale = new Intl.Locale(navigator.language); return locale.language; }; \ No newline at end of file diff --git a/src/i18n.js b/src/i18n.js index 3a16b74..24e7d1f 100644 --- a/src/i18n.js +++ b/src/i18n.js @@ -15,7 +15,6 @@ limitations under the License. */ import { createI18n } from 'vue-i18n'; -import getCurrentLanguage from './utils/currentLanguage'; export const fallbackLocale = 'en'; @@ -34,7 +33,7 @@ export const SUPPORTED_LANGUAGES = [ export const i18n = createI18n({ legacy: false, - locale: getCurrentLanguage(), + locale: fallbackLocale, fallbackLocale: fallbackLocale, messages: {} }); diff --git a/src/main.js b/src/main.js index 1b54fcb..c57f941 100644 --- a/src/main.js +++ b/src/main.js @@ -20,7 +20,6 @@ import { createPinia } from 'pinia'; import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'; import App from './App.vue' import { i18n, loadLanguage, fallbackLocale } from './i18n'; -import getCurrentLanguage from './utils/currentLanguage'; import router from './router' import './styles/common.css' import './styles/variables/colors.css' @@ -53,8 +52,7 @@ import { validateSettingsConfig } from './features/settings/utils/settingsValida fonts.forEach((font) => document.fonts.add(font)); await loadLanguage(fallbackLocale); - await loadLanguage(getCurrentLanguage()); - + const pinia = createPinia(); pinia.use(piniaPluginPersistedstate); diff --git a/src/utils/__tests__/currentLanguage.test.js b/src/utils/__tests__/currentLanguage.test.js deleted file mode 100644 index 079dee8..0000000 --- a/src/utils/__tests__/currentLanguage.test.js +++ /dev/null @@ -1,61 +0,0 @@ -/* -Copyright 2026 Seekra - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -import { describe, expect, test } from 'vitest'; -import getCurrentLanguage from '../currentLanguage'; - -describe('currentLanguage', () => { - test.for([ - { navigatorLanguage: 'en', localStorageLanguage: null, expected: 'en'}, - { navigatorLanguage: 'de', localStorageLanguage: null, expected: 'de'}, - { navigatorLanguage: 'fr', localStorageLanguage: null, expected: 'fr'}, - - { navigatorLanguage: 'en-US', localStorageLanguage: null, expected: 'en'}, - { navigatorLanguage: 'en-AU', localStorageLanguage: null, expected: 'en'}, - { navigatorLanguage: 'de-DE', localStorageLanguage: null, expected: 'de'}, - { navigatorLanguage: 'fr-FR', localStorageLanguage: null, expected: 'fr'}, - - { navigatorLanguage: 'en-us', localStorageLanguage: null, expected: 'en'}, - { navigatorLanguage: 'en-au', localStorageLanguage: null, expected: 'en'}, - { navigatorLanguage: 'de-de', localStorageLanguage: null, expected: 'de'}, - { navigatorLanguage: 'fr-fr', localStorageLanguage: null, expected: 'fr'}, - - { navigatorLanguage: 'zh-Hans-CN', localStorageLanguage: null, expected: 'zh'}, - { navigatorLanguage: 'zh-Hant-TW', localStorageLanguage: null, expected: 'zh'}, - { navigatorLanguage: 'uz-Latn-UZ', localStorageLanguage: null, expected: 'uz'}, - - { navigatorLanguage: 'en-US-u-ca-gregory', localStorageLanguage: null, expected: 'en'}, - { navigatorLanguage: 'de-DE-u-co-phonebk', localStorageLanguage: null, expected: 'de'}, - { navigatorLanguage: 'zh-Hant-TW-u-co-phonebk', localStorageLanguage: null, expected: 'zh'}, - - { navigatorLanguage: 'en', localStorageLanguage: 'de', expected: 'de'}, - { navigatorLanguage: 'de-DE', localStorageLanguage: 'en', expected: 'en'}, - { navigatorLanguage: 'de-de', localStorageLanguage: 'en', expected: 'en'}, - { navigatorLanguage: 'zh-Hans-CN', localStorageLanguage: 'fr', expected: 'fr'}, - { navigatorLanguage: 'en-US-u-ca-gregory', localStorageLanguage: 'zh', expected: 'zh'} - ])('returns the language $expected (navigator: $navigatorLanguage; local storage: $localStorageLanguage)', ({ navigatorLanguage, localStorageLanguage, expected }) => { - Object.defineProperty(navigator, 'language', { - value: navigatorLanguage, - configurable: true - }); - - if (localStorageLanguage) { - localStorage.setItem('locale', localStorageLanguage); - }; - - expect(getCurrentLanguage()).toBe(expected); - }); -}); \ No newline at end of file