import type { i18n } from 'i18next' import type { Accessor, JSX } from 'solid-js' import i18next, { changeLanguage, t } from 'i18next' import TimeAgo from 'javascript-time-ago' import en from 'javascript-time-ago/locale/en' import ru from 'javascript-time-ago/locale/ru' import Cookie from 'js-cookie' import { createContext, createEffect, createMemo, createSignal, Show, useContext } from 'solid-js' import { useRouter } from '../stores/router' TimeAgo.addLocale(en) TimeAgo.addLocale(ru) type LocalizeContextType = { t: i18n['t'] lang: Accessor setLang: (lang: Language) => void formatTime: (date: Date, options?: Intl.DateTimeFormatOptions) => string formatDate: (date: Date, options?: Intl.DateTimeFormatOptions) => string formatTimeAgo: (date: Date) => string } export type Language = 'ru' | 'en' const LocalizeContext = createContext() export function useLocalize() { return useContext(LocalizeContext) } export const LocalizeProvider = (props: { children: JSX.Element }) => { const [lang, setLang] = createSignal(i18next.language === 'en' ? 'en' : 'ru') const { searchParams, changeSearchParams } = useRouter<{ lng: string }>() createEffect(() => { if (!searchParams().lng) { return } const lng: Language = searchParams().lng === 'en' ? 'en' : 'ru' changeLanguage(lng) setLang(lng) Cookie.set('lng', lng) changeSearchParams({ lng: null }, true) }) 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 } return ( {props.children} ) }