diff --git a/public/locales/en/translation.json b/public/locales/en/translation.json index 9a0b007a..46c92689 100644 --- a/public/locales/en/translation.json +++ b/public/locales/en/translation.json @@ -418,6 +418,7 @@ "Username": "Username", "Userpic": "Userpic", "Users": "Users", + "User was not found": "User was not found", "Video format not supported": "Video format not supported", "Video": "Video", "Views": "Views", @@ -541,4 +542,4 @@ "Incorrect old password": "Incorrect old password", "Repeat new password": "Repeat new password", "Incorrect new password confirm": "Incorrect new password confirm" -} +} \ No newline at end of file diff --git a/public/locales/ru/translation.json b/public/locales/ru/translation.json index 08927e17..88ca457e 100644 --- a/public/locales/ru/translation.json +++ b/public/locales/ru/translation.json @@ -550,6 +550,7 @@ "topicKeywords": "{topic}, Discours.io, статьи, журналистика, исследования", "topics": "темы", "user already exist": "пользователь уже существует", + "User was not found": "Пользователь не найден", "verified": "уже подтверждён", "video": "видео", "view": "просмотр", @@ -568,4 +569,4 @@ "Incorrect old password": "Старый пароль не верен", "Repeat new password": "Повторите новый пароль", "Incorrect new password confirm": "Неверное подтверждение нового пароля" -} +} \ No newline at end of file diff --git a/src/components/Article/FullArticle.tsx b/src/components/Article/FullArticle.tsx index eb10ea09..3cea62c2 100644 --- a/src/components/Article/FullArticle.tsx +++ b/src/components/Article/FullArticle.tsx @@ -538,7 +538,7 @@ export const FullArticle = (props: Props) => { {(triggerRef: (el) => void) => (
diff --git a/src/components/Author/AuthorBadge/AuthorBadge.tsx b/src/components/Author/AuthorBadge/AuthorBadge.tsx index 665f300f..bcb29a29 100644 --- a/src/components/Author/AuthorBadge/AuthorBadge.tsx +++ b/src/components/Author/AuthorBadge/AuthorBadge.tsx @@ -54,7 +54,7 @@ export const AuthorBadge = (props: Props) => { requireAuthentication(() => { openPage(router, 'inbox') changeSearchParams({ - initChat: props.author.id.toString(), + initChat: props.author?.id.toString(), }) }, 'discussions') } diff --git a/src/components/Author/AuthorCard/AuthorCard.tsx b/src/components/Author/AuthorCard/AuthorCard.tsx index c3b1ccd3..f1b58fef 100644 --- a/src/components/Author/AuthorCard/AuthorCard.tsx +++ b/src/components/Author/AuthorCard/AuthorCard.tsx @@ -65,7 +65,7 @@ export const AuthorCard = (props: Props) => { requireAuthentication(() => { openPage(router, 'inbox') changeSearchParams({ - initChat: props.author.id.toString(), + initChat: props.author?.id.toString(), }) }, 'discussions') } diff --git a/src/components/Draft/Draft.tsx b/src/components/Draft/Draft.tsx index cfbc9b0c..b66b9c1a 100644 --- a/src/components/Draft/Draft.tsx +++ b/src/components/Draft/Draft.tsx @@ -60,7 +60,7 @@ export const Draft = (props: Props) => {
{t('Edit')} diff --git a/src/components/Feed/ArticleCard/ArticleCard.tsx b/src/components/Feed/ArticleCard/ArticleCard.tsx index 85f921a8..e8e8a44c 100644 --- a/src/components/Feed/ArticleCard/ArticleCard.tsx +++ b/src/components/Feed/ArticleCard/ArticleCard.tsx @@ -329,7 +329,7 @@ export const ArticleCard = (props: ArticleCardProps) => { {(triggerRef: (el) => void) => (
- + { try { const { errors } = await signIn({ email: email(), password: password() }) - console.error('[signIn errors]', errors) if (errors?.length > 0) { - if ( - errors.some( - (error) => - error.message.includes('bad user credentials') || error.message.includes('user not found'), - ) - ) { + console.error('[signIn errors]', errors) + if (errors.some((error) => error.message.includes('user has not signed up email & password'))) { setValidationErrors((prev) => ({ ...prev, password: t('Something went wrong, check email and password'), })) } else if (errors.some((error) => error.message.includes('user not found'))) { - setSubmitError('Пользователь не найден') + setSubmitError(t('User was not found')) } else if (errors.some((error) => error.message.includes('email not verified'))) { setSubmitError(
diff --git a/src/components/Nav/HeaderAuth.tsx b/src/components/Nav/HeaderAuth.tsx index d3e38709..57a978ca 100644 --- a/src/components/Nav/HeaderAuth.tsx +++ b/src/components/Nav/HeaderAuth.tsx @@ -103,7 +103,13 @@ export const HeaderAuth = (props: Props) => {
-
+
{t('Create post')} @@ -210,11 +216,17 @@ export const HeaderAuth = (props: Props) => { -
+ @@ -227,7 +239,7 @@ export const HeaderAuth = (props: Props) => { {t('Enter')} - {/**/} +
diff --git a/src/components/Topic/TopicBadge/TopicBadge.module.scss b/src/components/Topic/TopicBadge/TopicBadge.module.scss index 52edb734..6b818c60 100644 --- a/src/components/Topic/TopicBadge/TopicBadge.module.scss +++ b/src/components/Topic/TopicBadge/TopicBadge.module.scss @@ -45,7 +45,6 @@ .info { @include font-size(1.4rem); - border: none; // display: flex; @@ -63,13 +62,11 @@ .title { @include font-size(2.2rem); - font-weight: bold; } .description { @include font-size(1.6rem); - line-height: 1.4; margin: 0.8rem 0; -webkit-line-clamp: 2; @@ -107,7 +104,6 @@ .title { @include font-size(1.4rem); - font-weight: 500; line-height: 1em; color: var(--blue-500); @@ -116,9 +112,7 @@ .description { color: var(--black-400); - @include font-size(1.2rem); - font-weight: 500; margin: 0; } diff --git a/src/components/Topic/TopicBadge/TopicBadge.tsx b/src/components/Topic/TopicBadge/TopicBadge.tsx index fa7e577b..73afe366 100644 --- a/src/components/Topic/TopicBadge/TopicBadge.tsx +++ b/src/components/Topic/TopicBadge/TopicBadge.tsx @@ -48,7 +48,7 @@ export const TopicBadge = (props: Props) => { lang() === 'en' ? capitalize(props.topic.slug.replaceAll('-', ' ')) : props.topic.title return ( -
+
diff --git a/src/components/_shared/SolidSwiper/ArticleCardSwiper.tsx b/src/components/_shared/SolidSwiper/ArticleCardSwiper.tsx index 067748d5..c614cba1 100644 --- a/src/components/_shared/SolidSwiper/ArticleCardSwiper.tsx +++ b/src/components/_shared/SolidSwiper/ArticleCardSwiper.tsx @@ -37,7 +37,6 @@ export const ArticleCardSwiper = (props: Props) => { [styles.Swiper]: props.slides.length > 1, [styles.articleMode]: true, [styles.ArticleCardSwiper]: props.slides.length > 1, - [styles.unswiped]: props.slides.length === 1, })} > diff --git a/src/context/connect.tsx b/src/context/connect.tsx index dfd8d549..f8ebb1c9 100644 --- a/src/context/connect.tsx +++ b/src/context/connect.tsx @@ -30,53 +30,57 @@ const ConnectContext = createContext() export const ConnectProvider = (props: { children: JSX.Element }) => { const [messageHandlers, setHandlers] = createSignal([]) - // const [messages, setMessages] = createSignal>([]); const [connected, setConnected] = createSignal(false) const { session } = useSession() + const [retried, setRetried] = createSignal(0) const addHandler = (handler: MessageHandler) => { setHandlers((hhh) => [...hhh, handler]) } - const [retried, setRetried] = createSignal(0) createEffect(async () => { const token = session()?.access_token - if (token && !connected()) { + if (token && !connected() && retried() <= RECONNECT_TIMES) { console.info('[context.connect] init SSE connection') - await fetchEventSource('https://connect.discours.io', { - method: 'GET', - headers: { - 'Content-Type': 'application/json', - Authorization: token, - }, - onmessage(event) { - const m: SSEMessage = JSON.parse(event.data || '{}') - console.log('[context.connect] Received message:', m) - - // Iterate over all registered handlers and call them - messageHandlers().forEach((handler) => handler(m)) - }, - async onopen(response) { - console.log('[context.connect] SSE connection opened', response) - if (response.ok && response.headers.get('content-type') === EventStreamContentType) { - setConnected(true) - } else if (response.status === 401) { - throw new Error('unauthorized') - } else { - setRetried((r) => r + 1) - throw new Error('Internal Error') - } - }, - onclose() { - console.log('[context.connect] SSE connection closed by server') - setConnected(false) - }, - onerror(err) { - if (err.message === 'unauthorized' || retried() > RECONNECT_TIMES) { - throw err // rethrow to stop the operation - } - }, - }) + try { + await fetchEventSource('https://connect.discours.io', { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + Authorization: token, + }, + onmessage(event) { + const m: SSEMessage = JSON.parse(event.data || '{}') + console.log('[context.connect] Received message:', m) + messageHandlers().forEach((handler) => handler(m)) + }, + onopen: (response) => { + console.log('[context.connect] SSE connection opened', response) + if (response.ok && response.headers.get('content-type') === EventStreamContentType) { + setConnected(true) + setRetried(0) + return Promise.resolve() + } + return Promise.reject(`SSE: cannot connect to real-time updates, status: ${response.status}`) + }, + onclose() { + console.log('[context.connect] SSE connection closed by server') + setConnected(false) + if (retried() < RECONNECT_TIMES) { + setRetried((r) => r + 1) + } + }, + onerror(err) { + console.error('[context.connect] SSE connection error:', err) + setConnected(false) + if (retried() < RECONNECT_TIMES) { + setRetried((r) => r + 1) + } else throw Error(err) + }, + }) + } catch (error) { + console.error('[context.connect] SSE connection failed:', error) + } } }) diff --git a/src/context/session.tsx b/src/context/session.tsx index 45b79f79..27ed21e5 100644 --- a/src/context/session.tsx +++ b/src/context/session.tsx @@ -225,9 +225,12 @@ export const SessionProvider = (props: { const appdata = session()?.user.app_data if (appdata) { const { profile } = appdata - setAuthor(profile) - addAuthors([profile]) - if (!profile) loadAuthor() + if (profile?.id) { + setAuthor(profile) + addAuthors([profile]) + } else { + setTimeout(loadAuthor, 15) + } } } catch (e) { console.error(e) diff --git a/src/pages/create.page.tsx b/src/pages/create.page.tsx index 833d328e..e5b7e8a1 100644 --- a/src/pages/create.page.tsx +++ b/src/pages/create.page.tsx @@ -18,7 +18,7 @@ import styles from '../styles/Create.module.scss' const handleCreate = async (layout: LayoutType) => { const shout = await apiClient.createArticle({ article: { layout: layout } }) redirectPage(router, 'edit', { - shoutId: shout.id.toString(), + shoutId: shout?.id.toString(), }) } diff --git a/src/pages/edit.page.tsx b/src/pages/edit.page.tsx index 21353681..aaa08eee 100644 --- a/src/pages/edit.page.tsx +++ b/src/pages/edit.page.tsx @@ -1,4 +1,4 @@ -import { Show, Suspense, createEffect, createMemo, createSignal, lazy, on, onMount } from 'solid-js' +import { Show, Suspense, createEffect, createMemo, createSignal, lazy, on } from 'solid-js' import { AuthGuard } from '../components/AuthGuard' import { Loading } from '../components/_shared/Loading' @@ -7,7 +7,7 @@ import { useLocalize } from '../context/localize' import { useSession } from '../context/session' import { apiClient } from '../graphql/client/core' import { Shout } from '../graphql/schema/core.gen' -import { router } from '../stores/router' +import { router, useRouter } from '../stores/router' import { redirectPage } from '@nanostores/router' import { useSnackbar } from '../context/snackbar' @@ -33,6 +33,7 @@ const getContentTypeTitle = (layout: LayoutType) => { export const EditPage = () => { const { t } = useLocalize() const { session } = useSession() + const { page } = useRouter() const snackbar = useSnackbar() const fail = async (error: string) => { @@ -45,12 +46,22 @@ export const EditPage = () => { const [shoutId, setShoutId] = createSignal(0) const [shout, setShout] = createSignal() - onMount(() => { - const shoutId = window.location.pathname.split('/').pop() - const shoutIdFromUrl = Number.parseInt(shoutId ?? '0', 10) - console.debug(`editing shout ${shoutIdFromUrl}`) - if (shoutIdFromUrl) setShoutId(shoutIdFromUrl) - }) + createEffect( + on( + () => page(), + (p) => { + if (p?.path) { + console.debug(p?.path) + const shoutId = p?.path.split('/').pop() + const shoutIdFromUrl = Number.parseInt(shoutId ?? '0', 10) + console.debug(`editing shout ${shoutIdFromUrl}`) + if (shoutIdFromUrl) { + setShoutId(shoutIdFromUrl) + } + } + }, + ), + ) createEffect( on([session, shout, shoutId], async ([ses, sh, shid]) => { @@ -63,6 +74,7 @@ export const EditPage = () => { } } }), + { defer: true }, ) const title = createMemo(() => {