refactor: remove i18n dependency and related code
- Removed the i18n module and its related functions from the project. - Eliminated the usage of getActiveI18n and related locale handling in various components and stores. - Updated translation handling to use a new instance creation method. - Cleaned up unused imports and code related to language detection and cookie management. - Adjusted components to directly utilize the new translation setup.
This commit is contained in:
3
bun.lock
3
bun.lock
@@ -5,6 +5,7 @@
|
||||
"": {
|
||||
"name": "holistream",
|
||||
"dependencies": {
|
||||
"@hono/node-server": "^1.19.11",
|
||||
"@pinia/colada": "^0.21.7",
|
||||
"@unhead/vue": "^2.1.10",
|
||||
"@vueuse/core": "^14.2.1",
|
||||
@@ -169,6 +170,8 @@
|
||||
|
||||
"@esbuild/win32-x64": ["@esbuild/win32-x64@0.27.3", "", { "os": "win32", "cpu": "x64" }, "sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA=="],
|
||||
|
||||
"@hono/node-server": ["@hono/node-server@1.19.11", "", { "peerDependencies": { "hono": "^4" } }, "sha512-dr8/3zEaB+p0D2n/IUrlPF1HZm586qgJNXK1a9fhg/PzdtkK7Ksd5l312tJX2yBuALqDYBlG20QEbayqPyxn+g=="],
|
||||
|
||||
"@iconify/types": ["@iconify/types@2.0.0", "", {}, "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg=="],
|
||||
|
||||
"@iconify/utils": ["@iconify/utils@3.1.0", "", { "dependencies": { "@antfu/install-pkg": "^1.1.0", "@iconify/types": "^2.0.0", "mlly": "^1.8.0" } }, "sha512-Zlzem1ZXhI1iHeeERabLNzBHdOa4VhQbqAcOQaMKuTuyZCpwKbC2R4Dd0Zo3g9EAc+Y4fiarO8HIHRAth7+skw=="],
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
"tail": "wrangler tail"
|
||||
},
|
||||
"dependencies": {
|
||||
"@hono/node-server": "^1.19.11",
|
||||
"@pinia/colada": "^0.21.7",
|
||||
"@unhead/vue": "^2.1.10",
|
||||
"@vueuse/core": "^14.2.1",
|
||||
|
||||
@@ -13,10 +13,6 @@ async function render() {
|
||||
pinia.use(PiniaSharedState({ enable: true, initialize: true }));
|
||||
hydrateQueryCache(queryCache, appData.$colada || {});
|
||||
|
||||
Object.entries(appData).forEach(([key, value]) => {
|
||||
(window as any)[key] = value;
|
||||
});
|
||||
|
||||
await router.isReady();
|
||||
app.mount('body', true);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { computed, reactive, readonly } from 'vue';
|
||||
import { getActiveI18n } from '@/i18n';
|
||||
|
||||
export type AppConfirmOptions = {
|
||||
message: string;
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { getActiveI18n } from '@/i18n';
|
||||
import { computed, ref } from 'vue';
|
||||
|
||||
export interface QueueItem {
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
import type { i18n as I18nInstance } from 'i18next';
|
||||
|
||||
import { getClientI18nInstance } from '@/lib/translation/client';
|
||||
|
||||
import { defaultLocale, supportedLocales, type SupportedLocale } from './constants';
|
||||
|
||||
export { supportedLocales, defaultLocale } from './constants';
|
||||
export type { SupportedLocale } from './constants';
|
||||
export { localeCookieKey } from './constants';
|
||||
|
||||
export const normalizeLocale = (locale?: string): SupportedLocale => {
|
||||
if (!locale) return defaultLocale;
|
||||
const normalized = locale.toLowerCase().split('-')[0] as SupportedLocale;
|
||||
return supportedLocales.includes(normalized) ? normalized : defaultLocale;
|
||||
};
|
||||
|
||||
export const getActiveI18n = (): I18nInstance | undefined => {
|
||||
return import.meta.env.SSR ? undefined : getClientI18nInstance();
|
||||
};
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Hono } from 'hono';
|
||||
|
||||
import { serveStatic } from "@hono/node-server/serve-static";
|
||||
import { apiProxyMiddleware } from './server/middlewares/apiProxy';
|
||||
import { setupMiddlewares } from './server/middlewares/setup';
|
||||
import { registerDisplayRoutes } from './server/routes/display';
|
||||
@@ -15,7 +16,7 @@ setupMiddlewares(app);
|
||||
|
||||
// API proxy middleware (handles /r/*)
|
||||
app.use(apiProxyMiddleware);
|
||||
|
||||
app.use(serveStatic({ root: './public' }))
|
||||
// Routes
|
||||
registerWellKnownRoutes(app);
|
||||
registerMergeRoutes(app);
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
import type { i18n as I18nInstance } from 'i18next';
|
||||
|
||||
import { createI18nInstance, initI18nInstance } from '@/lib/translation';
|
||||
|
||||
let clientI18n: I18nInstance | undefined;
|
||||
|
||||
export const createI18nForClient = async (language?: string) => {
|
||||
if (!clientI18n) {
|
||||
clientI18n = createI18nInstance(false);
|
||||
}
|
||||
|
||||
return initI18nInstance(clientI18n, language, false);
|
||||
};
|
||||
|
||||
export const getClientI18nInstance = () => clientI18n;
|
||||
@@ -1,75 +1,44 @@
|
||||
import i18next, { type i18n as I18nInstance } from 'i18next';
|
||||
import LanguageDetector from 'i18next-browser-languagedetector';
|
||||
import I18NextHttpBackend from 'i18next-http-backend';
|
||||
import i18next from "i18next";
|
||||
import LanguageDetector from "i18next-browser-languagedetector";
|
||||
import I18NextHttpBackend, { HttpBackendOptions } from "i18next-http-backend";
|
||||
const backendOptions: HttpBackendOptions = {
|
||||
loadPath: 'http://localhost:5173/locales/{{lng}}/{{ns}}.json',
|
||||
request: (_options, url, _payload, callback) => {
|
||||
fetch(url)
|
||||
.then((res) =>
|
||||
res.json().then((r) => {
|
||||
callback(null, {
|
||||
data: JSON.stringify(r),
|
||||
status: 200,
|
||||
})
|
||||
})
|
||||
)
|
||||
.catch(() => {
|
||||
callback(null, {
|
||||
status: 500,
|
||||
data: '',
|
||||
})
|
||||
})
|
||||
},
|
||||
}
|
||||
export const createI18nInstance = (lng: string) => {
|
||||
console.log('Initializing i18n with language:', lng);
|
||||
const i18n = i18next.createInstance();
|
||||
|
||||
import { defaultLocale, localeCookieKey, supportedLocales, type SupportedLocale } from '@/i18n/constants';
|
||||
|
||||
const runtimeNamespace = 'translation';
|
||||
|
||||
const normalizeLanguage = (language?: string): SupportedLocale => {
|
||||
if (!language) return defaultLocale;
|
||||
const normalized = language.toLowerCase().split('-')[0] as SupportedLocale;
|
||||
return supportedLocales.includes(normalized) ? normalized : defaultLocale;
|
||||
};
|
||||
|
||||
const getLoadPath = () => {
|
||||
const cdnBase = import.meta.env.VITE_I18N_CDN_BASE_URL?.trim().replace(/\/+$/, '');
|
||||
if (cdnBase) {
|
||||
return `${cdnBase}/locales/{{lng}}/{{lng}}.json`;
|
||||
}
|
||||
return '/locales/{{lng}}/{{lng}}.json';
|
||||
};
|
||||
|
||||
export const createI18nInstance = (forServer: boolean) => {
|
||||
const instance = i18next.createInstance();
|
||||
|
||||
instance.use(I18NextHttpBackend);
|
||||
if (!forServer) {
|
||||
instance.use(LanguageDetector);
|
||||
}
|
||||
|
||||
return instance;
|
||||
};
|
||||
|
||||
export const initI18nInstance = async (
|
||||
instance: I18nInstance,
|
||||
language?: string,
|
||||
forServer: boolean = import.meta.env.SSR,
|
||||
) => {
|
||||
const lng = normalizeLanguage(language);
|
||||
|
||||
if (!instance.isInitialized) {
|
||||
await instance.init({
|
||||
supportedLngs: [...supportedLocales],
|
||||
fallbackLng: defaultLocale,
|
||||
load: 'languageOnly',
|
||||
lng,
|
||||
ns: [runtimeNamespace],
|
||||
defaultNS: runtimeNamespace,
|
||||
fallbackNS: runtimeNamespace,
|
||||
interpolation: {
|
||||
escapeValue: false,
|
||||
},
|
||||
backend: {
|
||||
loadPath: getLoadPath(),
|
||||
},
|
||||
...(forServer
|
||||
? {}
|
||||
: {
|
||||
detection: {
|
||||
order: ['cookie', 'navigator', 'htmlTag'],
|
||||
lookupCookie: localeCookieKey,
|
||||
caches: ['cookie'],
|
||||
},
|
||||
}),
|
||||
});
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
if (instance.resolvedLanguage !== lng) {
|
||||
await instance.changeLanguage(lng);
|
||||
}
|
||||
|
||||
return instance;
|
||||
i18n
|
||||
.use(I18NextHttpBackend)
|
||||
.use(LanguageDetector)
|
||||
.init({
|
||||
lng,
|
||||
supportedLngs: ["en", "vi"],
|
||||
fallbackLng: "en",
|
||||
defaultNS: "translation",
|
||||
ns: ['translation'],
|
||||
interpolation: {
|
||||
escapeValue: false,
|
||||
},
|
||||
backend: backendOptions,
|
||||
});
|
||||
return i18n;
|
||||
};
|
||||
export default createI18nInstance;
|
||||
@@ -1,6 +1,5 @@
|
||||
import type { ClassValue } from "clsx";
|
||||
import { clsx } from "clsx";
|
||||
import { getActiveI18n } from '@/i18n';
|
||||
import { twMerge } from "tailwind-merge";
|
||||
|
||||
export function cn(...inputs: ClassValue[]) {
|
||||
@@ -52,10 +51,10 @@ export function getImageAspectRatio(url: string): Promise<AspectInfo> {
|
||||
|
||||
|
||||
|
||||
const getRuntimeLocaleTag = () => {
|
||||
const locale = getActiveI18n()?.resolvedLanguage;
|
||||
return locale === 'vi' ? 'vi-VN' : 'en-US';
|
||||
};
|
||||
// const getRuntimeLocaleTag = () => {
|
||||
// const locale = getActiveI18n()?.resolvedLanguage;
|
||||
// return locale === 'vi' ? 'vi-VN' : 'en-US';
|
||||
// };
|
||||
|
||||
export const formatBytes = (bytes?: number) => {
|
||||
if (!bytes) return '0 B';
|
||||
@@ -63,7 +62,8 @@ export const formatBytes = (bytes?: number) => {
|
||||
const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];
|
||||
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
||||
const value = parseFloat((bytes / Math.pow(k, i)).toFixed(2));
|
||||
return `${new Intl.NumberFormat(getRuntimeLocaleTag()).format(value)} ${sizes[i]}`;
|
||||
return `${value} ${sizes[i]}`;
|
||||
// return `${new Intl.NumberFormat(getRuntimeLocaleTag()).format(value)} ${sizes[i]}`;
|
||||
};
|
||||
|
||||
export const formatDuration = (seconds?: number) => {
|
||||
@@ -80,7 +80,7 @@ export const formatDuration = (seconds?: number) => {
|
||||
|
||||
export const formatDate = (dateString: string = "", dateOnly: boolean = false) => {
|
||||
if (!dateString) return '';
|
||||
return new Date(dateString).toLocaleDateString(getRuntimeLocaleTag(), {
|
||||
return new Date(dateString).toLocaleDateString("en-US", {
|
||||
month: 'short',
|
||||
day: 'numeric',
|
||||
year: 'numeric',
|
||||
|
||||
19
src/main.ts
19
src/main.ts
@@ -5,13 +5,11 @@ import { createPinia } from 'pinia';
|
||||
import { createSSRApp } from 'vue';
|
||||
import { RouterView } from 'vue-router';
|
||||
|
||||
import type { i18n as I18nInstance } from 'i18next';
|
||||
import I18NextVue from 'i18next-vue';
|
||||
|
||||
import { createI18nInstance, initI18nInstance } from '@/lib/translation';
|
||||
import { createI18nForClient } from '@/lib/translation/client';
|
||||
|
||||
import { withErrorBoundary } from './lib/hoc/withErrorBoundary';
|
||||
import createI18nInstance from './lib/translation';
|
||||
import createAppRouter from './routes';
|
||||
|
||||
const bodyClass = ':uno: font-sans text-gray-800 antialiased flex flex-col min-h-screen';
|
||||
@@ -21,7 +19,7 @@ const getSerializedAppData = () => {
|
||||
return JSON.parse(document.getElementById('__APP_DATA__')?.innerText || '{}') as Record<string, any>;
|
||||
};
|
||||
|
||||
export async function createApp(lng: string = 'en', i18next?: I18nInstance) {
|
||||
export async function createApp(lng: string = 'en') {
|
||||
const pinia = createPinia();
|
||||
const app = createSSRApp(withErrorBoundary(RouterView));
|
||||
|
||||
@@ -35,13 +33,7 @@ export async function createApp(lng: string = 'en', i18next?: I18nInstance) {
|
||||
}
|
||||
});
|
||||
app.use(pinia);
|
||||
const runtimeI18n = import.meta.env.SSR
|
||||
? (i18next ?? createI18nInstance(true))
|
||||
: await createI18nForClient(lng);
|
||||
if (import.meta.env.SSR) {
|
||||
await initI18nInstance(runtimeI18n, lng, true);
|
||||
}
|
||||
app.use(I18NextVue, { i18next: runtimeI18n });
|
||||
app.use(I18NextVue, { i18next: createI18nInstance(lng) });
|
||||
app.use(PiniaColada, {
|
||||
pinia,
|
||||
plugins: [
|
||||
@@ -57,8 +49,6 @@ export async function createApp(lng: string = 'en', i18next?: I18nInstance) {
|
||||
});
|
||||
|
||||
const queryCache = useQueryCache();
|
||||
const router = createAppRouter();
|
||||
app.use(router);
|
||||
|
||||
if (!import.meta.env.SSR) {
|
||||
Object.entries(appData).forEach(([key, value]) => {
|
||||
@@ -69,5 +59,8 @@ export async function createApp(lng: string = 'en', i18next?: I18nInstance) {
|
||||
}
|
||||
}
|
||||
|
||||
const router = createAppRouter();
|
||||
app.use(router);
|
||||
|
||||
return { app, router, head, pinia, bodyClass, queryCache };
|
||||
}
|
||||
|
||||
@@ -172,12 +172,12 @@
|
||||
</section>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { computed } from 'vue';
|
||||
import { cn } from '@/lib/utils';
|
||||
import { useTranslation } from 'i18next-vue';
|
||||
import { computed } from 'vue';
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
const { t, i18next } = useTranslation();
|
||||
console.log('Current locale:', i18next);
|
||||
const getFeatureList = (key: string): string[] => {
|
||||
const localized = t(key, { returnObjects: true });
|
||||
return Array.isArray(localized) ? localized.map((item) => String(item)) : [];
|
||||
|
||||
@@ -12,9 +12,8 @@ import UploadIcon from '@/components/icons/UploadIcon.vue';
|
||||
import { useAppToast } from '@/composables/useAppToast';
|
||||
import { useAuthStore } from '@/stores/auth';
|
||||
import { useQuery } from '@pinia/colada';
|
||||
import { computed, ref } from 'vue';
|
||||
import { useTranslation } from 'i18next-vue';
|
||||
import { getActiveI18n } from '@/i18n';
|
||||
import { computed, ref } from 'vue';
|
||||
|
||||
const toast = useAppToast();
|
||||
const auth = useAuthStore();
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<script setup lang="ts">
|
||||
import { useAuthStore } from '@/stores/auth';
|
||||
import AppButton from '@/components/app/AppButton.vue';
|
||||
import AppDialog from '@/components/app/AppDialog.vue';
|
||||
import AppInput from '@/components/app/AppInput.vue';
|
||||
@@ -8,19 +7,18 @@ import CheckIcon from '@/components/icons/CheckIcon.vue';
|
||||
import LockIcon from '@/components/icons/LockIcon.vue';
|
||||
import TelegramIcon from '@/components/icons/TelegramIcon.vue';
|
||||
import XCircleIcon from '@/components/icons/XCircleIcon.vue';
|
||||
import { supportedLocales, type SupportedLocale } from '@/i18n/constants';
|
||||
import { normalizeLocale } from '@/i18n';
|
||||
import { useAppConfirm } from '@/composables/useAppConfirm';
|
||||
import { useAppToast } from '@/composables/useAppToast';
|
||||
import { computed, ref, watch } from 'vue';
|
||||
import { supportedLocales } from '@/i18n/constants';
|
||||
import { useAuthStore } from '@/stores/auth';
|
||||
import { useTranslation } from 'i18next-vue';
|
||||
import { computed, ref, watch } from 'vue';
|
||||
|
||||
const auth = useAuthStore();
|
||||
const toast = useAppToast();
|
||||
const confirm = useAppConfirm();
|
||||
const { t } = useTranslation();
|
||||
|
||||
const selectedLanguage = ref<SupportedLocale>(normalizeLocale((auth.user as any)?.language ?? (auth.user as any)?.locale));
|
||||
const languageSaving = ref(false);
|
||||
|
||||
const languageOptions = computed(() => supportedLocales.map((value) => ({
|
||||
@@ -29,7 +27,7 @@ const languageOptions = computed(() => supportedLocales.map((value) => ({
|
||||
})));
|
||||
|
||||
watch(() => auth.user, (nextUser) => {
|
||||
selectedLanguage.value = normalizeLocale((nextUser as any)?.language ?? (nextUser as any)?.locale);
|
||||
// selectedLanguage.value = normalizeLocale((nextUser as any)?.language ?? (nextUser as any)?.locale);
|
||||
}, { deep: true });
|
||||
|
||||
// 2FA state
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<script setup lang="ts">
|
||||
import type { ModelVideo } from '@/api/client';
|
||||
import { formatBytes, getStatusSeverity } from '@/lib/utils';
|
||||
import { computed } from 'vue';
|
||||
import { useTranslation } from 'i18next-vue';
|
||||
import { getActiveI18n } from '@/i18n';
|
||||
import { computed } from 'vue';
|
||||
// import { getActiveI18n } from '@/i18n';
|
||||
|
||||
const props = defineProps<{
|
||||
video: ModelVideo;
|
||||
|
||||
@@ -3,34 +3,18 @@ import { renderSSRHead } from '@unhead/vue/server';
|
||||
import { streamText } from 'hono/streaming';
|
||||
import { renderToWebStream } from 'vue/server-renderer';
|
||||
|
||||
import { localeCookieKey } from '@/i18n';
|
||||
import { createI18nInstance, initI18nInstance } from '@/lib/translation';
|
||||
import { buildBootstrapScript } from '@/lib/manifest';
|
||||
import { createApp } from '@/main';
|
||||
import { htmlEscape } from '@/server/utils/htmlEscape';
|
||||
import { useAuthStore } from '@/stores/auth';
|
||||
import type { Hono } from 'hono';
|
||||
|
||||
const parseCookie = (cookieHeader: string | undefined, key: string): string | undefined => {
|
||||
if (!cookieHeader) return undefined;
|
||||
const segments = cookieHeader.split(';');
|
||||
for (const segment of segments) {
|
||||
const [rawKey, ...rest] = segment.trim().split('=');
|
||||
if (rawKey !== key) continue;
|
||||
return decodeURIComponent(rest.join('='));
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
export function registerSSRRoutes(app: Hono) {
|
||||
app.get("*", async (c) => {
|
||||
const nonce = crypto.randomUUID();
|
||||
const url = new URL(c.req.url);
|
||||
const lang = c.get("language")
|
||||
const localeFromCookie = parseCookie(c.req.header('cookie'), localeCookieKey);
|
||||
const i18next = createI18nInstance(true);
|
||||
await initI18nInstance(i18next, localeFromCookie ?? lang, true);
|
||||
const { app: vueApp, router, head, pinia, bodyClass, queryCache } = await createApp(localeFromCookie ?? lang, i18next);
|
||||
const lang = c.get("language");
|
||||
const { app: vueApp, router, head, pinia, bodyClass, queryCache } = await createApp(lang);
|
||||
|
||||
vueApp.provide("honoContext", c);
|
||||
|
||||
@@ -49,7 +33,7 @@ export function registerSSRRoutes(app: Hono) {
|
||||
const appStream = renderToWebStream(vueApp, ctx);
|
||||
|
||||
// HTML Head
|
||||
await stream.write(`<!DOCTYPE html><html lang='${i18next.resolvedLanguage ?? lang}'><head>`);
|
||||
await stream.write(`<!DOCTYPE html><html lang='${lang}'><head>`);
|
||||
await stream.write("<base href='" + url.origin + "'/>");
|
||||
|
||||
// SSR Head tags
|
||||
@@ -79,7 +63,7 @@ export function registerSSRRoutes(app: Hono) {
|
||||
Object.assign(ctx, {
|
||||
$p: pinia.state.value,
|
||||
$colada: serializeQueryCache(queryCache),
|
||||
$locale: i18next.resolvedLanguage ?? lang,
|
||||
$locale: lang,
|
||||
});
|
||||
|
||||
// App data script
|
||||
|
||||
@@ -1,36 +1,16 @@
|
||||
import { defineStore } from 'pinia';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { ref, watch } from 'vue';
|
||||
import { client, ResponseResponse, type ModelUser } from '@/api/client';
|
||||
import { defaultLocale, localeCookieKey, type SupportedLocale } from '@/i18n/constants';
|
||||
import { getActiveI18n, normalizeLocale } from '@/i18n';
|
||||
import { TinyMqttClient } from '@/lib/liteMqtt';
|
||||
import { useTranslation } from 'i18next-vue';
|
||||
import { defineStore } from 'pinia';
|
||||
import { ref, watch } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
|
||||
type ProfileUpdatePayload = { username?: string; email?: string; language?: string; locale?: string };
|
||||
|
||||
const cookieMaxAge = 60 * 60 * 24 * 365;
|
||||
|
||||
const writeLocaleCookie = (locale: SupportedLocale) => {
|
||||
if (typeof document === 'undefined') return;
|
||||
document.cookie = `${localeCookieKey}=${encodeURIComponent(locale)}; path=/; max-age=${cookieMaxAge}; samesite=lax`;
|
||||
};
|
||||
|
||||
const resolveUserLocale = (target: Partial<ModelUser> | null | undefined): SupportedLocale => {
|
||||
const userLocale = (target as any)?.language ?? (target as any)?.locale;
|
||||
return normalizeLocale(typeof userLocale === 'string' ? userLocale : defaultLocale);
|
||||
};
|
||||
|
||||
const applyRuntimeLocale = (locale: SupportedLocale) => {
|
||||
const i18n = getActiveI18n();
|
||||
if (!i18n) return;
|
||||
i18n.changeLanguage(locale);
|
||||
};
|
||||
|
||||
export const useAuthStore = defineStore('auth', () => {
|
||||
const user = ref<ModelUser | null>(null);
|
||||
const router = useRouter();
|
||||
const t = (key: string, params?: Record<string, unknown>) =>
|
||||
getActiveI18n()?.t(key, params) ?? key;
|
||||
const { t } = useTranslation();
|
||||
const loading = ref(false);
|
||||
const error = ref<string | null>(null);
|
||||
const initialized = ref(false);
|
||||
@@ -55,11 +35,13 @@ export const useAuthStore = defineStore('auth', () => {
|
||||
}, { deep: true });
|
||||
|
||||
watch(user, (newUser) => {
|
||||
if (import.meta.env.SSR) return;
|
||||
const locale = resolveUserLocale(newUser);
|
||||
applyRuntimeLocale(locale);
|
||||
writeLocaleCookie(locale);
|
||||
}, { deep: true, immediate: true });
|
||||
if (import.meta.env.SSR || !initialized.value || !newUser) return;
|
||||
// const locale = getUserPreferredLocale(newUser);
|
||||
// const activeLocale = getActiveI18n()?.resolvedLanguage;
|
||||
// if (!locale || (activeLocale && normalizeLocale(activeLocale) === locale)) return;
|
||||
// applyRuntimeLocale(locale);
|
||||
// writeLocaleCookie(locale);
|
||||
}, { deep: true });
|
||||
// Initial check for session could go here if there was a /me endpoint or token check
|
||||
async function init() {
|
||||
if (initialized.value) return;
|
||||
@@ -70,8 +52,12 @@ export const useAuthStore = defineStore('auth', () => {
|
||||
}).then(r => r.json()).then(r => {
|
||||
if (r.data) {
|
||||
user.value = r.data.user as ModelUser;
|
||||
const resolvedLocale = resolveUserLocale(user.value);
|
||||
applyRuntimeLocale(resolvedLocale);
|
||||
// const profileLocale = getUserPreferredLocale(user.value);
|
||||
// const activeLocale = getActiveI18n()?.resolvedLanguage;
|
||||
// if (profileLocale && (!activeLocale || normalizeLocale(activeLocale) !== profileLocale)) {
|
||||
// applyRuntimeLocale(profileLocale);
|
||||
// writeLocaleCookie(profileLocale);
|
||||
// }
|
||||
}
|
||||
}).catch(() => { }).finally(() => {
|
||||
initialized.value = true;
|
||||
@@ -108,9 +94,11 @@ export const useAuthStore = defineStore('auth', () => {
|
||||
console.log("body", body);
|
||||
if (body && body.data) {
|
||||
user.value = body.data.user;
|
||||
const resolvedLocale = resolveUserLocale(user.value);
|
||||
applyRuntimeLocale(resolvedLocale);
|
||||
writeLocaleCookie(resolvedLocale);
|
||||
// const profileLocale = getUserPreferredLocale(user.value);
|
||||
// if (profileLocale) {
|
||||
// applyRuntimeLocale(profileLocale);
|
||||
// writeLocaleCookie(profileLocale);
|
||||
// }
|
||||
router.push('/');
|
||||
} else {
|
||||
throw new Error(t('auth.errors.loginNoUserData'));
|
||||
@@ -188,18 +176,18 @@ export const useAuthStore = defineStore('auth', () => {
|
||||
}
|
||||
|
||||
async function setLanguage(locale: string) {
|
||||
const normalizedLocale = normalizeLocale(locale);
|
||||
const previousLocale = resolveUserLocale(user.value);
|
||||
// const normalizedLocale = normalizeLocale(locale);
|
||||
// const previousLocale = resolveUserLocale(user.value);
|
||||
|
||||
// applyRuntimeLocale(normalizedLocale);
|
||||
// writeLocaleCookie(normalizedLocale);
|
||||
const previousUser = user.value ? { ...user.value } : null;
|
||||
|
||||
applyRuntimeLocale(normalizedLocale);
|
||||
writeLocaleCookie(normalizedLocale);
|
||||
|
||||
if (user.value) {
|
||||
user.value = {
|
||||
...user.value,
|
||||
language: normalizedLocale,
|
||||
locale: normalizedLocale,
|
||||
// language: normalizedLocale,
|
||||
// locale: normalizedLocale,
|
||||
} as ModelUser;
|
||||
}
|
||||
|
||||
@@ -208,14 +196,14 @@ export const useAuthStore = defineStore('auth', () => {
|
||||
}
|
||||
|
||||
try {
|
||||
await updateProfile({ language: normalizedLocale, locale: normalizedLocale });
|
||||
// await updateProfile({ language: normalizedLocale, locale: normalizedLocale });
|
||||
return { ok: true as const, fallbackOnly: false as const };
|
||||
} catch (e) {
|
||||
applyRuntimeLocale(previousLocale);
|
||||
// applyRuntimeLocale(previousLocale);
|
||||
if (previousUser) {
|
||||
user.value = previousUser as ModelUser;
|
||||
}
|
||||
writeLocaleCookie(normalizedLocale);
|
||||
// writeLocaleCookie(normalizedLocale);
|
||||
return { ok: false as const, fallbackOnly: true as const, error: e };
|
||||
}
|
||||
}
|
||||
@@ -257,7 +245,8 @@ export const useAuthStore = defineStore('auth', () => {
|
||||
setLanguage,
|
||||
logout: async () => {
|
||||
loading.value = true;
|
||||
const localeBeforeLogout = resolveUserLocale(user.value);
|
||||
// const activeLocale = getActiveI18n()?.resolvedLanguage;
|
||||
// const localeBeforeLogout = typeof activeLocale === 'string' ? normalizeLocale(activeLocale) : undefined;
|
||||
try {
|
||||
await client.auth.logoutCreate();
|
||||
user.value = null;
|
||||
@@ -267,8 +256,10 @@ export const useAuthStore = defineStore('auth', () => {
|
||||
user.value = null;
|
||||
router.push('/login');
|
||||
} finally {
|
||||
writeLocaleCookie(localeBeforeLogout);
|
||||
applyRuntimeLocale(localeBeforeLogout);
|
||||
// if (localeBeforeLogout) {
|
||||
// writeLocaleCookie(localeBeforeLogout);
|
||||
// applyRuntimeLocale(localeBeforeLogout);
|
||||
// }
|
||||
loading.value = false;
|
||||
}
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user