webapp/src/context/localize.tsx

96 lines
2.5 KiB
TypeScript
Raw Normal View History

2023-02-17 09:21:02 +00:00
import type { i18n } from 'i18next'
import type { Accessor, JSX } from 'solid-js'
import { createContext, createEffect, createMemo, createSignal, Show, useContext } from 'solid-js'
2023-02-17 09:21:02 +00:00
import { useRouter } from '../stores/router'
2023-05-01 18:32:32 +00:00
import i18next, { changeLanguage, t } from 'i18next'
2023-02-17 09:21:02 +00:00
import Cookie from 'js-cookie'
import TimeAgo from 'javascript-time-ago'
import en from 'javascript-time-ago/locale/en'
import ru from 'javascript-time-ago/locale/ru'
TimeAgo.addLocale(en)
TimeAgo.addLocale(ru)
2023-02-17 09:21:02 +00:00
type LocalizeContextType = {
t: i18n['t']
lang: Accessor<Language>
setLang: (lang: Language) => void
formatTime: (date: Date, options?: Intl.DateTimeFormatOptions) => string
formatDate: (date: Date, options?: Intl.DateTimeFormatOptions) => string
formatTimeAgo: (date: Date) => string
2023-02-17 09:21:02 +00:00
}
export type Language = 'ru' | 'en'
const LocalizeContext = createContext<LocalizeContextType>()
export function useLocalize() {
return useContext(LocalizeContext)
}
export const LocalizeProvider = (props: { children: JSX.Element }) => {
const [lang, setLang] = createSignal<Language>(i18next.language === 'en' ? 'en' : 'ru')
const { searchParams, changeSearchParam } = useRouter<{
lng: string
}>()
2023-02-17 09:21:02 +00:00
createEffect(() => {
if (!searchParams().lng) {
return
}
const lng: Language = searchParams().lng === 'en' ? 'en' : 'ru'
2023-05-01 18:32:32 +00:00
changeLanguage(lng)
2023-02-17 09:21:02 +00:00
setLang(lng)
Cookie.set('lng', lng)
changeSearchParam({ lng: null }, true)
2023-02-17 09:21:02 +00:00
})
const formatTime = (date: Date, options: Intl.DateTimeFormatOptions = {}) => {
const opts = Object.assign(
{},
{
hour: '2-digit',
minute: '2-digit'
},
options
)
return date.toLocaleTimeString(lang(), opts)
}
const formatDate = (date: Date, options: Intl.DateTimeFormatOptions = {}) => {
const opts = Object.assign(
{},
{
month: 'long',
day: 'numeric',
year: 'numeric'
},
options
)
let result = date.toLocaleDateString(lang(), opts)
if (lang() === 'ru') {
result = result.replace(' г.', '').replace('г.', '')
}
return result
}
const timeAgo = createMemo(() => new TimeAgo(lang()))
const formatTimeAgo = (date: Date) => timeAgo().format(date)
const value: LocalizeContextType = { t, lang, setLang, formatTime, formatDate, formatTimeAgo }
2023-02-17 09:21:02 +00:00
return (
<LocalizeContext.Provider value={value}>
<Show when={lang()} keyed={true}>
{props.children}
</Show>
</LocalizeContext.Provider>
)
}