no persistentAtom for locale

This commit is contained in:
tonyrewin 2022-09-24 02:42:19 +03:00
parent 0d9e301b0c
commit 3554a5ef77
11 changed files with 199 additions and 603 deletions

View File

@ -28,17 +28,17 @@
"vercel-build": "astro build" "vercel-build": "astro build"
}, },
"dependencies": { "dependencies": {
"@aws-sdk/client-s3": "^3.169.0", "@aws-sdk/client-s3": "^3.178.0",
"@nanostores/i18n": "^0.6.0", "@nanostores/i18n": "^0.7.0",
"@nanostores/persistent": "^0.6.2", "@nanostores/persistent": "^0.7.0",
"@nanostores/router": "^0.6.0", "@nanostores/router": "^0.7.0",
"@nanostores/solid": "^0.2.0", "@nanostores/solid": "^0.3.0",
"axios": "^0.27.2", "axios": "^0.27.2",
"google-translate-api-x": "^10.3.5", "google-translate-api-x": "^10.4.1",
"loglevel": "^1.8.0", "loglevel": "^1.8.0",
"loglevel-plugin-prefix": "^0.8.4", "loglevel-plugin-prefix": "^0.8.4",
"mailgun.js": "^8.0.1", "mailgun.js": "^8.0.1",
"nanostores": "^0.6.0", "nanostores": "^0.7.0",
"postcss-modules": "^5.0.0", "postcss-modules": "^5.0.0",
"rehype-autolink-headings": "^6.1.1", "rehype-autolink-headings": "^6.1.1",
"rehype-slug": "^5.0.1", "rehype-slug": "^5.0.1",
@ -46,33 +46,24 @@
"remark-code-titles": "^0.1.2" "remark-code-titles": "^0.1.2"
}, },
"devDependencies": { "devDependencies": {
"@astrojs/markdown-remark": "^1.0.0", "@astrojs/markdown-remark": "^1.1.2",
"@astrojs/mdx": "^0.11.1", "@astrojs/mdx": "^0.11.1",
"@astrojs/node": "^1.0.1", "@astrojs/node": "^1.0.1",
"@astrojs/partytown": "^1.0.0", "@astrojs/partytown": "^1.0.0",
"@astrojs/sitemap": "^1.0.0", "@astrojs/solid-js": "^1.1.0",
"@astrojs/solid-js": "^1.0.0",
"@astrojs/vercel": "^2.0.0", "@astrojs/vercel": "^2.0.0",
"@babel/core": "^7.18.13", "@babel/core": "^7.18.13",
"@graphql-codegen/cli": "^2.6.1", "@graphql-codegen/cli": "^2.12.1",
"@graphql-codegen/typescript": "^2.5.1", "@graphql-codegen/typescript": "^2.7.3",
"@graphql-codegen/typescript-operations": "^2.4.2", "@graphql-codegen/typescript-operations": "^2.5.3",
"@graphql-codegen/typescript-urql": "^3.5.12", "@graphql-codegen/typescript-urql": "^3.7.0",
"@graphql-codegen/urql-introspection": "^2.2.1", "@graphql-codegen/urql-introspection": "^2.2.1",
"@graphql-typed-document-node/core": "^3.1.1", "@graphql-typed-document-node/core": "^3.1.1",
"@popperjs/core": "^2.11.5", "@popperjs/core": "^2.11.6",
"@solid-devtools/debugger": "^0.9.0", "@solid-devtools/debugger": "^0.9.1",
"@solid-devtools/logger": "^0.4.7", "@solid-devtools/logger": "^0.4.7",
"@solid-primitives/clipboard": "^1.3.0", "@types/express": "^4.17.14",
"@solid-primitives/event-listener": "^2.2.0", "@types/node": "^18.7.19",
"@solid-primitives/intersection-observer": "^2.0.0",
"@solid-primitives/scheduled": "^1.0.1",
"@solid-primitives/script-loader": "^1.1.0",
"@solid-primitives/scroll": "^2.0.2",
"@solid-primitives/storage": "^1.3.1",
"@solidjs/meta": "^0.28.0",
"@types/express": "^4.17.13",
"@types/node": "^18.0.0",
"@types/uuid": "^8.3.4", "@types/uuid": "^8.3.4",
"@typescript-eslint/eslint-plugin": "^5.29.0", "@typescript-eslint/eslint-plugin": "^5.29.0",
"@typescript-eslint/parser": "^5.35.1", "@typescript-eslint/parser": "^5.35.1",
@ -99,59 +90,57 @@
"eslint-plugin-solid": "^0.7.1", "eslint-plugin-solid": "^0.7.1",
"eslint-plugin-sonarjs": "^0.15.0", "eslint-plugin-sonarjs": "^0.15.0",
"eslint-plugin-unicorn": "^43.0.2", "eslint-plugin-unicorn": "^43.0.2",
"graphql": "^16.5.0", "graphql": "^16.6.0",
"graphql-tag": "^2.12.6", "graphql-tag": "^2.12.6",
"graphql-ws": "^5.10.0", "graphql-ws": "^5.11.2",
"hast-util-select": "^5.0.1", "hast-util-select": "^5.0.2",
"husky": "^8.0.0", "husky": "^8.0.1",
"idb": "^7.0.1", "idb": "^7.0.1",
"jest": "^29.0.1", "jest": "^29.0.1",
"jsdom": "^20.0.0",
"lint-staged": "^13.0.3", "lint-staged": "^13.0.3",
"postcss": "^8.4.16", "postcss": "^8.4.16",
"prettier": "^2.7.0", "prettier": "^2.7.1",
"prettier-eslint": "^15.0.0", "prettier-eslint": "^15.0.1",
"prosemirror-commands": "^1.3.0", "prosemirror-commands": "^1.3.1",
"prosemirror-dropcursor": "^1.5.0", "prosemirror-dropcursor": "^1.6.0",
"prosemirror-example-setup": "^1.2.1", "prosemirror-example-setup": "^1.2.1",
"prosemirror-gapcursor": "^1.3.1", "prosemirror-gapcursor": "^1.3.1",
"prosemirror-history": "^1.3.0", "prosemirror-history": "^1.3.0",
"prosemirror-inputrules": "^1.2.0", "prosemirror-inputrules": "^1.2.0",
"prosemirror-keymap": "^1.2.0", "prosemirror-keymap": "^1.2.0",
"prosemirror-markdown": "^1.9.1", "prosemirror-markdown": "^1.9.4",
"prosemirror-menu": "^1.2.1", "prosemirror-menu": "^1.2.1",
"prosemirror-model": "1.16.1", "prosemirror-model": "1.18.1",
"prosemirror-schema-basic": "^1.2.0", "prosemirror-schema-basic": "^1.2.0",
"prosemirror-schema-list": "^1.1.6", "prosemirror-schema-list": "^1.2.2",
"prosemirror-state": "1.3.4", "prosemirror-state": "^1.4.1",
"prosemirror-view": "^1.26.2", "prosemirror-view": "^1.28.1",
"rollup": "~2.5.0", "rollup": "~2.79.1",
"sass": "^1.54.0", "sass": "^1.55.0",
"solid-devtools": "^0.16.2", "solid-devtools": "^0.16.2",
"solid-js": "^1.5.3", "solid-js": "^1.5.6",
"solid-js-form": "^0.1.5", "solid-js-form": "^0.1.5",
"solid-jsx": "^0.9.0", "solid-jsx": "^0.9.1",
"solid-social": "^0.9.0", "solid-social": "^0.9.0",
"solid-transition-group": "^0.0.11",
"solid-utils": "^0.8.1", "solid-utils": "^0.8.1",
"sort-package-json": "^1.57.0", "sort-package-json": "^1.57.0",
"stylelint": "^14.11.0", "stylelint": "^14.12.1",
"stylelint-config-css-modules": "^4.1.0", "stylelint-config-css-modules": "^4.1.0",
"stylelint-config-prettier-scss": "^0.0.1", "stylelint-config-prettier-scss": "^0.0.1",
"stylelint-config-standard-scss": "^5.0.0", "stylelint-config-standard-scss": "^5.0.0",
"stylelint-order": "^5.0.0", "stylelint-order": "^5.0.0",
"stylelint-scss": "^4.3.0", "stylelint-scss": "^4.3.0",
"swiper": "^8.3.2", "swiper": "^8.4.2",
"ts-debounce": "^4.0.0", "ts-debounce": "^4.0.0",
"ts-node": "^10.9.1", "ts-node": "^10.9.1",
"typescript": "4.7.4", "typescript": "^4.8.3",
"undici": "^5.10.0", "undici": "^5.10.0",
"unique-names-generator": "^4.7.1", "unique-names-generator": "^4.7.1",
"uuid": "^9.0.0", "uuid": "^9.0.0",
"vite": "^3.0.9", "vite": "^3.1.3",
"y-prosemirror": "^1.1.3", "y-prosemirror": "^1.1.3",
"y-protocols": "^1.0.5", "y-protocols": "^1.0.5",
"y-webrtc": "^10.2.2", "y-webrtc": "^10.2.3",
"yjs": "^13.5.38" "yjs": "^13.5.41"
} }
} }

