mirror of
https://github.com/MetaCubeX/metacubexd.git
synced 2024-12-25 19:14:12 +08:00
refactor(i18n): add i18n context provider
This commit is contained in:
parent
48ca8d6dfa
commit
e4a324625f
@ -19,6 +19,7 @@
|
||||
"@felte/validator-zod": "^1.0.17",
|
||||
"@fontsource/fira-sans": "^5.0.12",
|
||||
"@solid-primitives/clipboard": "^1.5.7",
|
||||
"@solid-primitives/context": "^0.2.1",
|
||||
"@solid-primitives/event-listener": "^2.3.0",
|
||||
"@solid-primitives/i18n": "^2.0.0",
|
||||
"@solid-primitives/keyed": "^1.2.0",
|
||||
|
11
pnpm-lock.yaml
generated
11
pnpm-lock.yaml
generated
@ -20,6 +20,9 @@ dependencies:
|
||||
'@solid-primitives/clipboard':
|
||||
specifier: ^1.5.7
|
||||
version: 1.5.7(solid-js@1.7.12)
|
||||
'@solid-primitives/context':
|
||||
specifier: ^0.2.1
|
||||
version: 0.2.1(solid-js@1.7.12)
|
||||
'@solid-primitives/event-listener':
|
||||
specifier: ^2.3.0
|
||||
version: 2.3.0(solid-js@1.7.12)
|
||||
@ -2032,6 +2035,14 @@ packages:
|
||||
solid-js: 1.7.12
|
||||
dev: false
|
||||
|
||||
/@solid-primitives/context@0.2.1(solid-js@1.7.12):
|
||||
resolution: {integrity: sha512-XIIwCOWpRKDersgkR9LNFXaJHIV8QlCFo/tq5bV0cAOZklcwOFcqi2bN+uWgEIQSWGjWXU2kc1H1/TzgYzVDlg==}
|
||||
peerDependencies:
|
||||
solid-js: ^1.6.12
|
||||
dependencies:
|
||||
solid-js: 1.7.12
|
||||
dev: false
|
||||
|
||||
/@solid-primitives/event-listener@2.3.0(solid-js@1.7.12):
|
||||
resolution: {integrity: sha512-0DS7DQZvCExWSpurVZC9/wjI8RmkhuOtWOy6Pp1Woq9ElMT9/bfjNpkwXsOwisLpcTqh9eUs17kp7jtpWcC20w==}
|
||||
peerDependencies:
|
||||
|
@ -45,7 +45,7 @@ const TagClientSourceIPWithNameForm: Component = () => {
|
||||
sourceIP: z.string().nonempty(),
|
||||
})
|
||||
|
||||
const { t } = useI18n()
|
||||
const [t] = useI18n()
|
||||
|
||||
const { form, reset } = createForm<z.infer<typeof schema>>({
|
||||
extend: validator({ schema }),
|
||||
@ -113,7 +113,7 @@ export const ConnectionsSettingsModal = (props: {
|
||||
onVisibleChange: (value: ConnectionsTableColumnVisibility) => void
|
||||
}) => {
|
||||
const modalID = MODAL.CONNECTIONS_SETTINGS
|
||||
const { t } = useI18n()
|
||||
const [t] = useI18n()
|
||||
const [activeKey, setActiveKey] =
|
||||
createSignal<CONNECTIONS_TABLE_ACCESSOR_KEY | null>(null)
|
||||
|
||||
|
@ -13,7 +13,7 @@ import {
|
||||
import { For, ParentComponent, Show, createSignal } from 'solid-js'
|
||||
import { Button, LogoText } from '~/components'
|
||||
import { LANG, ROUTES, themes } from '~/constants'
|
||||
import { useI18n } from '~/i18n'
|
||||
import { setLocale, useI18n } from '~/i18n'
|
||||
import { setCurTheme } from '~/signals'
|
||||
|
||||
const Nav: ParentComponent<{ href: string; tooltip: string }> = ({
|
||||
@ -62,7 +62,7 @@ const ThemeSwitcher = () => (
|
||||
)
|
||||
|
||||
export const Header = () => {
|
||||
const { t, locale } = useI18n()
|
||||
const [t] = useI18n()
|
||||
const navs = () => [
|
||||
{
|
||||
href: ROUTES.Overview,
|
||||
@ -154,11 +154,9 @@ export const Header = () => {
|
||||
<div class="flex items-center gap-2">
|
||||
<Button
|
||||
class="btn-circle btn-secondary btn-sm"
|
||||
onClick={() => {
|
||||
const curLocale = locale()
|
||||
|
||||
locale(curLocale === LANG.EN ? LANG.ZH : LANG.EN)
|
||||
}}
|
||||
onClick={() =>
|
||||
setLocale((locale) => (locale === LANG.EN ? LANG.ZH : LANG.EN))
|
||||
}
|
||||
icon={<IconLanguage />}
|
||||
/>
|
||||
|
||||
|
@ -4,7 +4,7 @@ import { useI18n } from '~/i18n'
|
||||
import { latencyQualityMap, useProxies } from '~/signals'
|
||||
|
||||
export const Latency = (props: { name?: string }) => {
|
||||
const { t } = useI18n()
|
||||
const [t] = useI18n()
|
||||
const { latencyMap } = useProxies()
|
||||
const [textClassName, setTextClassName] = createSignal('')
|
||||
const latency = createMemo(() => {
|
||||
|
@ -19,7 +19,7 @@ import {
|
||||
|
||||
export const LogsSettingsModal = () => {
|
||||
const modalID = MODAL.LOGS_SETTINGS
|
||||
const { t } = useI18n()
|
||||
const [t] = useI18n()
|
||||
|
||||
return (
|
||||
<dialog id={modalID} class="modal modal-bottom sm:modal-middle">
|
||||
|
@ -20,7 +20,7 @@ import {
|
||||
|
||||
export const ProxiesSettingsModal = () => {
|
||||
const modalID = MODAL.PROXIES_SETTINGS
|
||||
const { t } = useI18n()
|
||||
const [t] = useI18n()
|
||||
|
||||
return (
|
||||
<dialog id={modalID} class="modal modal-bottom sm:modal-middle">
|
||||
|
@ -14,13 +14,13 @@ const getSubscriptionsInfo = (subscriptionInfo: ISubscriptionInfo) => {
|
||||
const percentage = toFinite((((Download + Upload) / Total) * 100).toFixed(2))
|
||||
|
||||
const expirePrefix = () => {
|
||||
const { t } = useI18n()
|
||||
const [t] = useI18n()
|
||||
|
||||
return t('expire')
|
||||
}
|
||||
|
||||
const expireStr = () => {
|
||||
const { t } = useI18n()
|
||||
const [t] = useI18n()
|
||||
|
||||
if (Expire === 0) {
|
||||
return t('noExpire')
|
||||
|
@ -1,10 +1,11 @@
|
||||
import { createContextProvider } from '@solid-primitives/context'
|
||||
import * as i18n from '@solid-primitives/i18n'
|
||||
import { makePersisted } from '@solid-primitives/storage'
|
||||
import { createMemo, createSignal } from 'solid-js'
|
||||
import { createSignal } from 'solid-js'
|
||||
import { LANG } from '~/constants'
|
||||
import dict from './dict'
|
||||
import dict, { Dict } from './dict'
|
||||
|
||||
export const [curLocale, setCurLocale] = makePersisted(
|
||||
export const [locale, setLocale] = makePersisted(
|
||||
createSignal<LANG>(
|
||||
Reflect.has(dict, navigator.language)
|
||||
? (navigator.language as LANG)
|
||||
@ -16,12 +17,9 @@ export const [curLocale, setCurLocale] = makePersisted(
|
||||
},
|
||||
)
|
||||
|
||||
const locale = (localeName?: LANG) =>
|
||||
localeName ? setCurLocale(localeName) : curLocale()
|
||||
export const [I18nProvider, useMaybeI18n] = createContextProvider<
|
||||
[i18n.Translator<Dict>],
|
||||
{ locale: LANG }
|
||||
>((props) => [i18n.translator(() => i18n.flatten(dict[props.locale]))])
|
||||
|
||||
export const useI18n = () => {
|
||||
const curDict = createMemo(() => i18n.flatten(dict[curLocale()]))!
|
||||
const t = createMemo(() => i18n.translator(() => curDict()))
|
||||
|
||||
return { t: t(), locale }
|
||||
}
|
||||
export const useI18n = () => useMaybeI18n()!
|
||||
|
@ -7,14 +7,17 @@ import 'dayjs/locale/zh-cn'
|
||||
import relativeTime from 'dayjs/plugin/relativeTime'
|
||||
import { render } from 'solid-js/web'
|
||||
import { App } from '~/App'
|
||||
import { I18nProvider, locale } from '~/i18n'
|
||||
|
||||
dayjs.extend(relativeTime)
|
||||
|
||||
render(
|
||||
() => (
|
||||
<Router source={hashIntegration()}>
|
||||
<App />
|
||||
</Router>
|
||||
<I18nProvider locale={locale()}>
|
||||
<Router source={hashIntegration()}>
|
||||
<App />
|
||||
</Router>
|
||||
</I18nProvider>
|
||||
),
|
||||
document.getElementById('root')!,
|
||||
)
|
||||
|
@ -48,7 +48,7 @@ const dnsQueryFormSchema = z.object({
|
||||
})
|
||||
|
||||
const DNSQueryForm = () => {
|
||||
const { t } = useI18n()
|
||||
const [t] = useI18n()
|
||||
const request = useRequest()
|
||||
|
||||
const { form, isSubmitting } = createForm<z.infer<typeof dnsQueryFormSchema>>(
|
||||
@ -111,7 +111,7 @@ const configFormSchema = z.object({
|
||||
})
|
||||
|
||||
const ConfigForm = () => {
|
||||
const { t } = useI18n()
|
||||
const [t] = useI18n()
|
||||
const navigate = useNavigate()
|
||||
|
||||
const portList = [
|
||||
@ -352,7 +352,7 @@ const ConfigForm = () => {
|
||||
}
|
||||
|
||||
const ConfigForXd = () => {
|
||||
const { t } = useI18n()
|
||||
const [t] = useI18n()
|
||||
|
||||
return (
|
||||
<div class="grid grid-cols-1 gap-4 sm:grid-cols-2">
|
||||
@ -439,7 +439,7 @@ const Versions = () => {
|
||||
}
|
||||
|
||||
export default () => {
|
||||
const { t } = useI18n()
|
||||
const [t] = useI18n()
|
||||
|
||||
return (
|
||||
<div class="mx-auto flex max-w-screen-md flex-col gap-4">
|
||||
|
@ -78,7 +78,7 @@ const fuzzyFilter: FilterFn<Connection> = (row, columnId, value, addMeta) => {
|
||||
}
|
||||
|
||||
export default () => {
|
||||
const { t } = useI18n()
|
||||
const [t] = useI18n()
|
||||
|
||||
const [activeTab, setActiveTab] = createSignal(ActiveTab.activeConnections)
|
||||
const { activeConnections, closedConnections, paused, setPaused } =
|
||||
@ -88,7 +88,7 @@ export default () => {
|
||||
|
||||
const [selectedConnectionID, setSelectedConnectionID] = createSignal<string>()
|
||||
|
||||
const columns = createMemo<ColumnDef<Connection>[]>(() => [
|
||||
const columns: ColumnDef<Connection>[] = [
|
||||
{
|
||||
header: () => t('details'),
|
||||
enableGrouping: false,
|
||||
@ -243,7 +243,7 @@ export default () => {
|
||||
original.metadata.destinationIP ||
|
||||
original.metadata.host,
|
||||
},
|
||||
])
|
||||
]
|
||||
|
||||
const [grouping, setGrouping] = createSignal<GroupingState>([])
|
||||
const [sorting, setSorting] = makePersisted(
|
||||
@ -281,7 +281,7 @@ export default () => {
|
||||
},
|
||||
sortDescFirst: true,
|
||||
enableHiding: true,
|
||||
columns: columns(),
|
||||
columns,
|
||||
onGlobalFilterChange: setGlobalFilter,
|
||||
globalFilterFn: fuzzyFilter,
|
||||
onGroupingChange: setGrouping,
|
||||
|
@ -40,7 +40,7 @@ const fuzzyFilter: FilterFn<LogWithSeq> = (row, columnId, value, addMeta) => {
|
||||
}
|
||||
|
||||
export default () => {
|
||||
const { t } = useI18n()
|
||||
const [t] = useI18n()
|
||||
let seq = 1
|
||||
const [logs, setLogs] = createSignal<LogWithSeq[]>([])
|
||||
|
||||
|
@ -26,7 +26,7 @@ const TrafficWidget: ParentComponent<{ label: JSX.Element }> = (props) => (
|
||||
)
|
||||
|
||||
export default () => {
|
||||
const { t } = useI18n()
|
||||
const [t] = useI18n()
|
||||
|
||||
const [traffics, setTraffics] = createSignal<{ down: number; up: number }[]>(
|
||||
[],
|
||||
|
@ -34,7 +34,7 @@ enum ActiveTab {
|
||||
}
|
||||
|
||||
export default () => {
|
||||
const { t } = useI18n()
|
||||
const [t] = useI18n()
|
||||
const {
|
||||
proxies,
|
||||
selectProxyInGroup,
|
||||
|
@ -12,7 +12,7 @@ enum ActiveTab {
|
||||
}
|
||||
|
||||
export default () => {
|
||||
const { t } = useI18n()
|
||||
const [t] = useI18n()
|
||||
const {
|
||||
rules,
|
||||
ruleProviders,
|
||||
|
@ -23,7 +23,7 @@ const schema = z.object({
|
||||
})
|
||||
|
||||
export default () => {
|
||||
const { t } = useI18n()
|
||||
const [t] = useI18n()
|
||||
const navigate = useNavigate()
|
||||
|
||||
const onSetupSuccess = (id: string) => {
|
||||
|
@ -1,5 +1,5 @@
|
||||
import dayjs from 'dayjs'
|
||||
import { curLocale } from '~/i18n'
|
||||
import { locale } from '~/i18n'
|
||||
|
||||
export const formatTimeFromNow = (time: number | string) =>
|
||||
dayjs(time).locale(curLocale()).fromNow()
|
||||
dayjs(time).locale(locale()).fromNow()
|
||||
|
Loading…
x
Reference in New Issue
Block a user