langswitch-fix
This commit is contained in:
parent
4c7839aaff
commit
a5eaeab5cd
|
@ -5,10 +5,12 @@ import sassDts from 'vite-plugin-sass-dts'
|
|||
const isVercel = Boolean(process?.env.VERCEL)
|
||||
const isBun = Boolean(process.env.BUN)
|
||||
export default defineConfig({
|
||||
ssr: true,
|
||||
server: {
|
||||
preset: isVercel ? 'vercel_edge' : isBun ? 'bun' : 'node',
|
||||
port: 3000,
|
||||
},
|
||||
devOverlay: true,
|
||||
build: {
|
||||
chunkSizeWarningLimit: 1024,
|
||||
target: 'esnext',
|
||||
|
@ -33,7 +35,7 @@ export default defineConfig({
|
|||
preprocessorOptions: {
|
||||
scss: {
|
||||
additionalData: '@import "src/styles/imports";\n',
|
||||
includePaths: ['public', 'src/styles']
|
||||
includePaths: ['./public', './src/styles'],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
@ -1,127 +1,76 @@
|
|||
import { clsx } from 'clsx'
|
||||
import { For, createMemo } from 'solid-js'
|
||||
|
||||
import { For, createSignal, onMount } from 'solid-js'
|
||||
import { useLocalize } from '../../context/localize'
|
||||
import { Icon } from '../_shared/Icon'
|
||||
import { Newsletter } from '../_shared/Newsletter'
|
||||
|
||||
import styles from './Footer.module.scss'
|
||||
|
||||
export const Footer = () => {
|
||||
|
||||
const social = [
|
||||
{ name: 'facebook', href: 'https://facebook.com/discoursio' },
|
||||
{ name: 'vk', href: 'https://vk.com/discoursio' },
|
||||
{ name: 'twitter', href: 'https://twitter.com/discours_io' },
|
||||
{ name: 'telegram', href: 'https://t.me/discoursio' },
|
||||
]
|
||||
type FooterItem = {
|
||||
title: string
|
||||
slug: string
|
||||
rel?: string
|
||||
}
|
||||
export const FooterView = () => {
|
||||
const { t, lang } = useLocalize()
|
||||
const [footerLinks, setFooterLinks] = createSignal<Array<{ header: string, items: FooterItem[]}>>([])
|
||||
|
||||
const changeLangTitle = createMemo(() => (lang() === 'ru' ? 'English' : 'Русский'))
|
||||
const changeLangLink = createMemo(() => `?lng=${lang() === 'ru' ? 'en' : 'ru'}`)
|
||||
const links = createMemo(() => [
|
||||
{
|
||||
header: t('About the project'),
|
||||
items: [
|
||||
{
|
||||
title: t('Discours Manifest'),
|
||||
slug: '/about/manifest',
|
||||
},
|
||||
{
|
||||
title: t('How it works'),
|
||||
slug: '/about/guide',
|
||||
},
|
||||
{
|
||||
title: t('Dogma'),
|
||||
slug: '/about/dogma',
|
||||
},
|
||||
{
|
||||
title: t('Principles'),
|
||||
slug: '/about/principles',
|
||||
},
|
||||
{
|
||||
title: t('How to write an article'),
|
||||
slug: '/how-to-write-a-good-article',
|
||||
},
|
||||
],
|
||||
},
|
||||
onMount(() => {
|
||||
setFooterLinks([
|
||||
{
|
||||
header: t('About the project'),
|
||||
items: [
|
||||
{ title: t('Discours Manifest'), slug: '/about/manifest' },
|
||||
{ title: t('How it works'), slug: '/about/guide' },
|
||||
{ title: t('Dogma'), slug: '/about/dogma' },
|
||||
{ title: t('Principles'), slug: '/about/principles' },
|
||||
{ title: t('How to write an article'), slug: '/how-to-write-a-good-article' },
|
||||
],
|
||||
},
|
||||
{
|
||||
header: t('Participating'),
|
||||
items: [
|
||||
{ title: t('Suggest an idea'), slug: '/connect' },
|
||||
{ title: t('Become an author'), slug: '/create' },
|
||||
{ title: t('Support Discours'), slug: '/about/help' },
|
||||
{ title: t('Work with us'), slug: 'https://docs.google.com/forms/d/e/1FAIpQLSeNNvIzKlXElJtkPkYiXl-jQjlvsL9u4-kpnoRjz1O8Wo40xQ/viewform' },
|
||||
],
|
||||
},
|
||||
{
|
||||
header: t('Sections'),
|
||||
items: [
|
||||
{ title: t('Authors'), slug: '/authors' },
|
||||
{ title: t('Communities'), slug: '/community' },
|
||||
{ title: t('Partners'), slug: '/about/partners' },
|
||||
{ title: t('Special projects'), slug: '/about/projects' },
|
||||
{ title: lang() === 'ru' ? 'English' : 'Русский', slug: `?lng=${lang() === 'ru' ? 'en' : 'ru'}`, rel: 'external' },
|
||||
],
|
||||
},
|
||||
])
|
||||
})
|
||||
|
||||
{
|
||||
header: t('Participating'),
|
||||
items: [
|
||||
{
|
||||
title: t('Suggest an idea'),
|
||||
slug: '/connect',
|
||||
},
|
||||
{
|
||||
title: t('Become an author'),
|
||||
slug: '/create',
|
||||
},
|
||||
{
|
||||
title: t('Support Discours'),
|
||||
slug: '/about/help',
|
||||
},
|
||||
{
|
||||
title: t('Work with us'),
|
||||
slug: 'https://docs.google.com/forms/d/e/1FAIpQLSeNNvIzKlXElJtkPkYiXl-jQjlvsL9u4-kpnoRjz1O8Wo40xQ/viewform',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
{
|
||||
header: t('Sections'),
|
||||
items: [
|
||||
{
|
||||
title: t('Authors'),
|
||||
slug: '/authors',
|
||||
},
|
||||
{
|
||||
title: t('Communities'),
|
||||
slug: '/community',
|
||||
},
|
||||
{
|
||||
title: t('Partners'),
|
||||
slug: '/about/partners',
|
||||
},
|
||||
{
|
||||
title: t('Special projects'),
|
||||
slug: '/about/projects',
|
||||
},
|
||||
{
|
||||
title: changeLangTitle(),
|
||||
slug: changeLangLink(),
|
||||
rel: 'external',
|
||||
},
|
||||
],
|
||||
},
|
||||
])
|
||||
|
||||
const social = [
|
||||
{
|
||||
name: 'facebook',
|
||||
href: 'https://facebook.com/discoursio',
|
||||
},
|
||||
{
|
||||
name: 'vk',
|
||||
href: 'https://vk.com/discoursio',
|
||||
},
|
||||
{
|
||||
name: 'twitter',
|
||||
href: 'https://twitter.com/discours_io',
|
||||
},
|
||||
{
|
||||
name: 'telegram',
|
||||
href: 'https://t.me/discoursio',
|
||||
},
|
||||
]
|
||||
return (
|
||||
|
||||
<footer class={styles.discoursFooter}>
|
||||
<div class="wide-container">
|
||||
<div class="row">
|
||||
<For each={links()}>
|
||||
<For each={footerLinks()}>
|
||||
{({ header, items }) => (
|
||||
<div class="col-sm-8 col-md-6">
|
||||
<h5>{header}</h5>
|
||||
<h5>{t(header)}</h5>
|
||||
<ul>
|
||||
<For each={items}>
|
||||
{({ slug, title, ...rest }) => (
|
||||
{({ slug, title, rel }: FooterItem) => (
|
||||
<li>
|
||||
{' '}
|
||||
<a href={slug} {...rest}>
|
||||
{title}
|
||||
<a href={slug} rel={rel}>
|
||||
{rel ? title : t(title)}
|
||||
</a>{' '}
|
||||
</li>
|
||||
)}
|
||||
|
@ -147,16 +96,13 @@ export const Footer = () => {
|
|||
</div>
|
||||
<div class={clsx(styles.footerCopyrightSocial, 'col-md-6 col-lg-4')}>
|
||||
<For each={social}>
|
||||
{(social) => {
|
||||
const styleKey = `socialItem${social.name}` as keyof typeof styles
|
||||
return (
|
||||
<div class={clsx(styles.socialItem, styles[styleKey])}>
|
||||
<a href={social.href}>
|
||||
<Icon name={`${social.name}-white`} class={styles.icon} />
|
||||
</a>
|
||||
</div>
|
||||
)
|
||||
}}
|
||||
{(provider) => (
|
||||
<div class={clsx(styles.socialItem, styles[`socialItem${provider.name}` as keyof typeof styles])}>
|
||||
<a href={provider.href}>
|
||||
<Icon name={`${provider.name}-white`} class={styles.icon} />
|
||||
</a>
|
||||
</div>
|
||||
)}
|
||||
</For>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -4,7 +4,7 @@ import { Title } from '@solidjs/meta'
|
|||
import { clsx } from 'clsx'
|
||||
import { Show, createEffect, createSignal } from 'solid-js'
|
||||
|
||||
import { Footer } from '../Discours/Footer'
|
||||
import { FooterView } from '../Discours/Footer'
|
||||
import { Header } from '../Nav/Header'
|
||||
|
||||
import '../../styles/app.scss'
|
||||
|
@ -26,7 +26,7 @@ type Props = {
|
|||
}
|
||||
|
||||
export const PageLayout = (props: Props) => {
|
||||
const isHeaderFixed = props.isHeaderFixed === undefined ? true : props.isHeaderFixed
|
||||
const isHeaderFixed = (props.isHeaderFixed === undefined) ? true : props.isHeaderFixed
|
||||
const [scrollToComments, setScrollToComments] = createSignal<boolean>(false)
|
||||
|
||||
createEffect(() => {
|
||||
|
@ -56,7 +56,7 @@ export const PageLayout = (props: Props) => {
|
|||
{props.children}
|
||||
</main>
|
||||
<Show when={props.hideFooter !== true}>
|
||||
<Footer />
|
||||
<FooterView />
|
||||
</Show>
|
||||
</>
|
||||
)
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { useSearchParams } from '@solidjs/router'
|
||||
import type { Accessor, JSX } from 'solid-js'
|
||||
import { Show, createContext, createEffect, createMemo, createSignal, useContext } from 'solid-js'
|
||||
|
||||
import { Show, createContext, createEffect, createMemo, createSignal, on, onMount, useContext } from 'solid-js'
|
||||
import { TimeAgo, type i18n, i18next, i18nextInit } from '~/lib/i18next'
|
||||
|
||||
i18nextInit()
|
||||
|
@ -24,27 +23,22 @@ const LocalizeContext = createContext<LocalizeContextType>({
|
|||
export function useLocalize() {
|
||||
return useContext(LocalizeContext)
|
||||
}
|
||||
|
||||
type LocalizeSearchParams = {
|
||||
lng?: Language
|
||||
}
|
||||
export const LocalizeProvider = (props: { children: JSX.Element }) => {
|
||||
const [lang, setLang] = createSignal<Language>(i18next.language === 'en' ? 'en' : 'ru')
|
||||
const [searchParams, changeSearchParams] = useSearchParams<Record<string, string>>()
|
||||
createEffect(() => {
|
||||
if (!(searchParams?.lng || localStorage.getItem('lng'))) {
|
||||
return
|
||||
}
|
||||
try {
|
||||
const lng: Language = searchParams?.lng === 'en' ? 'en' : 'ru'
|
||||
|
||||
i18next.changeLanguage(lng)
|
||||
setLang(lng)
|
||||
if (searchParams?.lng) {
|
||||
changeSearchParams({ lng }, { replace: true })
|
||||
}
|
||||
localStorage?.setItem('lng', lng)
|
||||
} catch (e) {
|
||||
console.warn(e)
|
||||
}
|
||||
const [searchParams, changeSearchParams] = useSearchParams<LocalizeSearchParams>()
|
||||
// set lang effects
|
||||
onMount(() => {
|
||||
const lng = searchParams?.lng || localStorage?.getItem('lng') || 'ru'
|
||||
setLang(lng as Language)
|
||||
changeSearchParams({lng: undefined})
|
||||
})
|
||||
createEffect(on(lang, (lng: Language) => {
|
||||
localStorage.setItem('lng', lng || 'ru')
|
||||
i18next.changeLanguage(lng || 'ru')
|
||||
}))
|
||||
|
||||
const formatTime = (date: Date, options: Intl.DateTimeFormatOptions = {}) => {
|
||||
const opts = Object.assign(
|
||||
|
|
|
@ -164,7 +164,7 @@ export const UIProvider = (props: { children: JSX.Element }) => {
|
|||
}
|
||||
|
||||
const showModal = (modalType: ModalType, modalSource?: AuthModalSource) => {
|
||||
console.log('[context.ui] showModal()', modalType)
|
||||
// console.log('[context.ui] showModal()', modalType)
|
||||
if (modalSource) {
|
||||
setSearchParams({ source: modalSource })
|
||||
}
|
||||
|
@ -172,7 +172,7 @@ export const UIProvider = (props: { children: JSX.Element }) => {
|
|||
}
|
||||
|
||||
const hideModal = () => {
|
||||
console.log('[context.ui] hideModal()', modal())
|
||||
// console.log('[context.ui] hideModal()', modal())
|
||||
setTimeout(() => setModal(null), 1) // NOTE: modal rerender fix
|
||||
setSearchParams({ source: undefined, m: undefined, mode: undefined })
|
||||
}
|
||||
|
@ -184,7 +184,7 @@ export const UIProvider = (props: { children: JSX.Element }) => {
|
|||
[modal, () => searchParams?.m || ''],
|
||||
([m1, m2]) => {
|
||||
const m = m1 || m2 || ''
|
||||
console.log('[context.ui] search params change', m)
|
||||
m1 && console.log('[context.ui] search params change', m1)
|
||||
if (m) {
|
||||
showModal(m as ModalType)
|
||||
} else {
|
||||
|
|
|
@ -2,11 +2,14 @@ import i18next, { type i18n } from 'i18next'
|
|||
import HttpApi from 'i18next-http-backend'
|
||||
import ICU from 'i18next-icu'
|
||||
import TimeAgo from 'javascript-time-ago'
|
||||
import en from 'javascript-time-ago/locale/en'
|
||||
import ru from 'javascript-time-ago/locale/ru'
|
||||
import enTime from 'javascript-time-ago/locale/en'
|
||||
import ruTime from 'javascript-time-ago/locale/ru'
|
||||
import en from './locales/en/translation.json'
|
||||
import ru from './locales/ru/translation.json'
|
||||
|
||||
TimeAgo.addLocale(en)
|
||||
TimeAgo.addLocale(ru)
|
||||
|
||||
TimeAgo.addLocale(enTime)
|
||||
TimeAgo.addLocale(ruTime)
|
||||
|
||||
export const i18nextInit = async (lng = 'ru') => {
|
||||
if (!i18next.isInitialized) {
|
||||
|
@ -23,8 +26,8 @@ export const i18nextInit = async (lng = 'ru') => {
|
|||
load: 'languageOnly',
|
||||
initImmediate: false,
|
||||
resources: {
|
||||
ru: { translation: await import('./locales/ru/translation.json') },
|
||||
en: { translation: await import('./locales/en/translation.json') },
|
||||
ru: { translation: ru },
|
||||
en: { translation: en },
|
||||
},
|
||||
})
|
||||
// console.debug(i18next)
|
||||
|
|
|
@ -853,7 +853,7 @@ figure {
|
|||
position: relative;
|
||||
|
||||
@include media-breakpoint-up(lg) {
|
||||
padding-top: 130px;
|
||||
// padding-top: 130px;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user