View File

@ -7,7 +7,7 @@ import { createMemo } from 'solid-js'
import { translit } from '../../utils/ru2en' import { translit } from '../../utils/ru2en'
import { t } from '../../utils/intl' import { t } from '../../utils/intl'
import { session } from '../../stores/auth' import { session } from '../../stores/auth'
import { locale as locstore } from '../../stores/ui' import { locale } from '../../stores/ui'
import { follow, unfollow } from '../../stores/zine/common' import { follow, unfollow } from '../../stores/zine/common'
import { useStore } from '@nanostores/solid' import { useStore } from '@nanostores/solid'
@ -21,7 +21,6 @@ interface AuthorCardProps {
} }
export const AuthorCard = (props: AuthorCardProps) => { export const AuthorCard = (props: AuthorCardProps) => {
const locale = useStore(locstore)
const auth = useStore(session) const auth = useStore(session)
const subscribed = createMemo( const subscribed = createMemo(
() => () =>
@ -30,12 +29,12 @@ export const AuthorCard = (props: AuthorCardProps) => {
.pop() .pop()
) )
const canFollow = createMemo(() => !props.hideFollow && auth()?.user?.slug !== props.author.slug) const canFollow = createMemo(() => !props.hideFollow && auth()?.user?.slug !== props.author.slug)
const bio = createMemo(() => props.author.bio || t('Our regular contributor')) const bio = () => props.author.bio || t('Our regular contributor')
const name = createMemo(() => { const name = () => {
return props.author.name === 'Дискурс' && locale() !== 'ru' return props.author.name === 'Дискурс' && locale() !== 'ru'
? 'Discours' ? 'Discours'
: translit(props.author.name || '', locale() || 'ru') : translit(props.author.name || '', locale() || 'ru')
}) }
// TODO: reimplement AuthorCard // TODO: reimplement AuthorCard
return ( return (
<> <>

View File

@ -3,11 +3,9 @@ import './Footer.scss'
import { Icon } from '../Nav/Icon' import { Icon } from '../Nav/Icon'
import Subscribe from './Subscribe' import Subscribe from './Subscribe'
import { t } from '../../utils/intl' import { t } from '../../utils/intl'
import { locale as locstore } from '../../stores/ui' import { locale } from '../../stores/ui'
import { useStore } from '@nanostores/solid'
export const Footer = () => { export const Footer = () => {
const locale = useStore(locstore)
const locale_title = createMemo(() => (locale() === 'ru' ? 'English' : 'Русский')) const locale_title = createMemo(() => (locale() === 'ru' ? 'English' : 'Русский'))
const locale_link = createMemo(() => '?lang=' + (locale() === 'ru' ? 'en' : 'ru')) const locale_link = createMemo(() => '?lang=' + (locale() === 'ru' ? 'en' : 'ru'))
const links = createMemo(() => [ const links = createMemo(() => [

View File

@ -6,8 +6,7 @@ import { capitalize } from '../../utils'
import { translit } from '../../utils/ru2en' import { translit } from '../../utils/ru2en'
import { Icon } from '../Nav/Icon' import { Icon } from '../Nav/Icon'
import './Card.scss' import './Card.scss'
import { locale as localestore } from '../../stores/ui' import { locale } from '../../stores/ui'
import { useStore } from '@nanostores/solid'
import { handleClientRouteLinkClick } from '../../stores/router' import { handleClientRouteLinkClick } from '../../stores/router'
import { getLogger } from '../../utils/logger' import { getLogger } from '../../utils/logger'
@ -50,8 +49,6 @@ const getTitleAndSubtitle = (article: Shout): { title: string; subtitle: string
} }
export const ArticleCard = (props: ArticleCardProps) => { export const ArticleCard = (props: ArticleCardProps) => {
const locale = useStore(localestore)
const mainTopic = props.article.topics.find( const mainTopic = props.article.topics.find(
(articleTopic) => articleTopic.slug === props.article.mainTopic (articleTopic) => articleTopic.slug === props.article.mainTopic
) )

View File

@ -1,4 +1,4 @@
import { For, Show, createSignal, createMemo, createEffect, onMount, onCleanup } from 'solid-js' import { For, Show, createSignal, createMemo, createEffect, onMount, onCleanup, Suspense } from 'solid-js'
import Private from './Private' import Private from './Private'
import Notifications from './Notifications' import Notifications from './Notifications'
import { Icon } from './Icon' import { Icon } from './Icon'
@ -82,80 +82,82 @@ export const Header = (props: Props) => {
}) })
return ( return (
<header <Suspense>
classList={{ <header
['header--scrolled-top']: !getIsScrollingBottom() && getIsScrolled(), classList={{
['header--scrolled-bottom']: getIsScrollingBottom() && getIsScrolled() ['header--scrolled-top']: !getIsScrollingBottom() && getIsScrolled(),
}} ['header--scrolled-bottom']: getIsScrollingBottom() && getIsScrolled()
> }}
<Modal name="auth"> >
<AuthModal /> <Modal name="auth">
</Modal> <AuthModal />
<div class="wide-container"> </Modal>
<nav class="row header__inner" classList={{ fixed: fixed() }}> <div class="wide-container">
<div class="main-logo col-auto"> <nav class="row header__inner" classList={{ fixed: fixed() }}>
<a href={getPagePath(router, 'home')} onClick={handleClientRouteLinkClick}> <div class="main-logo col-auto">
<img src="/logo.svg" alt={t('Discours')} /> <a href={getPagePath(router, 'home')} onClick={handleClientRouteLinkClick}>
</a> <img src="/logo.svg" alt={t('Discours')} />
</div> </a>
<div class="col main-navigation"> </div>
<div class="article-header">{props.title}</div> <div class="col main-navigation">
<div class="article-header">{props.title}</div>
<ul class="col main-navigation text-xl inline-flex" classList={{ fixed: fixed() }}> <ul class="col main-navigation text-xl inline-flex" classList={{ fixed: fixed() }}>
<For each={resources}> <For each={resources}>
{(r) => ( {(r) => (
<li classList={{ selected: r.route === getPage().route }}> <li classList={{ selected: r.route === getPage().route }}>
<a href={getPagePath(router, r.route, null)} onClick={handleClientRouteLinkClick}> <a href={getPagePath(router, r.route, null)} onClick={handleClientRouteLinkClick}>
{r.name} {r.name}
</a> </a>
</li> </li>
)} )}
</For> </For>
<li class="header__search"> <li class="header__search">
<a href="#"> <a href="#">
<Icon name="search" /> <Icon name="search" />
{t('Search')} {t('Search')}
</a> </a>
</li> </li>
</ul> </ul>
</div> </div>
<div class="usernav"> <div class="usernav">
<div class="usercontrol col"> <div class="usercontrol col">
<div class="usercontrol__item"> <div class="usercontrol__item">
<a href="#auth" onClick={handleBellIconClick}> <a href="#auth" onClick={handleBellIconClick}>
<div> <div>
<Icon name="bell-white" counter={authorized() ? getWarnings().length : 1} /> <Icon name="bell-white" counter={authorized() ? getWarnings().length : 1} />
</div> </div>
</a> </a>
</div>
<Show when={visibleWarnings()}>
<div class="usercontrol__item notifications">
<Notifications />
</div> </div>
</Show>
<Show <Show when={visibleWarnings()}>
when={authorized()} <div class="usercontrol__item notifications">
fallback={ <Notifications />
<div class="usercontrol__item loginbtn">
<a href="#auth" onClick={handleEnterClick}>
{t('enter')}
</a>
</div> </div>
} </Show>
>
<Private /> <Show
</Show> when={authorized()}
fallback={
<div class="usercontrol__item loginbtn">
<a href="#auth" onClick={handleEnterClick}>
{t('enter')}
</a>
</div>
}
>
<Private />
</Show>
</div>
</div> </div>
</div> <div class="burger-container">
<div class="burger-container"> <div class="burger" classList={{ fixed: fixed() }} onClick={toggleFixed}>
<div class="burger" classList={{ fixed: fixed() }} onClick={toggleFixed}> <div />
<div /> </div>
</div> </div>
</div> </nav>
</nav> </div>
</div> </header>
</header> </Suspense>
) )
} }

View File

@ -3,12 +3,9 @@ import type { Topic } from '../../graphql/types.gen'
import { Icon } from './Icon' import { Icon } from './Icon'
import './Topics.scss' import './Topics.scss'
import { t } from '../../utils/intl' import { t } from '../../utils/intl'
import { locale as langstore } from '../../stores/ui' import { locale } from '../../stores/ui'
import { useStore } from '@nanostores/solid'
export const NavTopics = (props: { topics: Topic[] }) => { export const NavTopics = (props: { topics: Topic[] }) => {
const locale = useStore(langstore)
const tag = (t: Topic) => (/[ЁА-яё]/.test(t.title || '') && locale() !== 'ru' ? t.slug : t.title) const tag = (t: Topic) => (/[ЁА-яё]/.test(t.title || '') && locale() !== 'ru' ? t.slug : t.title)
// TODO: something about subtopics // TODO: something about subtopics

View File

@ -5,7 +5,7 @@ import { createMemo } from 'solid-js'
import type { Topic } from '../../graphql/types.gen' import type { Topic } from '../../graphql/types.gen'
import { FollowingEntity } from '../../graphql/types.gen' import { FollowingEntity } from '../../graphql/types.gen'
import { t } from '../../utils/intl' import { t } from '../../utils/intl'
import { locale as locstore } from '../../stores/ui' import { locale } from '../../stores/ui'
import { useStore } from '@nanostores/solid' import { useStore } from '@nanostores/solid'
import { session } from '../../stores/auth' import { session } from '../../stores/auth'
import { follow, unfollow } from '../../stores/zine/common' import { follow, unfollow } from '../../stores/zine/common'
@ -19,11 +19,8 @@ interface TopicProps {
} }
export const TopicCard = (props: TopicProps) => { export const TopicCard = (props: TopicProps) => {
const locale = useStore(locstore)
const auth = useStore(session) const auth = useStore(session)
const topic = createMemo(() => props.topic) const topic = createMemo(() => props.topic)
const subscribed = createMemo(() => { const subscribed = createMemo(() => {
return Boolean(auth()?.user?.slug) && topic().slug ? topic().slug in auth().info.topics : false return Boolean(auth()?.user?.slug) && topic().slug ? topic().slug in auth().info.topics : false
}) })

View File

@ -1,9 +1,5 @@
import { Title } from '@solidjs/meta'
export const ConnectView = () => ( export const ConnectView = () => (
<> <>
<Title>Дискурс: Предложить идею</Title>
<article class="container"> <article class="container">
<div class="row"> <div class="row">
<h1 class="col-md-8 offset-md-2"> <h1 class="col-md-8 offset-md-2">

View File

@ -22,6 +22,7 @@ import {
useArticlesStore useArticlesStore
} from '../../stores/zine/articles' } from '../../stores/zine/articles'
import { useTopAuthorsStore } from '../../stores/zine/topAuthors' import { useTopAuthorsStore } from '../../stores/zine/topAuthors'
import { locale } from '../../stores/ui'
const log = getLogger('home view') const log = getLogger('home view')
@ -85,7 +86,7 @@ export const HomeView = (props: HomeProps) => {
} }
return ( return (
<> <Show when={locale()}>
<NavTopics topics={getRandomTopics()} /> <NavTopics topics={getRandomTopics()} />
<Row5 articles={getSortedArticles().slice(0, 5)} /> <Row5 articles={getSortedArticles().slice(0, 5)} />
@ -149,6 +150,6 @@ export const HomeView = (props: HomeProps) => {
{t('Load more')} {t('Load more')}
</button> </button>
</p> </p>
</> </Show>
) )
} }

View File

@ -1,9 +1,10 @@
import { persistentAtom } from '@nanostores/persistent' //import { persistentAtom } from '@nanostores/persistent'
import { atom } from 'nanostores' import { atom } from 'nanostores'
import { useStore } from '@nanostores/solid' import { useStore } from '@nanostores/solid'
import { createSignal } from 'solid-js'
export const locale = persistentAtom<string>('locale', 'ru') //export const locale = persistentAtom<string>('locale', 'ru')
export const [locale, setLocale] = createSignal('ru')
export type ModalType = 'auth' | 'subscribe' | 'feedback' | 'share' | 'thank' | 'donate' | null export type ModalType = 'auth' | 'subscribe' | 'feedback' | 'share' | 'thank' | 'donate' | null
type WarnKind = 'error' | 'warn' | 'info' type WarnKind = 'error' | 'warn' | 'info'

525
yarn.lock

File diff suppressed because it is too large Load Diff