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": {
|
||||
"@tailwindcss/vite": "^4.1.6",
|
||||
"@types/node": "^22.15.17",
|
||||
"axios": "^1.11.0",
|
||||
"@vueuse/components": "^13.3.0",
|
||||
"@vueuse/core": "^13.3.0",
|
||||
"arktype": "^2.1.29",
|
||||
"axios": "^1.11.0",
|
||||
"bulma": "^1.0.4",
|
||||
"tailwindcss": "^4.1.6",
|
||||
"vue": "^3.5.13",
|
||||
|
|
|
|||
|
|
@ -1,20 +1,50 @@
|
|||
import en_US from "../locales/en_US";
|
||||
import vp_VL from "../locales/vp_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 { 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 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 {
|
||||
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>>(() => {
|
||||
return fallbackProxy<Locale>(
|
||||
locales[opt.locale ?? localeId.value],
|
||||
|
|
@ -23,7 +53,7 @@ export function useLocale(opt: UseLocaleOptions = {}) {
|
|||
});
|
||||
|
||||
return readonly(locale);
|
||||
}
|
||||
};
|
||||
|
||||
export interface UseLocaleOptions {
|
||||
locale?: LocaleId;
|
||||
|
|
|
|||
94
pnpm-lock.yaml
generated
94
pnpm-lock.yaml
generated
|
|
@ -10,7 +10,7 @@ importers:
|
|||
devDependencies:
|
||||
turbo:
|
||||
specifier: ^2.5.4
|
||||
version: 2.5.4
|
||||
version: 2.8.0
|
||||
|
||||
apps/vdb-backend:
|
||||
dependencies:
|
||||
|
|
@ -81,6 +81,9 @@ importers:
|
|||
'@vueuse/core':
|
||||
specifier: ^13.3.0
|
||||
version: 13.3.0(vue@3.5.16(typescript@5.8.3))
|
||||
arktype:
|
||||
specifier: ^2.1.29
|
||||
version: 2.1.29
|
||||
axios:
|
||||
specifier: ^1.11.0
|
||||
version: 1.11.0
|
||||
|
|
@ -156,6 +159,12 @@ packages:
|
|||
resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==}
|
||||
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':
|
||||
resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
|
@ -1019,6 +1028,12 @@ packages:
|
|||
argparse@2.0.1:
|
||||
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:
|
||||
resolution: {integrity: sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==}
|
||||
engines: {node: '>=8'}
|
||||
|
|
@ -2504,70 +2519,36 @@ packages:
|
|||
tunnel-agent@0.6.0:
|
||||
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:
|
||||
resolution: {integrity: sha512-N7f4PYqz25yk8c5kituk09bJ89tE4wPPqKXgYccT6nbEQnGnrdvlyCHLyqViNObTgjjrddqjb1hmDkv7VcxE0g==}
|
||||
cpu: [x64]
|
||||
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:
|
||||
resolution: {integrity: sha512-eVzejaP5fn51gmJAPW68U6mSjFaAZ26rPiE36mMdk+tMC4XBGmJHT/fIgrhcrXMvINCl27RF8VmguRe+MBlSuQ==}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
|
||||
turbo-linux-64@2.5.4:
|
||||
resolution: {integrity: sha512-5May2kjWbc8w4XxswGAl74GZ5eM4Gr6IiroqdLhXeXyfvWEdm2mFYCSWOzz0/z5cAgqyGidF1jt1qzUR8hTmOA==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
|
||||
turbo-linux-64@2.8.0:
|
||||
resolution: {integrity: sha512-ILR45zviYae3icf4cmUISdj8X17ybNcMh3Ms4cRdJF5sS50qDDTv8qeWqO/lPeHsu6r43gVWDofbDZYVuXYL7Q==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
|
||||
turbo-linux-arm64@2.5.4:
|
||||
resolution: {integrity: sha512-/2yqFaS3TbfxV3P5yG2JUI79P7OUQKOUvAnx4MV9Bdz6jqHsHwc9WZPpO4QseQm+NvmgY6ICORnoVPODxGUiJg==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
|
||||
turbo-linux-arm64@2.8.0:
|
||||
resolution: {integrity: sha512-z9pUa8ENFuHmadPfjEYMRWlXO82t1F/XBDx2XTg+cWWRZHf85FnEB6D4ForJn/GoKEEvwdPhFLzvvhOssom2ug==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
|
||||
turbo-windows-64@2.5.4:
|
||||
resolution: {integrity: sha512-EQUO4SmaCDhO6zYohxIjJpOKRN3wlfU7jMAj3CgcyTPvQR/UFLEKAYHqJOnJtymbQmiiM/ihX6c6W6Uq0yC7mA==}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
turbo-windows-64@2.8.0:
|
||||
resolution: {integrity: sha512-J6juRSRjmSErEqJCv7nVIq2DgZ2NHXqyeV8NQTFSyIvrThKiWe7FDOO6oYpuR06+C1NW82aoN4qQt4/gYvz25w==}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
turbo-windows-arm64@2.5.4:
|
||||
resolution: {integrity: sha512-oQ8RrK1VS8lrxkLriotFq+PiF7iiGgkZtfLKF4DDKsmdbPo0O9R2mQxm7jHLuXraRCuIQDWMIw6dpcr7Iykf4A==}
|
||||
cpu: [arm64]
|
||||
os: [win32]
|
||||
|
||||
turbo-windows-arm64@2.8.0:
|
||||
resolution: {integrity: sha512-qarBZvCu6uka35739TS+y/3CBU3zScrVAfohAkKHG+So+93Wn+5tKArs8HrO2fuTaGou8fMIeTV7V5NgzCVkSQ==}
|
||||
cpu: [arm64]
|
||||
os: [win32]
|
||||
|
||||
turbo@2.5.4:
|
||||
resolution: {integrity: sha512-kc8ZibdRcuWUG1pbYSBFWqmIjynlD8Lp7IB6U3vIzvOv9VG+6Sp8bzyeBWE3Oi8XV5KsQrznyRTBPvrf99E4mA==}
|
||||
hasBin: true
|
||||
|
||||
turbo@2.8.0:
|
||||
resolution: {integrity: sha512-hYbxnLEdvJF+DLALS+Ia+PbfNtn0sDP0hH2u9AFoskSUDmcVHSrtwHpzdX94MrRJKo9D9tYxY3MyP20gnlrWyA==}
|
||||
hasBin: true
|
||||
|
|
@ -2862,6 +2843,12 @@ snapshots:
|
|||
'@jridgewell/gen-mapping': 0.3.8
|
||||
'@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-validator-identifier@7.27.1': {}
|
||||
|
|
@ -3637,6 +3624,16 @@ snapshots:
|
|||
|
||||
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: {}
|
||||
|
||||
ast-kit@1.4.3:
|
||||
|
|
@ -5287,51 +5284,24 @@ snapshots:
|
|||
dependencies:
|
||||
safe-buffer: 5.2.1
|
||||
|
||||
turbo-darwin-64@2.5.4:
|
||||
optional: true
|
||||
|
||||
turbo-darwin-64@2.8.0:
|
||||
optional: true
|
||||
|
||||
turbo-darwin-arm64@2.5.4:
|
||||
optional: true
|
||||
|
||||
turbo-darwin-arm64@2.8.0:
|
||||
optional: true
|
||||
|
||||
turbo-linux-64@2.5.4:
|
||||
optional: true
|
||||
|
||||
turbo-linux-64@2.8.0:
|
||||
optional: true
|
||||
|
||||
turbo-linux-arm64@2.5.4:
|
||||
optional: true
|
||||
|
||||
turbo-linux-arm64@2.8.0:
|
||||
optional: true
|
||||
|
||||
turbo-windows-64@2.5.4:
|
||||
optional: true
|
||||
|
||||
turbo-windows-64@2.8.0:
|
||||
optional: true
|
||||
|
||||
turbo-windows-arm64@2.5.4:
|
||||
optional: true
|
||||
|
||||
turbo-windows-arm64@2.8.0:
|
||||
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:
|
||||
optionalDependencies:
|
||||
turbo-darwin-64: 2.8.0
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue