feat: store locale in localStorage to persist across page loads
This commit is contained in:
parent
4852f2d5d1
commit
59674292be
3 changed files with 70 additions and 69 deletions
|
|
@ -11,9 +11,10 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tailwindcss/vite": "^4.1.6",
|
"@tailwindcss/vite": "^4.1.6",
|
||||||
"@types/node": "^22.15.17",
|
"@types/node": "^22.15.17",
|
||||||
"axios": "^1.11.0",
|
|
||||||
"@vueuse/components": "^13.3.0",
|
"@vueuse/components": "^13.3.0",
|
||||||
"@vueuse/core": "^13.3.0",
|
"@vueuse/core": "^13.3.0",
|
||||||
|
"arktype": "^2.1.29",
|
||||||
|
"axios": "^1.11.0",
|
||||||
"bulma": "^1.0.4",
|
"bulma": "^1.0.4",
|
||||||
"tailwindcss": "^4.1.6",
|
"tailwindcss": "^4.1.6",
|
||||||
"vue": "^3.5.13",
|
"vue": "^3.5.13",
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,50 @@
|
||||||
import en_US from "../locales/en_US";
|
import en_US from "../locales/en_US";
|
||||||
import vp_VL from "../locales/vp_VL";
|
import vp_VL from "../locales/vp_VL";
|
||||||
import wp_VL from "../locales/wp_VL";
|
import wp_VL from "../locales/wp_VL";
|
||||||
import { computed, readonly, ref, type DeepReadonly } from "vue";
|
import { computed, readonly, type DeepReadonly } from "vue";
|
||||||
import type { Locale } from "./locale";
|
import type { Locale } from "./locale";
|
||||||
import type { DeepPartial } from "@/utils/deep-partial";
|
import type { DeepPartial } from "@/utils/deep-partial";
|
||||||
|
import { useLocalStorage } from "@vueuse/core";
|
||||||
|
import { type } from "arktype";
|
||||||
|
|
||||||
export const LOCALE_IDS = ["en_US", "vp_VL", "wp_VL"] as const;
|
export const LOCALE_IDS = ["en_US", "vp_VL", "wp_VL"] as const;
|
||||||
export type LocaleId = (typeof LOCALE_IDS)[number];
|
|
||||||
|
export type LocaleId = typeof LocaleId.infer;
|
||||||
|
export const LocaleId = type.enumerated(...LOCALE_IDS);
|
||||||
|
|
||||||
|
export const DEFAULT_LOCALE_ID = "en_US" satisfies LocaleId;
|
||||||
|
|
||||||
const locales = { en_US, vp_VL, wp_VL } as const satisfies {
|
const locales = { en_US, vp_VL, wp_VL } as const satisfies {
|
||||||
en_US: Locale;
|
en_US: Locale;
|
||||||
} & Record<Exclude<LocaleId, "en_US">, DeepPartial<Locale>>;
|
} & Record<Exclude<LocaleId, typeof DEFAULT_LOCALE_ID>, DeepPartial<Locale>>;
|
||||||
|
|
||||||
export const localeId = ref<LocaleId>("en_US");
|
// users could manually edit localStorage to make this value anything, so we need to validate it
|
||||||
|
const localStorageLocaleId = useLocalStorage<unknown>(
|
||||||
|
"localeId",
|
||||||
|
DEFAULT_LOCALE_ID,
|
||||||
|
);
|
||||||
|
|
||||||
export function useLocale(opt: UseLocaleOptions = {}) {
|
export const localeId = computed({
|
||||||
|
get: (): LocaleId => {
|
||||||
|
const localeIdRes = LocaleId(localStorageLocaleId.value);
|
||||||
|
if (localeIdRes instanceof type.errors) {
|
||||||
|
// if invalid LocaleId, reset to default
|
||||||
|
localStorageLocaleId.value = DEFAULT_LOCALE_ID;
|
||||||
|
return DEFAULT_LOCALE_ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
// else return user's selection
|
||||||
|
const localeId = localeIdRes;
|
||||||
|
return localeId;
|
||||||
|
},
|
||||||
|
// custom setter to ensure it is only set to a valid LocaleId by our code
|
||||||
|
// (since the localStorage ref is typed as `unknown`, it can be set to any value)
|
||||||
|
set: (id: LocaleId) => {
|
||||||
|
localStorageLocaleId.value = id;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export const useLocale = (opt: UseLocaleOptions = {}) => {
|
||||||
const locale = computed<DeepReadonly<Locale>>(() => {
|
const locale = computed<DeepReadonly<Locale>>(() => {
|
||||||
return fallbackProxy<Locale>(
|
return fallbackProxy<Locale>(
|
||||||
locales[opt.locale ?? localeId.value],
|
locales[opt.locale ?? localeId.value],
|
||||||
|
|
@ -23,7 +53,7 @@ export function useLocale(opt: UseLocaleOptions = {}) {
|
||||||
});
|
});
|
||||||
|
|
||||||
return readonly(locale);
|
return readonly(locale);
|
||||||
}
|
};
|
||||||
|
|
||||||
export interface UseLocaleOptions {
|
export interface UseLocaleOptions {
|
||||||
locale?: LocaleId;
|
locale?: LocaleId;
|
||||||
|
|
|
||||||
94
pnpm-lock.yaml
generated
94
pnpm-lock.yaml
generated
|
|
@ -10,7 +10,7 @@ importers:
|
||||||
devDependencies:
|
devDependencies:
|
||||||
turbo:
|
turbo:
|
||||||
specifier: ^2.5.4
|
specifier: ^2.5.4
|
||||||
version: 2.5.4
|
version: 2.8.0
|
||||||
|
|
||||||
apps/vdb-backend:
|
apps/vdb-backend:
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|
@ -81,6 +81,9 @@ importers:
|
||||||
'@vueuse/core':
|
'@vueuse/core':
|
||||||
specifier: ^13.3.0
|
specifier: ^13.3.0
|
||||||
version: 13.3.0(vue@3.5.16(typescript@5.8.3))
|
version: 13.3.0(vue@3.5.16(typescript@5.8.3))
|
||||||
|
arktype:
|
||||||
|
specifier: ^2.1.29
|
||||||
|
version: 2.1.29
|
||||||
axios:
|
axios:
|
||||||
specifier: ^1.11.0
|
specifier: ^1.11.0
|
||||||
version: 1.11.0
|
version: 1.11.0
|
||||||
|
|
@ -156,6 +159,12 @@ packages:
|
||||||
resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==}
|
resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==}
|
||||||
engines: {node: '>=6.0.0'}
|
engines: {node: '>=6.0.0'}
|
||||||
|
|
||||||
|
'@ark/schema@0.56.0':
|
||||||
|
resolution: {integrity: sha512-ECg3hox/6Z/nLajxXqNhgPtNdHWC9zNsDyskwO28WinoFEnWow4IsERNz9AnXRhTZJnYIlAJ4uGn3nlLk65vZA==}
|
||||||
|
|
||||||
|
'@ark/util@0.56.0':
|
||||||
|
resolution: {integrity: sha512-BghfRC8b9pNs3vBoDJhcta0/c1J1rsoS1+HgVUreMFPdhz/CRAKReAu57YEllNaSy98rWAdY1gE+gFup7OXpgA==}
|
||||||
|
|
||||||
'@babel/helper-string-parser@7.27.1':
|
'@babel/helper-string-parser@7.27.1':
|
||||||
resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==}
|
resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==}
|
||||||
engines: {node: '>=6.9.0'}
|
engines: {node: '>=6.9.0'}
|
||||||
|
|
@ -1019,6 +1028,12 @@ packages:
|
||||||
argparse@2.0.1:
|
argparse@2.0.1:
|
||||||
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
|
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
|
||||||
|
|
||||||
|
arkregex@0.0.5:
|
||||||
|
resolution: {integrity: sha512-ncYjBdLlh5/QnVsAA8De16Tc9EqmYM7y/WU9j+236KcyYNUXogpz3sC4ATIZYzzLxwI+0sEOaQLEmLmRleaEXw==}
|
||||||
|
|
||||||
|
arktype@2.1.29:
|
||||||
|
resolution: {integrity: sha512-jyfKk4xIOzvYNayqnD8ZJQqOwcrTOUbIU4293yrzAjA3O1dWh61j71ArMQ6tS/u4pD7vabSPe7nG3RCyoXW6RQ==}
|
||||||
|
|
||||||
arrify@2.0.1:
|
arrify@2.0.1:
|
||||||
resolution: {integrity: sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==}
|
resolution: {integrity: sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
|
|
@ -2504,70 +2519,36 @@ packages:
|
||||||
tunnel-agent@0.6.0:
|
tunnel-agent@0.6.0:
|
||||||
resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==}
|
resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==}
|
||||||
|
|
||||||
turbo-darwin-64@2.5.4:
|
|
||||||
resolution: {integrity: sha512-ah6YnH2dErojhFooxEzmvsoZQTMImaruZhFPfMKPBq8sb+hALRdvBNLqfc8NWlZq576FkfRZ/MSi4SHvVFT9PQ==}
|
|
||||||
cpu: [x64]
|
|
||||||
os: [darwin]
|
|
||||||
|
|
||||||
turbo-darwin-64@2.8.0:
|
turbo-darwin-64@2.8.0:
|
||||||
resolution: {integrity: sha512-N7f4PYqz25yk8c5kituk09bJ89tE4wPPqKXgYccT6nbEQnGnrdvlyCHLyqViNObTgjjrddqjb1hmDkv7VcxE0g==}
|
resolution: {integrity: sha512-N7f4PYqz25yk8c5kituk09bJ89tE4wPPqKXgYccT6nbEQnGnrdvlyCHLyqViNObTgjjrddqjb1hmDkv7VcxE0g==}
|
||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [darwin]
|
os: [darwin]
|
||||||
|
|
||||||
turbo-darwin-arm64@2.5.4:
|
|
||||||
resolution: {integrity: sha512-2+Nx6LAyuXw2MdXb7pxqle3MYignLvS7OwtsP9SgtSBaMlnNlxl9BovzqdYAgkUW3AsYiQMJ/wBRb7d+xemM5A==}
|
|
||||||
cpu: [arm64]
|
|
||||||
os: [darwin]
|
|
||||||
|
|
||||||
turbo-darwin-arm64@2.8.0:
|
turbo-darwin-arm64@2.8.0:
|
||||||
resolution: {integrity: sha512-eVzejaP5fn51gmJAPW68U6mSjFaAZ26rPiE36mMdk+tMC4XBGmJHT/fIgrhcrXMvINCl27RF8VmguRe+MBlSuQ==}
|
resolution: {integrity: sha512-eVzejaP5fn51gmJAPW68U6mSjFaAZ26rPiE36mMdk+tMC4XBGmJHT/fIgrhcrXMvINCl27RF8VmguRe+MBlSuQ==}
|
||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [darwin]
|
os: [darwin]
|
||||||
|
|
||||||
turbo-linux-64@2.5.4:
|
|
||||||
resolution: {integrity: sha512-5May2kjWbc8w4XxswGAl74GZ5eM4Gr6IiroqdLhXeXyfvWEdm2mFYCSWOzz0/z5cAgqyGidF1jt1qzUR8hTmOA==}
|
|
||||||
cpu: [x64]
|
|
||||||
os: [linux]
|
|
||||||
|
|
||||||
turbo-linux-64@2.8.0:
|
turbo-linux-64@2.8.0:
|
||||||
resolution: {integrity: sha512-ILR45zviYae3icf4cmUISdj8X17ybNcMh3Ms4cRdJF5sS50qDDTv8qeWqO/lPeHsu6r43gVWDofbDZYVuXYL7Q==}
|
resolution: {integrity: sha512-ILR45zviYae3icf4cmUISdj8X17ybNcMh3Ms4cRdJF5sS50qDDTv8qeWqO/lPeHsu6r43gVWDofbDZYVuXYL7Q==}
|
||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
|
||||||
turbo-linux-arm64@2.5.4:
|
|
||||||
resolution: {integrity: sha512-/2yqFaS3TbfxV3P5yG2JUI79P7OUQKOUvAnx4MV9Bdz6jqHsHwc9WZPpO4QseQm+NvmgY6ICORnoVPODxGUiJg==}
|
|
||||||
cpu: [arm64]
|
|
||||||
os: [linux]
|
|
||||||
|
|
||||||
turbo-linux-arm64@2.8.0:
|
turbo-linux-arm64@2.8.0:
|
||||||
resolution: {integrity: sha512-z9pUa8ENFuHmadPfjEYMRWlXO82t1F/XBDx2XTg+cWWRZHf85FnEB6D4ForJn/GoKEEvwdPhFLzvvhOssom2ug==}
|
resolution: {integrity: sha512-z9pUa8ENFuHmadPfjEYMRWlXO82t1F/XBDx2XTg+cWWRZHf85FnEB6D4ForJn/GoKEEvwdPhFLzvvhOssom2ug==}
|
||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
|
||||||
turbo-windows-64@2.5.4:
|
|
||||||
resolution: {integrity: sha512-EQUO4SmaCDhO6zYohxIjJpOKRN3wlfU7jMAj3CgcyTPvQR/UFLEKAYHqJOnJtymbQmiiM/ihX6c6W6Uq0yC7mA==}
|
|
||||||
cpu: [x64]
|
|
||||||
os: [win32]
|
|
||||||
|
|
||||||
turbo-windows-64@2.8.0:
|
turbo-windows-64@2.8.0:
|
||||||
resolution: {integrity: sha512-J6juRSRjmSErEqJCv7nVIq2DgZ2NHXqyeV8NQTFSyIvrThKiWe7FDOO6oYpuR06+C1NW82aoN4qQt4/gYvz25w==}
|
resolution: {integrity: sha512-J6juRSRjmSErEqJCv7nVIq2DgZ2NHXqyeV8NQTFSyIvrThKiWe7FDOO6oYpuR06+C1NW82aoN4qQt4/gYvz25w==}
|
||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [win32]
|
os: [win32]
|
||||||
|
|
||||||
turbo-windows-arm64@2.5.4:
|
|
||||||
resolution: {integrity: sha512-oQ8RrK1VS8lrxkLriotFq+PiF7iiGgkZtfLKF4DDKsmdbPo0O9R2mQxm7jHLuXraRCuIQDWMIw6dpcr7Iykf4A==}
|
|
||||||
cpu: [arm64]
|
|
||||||
os: [win32]
|
|
||||||
|
|
||||||
turbo-windows-arm64@2.8.0:
|
turbo-windows-arm64@2.8.0:
|
||||||
resolution: {integrity: sha512-qarBZvCu6uka35739TS+y/3CBU3zScrVAfohAkKHG+So+93Wn+5tKArs8HrO2fuTaGou8fMIeTV7V5NgzCVkSQ==}
|
resolution: {integrity: sha512-qarBZvCu6uka35739TS+y/3CBU3zScrVAfohAkKHG+So+93Wn+5tKArs8HrO2fuTaGou8fMIeTV7V5NgzCVkSQ==}
|
||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [win32]
|
os: [win32]
|
||||||
|
|
||||||
turbo@2.5.4:
|
|
||||||
resolution: {integrity: sha512-kc8ZibdRcuWUG1pbYSBFWqmIjynlD8Lp7IB6U3vIzvOv9VG+6Sp8bzyeBWE3Oi8XV5KsQrznyRTBPvrf99E4mA==}
|
|
||||||
hasBin: true
|
|
||||||
|
|
||||||
turbo@2.8.0:
|
turbo@2.8.0:
|
||||||
resolution: {integrity: sha512-hYbxnLEdvJF+DLALS+Ia+PbfNtn0sDP0hH2u9AFoskSUDmcVHSrtwHpzdX94MrRJKo9D9tYxY3MyP20gnlrWyA==}
|
resolution: {integrity: sha512-hYbxnLEdvJF+DLALS+Ia+PbfNtn0sDP0hH2u9AFoskSUDmcVHSrtwHpzdX94MrRJKo9D9tYxY3MyP20gnlrWyA==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
@ -2862,6 +2843,12 @@ snapshots:
|
||||||
'@jridgewell/gen-mapping': 0.3.8
|
'@jridgewell/gen-mapping': 0.3.8
|
||||||
'@jridgewell/trace-mapping': 0.3.25
|
'@jridgewell/trace-mapping': 0.3.25
|
||||||
|
|
||||||
|
'@ark/schema@0.56.0':
|
||||||
|
dependencies:
|
||||||
|
'@ark/util': 0.56.0
|
||||||
|
|
||||||
|
'@ark/util@0.56.0': {}
|
||||||
|
|
||||||
'@babel/helper-string-parser@7.27.1': {}
|
'@babel/helper-string-parser@7.27.1': {}
|
||||||
|
|
||||||
'@babel/helper-validator-identifier@7.27.1': {}
|
'@babel/helper-validator-identifier@7.27.1': {}
|
||||||
|
|
@ -3637,6 +3624,16 @@ snapshots:
|
||||||
|
|
||||||
argparse@2.0.1: {}
|
argparse@2.0.1: {}
|
||||||
|
|
||||||
|
arkregex@0.0.5:
|
||||||
|
dependencies:
|
||||||
|
'@ark/util': 0.56.0
|
||||||
|
|
||||||
|
arktype@2.1.29:
|
||||||
|
dependencies:
|
||||||
|
'@ark/schema': 0.56.0
|
||||||
|
'@ark/util': 0.56.0
|
||||||
|
arkregex: 0.0.5
|
||||||
|
|
||||||
arrify@2.0.1: {}
|
arrify@2.0.1: {}
|
||||||
|
|
||||||
ast-kit@1.4.3:
|
ast-kit@1.4.3:
|
||||||
|
|
@ -5287,51 +5284,24 @@ snapshots:
|
||||||
dependencies:
|
dependencies:
|
||||||
safe-buffer: 5.2.1
|
safe-buffer: 5.2.1
|
||||||
|
|
||||||
turbo-darwin-64@2.5.4:
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
turbo-darwin-64@2.8.0:
|
turbo-darwin-64@2.8.0:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
turbo-darwin-arm64@2.5.4:
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
turbo-darwin-arm64@2.8.0:
|
turbo-darwin-arm64@2.8.0:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
turbo-linux-64@2.5.4:
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
turbo-linux-64@2.8.0:
|
turbo-linux-64@2.8.0:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
turbo-linux-arm64@2.5.4:
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
turbo-linux-arm64@2.8.0:
|
turbo-linux-arm64@2.8.0:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
turbo-windows-64@2.5.4:
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
turbo-windows-64@2.8.0:
|
turbo-windows-64@2.8.0:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
turbo-windows-arm64@2.5.4:
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
turbo-windows-arm64@2.8.0:
|
turbo-windows-arm64@2.8.0:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
turbo@2.5.4:
|
|
||||||
optionalDependencies:
|
|
||||||
turbo-darwin-64: 2.5.4
|
|
||||||
turbo-darwin-arm64: 2.5.4
|
|
||||||
turbo-linux-64: 2.5.4
|
|
||||||
turbo-linux-arm64: 2.5.4
|
|
||||||
turbo-windows-64: 2.5.4
|
|
||||||
turbo-windows-arm64: 2.5.4
|
|
||||||
|
|
||||||
turbo@2.8.0:
|
turbo@2.8.0:
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
turbo-darwin-64: 2.8.0
|
turbo-darwin-64: 2.8.0
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue