From 891d29ff6aab07d2b0a89e0a6d388587fb78206a Mon Sep 17 00:00:00 2001 From: Ilya Y <75578537+ilya-bkv@users.noreply.github.com> Date: Thu, 19 Oct 2023 18:05:22 +0300 Subject: [PATCH 001/129] signIn/getSession optimizaiton frontend (#272) Co-authored-by: Igor Lobanov --- .../Author/AuthorBadge/AuthorBadge.tsx | 11 +++--- .../Author/AuthorCard/AuthorCard.tsx | 11 +++--- src/components/Feed/Sidebar/Sidebar.tsx | 34 +++++++------------ src/components/Nav/HeaderAuth.tsx | 8 ++--- src/components/Topic/Card.tsx | 12 +++---- src/components/Topic/Full.tsx | 8 +++-- .../Topic/TopicBadge/TopicBadge.tsx | 16 ++++----- src/components/Views/AllAuthors.tsx | 5 +-- src/components/Views/AllTopics.tsx | 4 +-- src/context/session.tsx | 29 +++++++++++++--- src/graphql/mutation/auth-confirm-email.ts | 7 ---- src/graphql/mutation/my-session.ts | 7 ---- src/graphql/query/my-subscriptions.ts | 21 ++++++++++++ src/graphql/types.gen.ts | 15 ++++---- src/utils/apiClient.ts | 10 +++++- 15 files changed, 109 insertions(+), 89 deletions(-) create mode 100644 src/graphql/query/my-subscriptions.ts diff --git a/src/components/Author/AuthorBadge/AuthorBadge.tsx b/src/components/Author/AuthorBadge/AuthorBadge.tsx index e8730fb3..d5f7bc42 100644 --- a/src/components/Author/AuthorBadge/AuthorBadge.tsx +++ b/src/components/Author/AuthorBadge/AuthorBadge.tsx @@ -17,13 +17,14 @@ export const AuthorBadge = (props: Props) => { const [isSubscribing, setIsSubscribing] = createSignal(false) const { session, - actions: { loadSession, requireAuthentication } + subscriptions, + actions: { loadSubscriptions, requireAuthentication } } = useSession() const { t, formatDate } = useLocalize() - const subscribed = createMemo(() => { - return session()?.news?.authors?.some((u) => u === props.author.slug) || false - }) + const subscribed = createMemo(() => + subscriptions().authors.some((author) => author.slug === props.author.slug) + ) const subscribe = async (really = true) => { setIsSubscribing(true) @@ -32,7 +33,7 @@ export const AuthorBadge = (props: Props) => { ? follow({ what: FollowingEntity.Author, slug: props.author.slug }) : unfollow({ what: FollowingEntity.Author, slug: props.author.slug })) - await loadSession() + await loadSubscriptions() setIsSubscribing(false) } const handleSubscribe = (really: boolean) => { diff --git a/src/components/Author/AuthorCard/AuthorCard.tsx b/src/components/Author/AuthorCard/AuthorCard.tsx index 9ac66a04..f13082b2 100644 --- a/src/components/Author/AuthorCard/AuthorCard.tsx +++ b/src/components/Author/AuthorCard/AuthorCard.tsx @@ -50,8 +50,9 @@ export const AuthorCard = (props: Props) => { const { t, lang } = useLocalize() const { session, + subscriptions, isSessionLoaded, - actions: { loadSession, requireAuthentication } + actions: { loadSubscriptions, requireAuthentication } } = useSession() const [isSubscribing, setIsSubscribing] = createSignal(false) @@ -59,9 +60,9 @@ export const AuthorCard = (props: Props) => { const [subscriptionFilter, setSubscriptionFilter] = createSignal('all') const [userpicUrl, setUserpicUrl] = createSignal() - const subscribed = createMemo(() => { - return session()?.news?.authors?.some((u) => u === props.author.slug) || false - }) + const subscribed = createMemo(() => + subscriptions().authors.some((author) => author.slug === props.author.slug) + ) const subscribe = async (really = true) => { setIsSubscribing(true) @@ -70,7 +71,7 @@ export const AuthorCard = (props: Props) => { ? follow({ what: FollowingEntity.Author, slug: props.author.slug }) : unfollow({ what: FollowingEntity.Author, slug: props.author.slug })) - await loadSession() + await loadSubscriptions() setIsSubscribing(false) } diff --git a/src/components/Feed/Sidebar/Sidebar.tsx b/src/components/Feed/Sidebar/Sidebar.tsx index 070c8c99..21b0bbe7 100644 --- a/src/components/Feed/Sidebar/Sidebar.tsx +++ b/src/components/Feed/Sidebar/Sidebar.tsx @@ -20,7 +20,7 @@ type FeedSidebarProps = { export const Sidebar = (props: FeedSidebarProps) => { const { t } = useLocalize() const { seen } = useSeenStore() - const { session } = useSession() + const { subscriptions } = useSession() const { page } = useRouter() const { authorEntities } = useAuthorsStore({ authors: props.authors }) const { articlesByTopic } = useArticlesStore() @@ -118,7 +118,7 @@ export const Sidebar = (props: FeedSidebarProps) => { - + 0 || subscriptions().topics.length > 0}>

{ @@ -129,39 +129,31 @@ export const Sidebar = (props: FeedSidebarProps) => {

{t('Newsletter')}

-
-
- - - -
-
- +

{ +type Props = { + variant?: 'mobileSubscription' +} +export const Subscribe = (props: Props) => { const { t } = useLocalize() const [title, setTitle] = createSignal('') @@ -69,19 +71,36 @@ export default () => { } return ( -

+ -
- -
+ + + + +
{emailError()}
diff --git a/src/components/_shared/Subscribe/index.ts b/src/components/_shared/Subscribe/index.ts new file mode 100644 index 00000000..77ee7e60 --- /dev/null +++ b/src/components/_shared/Subscribe/index.ts @@ -0,0 +1 @@ +export { Subscribe } from './Subscribe' diff --git a/src/pages/about/manifest.page.tsx b/src/pages/about/manifest.page.tsx index 9878de07..a4d2e4aa 100644 --- a/src/pages/about/manifest.page.tsx +++ b/src/pages/about/manifest.page.tsx @@ -2,7 +2,7 @@ import { createSignal, Show } from 'solid-js' import { PageLayout } from '../../components/_shared/PageLayout' import { Modal } from '../../components/Nav/Modal' import { Feedback } from '../../components/Discours/Feedback' -import Subscribe from '../../components/Discours/Subscribe' +import { Subscribe } from '../../components/_shared/Subscribe' import Opener from '../../components/Nav/Modal/Opener' import { Icon } from '../../components/_shared/Icon' From 5912e6e1a1b826e8195a63983159afb6d46f6c29 Mon Sep 17 00:00:00 2001 From: Ilya Y <75578537+ilya-bkv@users.noreply.github.com> Date: Mon, 23 Oct 2023 14:02:01 +0300 Subject: [PATCH 004/129] en locale fix (#276) Co-authored-by: Igor Lobanov --- public/locales/en/translation.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/public/locales/en/translation.json b/public/locales/en/translation.json index cad81887..cdfd8ca5 100644 --- a/public/locales/en/translation.json +++ b/public/locales/en/translation.json @@ -300,9 +300,9 @@ "Subscribe us": "Subscribe us", "Subscribe what you like to tune your personal feed": "Subscribe to topics that interest you to customize your personal feed and get instant updates on new posts and discussions", "Subscribe who you like to tune your personal feed": "Subscribe to authors you're interested in to customize your personal feed and get instant updates on new posts and discussions", - "SubscriberWithCount": "{count, plural, =0 {no followers} one {{count} follower} other {{count} followers}", + "SubscriberWithCount": "{count, plural, =0 {no followers} one {{count} follower} other {{count} followers}}", "Subscription": "Subscription", - "SubscriptionWithCount": "{count, plural, =0 {no subscriptions} one {{count} subscription} other {{count} subscriptions}", + "SubscriptionWithCount": "{count, plural, =0 {no subscriptions} one {{count} subscription} other {{count} subscriptions}}", "Subscriptions": "Subscriptions", "Substrate": "Substrate", "Success": "Success", From 023e0067f8a0bc7524b6a95fd3a38e8cc93f1aca Mon Sep 17 00:00:00 2001 From: Ilya Y <75578537+ilya-bkv@users.noreply.github.com> Date: Mon, 23 Oct 2023 14:15:19 +0300 Subject: [PATCH 005/129] Feature/en locale fix (#278) * en locale fix * lint --------- Co-authored-by: Igor Lobanov --- src/components/Article/Comment.tsx | 1 - src/components/Article/FullArticle.tsx | 1 - .../Author/AuthorCard/AuthorCard.module.scss | 11 +++++++++-- src/components/Feed/Sidebar/Sidebar.tsx | 11 +---------- .../NotificationView/NotificationView.tsx | 2 +- src/components/Views/AllTopics.tsx | 2 +- src/components/Views/Author/Author.tsx | 1 - src/components/Views/Feed.tsx | 6 +----- .../Views/PublishSettings/PublishSettings.module.scss | 6 +++++- .../_shared/GroupAvatar/GroupAvatar.module.scss | 5 +++++ .../_shared/Subscribe/Subscribe.module.scss | 1 + 11 files changed, 24 insertions(+), 23 deletions(-) diff --git a/src/components/Article/Comment.tsx b/src/components/Article/Comment.tsx index dc723c6a..a49070e7 100644 --- a/src/components/Article/Comment.tsx +++ b/src/components/Article/Comment.tsx @@ -3,7 +3,6 @@ import { clsx } from 'clsx' import { getPagePath } from '@nanostores/router' import MD from './MD' -import { AuthorCard } from '../Author/AuthorCard' import { Userpic } from '../Author/Userpic' import { CommentRatingControl } from './CommentRatingControl' import { CommentDate } from './CommentDate' diff --git a/src/components/Article/FullArticle.tsx b/src/components/Article/FullArticle.tsx index cb8e3b26..c9d7233f 100644 --- a/src/components/Article/FullArticle.tsx +++ b/src/components/Article/FullArticle.tsx @@ -11,7 +11,6 @@ import { MediaItem } from '../../pages/types' import { DEFAULT_HEADER_OFFSET, router, useRouter } from '../../stores/router' import { getDescription } from '../../utils/meta' import { imageProxy } from '../../utils/imageProxy' -import { AuthorCard } from '../Author/AuthorCard' import { TableOfContents } from '../TableOfContents' import { AudioPlayer } from './AudioPlayer' import { SharePopup } from './SharePopup' diff --git a/src/components/Author/AuthorCard/AuthorCard.module.scss b/src/components/Author/AuthorCard/AuthorCard.module.scss index d51d1a66..0d990d4b 100644 --- a/src/components/Author/AuthorCard/AuthorCard.module.scss +++ b/src/components/Author/AuthorCard/AuthorCard.module.scss @@ -11,19 +11,22 @@ @include media-breakpoint-down(md) { justify-content: center; } + @include media-breakpoint-up(md) { margin-bottom: 2.4rem; } .authorName { @include font-size(4rem); + font-weight: 700; margin-bottom: 0.2em; } .authorAbout { - color: #696969; @include font-size(2rem); + + color: #696969; font-weight: 500; margin-top: 1.5rem; } @@ -119,6 +122,7 @@ .authorName { @include font-size(4rem); + line-height: 1.1; } @@ -172,9 +176,10 @@ } .authorSubscribeSocialLabel { + @include font-size(1.6rem); + color: #000; display: block; - @include font-size(1.6rem); left: 100%; padding-left: 0.4rem; position: absolute; @@ -429,9 +434,11 @@ &:nth-child(1) { z-index: 2; } + &:nth-child(2) { z-index: 1; } + &:not(:last-child) { margin-right: -4px; box-shadow: 0 0 0 1px var(--background-color); diff --git a/src/components/Feed/Sidebar/Sidebar.tsx b/src/components/Feed/Sidebar/Sidebar.tsx index 21b0bbe7..3185729e 100644 --- a/src/components/Feed/Sidebar/Sidebar.tsx +++ b/src/components/Feed/Sidebar/Sidebar.tsx @@ -1,8 +1,5 @@ import { createSignal, For, Show } from 'solid-js' -import type { Author } from '../../../graphql/types.gen' -import { useAuthorsStore } from '../../../stores/zine/authors' import { Icon } from '../../_shared/Icon' -import { useTopicsStore } from '../../../stores/zine/topics' import { useArticlesStore } from '../../../stores/zine/articles' import { useSeenStore } from '../../../stores/zine/seen' import { useSession } from '../../../context/session' @@ -13,18 +10,12 @@ import { Userpic } from '../../Author/Userpic' import { getPagePath } from '@nanostores/router' import { router, useRouter } from '../../../stores/router' -type FeedSidebarProps = { - authors: Author[] -} - -export const Sidebar = (props: FeedSidebarProps) => { +export const Sidebar = () => { const { t } = useLocalize() const { seen } = useSeenStore() const { subscriptions } = useSession() const { page } = useRouter() - const { authorEntities } = useAuthorsStore({ authors: props.authors }) const { articlesByTopic } = useArticlesStore() - const { topicEntities } = useTopicsStore() const [isSubscriptionsVisible, setSubscriptionsVisible] = createSignal(true) const checkTopicIsSeen = (topicSlug: string) => { diff --git a/src/components/NotificationsPanel/NotificationView/NotificationView.tsx b/src/components/NotificationsPanel/NotificationView/NotificationView.tsx index ab995a6e..ae5b1dd9 100644 --- a/src/components/NotificationsPanel/NotificationView/NotificationView.tsx +++ b/src/components/NotificationsPanel/NotificationView/NotificationView.tsx @@ -1,5 +1,5 @@ import { clsx } from 'clsx' -import type { Author, Notification } from '../../../graphql/types.gen' +import type { Notification } from '../../../graphql/types.gen' import { createMemo, createSignal, onMount, Show } from 'solid-js' import { NotificationType } from '../../../graphql/types.gen' import { getPagePath, openPage } from '@nanostores/router' diff --git a/src/components/Views/AllTopics.tsx b/src/components/Views/AllTopics.tsx index 5ef4de47..b3a37296 100644 --- a/src/components/Views/AllTopics.tsx +++ b/src/components/Views/AllTopics.tsx @@ -34,7 +34,7 @@ export const AllTopicsView = (props: AllTopicsViewProps) => { sortBy: searchParams().by || 'shouts' }) - const { session, subscriptions } = useSession() + const { subscriptions } = useSession() onMount(() => { if (!searchParams().by) { diff --git a/src/components/Views/Author/Author.tsx b/src/components/Views/Author/Author.tsx index 2d7df575..3fd947b3 100644 --- a/src/components/Views/Author/Author.tsx +++ b/src/components/Views/Author/Author.tsx @@ -35,7 +35,6 @@ export const AuthorView = (props: Props) => { const { authorEntities } = useAuthorsStore({ authors: [props.author] }) const { page: getPage } = useRouter() - const { user } = useSession() const author = createMemo(() => authorEntities()[props.authorSlug]) const [isLoadMoreButtonVisible, setIsLoadMoreButtonVisible] = createSignal(false) const [isBioExpanded, setIsBioExpanded] = createSignal(false) diff --git a/src/components/Views/Feed.tsx b/src/components/Views/Feed.tsx index 87be1c19..458d86ad 100644 --- a/src/components/Views/Feed.tsx +++ b/src/components/Views/Feed.tsx @@ -1,10 +1,8 @@ import { createEffect, createSignal, For, on, onMount, Show } from 'solid-js' import { Icon } from '../_shared/Icon' import { ArticleCard } from '../Feed/ArticleCard' -import { AuthorCard } from '../Author/AuthorCard' import { Sidebar } from '../Feed/Sidebar' import { useArticlesStore, resetSortedArticles } from '../../stores/zine/articles' -import { useAuthorsStore } from '../../stores/zine/authors' import { useTopicsStore } from '../../stores/zine/topics' import { useTopAuthorsStore } from '../../stores/zine/topAuthors' import { clsx } from 'clsx' @@ -50,8 +48,6 @@ export const FeedView = (props: Props) => { // state const { sortedArticles } = useArticlesStore() - - const { sortedAuthors } = useAuthorsStore() const { topTopics } = useTopicsStore() const { topAuthors } = useTopAuthorsStore() const [isLoadMoreButtonVisible, setIsLoadMoreButtonVisible] = createSignal(false) @@ -115,7 +111,7 @@ export const FeedView = (props: Props) => {
- +
diff --git a/src/components/Views/PublishSettings/PublishSettings.module.scss b/src/components/Views/PublishSettings/PublishSettings.module.scss index c9d23b34..0807c6bf 100644 --- a/src/components/Views/PublishSettings/PublishSettings.module.scss +++ b/src/components/Views/PublishSettings/PublishSettings.module.scss @@ -119,7 +119,10 @@ font-weight: 400; line-height: 1.3; margin-bottom: 0.8rem; - transition: color 0.2s, background-color 0.2s, box-shadow 0.2s; + transition: + color 0.2s, + background-color 0.2s, + box-shadow 0.2s; } .shoutAuthor { @@ -154,6 +157,7 @@ padding: 1rem 0; gap: 1rem; } + .cancel { margin-right: auto; } diff --git a/src/components/_shared/GroupAvatar/GroupAvatar.module.scss b/src/components/_shared/GroupAvatar/GroupAvatar.module.scss index 4bd8f041..a1acea31 100644 --- a/src/components/_shared/GroupAvatar/GroupAvatar.module.scss +++ b/src/components/_shared/GroupAvatar/GroupAvatar.module.scss @@ -18,6 +18,7 @@ left: 0; top: 0; } + &:nth-child(2) { right: 0; bottom: 0; @@ -32,10 +33,12 @@ left: 14px; top: 0; } + &:nth-child(2) { left: 0; top: 17px; } + &:nth-child(3) { right: 0; top: 21px; @@ -53,10 +56,12 @@ left: 0; top: 0; } + &:nth-child(2) { right: 0; top: 0; } + &:nth-child(3) { left: 0; bottom: 0; diff --git a/src/components/_shared/Subscribe/Subscribe.module.scss b/src/components/_shared/Subscribe/Subscribe.module.scss index 24f90587..1160df51 100644 --- a/src/components/_shared/Subscribe/Subscribe.module.scss +++ b/src/components/_shared/Subscribe/Subscribe.module.scss @@ -17,6 +17,7 @@ .input { @include font-size(2rem); + background: none; color: #fff; font-family: inherit; From 704adcd4be3e5539d09351e2bcdb71d3649bd599 Mon Sep 17 00:00:00 2001 From: Ilya Y <75578537+ilya-bkv@users.noreply.github.com> Date: Mon, 23 Oct 2023 18:18:10 +0300 Subject: [PATCH 006/129] Comments improvements & bugfix (#277) * Mobile header Subscribe * Comments improvements & bugfix --- .../Article/{ => Comment}/Comment.module.scss | 41 +++++++++++-------- .../Article/{ => Comment}/Comment.tsx | 37 ++++++++--------- src/components/Article/Comment/index.ts | 1 + .../{ => CommentDate}/CommentDate.module.scss | 21 ++++++++++ .../Article/{ => CommentDate}/CommentDate.tsx | 18 +++++--- src/components/Article/CommentDate/index.ts | 1 + .../_shared/Subscribe/Subscribe.tsx | 8 +++- 7 files changed, 85 insertions(+), 42 deletions(-) rename src/components/Article/{ => Comment}/Comment.module.scss (89%) rename src/components/Article/{ => Comment}/Comment.tsx (89%) create mode 100644 src/components/Article/Comment/index.ts rename src/components/Article/{ => CommentDate}/CommentDate.module.scss (62%) rename src/components/Article/{ => CommentDate}/CommentDate.tsx (63%) create mode 100644 src/components/Article/CommentDate/index.ts diff --git a/src/components/Article/Comment.module.scss b/src/components/Article/Comment/Comment.module.scss similarity index 89% rename from src/components/Article/Comment.module.scss rename to src/components/Article/Comment/Comment.module.scss index eb8eea1b..31abe6db 100644 --- a/src/components/Article/Comment.module.scss +++ b/src/components/Article/Comment/Comment.module.scss @@ -1,10 +1,14 @@ .comment { margin: 0 0 0.5em; - padding: 1rem; + padding: 0 1rem; transition: background-color 0.3s; position: relative; list-style: none; + & .comment { + margin-right: -1rem; + } + &.isNew { border-radius: 6px; background: rgb(38 56 217 / 5%); @@ -18,7 +22,7 @@ &::before, &::after { content: ''; - left: 0; + left: -14px; position: absolute; } @@ -26,9 +30,9 @@ border-bottom: 2px solid #ccc; border-left: 2px solid #ccc; border-radius: 0 0 0 1.2rem; - top: -1rem; - height: 2.4rem; - width: 1.2rem; + top: -24px; + height: 50px; + width: 12px; } &::after { @@ -57,6 +61,14 @@ align-items: center; margin-bottom: 1.4rem; } + + .commentControl:not(.commentControlReply) { + opacity: 0; + } + + &:hover .commentControl { + opacity: 1; + } } .commentContent { @@ -71,12 +83,6 @@ } } -.commentControls { - @include font-size(1.2rem); - - margin-bottom: 0.5em; -} - .commentControlReply, .commentControlShare, .commentControlDelete, @@ -104,7 +110,7 @@ .commentControl { border: none; - color: #696969; + color: var(--secondary-color); cursor: pointer; display: inline-flex; line-height: 1.2; @@ -117,8 +123,8 @@ vertical-align: top; &:hover { - background: #000; - color: #fff; + background: var(--background-color-invert); + color: var(--default-color-invert); .icon { filter: invert(1); @@ -173,9 +179,10 @@ } .articleAuthor { - color: #2638d9; - font-size: 12px; - margin-right: 12px; + @include font-size(1.2rem); + + color: var(--blue-500); + margin: 0.3rem 1rem 0; } .articleLink { diff --git a/src/components/Article/Comment.tsx b/src/components/Article/Comment/Comment.tsx similarity index 89% rename from src/components/Article/Comment.tsx rename to src/components/Article/Comment/Comment.tsx index a49070e7..dc43c7ee 100644 --- a/src/components/Article/Comment.tsx +++ b/src/components/Article/Comment/Comment.tsx @@ -2,26 +2,26 @@ import { Show, createMemo, createSignal, For, lazy, Suspense } from 'solid-js' import { clsx } from 'clsx' import { getPagePath } from '@nanostores/router' -import MD from './MD' -import { Userpic } from '../Author/Userpic' -import { CommentRatingControl } from './CommentRatingControl' -import { CommentDate } from './CommentDate' -import { ShowIfAuthenticated } from '../_shared/ShowIfAuthenticated' -import { Icon } from '../_shared/Icon' +import MD from '../MD' +import { Userpic } from '../../Author/Userpic' +import { CommentRatingControl } from '../CommentRatingControl' +import { CommentDate } from '../CommentDate' +import { ShowIfAuthenticated } from '../../_shared/ShowIfAuthenticated' +import { Icon } from '../../_shared/Icon' -import { useSession } from '../../context/session' -import { useLocalize } from '../../context/localize' -import { useReactions } from '../../context/reactions' -import { useSnackbar } from '../../context/snackbar' -import { useConfirm } from '../../context/confirm' +import { useSession } from '../../../context/session' +import { useLocalize } from '../../../context/localize' +import { useReactions } from '../../../context/reactions' +import { useSnackbar } from '../../../context/snackbar' +import { useConfirm } from '../../../context/confirm' -import { Author, Reaction, ReactionKind } from '../../graphql/types.gen' -import { router } from '../../stores/router' +import { Author, Reaction, ReactionKind } from '../../../graphql/types.gen' +import { router } from '../../../stores/router' import styles from './Comment.module.scss' -import { AuthorLink } from '../Author/AhtorLink' +import { AuthorLink } from '../../Author/AhtorLink' -const SimplifiedEditor = lazy(() => import('../Editor/SimplifiedEditor')) +const SimplifiedEditor = lazy(() => import('../../Editor/SimplifiedEditor')) type Props = { comment: Reaction @@ -166,9 +166,7 @@ export const Comment = (props: Props) => {
- - - +
@@ -183,6 +181,7 @@ export const Comment = (props: Props) => { placeholder={t('Write a comment...')} onSubmit={(value) => handleUpdate(value)} submitByCtrlEnter={true} + onCancel={() => setEditMode(false)} setClear={clearEditor()} /> @@ -190,7 +189,7 @@ export const Comment = (props: Props) => {
-
+
+
Подпишитесь на рассылку лучших публикаций
{emailError()}
diff --git a/src/pages/about/discussionRules.page.tsx b/src/pages/about/discussionRules.page.tsx index 7f03e424..5a97f12b 100644 --- a/src/pages/about/discussionRules.page.tsx +++ b/src/pages/about/discussionRules.page.tsx @@ -4,7 +4,7 @@ import { Title } from '@solidjs/meta' export const DiscussionRulesPage = () => { const { t } = useLocalize() - const title = t('Discussion rules') + const title = t('Discussion rules in social networks') return ( {title} diff --git a/src/pages/about/principles.page.tsx b/src/pages/about/principles.page.tsx index 88378c9f..314f1895 100644 --- a/src/pages/about/principles.page.tsx +++ b/src/pages/about/principles.page.tsx @@ -61,7 +61,7 @@ export const PrinciplesPage = () => {

- Как участвовать в самиздате + Как у нас принято себя вести

diff --git a/src/styles/app.scss b/src/styles/app.scss index 4f75474e..46347217 100644 --- a/src/styles/app.scss +++ b/src/styles/app.scss @@ -987,8 +987,11 @@ details { .description { @include font-size(1.4rem); - color: rgba(0 0 0 / 40%); + + .pretty-form__item + & { + margin-top: -2rem; + } } [data-custom-scroll='on'] { From 7b5324a7281aca7deb9349749784ec014784a61d Mon Sep 17 00:00:00 2001 From: Ilya Y <75578537+ilya-bkv@users.noreply.github.com> Date: Tue, 24 Oct 2023 13:43:52 +0300 Subject: [PATCH 008/129] fix typo errors (#279) --- public/locales/en/translation.json | 3 ++- public/locales/ru/translation.json | 1 + src/components/Nav/HeaderAuth.tsx | 4 ++-- src/components/_shared/Subscribe/Subscribe.tsx | 2 +- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/public/locales/en/translation.json b/public/locales/en/translation.json index d5c49e3c..e0305bd7 100644 --- a/public/locales/en/translation.json +++ b/public/locales/en/translation.json @@ -183,8 +183,8 @@ "Join the global community of authors!": "Join the global community of authors from all over the world!", "Just start typing...": "Just start typing...", "Knowledge base": "Knowledge base", - "Last rev.": "Посл. изм.", "Language": "Language", + "Last rev.": "Посл. изм.", "Let's log in": "Let's log in", "Link copied": "Link copied", "Link sent, check your email": "Link sent, check your email", @@ -299,6 +299,7 @@ "Start conversation": "Start a conversation", "Subsccriptions": "Subscriptions", "Subscribe": "Subscribe", + "Subscribe to the best publications newsletter": "Subscribe to the best publications newsletter", "Subscribe us": "Subscribe us", "Subscribe what you like to tune your personal feed": "Subscribe to topics that interest you to customize your personal feed and get instant updates on new posts and discussions", "Subscribe who you like to tune your personal feed": "Subscribe to authors you're interested in to customize your personal feed and get instant updates on new posts and discussions", diff --git a/public/locales/ru/translation.json b/public/locales/ru/translation.json index fc2f9075..b7b19cfb 100644 --- a/public/locales/ru/translation.json +++ b/public/locales/ru/translation.json @@ -318,6 +318,7 @@ "Subheader": "Подзаголовок", "Subscribe": "Подписаться", "Subscribe to comments": "Подписаться на комментарии", + "Subscribe to the best publications newsletter": "Подпишитесь на рассылку лучших публикаций", "Subscribe us": "Подпишитесь на нас", "Subscribe what you like to tune your personal feed": "Подпишитесь на интересующие вас темы, чтобы настроить вашу персональную ленту и моментально узнавать о новых публикациях и обсуждениях", "Subscribe who you like to tune your personal feed": "Подпишитесь на интересующих вас авторов, чтобы настроить вашу персональную ленту и моментально узнавать о новых публикациях и обсуждениях", diff --git a/src/components/Nav/HeaderAuth.tsx b/src/components/Nav/HeaderAuth.tsx index 431bb9d7..fe7eb0a6 100644 --- a/src/components/Nav/HeaderAuth.tsx +++ b/src/components/Nav/HeaderAuth.tsx @@ -143,8 +143,8 @@ export const HeaderAuth = (props: Props) => {

- - + +
diff --git a/src/components/_shared/Subscribe/Subscribe.tsx b/src/components/_shared/Subscribe/Subscribe.tsx index 214ebb1a..68d45d75 100644 --- a/src/components/_shared/Subscribe/Subscribe.tsx +++ b/src/components/_shared/Subscribe/Subscribe.tsx @@ -106,7 +106,7 @@ export const Subscribe = (props: Props) => {
-
Подпишитесь на рассылку лучших публикаций
+
Подпишитесь на рассылку лучших публикаций
{emailError()}
From 18c98fef32772408561cbb15b2c4181ae80ebeca Mon Sep 17 00:00:00 2001 From: Ilya Y <75578537+ilya-bkv@users.noreply.github.com> Date: Tue, 24 Oct 2023 22:20:05 +0300 Subject: [PATCH 009/129] meta fixed (#280) Co-authored-by: Igor Lobanov --- src/pages/about/help.page.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/about/help.page.tsx b/src/pages/about/help.page.tsx index cded23cb..250f0c5e 100644 --- a/src/pages/about/help.page.tsx +++ b/src/pages/about/help.page.tsx @@ -15,8 +15,8 @@ export const HelpPage = () => { return ( {t('Support us')} - Здесь можно поддержать Дискурс материально. - Discours.io, помощь, благотворительность + + {/*Благодарим!*/} From d6c4ec68ee78b273cccf3f046ffd8a6023e30e24 Mon Sep 17 00:00:00 2001 From: kvakazyambra Date: Wed, 25 Oct 2023 00:43:50 +0300 Subject: [PATCH 010/129] Confirm modal style fixes --- src/components/Article/Comment/Comment.module.scss | 2 +- src/components/Nav/ConfirmModal/ConfirmModal.module.scss | 9 ++++++--- src/components/Nav/Modal/Modal.module.scss | 8 ++++++-- src/styles/app.scss | 2 +- 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/components/Article/Comment/Comment.module.scss b/src/components/Article/Comment/Comment.module.scss index 31abe6db..c0cc356b 100644 --- a/src/components/Article/Comment/Comment.module.scss +++ b/src/components/Article/Comment/Comment.module.scss @@ -207,7 +207,7 @@ .articleLinkIcon { display: inline-block; - margin-right: 1em; + margin: 0 1em; vertical-align: middle; width: 1em; } diff --git a/src/components/Nav/ConfirmModal/ConfirmModal.module.scss b/src/components/Nav/ConfirmModal/ConfirmModal.module.scss index b955ec59..fc56f732 100644 --- a/src/components/Nav/ConfirmModal/ConfirmModal.module.scss +++ b/src/components/Nav/ConfirmModal/ConfirmModal.module.scss @@ -2,18 +2,21 @@ position: relative; .confirmModalTitle { - @include font-size(2rem); - + @include font-size(3.2rem); font-weight: 700; color: var(--default-color); text-align: center; + + @include media-breakpoint-up(sm) { + margin: 0 10%; + } } .confirmModalActions { display: flex; justify-content: space-between; margin-top: 4rem; - gap: 2rem; + gap: 0.5rem; .confirmAction { flex: 1; diff --git a/src/components/Nav/Modal/Modal.module.scss b/src/components/Nav/Modal/Modal.module.scss index 9dafa21a..54e71ee7 100644 --- a/src/components/Nav/Modal/Modal.module.scss +++ b/src/components/Nav/Modal/Modal.module.scss @@ -63,17 +63,21 @@ width: 100%; @include media-breakpoint-up(sm) { - max-width: 460px; + max-width: 600px; } @include media-breakpoint-up(md) { - width: 50%; + width: 65%; } .close { right: 1.6rem; top: 1.6rem; } + + .modalInner { + padding: 3.8rem 2rem 2rem; + } } } diff --git a/src/styles/app.scss b/src/styles/app.scss index 46347217..44b7e5a0 100644 --- a/src/styles/app.scss +++ b/src/styles/app.scss @@ -18,7 +18,7 @@ --secondary-color: #85878a; --placeholder-color: #9fa1a7; --placeholder-color-semi: rgba(159, 169, 167, 0.2); - --danger-color: #fc6847; + --danger-color: #d00820; --lightgray-color: rgb(84 16 17 / 6%); --font: -apple-system, blinkmacsystemfont, 'Segoe UI', roboto, oxygen, ubuntu, cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; From 42cfc02ef637d3a27fb7c0572dbe3703d6241fcb Mon Sep 17 00:00:00 2001 From: kvakazyambra Date: Wed, 25 Oct 2023 00:44:10 +0300 Subject: [PATCH 011/129] Snackbar style fixes --- public/icons/check-success.svg | 4 ++++ src/components/Nav/Snackbar.module.scss | 15 ++++++++++++++- src/components/Nav/Snackbar.tsx | 11 +++++++++-- 3 files changed, 27 insertions(+), 3 deletions(-) create mode 100644 public/icons/check-success.svg diff --git a/public/icons/check-success.svg b/public/icons/check-success.svg new file mode 100644 index 00000000..61549770 --- /dev/null +++ b/public/icons/check-success.svg @@ -0,0 +1,4 @@ + + + diff --git a/src/components/Nav/Snackbar.module.scss b/src/components/Nav/Snackbar.module.scss index ade8289a..a0fb8e64 100644 --- a/src/components/Nav/Snackbar.module.scss +++ b/src/components/Nav/Snackbar.module.scss @@ -2,15 +2,28 @@ min-height: 2px; background-color: var(--default-color); color: #fff; + font-size: 2rem; + font-weight: 500; transition: background-color 0.3s; &.error { background-color: #d00820; } + + &.success { + .icon { + height: 1.8em; + margin-right: 0.5em; + margin-top: 0.1em; + width: 1.8em; + } + } } .content { - transition: height 0.3s, color 0.3s; + transition: + height 0.3s, + color 0.3s; height: 60px; display: flex; align-items: center; diff --git a/src/components/Nav/Snackbar.tsx b/src/components/Nav/Snackbar.tsx index bf2113a0..540e41bb 100644 --- a/src/components/Nav/Snackbar.tsx +++ b/src/components/Nav/Snackbar.tsx @@ -3,6 +3,7 @@ import { useSnackbar } from '../../context/snackbar' import styles from './Snackbar.module.scss' import { Transition } from 'solid-transition-group' import { clsx } from 'clsx' +import { Icon } from '../_shared/Icon' export const Snackbar = () => { const { snackbarMessage } = useSnackbar() @@ -10,7 +11,8 @@ export const Snackbar = () => { return (
{ onExit={(el, done) => setTimeout(() => done(), 300)} > -
{snackbarMessage().body}
+
+ + + + {snackbarMessage().body} +
From 0652c204b58417358c6d0d369e1bd733eca4ead2 Mon Sep 17 00:00:00 2001 From: Igor Lobanov Date: Wed, 25 Oct 2023 15:57:21 +0200 Subject: [PATCH 012/129] profile shouts fix 1 --- src/pages/author.page.server.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/author.page.server.ts b/src/pages/author.page.server.ts index 479e7fc7..9564e3d9 100644 --- a/src/pages/author.page.server.ts +++ b/src/pages/author.page.server.ts @@ -7,7 +7,7 @@ export const onBeforeRender = async (pageContext: PageContext) => { const { slug } = pageContext.routeParams const authorShouts = await apiClient.getShouts({ - filters: { author: slug }, + filters: { author: slug, visibility: 'community' }, limit: PRERENDERED_ARTICLES_COUNT }) const author = await apiClient.getAuthor({ slug }) From b85c05a8c3cfa919e37adbca0a1d45feec138e23 Mon Sep 17 00:00:00 2001 From: Ilya Y <75578537+ilya-bkv@users.noreply.github.com> Date: Wed, 25 Oct 2023 18:04:23 +0300 Subject: [PATCH 013/129] Feature/toggle mobile header (#281) - toggle language - toggle menu on current link --- src/components/Nav/Header/Header.tsx | 32 ++++++++++++++++++++++------ src/components/Nav/Header/Link.tsx | 6 +++++- 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/src/components/Nav/Header/Header.tsx b/src/components/Nav/Header/Header.tsx index 65b27900..ec058081 100644 --- a/src/components/Nav/Header/Header.tsx +++ b/src/components/Nav/Header/Header.tsx @@ -12,7 +12,7 @@ import { Icon } from '../../_shared/Icon' import type { Topic } from '../../../graphql/types.gen' import { useModalStore } from '../../../stores/ui' -import { router, useRouter } from '../../../stores/router' +import { router, ROUTES, useRouter } from '../../../stores/router' import { getDescription } from '../../../utils/meta' @@ -38,11 +38,14 @@ type HeaderSearchParams = { source?: string } +const handleSwitchLanguage = (event) => { + location.href = `${location.href}${location.href.includes('?') ? '&' : '?'}lng=${event.target.value}` +} + export const Header = (props: Props) => { const { t, lang } = useLocalize() - const { modal } = useModalStore() - + const { page } = useRouter() const { actions: { requireAuthentication } } = useSession() @@ -59,7 +62,6 @@ export const Header = (props: Props) => { const [isTopicsVisible, setIsTopicsVisible] = createSignal(false) const [isZineVisible, setIsZineVisible] = createSignal(false) const [isFeedVisible, setIsFeedVisible] = createSignal(false) - const toggleFixed = () => setFixed((oldFixed) => !oldFixed) const tag = (topic: Topic) => @@ -148,6 +150,15 @@ export const Header = (props: Props) => { setRandomTopics(topics) }) + const handleToggleMenuByLink = (event: MouseEvent, route: keyof typeof ROUTES) => { + if (!fixed()) { + return + } + event.preventDefault() + if (page().route === route) { + toggleFixed() + } + } return (
{ routeName="home" active={isZineVisible()} body={t('journal')} + onClick={(event) => handleToggleMenuByLink(event, 'home')} /> toggleSubnavigation(true, setIsFeedVisible)} @@ -203,6 +215,7 @@ export const Header = (props: Props) => { routeName="feed" active={isFeedVisible()} body={t('feed')} + onClick={(event) => handleToggleMenuByLink(event, 'feed')} /> toggleSubnavigation(true, setIsTopicsVisible)} @@ -210,12 +223,14 @@ export const Header = (props: Props) => { routeName="topics" active={isTopicsVisible()} body={t('topics')} + onClick={(event) => handleToggleMenuByLink(event, 'topics')} /> hideSubnavigation(event, 0)} onMouseOut={(event) => hideSubnavigation(event, 0)} routeName="authors" body={t('authors')} + onClick={(event) => handleToggleMenuByLink(event, 'authors')} /> toggleSubnavigation(true, setIsKnowledgeBaseVisible)} @@ -223,6 +238,7 @@ export const Header = (props: Props) => { routeName="guide" body={t('Knowledge base')} active={isKnowledgeBaseVisible()} + onClick={(event) => handleToggleMenuByLink(event, 'guide')} /> @@ -283,8 +299,12 @@ export const Header = (props: Props) => {

{t('Newsletter')}

-

{t('Newsletter')}

- diff --git a/src/components/Nav/Header/Link.tsx b/src/components/Nav/Header/Link.tsx index 81648617..bbad79b9 100644 --- a/src/components/Nav/Header/Link.tsx +++ b/src/components/Nav/Header/Link.tsx @@ -10,13 +10,17 @@ type Props = { routeName?: keyof typeof ROUTES body: string active?: boolean + onClick?: (event: MouseEvent) => void } export const Link = (props: Props) => { const { page } = useRouter() const isSelected = page().route === props.routeName return ( -
  • +
  • {children}} From 6adbd573d9d367c0bb29d74c3d38f13a543bf8c8 Mon Sep 17 00:00:00 2001 From: kvakazyambra Date: Thu, 26 Oct 2023 00:00:21 +0300 Subject: [PATCH 014/129] Minor style fixes --- src/components/Article/Comment/Comment.module.scss | 7 ++----- src/components/Author/AuthorCard/AuthorCard.module.scss | 2 +- src/components/Feed/ArticleCard/ArticleCard.module.scss | 3 +-- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/components/Article/Comment/Comment.module.scss b/src/components/Article/Comment/Comment.module.scss index c0cc356b..ace30d04 100644 --- a/src/components/Article/Comment/Comment.module.scss +++ b/src/components/Article/Comment/Comment.module.scss @@ -65,10 +65,6 @@ .commentControl:not(.commentControlReply) { opacity: 0; } - - &:hover .commentControl { - opacity: 1; - } } .commentContent { @@ -77,7 +73,8 @@ .commentControlShare, .commentControlDelete, .commentControlEdit, - .commentControlComplain { + .commentControlComplain, + .commentControl { opacity: 1; } } diff --git a/src/components/Author/AuthorCard/AuthorCard.module.scss b/src/components/Author/AuthorCard/AuthorCard.module.scss index 0d990d4b..f55732b3 100644 --- a/src/components/Author/AuthorCard/AuthorCard.module.scss +++ b/src/components/Author/AuthorCard/AuthorCard.module.scss @@ -1,6 +1,6 @@ .author { display: flex; - align-items: flex-start; + align-items: center; flex-flow: row nowrap; margin-bottom: 1.6rem; diff --git a/src/components/Feed/ArticleCard/ArticleCard.module.scss b/src/components/Feed/ArticleCard/ArticleCard.module.scss index 0be9a666..60aab1e6 100644 --- a/src/components/Feed/ArticleCard/ArticleCard.module.scss +++ b/src/components/Feed/ArticleCard/ArticleCard.module.scss @@ -68,8 +68,6 @@ a:link { border: none; - position: relative; - overflow: hidden; &::before { content: ''; @@ -591,6 +589,7 @@ .shoutCardLinkContainer { background: var(--default-color); + color: var(--link-hover-color); } } } From 919c9ff7ea7f0ba09cf4433b7c7b511d39be048d Mon Sep 17 00:00:00 2001 From: kvakazyambra Date: Thu, 26 Oct 2023 00:00:48 +0300 Subject: [PATCH 015/129] Sidebar icons style fixes --- src/components/Feed/Sidebar/Sidebar.module.scss | 6 +++++- src/components/Feed/Sidebar/Sidebar.tsx | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/components/Feed/Sidebar/Sidebar.module.scss b/src/components/Feed/Sidebar/Sidebar.module.scss index 5735b053..8f3fbac5 100644 --- a/src/components/Feed/Sidebar/Sidebar.module.scss +++ b/src/components/Feed/Sidebar/Sidebar.module.scss @@ -16,7 +16,7 @@ } .sidebarItemName { - align-items: baseline; + align-items: center; display: flex; position: relative; @@ -26,6 +26,10 @@ } } + .userpic { + margin-right: 1.2rem; + } + .selected { font-weight: 700; } diff --git a/src/components/Feed/Sidebar/Sidebar.tsx b/src/components/Feed/Sidebar/Sidebar.tsx index 3185729e..1ae62261 100644 --- a/src/components/Feed/Sidebar/Sidebar.tsx +++ b/src/components/Feed/Sidebar/Sidebar.tsx @@ -128,7 +128,7 @@ export const Sidebar = () => { classList={{ [styles.unread]: checkAuthorIsSeen(author.slug) }} >
    - + {author.name}
    From c459db5813c1102a2f31479bd9fadea56abc5e88 Mon Sep 17 00:00:00 2001 From: kvakazyambra Date: Thu, 26 Oct 2023 00:41:04 +0300 Subject: [PATCH 016/129] Voters list style fixes --- .../ProfileSettingsNavigation.module.scss | 20 +++++++++++++++---- .../_shared/Popup/Popup.module.scss | 10 ++++++---- .../_shared/VotersList/VotersList.module.scss | 10 +++++++--- .../_shared/VotersList/VotersList.tsx | 6 +++++- 4 files changed, 34 insertions(+), 12 deletions(-) diff --git a/src/components/Nav/ProfileSettingsNavigation/ProfileSettingsNavigation.module.scss b/src/components/Nav/ProfileSettingsNavigation/ProfileSettingsNavigation.module.scss index 5557d067..8c860c4c 100644 --- a/src/components/Nav/ProfileSettingsNavigation/ProfileSettingsNavigation.module.scss +++ b/src/components/Nav/ProfileSettingsNavigation/ProfileSettingsNavigation.module.scss @@ -1,6 +1,5 @@ .navigationHeader { @include font-size(1.8rem); - font-weight: bold; margin-top: 1.1em; } @@ -8,12 +7,25 @@ .navigation { @include font-size(1.4rem); + @include media-breakpoint-down(md) { + display: flex; + + li { + margin-right: 2.4rem; + } + } + + a { + border: none; + } + .active { a { - text-decoration: none; - color: var(--default-color-invert); - background: var(--background-color-invert); + border-bottom: 2px solid; cursor: inherit; + font-weight: bold; + pointer-events: none; + text-decoration: none; } } } diff --git a/src/components/_shared/Popup/Popup.module.scss b/src/components/_shared/Popup/Popup.module.scss index d16a0e05..79985fd6 100644 --- a/src/components/_shared/Popup/Popup.module.scss +++ b/src/components/_shared/Popup/Popup.module.scss @@ -31,7 +31,6 @@ &.bordered { @include font-size(1.6rem); - border: 2px solid #000; padding: 2.4rem; @@ -46,7 +45,6 @@ &.tiny { @include font-size(1.4rem); - box-shadow: 0 4px 60px rgb(0 0 0 / 10%); padding: 1rem; @@ -60,8 +58,12 @@ } &.horizontalAnchorCenter { - left: 50%; - transform: translateX(-50%); + left: -24px; + + @include media-breakpoint-up(md) { + left: 50%; + transform: translateX(-50%); + } } &.horizontalAnchorRight { diff --git a/src/components/_shared/VotersList/VotersList.module.scss b/src/components/_shared/VotersList/VotersList.module.scss index ebfdc439..a36497ed 100644 --- a/src/components/_shared/VotersList/VotersList.module.scss +++ b/src/components/_shared/VotersList/VotersList.module.scss @@ -17,14 +17,18 @@ align-items: center; margin-right: 1.2rem; - a { + a:link { text-decoration: none; border: none; + + &:hover { + background: #000; + color: #fff; + } } .userpic { - width: 24px; - height: 24px; + margin-right: 0.8rem; } } } diff --git a/src/components/_shared/VotersList/VotersList.tsx b/src/components/_shared/VotersList/VotersList.tsx index a470eae3..f71fadf9 100644 --- a/src/components/_shared/VotersList/VotersList.tsx +++ b/src/components/_shared/VotersList/VotersList.tsx @@ -22,7 +22,11 @@ export const VotersList = (props: Props) => { {(reaction) => (
  • {reaction.kind === ReactionKind.Like ? ( From b0706b1560a1085fb8305b1946ff5502b4b8276d Mon Sep 17 00:00:00 2001 From: kvakazyambra Date: Thu, 26 Oct 2023 00:41:34 +0300 Subject: [PATCH 017/129] Header mobile style fixes --- src/components/Nav/Header/Header.module.scss | 9 ++++----- src/components/Nav/Header/Header.tsx | 1 - 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/components/Nav/Header/Header.module.scss b/src/components/Nav/Header/Header.module.scss index 56faae9f..4537f844 100644 --- a/src/components/Nav/Header/Header.module.scss +++ b/src/components/Nav/Header/Header.module.scss @@ -74,11 +74,10 @@ img { height: 20px; - margin-top: 0.3rem; object-fit: contain; object-position: left; position: relative; - top: 0.3rem; + top: 0.1rem; transition: height 0.2s; vertical-align: middle; width: 100px; @@ -308,7 +307,7 @@ .burger { cursor: pointer; - height: 1.8rem; + height: 1.6rem; display: inline-block; position: relative; vertical-align: middle; @@ -356,13 +355,13 @@ } &::after { - bottom: 0.8rem; + bottom: 0.7rem; transform: rotate(-45deg); } &::before { transform: rotate(45deg); - top: 0.8rem; + top: 0.7rem; } } } diff --git a/src/components/Nav/Header/Header.tsx b/src/components/Nav/Header/Header.tsx index ec058081..00a9b056 100644 --- a/src/components/Nav/Header/Header.tsx +++ b/src/components/Nav/Header/Header.tsx @@ -323,7 +323,6 @@ export const Header = (props: Props) => { />
    {t('Discours')} © 2015–{new Date().getFullYear()}{' '} - {t('Terms of use')}
    From 15691a973d9c3cf36a0a64f68378374269f3dff4 Mon Sep 17 00:00:00 2001 From: Ilya Y <75578537+ilya-bkv@users.noreply.github.com> Date: Thu, 26 Oct 2023 06:17:23 +0300 Subject: [PATCH 018/129] homepage slider conditional render (#283) --- src/components/Views/Home.tsx | 64 +++++++++++++++++++---------------- 1 file changed, 34 insertions(+), 30 deletions(-) diff --git a/src/components/Views/Home.tsx b/src/components/Views/Home.tsx index 3c326c40..90bbfbe3 100644 --- a/src/components/Views/Home.tsx +++ b/src/components/Views/Home.tsx @@ -129,21 +129,23 @@ export const HomeView = (props: Props) => { nodate={true} /> - - - {(a: Shout) => ( - - )} - - + + + + {(a: Shout) => ( + + )} + + + @@ -159,21 +161,23 @@ export const HomeView = (props: Props) => { {randomLayout()} - - - {(a: Shout) => ( - - )} - - + + + + {(a: Shout) => ( + + )} + + + Date: Fri, 27 Oct 2023 00:13:59 +0300 Subject: [PATCH 019/129] Minor style fixes --- src/components/Article/Comment/Comment.module.scss | 6 +++++- src/components/Author/AhtorLink/AhtorLink.module.scss | 3 ++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/components/Article/Comment/Comment.module.scss b/src/components/Article/Comment/Comment.module.scss index ace30d04..2a77ccb8 100644 --- a/src/components/Article/Comment/Comment.module.scss +++ b/src/components/Article/Comment/Comment.module.scss @@ -204,9 +204,13 @@ .articleLinkIcon { display: inline-block; - margin: 0 1em; + margin-right: 1em; vertical-align: middle; width: 1em; + + @include media-breakpoint-up(md) { + margin-left: 1em; + } } .commentDates { diff --git a/src/components/Author/AhtorLink/AhtorLink.module.scss b/src/components/Author/AhtorLink/AhtorLink.module.scss index ef7e911e..848ef5ca 100644 --- a/src/components/Author/AhtorLink/AhtorLink.module.scss +++ b/src/components/Author/AhtorLink/AhtorLink.module.scss @@ -1,6 +1,6 @@ .AuthorLink { .link { - display: flex; + display: inline-flex; flex-direction: row; flex-wrap: nowrap; align-items: center; @@ -8,6 +8,7 @@ justify-content: center; padding: 0; border-bottom: none; + vertical-align: text-bottom; &:hover { background: unset !important; From a54d592038df2578cdcd7eae104c34101f708e8d Mon Sep 17 00:00:00 2001 From: Ilya Y <75578537+ilya-bkv@users.noreply.github.com> Date: Fri, 27 Oct 2023 21:50:13 +0300 Subject: [PATCH 020/129] Feature/thumbor (#284) * thumbor integration * disabled lazy loading for some images * add profile userpic upload error message --------- Co-authored-by: Igor Lobanov --- api/image.mjs | 24 ------------ package.json | 3 +- .../Article/AudioHeader/AudioHeader.tsx | 4 +- .../Article/AudioPlayer/AudioPlayer.tsx | 4 +- src/components/Article/FullArticle.tsx | 6 ++- .../Author/Userpic/Userpic.module.scss | 7 ---- src/components/Author/Userpic/Userpic.tsx | 39 ++++++------------- src/components/Editor/Editor.tsx | 7 ++-- src/components/Editor/SimplifiedEditor.tsx | 3 +- .../UploadModalContent/UploadModalContent.tsx | 23 +++++++---- .../Feed/ArticleCard/ArticleCard.module.scss | 1 + .../Feed/ArticleCard/ArticleCard.tsx | 10 ++--- src/components/Inbox/DialogAvatar.tsx | 7 +++- src/components/Nav/Header/Header.module.scss | 10 +++-- .../Topic/TopicBadge/TopicBadge.tsx | 8 +++- .../Views/Author/Author.module.scss | 5 ++- src/components/Views/Author/Author.tsx | 1 - src/components/Views/Edit.tsx | 6 ++- .../Views/PublishSettings/PublishSettings.tsx | 8 +--- .../CheckButton/CheckButton.module.scss | 2 + src/components/_shared/DropArea/DropArea.tsx | 4 +- .../FloatingPanel/FloatingPanel.module.scss | 4 -- src/components/_shared/Image/Image.tsx | 17 +++++--- .../_shared/Popup/Popup.module.scss | 2 + .../_shared/SolidSwiper/SolidSwiper.tsx | 13 ++++--- .../_shared/SolidSwiper/Swiper.module.scss | 14 ++++--- src/pages/index.page.tsx | 6 ++- src/pages/profile/Settings.module.scss | 12 +++++- src/pages/profile/profileSettings.page.tsx | 12 ++++-- src/utils/config.ts | 3 ++ src/utils/getImageUrl.ts | 29 ++++++++++++++ src/utils/handleImageUpload.ts | 22 +++++++++++ src/utils/imageProxy.ts | 8 ---- src/utils/renderUploadedImage.ts | 3 +- 34 files changed, 186 insertions(+), 141 deletions(-) delete mode 100644 api/image.mjs create mode 100644 src/utils/getImageUrl.ts create mode 100644 src/utils/handleImageUpload.ts delete mode 100644 src/utils/imageProxy.ts diff --git a/api/image.mjs b/api/image.mjs deleted file mode 100644 index 6311d618..00000000 --- a/api/image.mjs +++ /dev/null @@ -1,24 +0,0 @@ -import fetch from 'node-fetch' - -export default async function handler(req, res) { - const imageUrl = req.query.url - - if (!imageUrl) { - return res.status(400).send('Missing URL parameter') - } - - try { - const imageRes = await fetch(imageUrl) - - if (!imageRes.ok) { - return res.status(404).send('Image not found') - } - - res.setHeader('Content-Type', imageRes.headers.get('content-type')) - - imageRes.body.pipe(res) - } catch (err) { - console.error(err) - return res.status(404).send('Error') - } -} diff --git a/package.json b/package.json index 789d8af9..988290eb 100644 --- a/package.json +++ b/package.json @@ -34,8 +34,7 @@ "i18next-icu": "2.3.0", "intl-messageformat": "10.5.3", "just-throttle": "4.2.0", - "mailgun.js": "8.2.1", - "node-fetch": "3.3.1" + "mailgun.js": "8.2.1" }, "devDependencies": { "@babel/core": "7.21.8", diff --git a/src/components/Article/AudioHeader/AudioHeader.tsx b/src/components/Article/AudioHeader/AudioHeader.tsx index 09f80bd9..ac8f38d4 100644 --- a/src/components/Article/AudioHeader/AudioHeader.tsx +++ b/src/components/Article/AudioHeader/AudioHeader.tsx @@ -1,11 +1,11 @@ import { clsx } from 'clsx' import styles from './AudioHeader.module.scss' -import { imageProxy } from '../../../utils/imageProxy' import { MediaItem } from '../../../pages/types' import { createSignal, Show } from 'solid-js' import { Icon } from '../../_shared/Icon' import { Topic } from '../../../graphql/types.gen' import { CardTopic } from '../../Feed/CardTopic' +import { Image } from '../../_shared/Image' type Props = { title: string @@ -19,7 +19,7 @@ export const AudioHeader = (props: Props) => { return (
    - {props.title} + {props.title}
    - {title + {title}
    diff --git a/src/components/Inbox/DialogAvatar.tsx b/src/components/Inbox/DialogAvatar.tsx index a04a058c..bb3382dc 100644 --- a/src/components/Inbox/DialogAvatar.tsx +++ b/src/components/Inbox/DialogAvatar.tsx @@ -2,7 +2,7 @@ import { Show, createMemo } from 'solid-js' import './DialogCard.module.scss' import styles from './DialogAvatar.module.scss' import { clsx } from 'clsx' -import { imageProxy } from '../../utils/imageProxy' +import { getImageUrl } from '../../utils/getImageUrl' type Props = { name: string @@ -47,7 +47,10 @@ const DialogAvatar = (props: Props) => { style={{ 'background-color': `${randomBg()}` }} > {nameFirstLetter()}}> -
    +
    ) diff --git a/src/components/Nav/Header/Header.module.scss b/src/components/Nav/Header/Header.module.scss index 4537f844..37a11d66 100644 --- a/src/components/Nav/Header/Header.module.scss +++ b/src/components/Nav/Header/Header.module.scss @@ -114,6 +114,7 @@ .mainNavigationWrapper { @include font-size(1.7rem); + position: relative; @include media-breakpoint-down(lg) { @@ -127,7 +128,7 @@ .mainNavigation { font-size: 1.4rem !important; - //margin: 0 0 0 -0.4rem !important; + // margin: 0 0 0 -0.4rem !important; opacity: 1; transition: opacity 0.3s; @@ -202,7 +203,7 @@ li { margin-bottom: 0 !important; - &:first-letter { + &::first-letter { text-transform: capitalize; } } @@ -293,7 +294,7 @@ .burgerContainer { box-sizing: content-box; display: inline-flex; - //float: right; + // float: right; padding-left: 0; @include media-breakpoint-up(sm) { @@ -383,6 +384,7 @@ .articleHeader { @include font-size(1.4rem); + left: $container-padding-x; margin: 0.2em 0; overflow: hidden; @@ -624,7 +626,7 @@ } a:hover { - //background-color: var(--link-hover-background) !important; + // background-color: var(--link-hover-background) !important; } } diff --git a/src/components/Topic/TopicBadge/TopicBadge.tsx b/src/components/Topic/TopicBadge/TopicBadge.tsx index a96f34e8..c76f60b3 100644 --- a/src/components/Topic/TopicBadge/TopicBadge.tsx +++ b/src/components/Topic/TopicBadge/TopicBadge.tsx @@ -2,12 +2,12 @@ import { clsx } from 'clsx' import styles from './TopicBadge.module.scss' import { FollowingEntity, Topic } from '../../../graphql/types.gen' import { createMemo, createSignal, Show } from 'solid-js' -import { imageProxy } from '../../../utils/imageProxy' import { Button } from '../../_shared/Button' import { useSession } from '../../../context/session' import { useLocalize } from '../../../context/localize' import { follow, unfollow } from '../../../stores/zine/common' import { CheckButton } from '../../_shared/CheckButton' +import { getImageUrl } from '../../../utils/getImageUrl' type Props = { topic: Topic @@ -43,7 +43,11 @@ export const TopicBadge = (props: Props) => { {props.topic.title} diff --git a/src/components/Views/Author/Author.module.scss b/src/components/Views/Author/Author.module.scss index a9215987..a898c9db 100644 --- a/src/components/Views/Author/Author.module.scss +++ b/src/components/Views/Author/Author.module.scss @@ -30,12 +30,14 @@ .ratingContainer { @include font-size(1.5rem); + display: inline-flex; vertical-align: top; } .ratingControl { @include font-size(1.5rem); + display: inline-flex; margin-left: 1em; vertical-align: middle; @@ -103,10 +105,11 @@ } .longBioExpandedControl { + @include font-size(1.6rem); + border-radius: 1.2rem; display: block; height: auto; - @include font-size(1.6rem); padding-bottom: 1.2rem; padding-top: 1.2rem; position: relative; diff --git a/src/components/Views/Author/Author.tsx b/src/components/Views/Author/Author.tsx index 3fd947b3..f0e432ca 100644 --- a/src/components/Views/Author/Author.tsx +++ b/src/components/Views/Author/Author.tsx @@ -17,7 +17,6 @@ import { Comment } from '../../Article/Comment' import { useLocalize } from '../../../context/localize' import { AuthorRatingControl } from '../../Author/AuthorRatingControl' import { getPagePath } from '@nanostores/router' -import { useSession } from '../../../context/session' import { Loading } from '../../_shared/Loading' type Props = { diff --git a/src/components/Views/Edit.tsx b/src/components/Views/Edit.tsx index 5a1eafe3..0ada4297 100644 --- a/src/components/Views/Edit.tsx +++ b/src/components/Views/Edit.tsx @@ -8,7 +8,6 @@ import { ShoutForm, useEditorContext } from '../../context/editor' import { Editor, Panel } from '../Editor' import { Icon } from '../_shared/Icon' import styles from './Edit.module.scss' -import { imageProxy } from '../../utils/imageProxy' import { GrowingTextarea } from '../_shared/GrowingTextarea' import { VideoUploader } from '../Editor/VideoUploader' import { AudioUploader } from '../Editor/AudioUploader' @@ -24,6 +23,7 @@ import { createStore } from 'solid-js/store' import SimplifiedEditor from '../Editor/SimplifiedEditor' import { isDesktop } from '../../utils/media-query' import { TableOfContents } from '../TableOfContents' +import { getImageUrl } from '../../utils/getImageUrl' type Props = { shout: Shout @@ -362,7 +362,9 @@ export const EditView = (props: Props) => { >
    diff --git a/src/components/Views/PublishSettings/PublishSettings.tsx b/src/components/Views/PublishSettings/PublishSettings.tsx index b9f62582..de277609 100644 --- a/src/components/Views/PublishSettings/PublishSettings.tsx +++ b/src/components/Views/PublishSettings/PublishSettings.tsx @@ -4,7 +4,6 @@ import { createSignal, onMount, Show } from 'solid-js' import { TopicSelect, UploadModalContent } from '../../Editor' import { Button } from '../../_shared/Button' import { hideModal, showModal } from '../../../stores/ui' -import { imageProxy } from '../../../utils/imageProxy' import { ShoutForm, useEditorContext } from '../../../context/editor' import { useLocalize } from '../../../context/localize' import { Modal } from '../../Nav/Modal' @@ -20,6 +19,7 @@ import { GrowingTextarea } from '../../_shared/GrowingTextarea' import { createStore } from 'solid-js/store' import { UploadedFile } from '../../../pages/types' import SimplifiedEditor, { MAX_DESCRIPTION_LIMIT } from '../../Editor/SimplifiedEditor' +import { Image } from '../../_shared/Image' type Props = { shoutId: number @@ -141,11 +141,7 @@ export const PublishSettings = (props: Props) => { >
    - {initialData.title} + {initialData.title}
    diff --git a/src/components/_shared/CheckButton/CheckButton.module.scss b/src/components/_shared/CheckButton/CheckButton.module.scss index d62742f1..f7d6fd94 100644 --- a/src/components/_shared/CheckButton/CheckButton.module.scss +++ b/src/components/_shared/CheckButton/CheckButton.module.scss @@ -21,9 +21,11 @@ &:hover { background: var(--background-color-invert); color: var(--default-color-invert); + .check { display: none; } + .close { display: block; } diff --git a/src/components/_shared/DropArea/DropArea.tsx b/src/components/_shared/DropArea/DropArea.tsx index 2430d46b..8b0ca6e6 100644 --- a/src/components/_shared/DropArea/DropArea.tsx +++ b/src/components/_shared/DropArea/DropArea.tsx @@ -7,6 +7,7 @@ import { validateFiles } from '../../../utils/validateFile' import type { FileTypeToUpload } from '../../../pages/types' import { handleFileUpload } from '../../../utils/handleFileUpload' import { UploadedFile } from '../../../pages/types' +import { handleImageUpload } from '../../../utils/handleImageUpload' type Props = { class?: string @@ -30,7 +31,8 @@ export const DropArea = (props: Props) => { const results: UploadedFile[] = [] for (const file of files) { - const result = await handleFileUpload(file) + const handler = props.fileType === 'image' ? handleImageUpload : handleFileUpload + const result = await handler(file) results.push(result) } props.onUpload(results) diff --git a/src/components/_shared/FloatingPanel/FloatingPanel.module.scss b/src/components/_shared/FloatingPanel/FloatingPanel.module.scss index b21e0326..f5e72ec7 100644 --- a/src/components/_shared/FloatingPanel/FloatingPanel.module.scss +++ b/src/components/_shared/FloatingPanel/FloatingPanel.module.scss @@ -3,18 +3,14 @@ bottom: 20px; left: 0; right: 0; - display: none; align-items: center; justify-content: space-between; - max-width: 430px; width: auto; height: auto; - margin: 0 auto; padding: 14px; - background-color: var(--background-color); border: 2px solid black; diff --git a/src/components/_shared/Image/Image.tsx b/src/components/_shared/Image/Image.tsx index fa957458..df5ae79c 100644 --- a/src/components/_shared/Image/Image.tsx +++ b/src/components/_shared/Image/Image.tsx @@ -1,9 +1,16 @@ import { splitProps } from 'solid-js' import type { JSX } from 'solid-js' -import { imageProxy } from '../../../utils/imageProxy' +import { getImageUrl } from '../../../utils/getImageUrl' -export const Image = (props: JSX.ImgHTMLAttributes) => { - const [local, others] = splitProps(props, ['src']) - - return +type Props = JSX.ImgHTMLAttributes & { + width: number + alt: string +} + +export const Image = (props: Props) => { + const [local, others] = splitProps(props, ['src', 'alt']) + + const src = getImageUrl(local.src, { width: others.width }) + + return {local.alt} } diff --git a/src/components/_shared/Popup/Popup.module.scss b/src/components/_shared/Popup/Popup.module.scss index 79985fd6..0bdde227 100644 --- a/src/components/_shared/Popup/Popup.module.scss +++ b/src/components/_shared/Popup/Popup.module.scss @@ -31,6 +31,7 @@ &.bordered { @include font-size(1.6rem); + border: 2px solid #000; padding: 2.4rem; @@ -45,6 +46,7 @@ &.tiny { @include font-size(1.4rem); + box-shadow: 0 4px 60px rgb(0 0 0 / 10%); padding: 1rem; diff --git a/src/components/_shared/SolidSwiper/SolidSwiper.tsx b/src/components/_shared/SolidSwiper/SolidSwiper.tsx index 0c670873..faad65d5 100644 --- a/src/components/_shared/SolidSwiper/SolidSwiper.tsx +++ b/src/components/_shared/SolidSwiper/SolidSwiper.tsx @@ -9,14 +9,15 @@ import { createFileUploader } from '@solid-primitives/upload' import SwiperCore, { Manipulation, Navigation, Pagination } from 'swiper' import { SwiperRef } from './swiper' import { validateFiles } from '../../../utils/validateFile' -import { handleFileUpload } from '../../../utils/handleFileUpload' import { useSnackbar } from '../../../context/snackbar' import { Loading } from '../Loading' -import { imageProxy } from '../../../utils/imageProxy' import { clsx } from 'clsx' import styles from './Swiper.module.scss' import { composeMediaItems } from '../../../utils/composeMediaItems' import SimplifiedEditor from '../../Editor/SimplifiedEditor' +import { handleImageUpload } from '../../../utils/handleImageUpload' +import { getImageUrl } from '../../../utils/getImageUrl' +import { Image } from '../Image' type Props = { images: MediaItem[] @@ -95,7 +96,7 @@ export const SolidSwiper = (props: Props) => { setLoading(true) const results: UploadedFile[] = [] for (const file of selectedFiles) { - const result = await handleFileUpload(file) + const result = await handleImageUpload(file) results.push(result) } props.onImagesAdd(composeMediaItems(results)) @@ -172,7 +173,7 @@ export const SolidSwiper = (props: Props) => { // @ts-ignore
    - {slide.title} + {slide.title} {(triggerRef: (el) => void) => ( @@ -232,7 +233,9 @@ export const SolidSwiper = (props: Props) => {
    diff --git a/src/components/_shared/SolidSwiper/Swiper.module.scss b/src/components/_shared/SolidSwiper/Swiper.module.scss index 33a4eb1e..44ecd210 100644 --- a/src/components/_shared/SolidSwiper/Swiper.module.scss +++ b/src/components/_shared/SolidSwiper/Swiper.module.scss @@ -82,6 +82,10 @@ $navigation-reserve: 32px; &.editorMode { color: #0d0d0d; + + .holder { + width: 100%; + } } .action { @@ -112,6 +116,7 @@ $navigation-reserve: 32px; .counter { @include font-size(1.2rem); + position: absolute; z-index: 2; top: 477px; @@ -139,11 +144,6 @@ $navigation-reserve: 32px; display: flex; } } - &.editorMode { - .holder { - width: 100%; - } - } .navigation { background: rgb(0 0 0 / 40%); @@ -253,7 +253,9 @@ $navigation-reserve: 32px; background-color: var(--placeholder-color-semi); opacity: 0.5; filter: grayscale(1); - transition: filter 0.3s ease-in-out, opacity 0.5s ease-in-out; + transition: + filter 0.3s ease-in-out, + opacity 0.5s ease-in-out; .thumbAction { display: none; diff --git a/src/pages/index.page.tsx b/src/pages/index.page.tsx index d3aada42..c086cb46 100644 --- a/src/pages/index.page.tsx +++ b/src/pages/index.page.tsx @@ -18,8 +18,10 @@ export const HomePage = (props: PageProps) => { return } - await loadShouts({ filters: { visibility: 'public' }, limit: PRERENDERED_ARTICLES_COUNT }) - await loadRandomTopics({ amount: RANDOM_TOPICS_COUNT }) + await Promise.all([ + loadShouts({ filters: { visibility: 'public' }, limit: PRERENDERED_ARTICLES_COUNT }), + loadRandomTopics({ amount: RANDOM_TOPICS_COUNT }) + ]) setIsLoaded(true) }) diff --git a/src/pages/profile/Settings.module.scss b/src/pages/profile/Settings.module.scss index a6ce9407..54d620e3 100644 --- a/src/pages/profile/Settings.module.scss +++ b/src/pages/profile/Settings.module.scss @@ -17,6 +17,14 @@ h5 { margin-top: 3rem; } +.error { + @include font-size(1.6rem); + + text-align: center; + color: var(--danger-color); + margin-top: 1.6rem; +} + .multipleControlsItem { position: relative; @@ -133,7 +141,9 @@ h5 { color: #000; display: flex; padding: 0.8em 1em; - transition: background-color 0.3s, color 0.3s; + transition: + background-color 0.3s, + color 0.3s; &:hover { background: #000; diff --git a/src/pages/profile/profileSettings.page.tsx b/src/pages/profile/profileSettings.page.tsx index 3d8de392..c5251456 100644 --- a/src/pages/profile/profileSettings.page.tsx +++ b/src/pages/profile/profileSettings.page.tsx @@ -12,19 +12,20 @@ import { useSession } from '../../context/session' import FloatingPanel from '../../components/_shared/FloatingPanel/FloatingPanel' import { useSnackbar } from '../../context/snackbar' import { useLocalize } from '../../context/localize' -import { handleFileUpload } from '../../utils/handleFileUpload' import { Userpic } from '../../components/Author/Userpic' import { createStore } from 'solid-js/store' import { clone } from '../../utils/clone' import SimplifiedEditor from '../../components/Editor/SimplifiedEditor' import { GrowingTextarea } from '../../components/_shared/GrowingTextarea' import { AuthGuard } from '../../components/AuthGuard' +import { handleImageUpload } from '../../utils/handleImageUpload' export const ProfileSettingsPage = () => { const { t } = useLocalize() const [addLinkForm, setAddLinkForm] = createSignal(false) const [incorrectUrl, setIncorrectUrl] = createSignal(false) const [isUserpicUpdating, setIsUserpicUpdating] = createSignal(false) + const [uploadError, setUploadError] = createSignal(false) const [isFloatingPanelVisible, setIsFloatingPanelVisible] = createSignal(false) const { @@ -63,14 +64,16 @@ export const ProfileSettingsPage = () => { const { selectFiles } = createFileUploader({ multiple: false, accept: 'image/*' }) const handleAvatarClick = async () => { - await selectFiles(async ([uploadFile]) => { + selectFiles(async ([uploadFile]) => { try { + setUploadError(false) setIsUserpicUpdating(true) - const result = await handleFileUpload(uploadFile) + const result = await handleImageUpload(uploadFile) updateFormField('userpic', result.url) setIsUserpicUpdating(false) setIsFloatingPanelVisible(true) } catch (error) { + setUploadError(true) console.error('[upload avatar] error', error) } }) @@ -131,6 +134,9 @@ export const ProfileSettingsPage = () => { onClick={handleAvatarClick} loading={isUserpicUpdating()} /> + +
    {t('Upload error')}
    +

    {t('Name')}

    diff --git a/src/utils/config.ts b/src/utils/config.ts index e0c3788b..3039e213 100644 --- a/src/utils/config.ts +++ b/src/utils/config.ts @@ -3,4 +3,7 @@ export const isDev = import.meta.env.MODE === 'development' const defaultApiUrl = 'https://testapi.discours.io' export const apiBaseUrl = import.meta.env.PUBLIC_API_URL || defaultApiUrl +const defaultThumborUrl = 'https://images.discours.io' +export const thumborUrl = import.meta.env.PUBLIC_THUMBOR_URL || defaultThumborUrl + export const SENTRY_DSN = import.meta.env.PUBLIC_SENTRY_DSN || '' diff --git a/src/utils/getImageUrl.ts b/src/utils/getImageUrl.ts new file mode 100644 index 00000000..a36b4544 --- /dev/null +++ b/src/utils/getImageUrl.ts @@ -0,0 +1,29 @@ +import { thumborUrl } from './config' + +const getSizeUrlPart = (options: { width?: number; height?: number } = {}) => { + const widthString = options.width ? options.width.toString() : '' + const heightString = options.height ? options.height.toString() : '' + + if (!widthString && !heightString) { + return '' + } + + return `${widthString}x${heightString}/` +} + +// I'm not proud of this +export const getImageUrl = (src: string, options: { width?: number; height?: number } = {}) => { + const sizeUrlPart = getSizeUrlPart(options) + + if (!src.startsWith(thumborUrl)) { + return `${thumborUrl}/unsafe/${sizeUrlPart}${src}` + } + + if (src.startsWith(`${thumborUrl}/unsafe`)) { + const thumborKey = src.replace(`${thumborUrl}/unsafe`, '') + return `${thumborUrl}/unsafe/${sizeUrlPart}${thumborKey}` + } + + const thumborKey = src.replace(`${thumborUrl}`, '') + return `${thumborUrl}/${sizeUrlPart}${thumborKey}` +} diff --git a/src/utils/handleImageUpload.ts b/src/utils/handleImageUpload.ts new file mode 100644 index 00000000..92ab03a3 --- /dev/null +++ b/src/utils/handleImageUpload.ts @@ -0,0 +1,22 @@ +import { UploadFile } from '@solid-primitives/upload' +import { UploadedFile } from '../pages/types' +import { thumborUrl } from './config' + +export const handleImageUpload = async (uploadFile: UploadFile): Promise => { + const formData = new FormData() + formData.append('media', uploadFile.file, uploadFile.name) + const response = await fetch(`${thumborUrl}/image`, { + method: 'POST', + body: formData + }) + + const location = response.headers.get('Location') + + const url = `${thumborUrl}/unsafe/production${location.slice(0, location.lastIndexOf('/'))}` + const originalFilename = location.slice(location.lastIndexOf('/') + 1) + + return { + originalFilename, + url + } +} diff --git a/src/utils/imageProxy.ts b/src/utils/imageProxy.ts deleted file mode 100644 index c48530e6..00000000 --- a/src/utils/imageProxy.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { isDev } from './config' -export const imageProxy = (url: string) => { - return `${isDev ? 'https://new.discours.io' : ''}/api/image?url=${encodeURI(url)}` -} - -export const audioProxy = (url: string) => { - return `${isDev ? 'https://new.discours.io' : ''}/api/audio?url=${encodeURI(url)}` -} diff --git a/src/utils/renderUploadedImage.ts b/src/utils/renderUploadedImage.ts index 40b95f14..e4e61279 100644 --- a/src/utils/renderUploadedImage.ts +++ b/src/utils/renderUploadedImage.ts @@ -1,5 +1,4 @@ import { UploadedFile } from '../pages/types' -import { imageProxy } from './imageProxy' import { hideModal } from '../stores/ui' import { Editor } from '@tiptap/core' @@ -22,7 +21,7 @@ export const renderUploadedImage = (editor: Editor, image: UploadedFile) => { { type: 'image', attrs: { - src: imageProxy(image.url) + src: image.url } } ] From 93cb38006b20212090eb3d508ca03d18fcc03118 Mon Sep 17 00:00:00 2001 From: Ilya Y <75578537+ilya-bkv@users.noreply.github.com> Date: Mon, 30 Oct 2023 14:20:33 +0300 Subject: [PATCH 021/129] Fix/i18n fix (#286) i18n fix --- public/locales/en/translation.json | 12 ++++++++++-- public/locales/ru/translation.json | 12 ++++++++++-- src/components/Feed/Sidebar/Sidebar.tsx | 4 ++-- src/components/Nav/Header/Header.tsx | 22 +++++++++++----------- 4 files changed, 33 insertions(+), 17 deletions(-) diff --git a/public/locales/en/translation.json b/public/locales/en/translation.json index e0305bd7..0b6965b4 100644 --- a/public/locales/en/translation.json +++ b/public/locales/en/translation.json @@ -90,6 +90,7 @@ "Create gallery": "Create gallery", "Create post": "Create post", "Create video": "Create video", + "Culture": "Culture", "Date of Birth": "Date of Birth", "Decline": "Decline", "Delete": "Delete", @@ -121,6 +122,7 @@ "Enter your new password": "Enter your new password", "Error": "Error", "Everything is ok, please give us your email address": "It's okay, just enter your email address to receive a password reset link.", + "Experience": "Experience", "FAQ": "Tips and suggestions", "Favorite": "Favorites", "Favorite topics": "Favorite topics", @@ -169,6 +171,7 @@ "Independant magazine with an open horizontal cooperation about culture, science and society": "Independant magazine with an open horizontal cooperation about culture, science and society", "Insert footnote": "Insert footnote", "Insert video link": "Insert video link", + "Interview": "Interview", "Introduce": "Introduction", "Invalid email": "Check if your email is correct", "Invalid image URL": "Invalid image URL", @@ -229,6 +232,7 @@ "Our regular contributor": "Our regular contributor", "Paragraphs": "Абзацев", "Participating": "Participating", + "Participation": "Participation", "Partners": "Partners", "Password": "Password", "Password again": "Password again", @@ -247,6 +251,8 @@ "Please enter password": "Please enter a password", "Please enter password again": "Please enter password again", "Please, confirm email": "Please confirm email", + "Podcasts": "Podcasts", + "Poetry": "Poetry", "Popular": "Popular", "Popular authors": "Popular authors", "Principles": "Community principles", @@ -266,6 +272,7 @@ "Remove link": "Remove link", "Reply": "Reply", "Report": "Complain", + "Reports": "Reports", "Required": "Required", "Resend code": "Send confirmation", "Restore password": "Restore password", @@ -289,11 +296,13 @@ "Show table of contents": "Show table of contents", "Slug": "Slug", "Social networks": "Social networks", + "Society": "Society", "Something went wrong, check email and password": "Something went wrong. Check your email and password", "Something went wrong, please try again": "Something went wrong, please try again", "Song lyrics": "Song lyrics...", "Song title": "Song title", "Sorry, this address is already taken, please choose another one.": "Sorry, this address is already taken, please choose another one", + "Special Projects": "Special Projects", "Special projects": "Special projects", "Specify the source and the name of the author": "Specify the source and the name of the author", "Start conversation": "Start a conversation", @@ -316,6 +325,7 @@ "Terms of use": "Site rules", "Text checking": "Text checking", "Thank you": "Thank you", + "Theory": "Theory", "There are unsaved changes in your profile settings. Are you sure you want to leave the page without saving?": "There are unsaved changes in your profile settings. Are you sure you want to leave the page without saving?", "There are unsaved changes in your publishing settings. Are you sure you want to leave the page without saving?": "There are unsaved changes in your publishing settings. Are you sure you want to leave the page without saving?", "This comment has not yet been rated": "This comment has not yet been rated", @@ -379,7 +389,6 @@ "You've reached a non-existed page": "You've reached a non-existed page", "Your email": "Your email", "Your name will appear on your profile page and as your signature in publications, comments and responses.": "Your name will appear on your profile page and as your signature in publications, comments and responses", - "accomplices": "accomplices", "actions": "actions", "add link": "add link", "all topics": "all topics", @@ -403,7 +412,6 @@ "feed": "feed", "follower": "follower", "followersWithCount": "{count} {count, plural, one {follower} other {followers}}", - "general feed": "general tape", "header 1": "header 1", "header 2": "header 2", "header 3": "header 3", diff --git a/public/locales/ru/translation.json b/public/locales/ru/translation.json index b7b19cfb..eaaeb3c2 100644 --- a/public/locales/ru/translation.json +++ b/public/locales/ru/translation.json @@ -3,7 +3,6 @@ "A short introduction to keep the reader interested": "Добавьте вступление, чтобы заинтересовать читателя", "About": "О себе", "About the project": "О проекте", - "Accomplices": "Соучастники", "Add a few topics so that the reader knows what your content is about and can find it on pages of topics that interest them. Topics can be swapped, the first topic becomes the title": "Добавьте несколько тем, чтобы читатель знал, о чем ваш материал, и мог найти его на страницах интересных ему тем. Темы можно менять местами, первая тема становится заглавной", "Add a link or click plus to embed media": "Добавьте ссылку или нажмите плюс для вставки медиа", "Add an embed widget": "Добавить embed-виджет", @@ -94,6 +93,7 @@ "Create gallery": "Создать галерею", "Create post": "Создать публикацию", "Create video": "Создать видео", + "Culture": "Культура", "Date of Birth": "Дата рождения", "Decline": "Отмена", "Delete": "Удалить", @@ -126,6 +126,7 @@ "Enter your new password": "Введите новый пароль", "Error": "Ошибка", "Everything is ok, please give us your email address": "Ничего страшного, просто укажите свою почту, чтобы получить ссылку для сброса пароля.", + "Experience": "Личный опыт", "FAQ": "Советы и предложения", "Favorite": "Избранное", "Favorite topics": "Избранные темы", @@ -177,6 +178,7 @@ "Independant magazine with an open horizontal cooperation about culture, science and society": "Независимый журнал с открытой горизонтальной редакцией о культуре, науке и обществе", "Insert footnote": "Вставить сноску", "Insert video link": "Вставить ссылку на видео", + "Interview": "Интервью", "Introduce": "Представление", "Invalid email": "Проверьте правильность ввода почты", "Invalid image URL": "Некорректная ссылка на изображение", @@ -240,6 +242,7 @@ "Our regular contributor": "Наш постоянный автор", "Paragraphs": "Абзацев", "Participating": "Участвовать", + "Participation": "Соучастие", "Partners": "Партнёры", "Password": "Пароль", "Password again": "Пароль ещё раз", @@ -258,6 +261,8 @@ "Please enter password": "Пожалуйста, введите пароль", "Please enter password again": "Пожалуйста, введите пароль ещё рез", "Please, confirm email": "Пожалуйста, подтвердите электронную почту", + "Podcasts": "Подкасты", + "Poetry": "Поэзия", "Popular": "Популярное", "Popular authors": "Популярные авторы", "Preview": "Предпросмотр", @@ -282,6 +287,7 @@ "Remove link": "Убрать ссылку", "Reply": "Ответить", "Report": "Пожаловаться", + "Reports": "Репортажи", "Required": "Поле обязательно для заполнения", "Resend code": "Выслать подтверждение", "Restore password": "Восстановить пароль", @@ -307,11 +313,13 @@ "Show table of contents": "Показать главление", "Slug": "Постоянная ссылка", "Social networks": "Социальные сети", + "Society": "Общество", "Something went wrong, check email and password": "Что-то пошло не так. Проверьте адрес электронной почты и пароль", "Something went wrong, please try again": "Что-то пошло не так, попробуйте еще раз", "Song lyrics": "Текст песни...", "Song title": "Название песни", "Sorry, this address is already taken, please choose another one.": "Увы, этот адрес уже занят, выберите другой", + "Special Projects": "Спецпроекты", "Special projects": "Спецпроекты", "Specify the source and the name of the author": "Укажите источник и имя автора", "Start conversation": "Начать беседу", @@ -335,6 +343,7 @@ "Terms of use": "Правила сайта", "Text checking": "Проверка текста", "Thank you": "Благодарности", + "Theory": "Теории", "There are unsaved changes in your profile settings. Are you sure you want to leave the page without saving?": "В настройках вашего профиля есть несохраненные изменения. Уверены, что хотите покинуть страницу без сохранения?", "There are unsaved changes in your publishing settings. Are you sure you want to leave the page without saving?": "В настройках публикации есть несохраненные изменения. Уверены, что хотите покинуть страницу без сохранения?", "This comment has not yet been rated": "Этот комментарий еще пока никто не оценил", @@ -426,7 +435,6 @@ "feed": "лента", "follower": "подписчик", "followersWithCount": "{count} {count, plural, one {подписчик} few {подписчика} other {подписчиков}}", - "general feed": "Общая лента", "header 1": "заголовок 1", "header 2": "заголовок 2", "header 3": "заголовок 3", diff --git a/src/components/Feed/Sidebar/Sidebar.tsx b/src/components/Feed/Sidebar/Sidebar.tsx index 1ae62261..a62441b1 100644 --- a/src/components/Feed/Sidebar/Sidebar.tsx +++ b/src/components/Feed/Sidebar/Sidebar.tsx @@ -38,7 +38,7 @@ export const Sidebar = () => { > - {t('general feed')} + {t('All')}

  • @@ -64,7 +64,7 @@ export const Sidebar = () => { > - {t('Accomplices')} + {t('Participation')} diff --git a/src/components/Nav/Header/Header.tsx b/src/components/Nav/Header/Header.tsx index 00a9b056..7dbe5026 100644 --- a/src/components/Nav/Header/Header.tsx +++ b/src/components/Nav/Header/Header.tsx @@ -406,31 +406,31 @@ export const Header = (props: Props) => { {t('Art')}
  • - Подкасты + {t('Podcasts')}
  • - Спецпроекты + {t('Special Projects')}
  • - #Интервью + #{t('Interview')}
  • - #Репортажи + #{t('Reports')}
  • - #Личный опыт + #{t('Experience')}
  • - #Общество + #{t('Society')}
  • - #Культура + #{t('Culture')}
  • - #Теории + #{t('Theory')}
  • - #Поэзия + #{t('Poetry')}
  • @@ -479,7 +479,7 @@ export const Header = (props: Props) => { - {t('general feed')} + {t('All')}
  • @@ -496,7 +496,7 @@ export const Header = (props: Props) => { - {t('Accomplices')} + {t('Participation')} From bfb3fd570c8921b3a4238928e5a8143933d8372c Mon Sep 17 00:00:00 2001 From: Ilya Y <75578537+ilya-bkv@users.noreply.github.com> Date: Mon, 30 Oct 2023 14:29:15 +0300 Subject: [PATCH 022/129] Delete audio cover in Editor (#285) --- src/components/Views/Edit.module.scss | 18 ++++++++++++++++++ src/components/Views/Edit.tsx | 15 ++++++++++++++- src/context/editor.tsx | 2 +- 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/src/components/Views/Edit.module.scss b/src/components/Views/Edit.module.scss index 6f77ab2d..e8f342b4 100644 --- a/src/components/Views/Edit.module.scss +++ b/src/components/Views/Edit.module.scss @@ -213,6 +213,24 @@ background-position: center; background-size: cover; background-repeat: no-repeat; + position: relative; + + .delete { + position: absolute; + width: 32px; + height: 32px; + padding: 10px; + border-radius: 50%; + top: 4px; + right: 4px; + background-color: rgba(black, 0.5); + cursor: pointer; + display: none; + } + + &:hover .delete { + display: block; + } } } diff --git a/src/components/Views/Edit.tsx b/src/components/Views/Edit.tsx index 0ada4297..f24e6f26 100644 --- a/src/components/Views/Edit.tsx +++ b/src/components/Views/Edit.tsx @@ -24,6 +24,7 @@ import SimplifiedEditor from '../Editor/SimplifiedEditor' import { isDesktop } from '../../utils/media-query' import { TableOfContents } from '../TableOfContents' import { getImageUrl } from '../../utils/getImageUrl' +import { Popover } from '../_shared/Popover' type Props = { shout: Shout @@ -365,7 +366,19 @@ export const EditView = (props: Props) => { style={{ 'background-image': `url(${getImageUrl(form.coverImageUrl, { width: 1600 })})` }} - /> + > + + {(triggerRef: (el) => void) => ( +
    setForm('coverImageUrl', null)} + > + +
    + )} +
    + diff --git a/src/context/editor.tsx b/src/context/editor.tsx index 75812c53..a15d261c 100644 --- a/src/context/editor.tsx +++ b/src/context/editor.tsx @@ -26,7 +26,7 @@ export type ShoutForm = { selectedTopics: Topic[] mainTopic?: Topic body: string - coverImageUrl: string + coverImageUrl?: string media?: string } From 3a5b279f78977c3f766f4d671d1a1a230dc965db Mon Sep 17 00:00:00 2001 From: kvakazyambra Date: Tue, 31 Oct 2023 18:22:00 +0300 Subject: [PATCH 023/129] Fixed mobile article footer --- public/locales/en/translation.json | 1 + public/locales/ru/translation.json | 1 + src/components/Article/Article.module.scss | 28 +++++++++++++++++++++- src/components/Article/FullArticle.tsx | 5 +++- 4 files changed, 33 insertions(+), 2 deletions(-) diff --git a/public/locales/en/translation.json b/public/locales/en/translation.json index 0b6965b4..97824a78 100644 --- a/public/locales/en/translation.json +++ b/public/locales/en/translation.json @@ -447,5 +447,6 @@ "user already exist": "user already exists", "video": "video", "view": "view", + "viewsWithCount": "{count} {count, plural, one {view} other {views}}", "yesterday": "yesterday" } diff --git a/public/locales/ru/translation.json b/public/locales/ru/translation.json index eaaeb3c2..87576d99 100644 --- a/public/locales/ru/translation.json +++ b/public/locales/ru/translation.json @@ -471,5 +471,6 @@ "user already exist": "пользователь уже существует", "video": "видео", "view": "просмотр", + "viewsWithCount": "{count} {count, plural, one {просмотр} few {просмотрa} other {просмотров}}", "yesterday": "вчера" } diff --git a/src/components/Article/Article.module.scss b/src/components/Article/Article.module.scss index 0d2a8b66..27c7039a 100644 --- a/src/components/Article/Article.module.scss +++ b/src/components/Article/Article.module.scss @@ -390,12 +390,38 @@ img { } @include media-breakpoint-down(sm) { - flex: 1 100%; + flex: 1 40%; } } .shoutStatsItemViews { cursor: default; + + @include media-breakpoint-down(sm) { + color: rgb(0 0 0 / 0.4); + flex: 1 40%; + justify-content: end; + margin-right: 0; + order: 10; + + .icon { + display: none !important; + } + } +} + +.shoutStatsItemLabel { + margin-left: 0.3em; + + @include media-breakpoint-up(sm) { + display: none; + } +} + +.shoutStatsItemCount { + @include media-breakpoint-down(sm) { + display: none; + } } .shoutStatsItemAdditionalDataItem { diff --git a/src/components/Article/FullArticle.tsx b/src/components/Article/FullArticle.tsx index 35ec0935..4986b99b 100644 --- a/src/components/Article/FullArticle.tsx +++ b/src/components/Article/FullArticle.tsx @@ -360,7 +360,10 @@ export const FullArticle = (props: Props) => {
    - {props.article.stat?.viewed} + {props.article.stat?.viewed} + + {t('viewsWithCount', { count: props.article.stat?.viewed })} +
    From d64449fb33de5bacea222485be8c4b913888f692 Mon Sep 17 00:00:00 2001 From: kvakazyambra Date: Tue, 31 Oct 2023 19:44:00 +0300 Subject: [PATCH 024/129] Fixed buttons style on the author page --- .../Author/AuthorCard/AuthorCard.module.scss | 33 +++++++++++++++++++ .../Author/AuthorCard/AuthorCard.tsx | 13 ++++++-- 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/src/components/Author/AuthorCard/AuthorCard.module.scss b/src/components/Author/AuthorCard/AuthorCard.module.scss index f55732b3..f04d86ff 100644 --- a/src/components/Author/AuthorCard/AuthorCard.module.scss +++ b/src/components/Author/AuthorCard/AuthorCard.module.scss @@ -76,6 +76,39 @@ @include media-breakpoint-down(lg) { flex-wrap: wrap; } + + .buttonSubscribe { + aspect-ratio: auto; + background-color: #000; + border: 1px solid #000; + border-radius: 0.8rem; + color: #fff; + float: none; + padding-bottom: 0.6rem; + padding-top: 0.6rem; + width: 10em; + + .icon { + margin-right: 0.5em; + + img { + filter: invert(1); + } + } + + &:hover { + background: #fff; + color: #000; + + .icon img { + filter: invert(0); + } + } + + img { + vertical-align: text-top; + } + } } .authorDetails { diff --git a/src/components/Author/AuthorCard/AuthorCard.tsx b/src/components/Author/AuthorCard/AuthorCard.tsx index 206a8af2..a40425ab 100644 --- a/src/components/Author/AuthorCard/AuthorCard.tsx +++ b/src/components/Author/AuthorCard/AuthorCard.tsx @@ -202,8 +202,17 @@ export const AuthorCard = (props: Props) => { when={isProfileOwner()} fallback={
    -
    } > From 4ca01e5a027e44a3712c4c2b05bb98b2e5232875 Mon Sep 17 00:00:00 2001 From: kvakazyambra Date: Wed, 1 Nov 2023 00:21:30 +0300 Subject: [PATCH 025/129] Header buttons style fixes --- src/components/Nav/Header/Header.module.scss | 27 +++++++++++- src/components/Nav/Header/Header.tsx | 5 +++ src/components/Nav/HeaderAuth.tsx | 43 ++++++++++++-------- 3 files changed, 55 insertions(+), 20 deletions(-) diff --git a/src/components/Nav/Header/Header.module.scss b/src/components/Nav/Header/Header.module.scss index 37a11d66..7f34ffc7 100644 --- a/src/components/Nav/Header/Header.module.scss +++ b/src/components/Nav/Header/Header.module.scss @@ -482,6 +482,28 @@ width: 100%; } } + + .editorControl { + border-radius: 1.2em; + + &:hover { + background: var(--background-color-invert); + } + } + + .settingsControl { + border-radius: 100%; + padding: 0.8rem !important; + min-width: 4rem !important; + + &:hover { + background: var(--background-color-invert); + + img { + filter: invert(1); + } + } + } } .userControlItem { @@ -620,13 +642,14 @@ } .textLabel { - background-color: var(--link-hover-background); color: var(--link-hover-color); } } a:hover { - // background-color: var(--link-hover-background) !important; + .textLabel { + background-color: var(--link-hover-background); + } } } diff --git a/src/components/Nav/Header/Header.tsx b/src/components/Nav/Header/Header.tsx index 7dbe5026..22179cee 100644 --- a/src/components/Nav/Header/Header.tsx +++ b/src/components/Nav/Header/Header.tsx @@ -24,6 +24,7 @@ import { apiClient } from '../../../utils/apiClient' import { RANDOM_TOPICS_COUNT } from '../../Views/Home' import { Link } from './Link' import { Subscribe } from '../../_shared/Subscribe' +import { SearchModal } from '../SearchModal/SearchModal' type Props = { title?: string @@ -183,6 +184,10 @@ export const Header = (props: Props) => { + + + +
    - -
    - + +
    +
    Date: Sat, 11 Nov 2023 20:42:03 +0300 Subject: [PATCH 085/129] Fixed article card hover style --- src/components/Feed/ArticleCard/ArticleCard.module.scss | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/components/Feed/ArticleCard/ArticleCard.module.scss b/src/components/Feed/ArticleCard/ArticleCard.module.scss index 2974f97d..152037cb 100644 --- a/src/components/Feed/ArticleCard/ArticleCard.module.scss +++ b/src/components/Feed/ArticleCard/ArticleCard.module.scss @@ -483,9 +483,11 @@ &::after { background: rgb(0 0 0 / 60%); content: ''; - height: 100%; + height: 102%; + left: -1%; position: absolute; - width: 100%; + top: -1%; + width: 102%; z-index: 1; } } From 2c7e98acdfc9db658e61389a90b9608b8d2248be Mon Sep 17 00:00:00 2001 From: kvakazyambra Date: Sat, 11 Nov 2023 21:16:48 +0300 Subject: [PATCH 086/129] Fixed article card hover style --- src/components/Feed/ArticleCard/ArticleCard.module.scss | 7 ++++--- src/components/_shared/SolidSwiper/ArticleCardSwiper.tsx | 2 ++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/components/Feed/ArticleCard/ArticleCard.module.scss b/src/components/Feed/ArticleCard/ArticleCard.module.scss index 152037cb..660df8ca 100644 --- a/src/components/Feed/ArticleCard/ArticleCard.module.scss +++ b/src/components/Feed/ArticleCard/ArticleCard.module.scss @@ -12,7 +12,7 @@ } &:hover { - .shoutCardCover img { + .shoutCardCover { transform: scale(1.05); } } @@ -89,6 +89,7 @@ } .shoutCardCoverContainer { + overflow: hidden; position: relative; } @@ -99,13 +100,13 @@ overflow: hidden; padding-bottom: 56.2%; position: relative; + transform-origin: 50% 50%; + transition: transform 1s ease-in-out; img { height: 100%; object-fit: cover; position: absolute; - transform-origin: 50% 50%; - transition: transform 1s ease-in-out; width: 100%; } diff --git a/src/components/_shared/SolidSwiper/ArticleCardSwiper.tsx b/src/components/_shared/SolidSwiper/ArticleCardSwiper.tsx index 0ce768fb..bbfec7a1 100644 --- a/src/components/_shared/SolidSwiper/ArticleCardSwiper.tsx +++ b/src/components/_shared/SolidSwiper/ArticleCardSwiper.tsx @@ -47,11 +47,13 @@ export const ArticleCardSwiper = (props: Props) => { round-lengths={true} loop={true} speed={800} + /* autoplay={{ disableOnInteraction: false, delay: 6000, pauseOnMouseEnter: true }} +*/ > {(slide, index) => ( From 4121d99a7323a5e65568de518f8ddd0d912c6e94 Mon Sep 17 00:00:00 2001 From: Ilya Y <75578537+ilya-bkv@users.noreply.github.com> Date: Mon, 13 Nov 2023 11:05:05 +0300 Subject: [PATCH 087/129] Feature/lightbox (#309) add Lightbox --- src/components/Article/Article.module.scss | 1 + src/components/Article/FullArticle.tsx | 25 +++++++-- .../_shared/Lightbox/Lightbox.module.scss | 52 +++++++++++++++++ src/components/_shared/Lightbox/Lightbox.tsx | 56 +++++++++++++++++++ src/components/_shared/Lightbox/index.ts | 1 + src/context/profile.tsx | 3 - 6 files changed, 131 insertions(+), 7 deletions(-) create mode 100644 src/components/_shared/Lightbox/Lightbox.module.scss create mode 100644 src/components/_shared/Lightbox/Lightbox.tsx create mode 100644 src/components/_shared/Lightbox/index.ts diff --git a/src/components/Article/Article.module.scss b/src/components/Article/Article.module.scss index 1ea954ba..ed15b000 100644 --- a/src/components/Article/Article.module.scss +++ b/src/components/Article/Article.module.scss @@ -36,6 +36,7 @@ img { img { display: block; margin-bottom: 0.5em; + cursor: zoom-in; } blockquote, diff --git a/src/components/Article/FullArticle.tsx b/src/components/Article/FullArticle.tsx index 5ea1a86d..39586bb4 100644 --- a/src/components/Article/FullArticle.tsx +++ b/src/components/Article/FullArticle.tsx @@ -27,6 +27,7 @@ import { createPopper } from '@popperjs/core' import { AuthorBadge } from '../Author/AuthorBadge' import { getImageUrl } from '../../utils/getImageUrl' import { FeedArticlePopup } from '../Feed/FeedArticlePopup' +import { Lightbox } from '../_shared/Lightbox' type Props = { article: Shout @@ -49,6 +50,8 @@ const scrollTo = (el: HTMLElement) => { } export const FullArticle = (props: Props) => { + const [selectedImage, setSelectedImage] = createSignal('') + const { t, formatDate } = useLocalize() const { user, @@ -169,7 +172,7 @@ export const FullArticle = (props: Props) => { document.body.appendChild(tooltip) if (element.hasAttribute('href')) { - element.setAttribute('href', 'javascript: void(0);') + element.setAttribute('href', 'javascript: void(0)') } const popperInstance = createPopper(element, tooltip, { @@ -230,7 +233,19 @@ export const FullArticle = (props: Props) => { }) }) - const [isActionPopupActive, setIsActionPopupActive] = createSignal(false) + const openLightbox = (image) => { + setSelectedImage(image) + } + const handleLightboxClose = () => { + setSelectedImage() + } + + const handleArticleBodyClick = (event) => { + if (event.target.tagName === 'IMG') { + const src = event.target.src + openLightbox(getImageUrl(src)) + } + } return ( <> @@ -313,7 +328,7 @@ export const FullArticle = (props: Props) => { -
    +
    }> @@ -433,7 +448,6 @@ export const FullArticle = (props: Props) => { description={getDescription(props.article.body)} imageUrl={props.article.cover} shareUrl={getShareUrl({ pathname: `/${props.article.slug}` })} - isVisible={(value) => setIsActionPopupActive(value)} trigger={
    + + + ) } diff --git a/src/components/_shared/Lightbox/Lightbox.module.scss b/src/components/_shared/Lightbox/Lightbox.module.scss new file mode 100644 index 00000000..834c8750 --- /dev/null +++ b/src/components/_shared/Lightbox/Lightbox.module.scss @@ -0,0 +1,52 @@ +.Lightbox { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgb(0 0 0 / 80%); + display: flex; + align-items: center; + justify-content: center; + z-index: 10000; + + .image { + max-width: 90%; + max-height: 80%; + cursor: pointer; + } + + .close { + position: absolute; + top: 20px; + right: 40px; + font-size: 30px; + color: white; + cursor: pointer; + width: 20px; + height: 20px; + } + + .zoomControls { + display: flex; + position: absolute; + bottom: 16px; + left: 50%; + height: 24px; + gap: 1rem; + transform: translateX(-50%); + + .control { + border-radius: 50%; + width: 24px; + height: 24px; + font-size: 20px; + line-height: 1; + display: flex; + align-items: center; + justify-content: center; + border: 2px solid #fff; + color: #fff; + } + } +} diff --git a/src/components/_shared/Lightbox/Lightbox.tsx b/src/components/_shared/Lightbox/Lightbox.tsx new file mode 100644 index 00000000..a90bf219 --- /dev/null +++ b/src/components/_shared/Lightbox/Lightbox.tsx @@ -0,0 +1,56 @@ +import { clsx } from 'clsx' +import styles from './Lightbox.module.scss' +import { createSignal } from 'solid-js' +import { Icon } from '../Icon' + +type Props = { + class?: string + image: string + onClose: () => void +} + +const ZOOM_STEP = 1.08 +export const Lightbox = (props: Props) => { + const [zoomLevel, setZoomLevel] = createSignal(1) + + const closeLightbox = () => { + props.onClose() + } + + const zoomIn = (event) => { + event.stopPropagation() + setZoomLevel(zoomLevel() * ZOOM_STEP) + } + const zoomOut = (event) => { + event.stopPropagation() + setZoomLevel(zoomLevel() / ZOOM_STEP) + } + + const lightboxStyle = () => ({ + transform: `scale(${zoomLevel()})`, + transition: 'transform 0.3s ease' + }) + + return ( +
    + + + +
    + + +
    + {''} event.stopPropagation()} + /> +
    + ) +} diff --git a/src/components/_shared/Lightbox/index.ts b/src/components/_shared/Lightbox/index.ts new file mode 100644 index 00000000..2b06237a --- /dev/null +++ b/src/components/_shared/Lightbox/index.ts @@ -0,0 +1 @@ +export { Lightbox } from './Lightbox' diff --git a/src/context/profile.tsx b/src/context/profile.tsx index 5c55b500..ed6f13c3 100644 --- a/src/context/profile.tsx +++ b/src/context/profile.tsx @@ -69,9 +69,6 @@ const useProfileForm = () => { }) } } - createEffect(() => { - console.log('!!! FL:', form.links) - }) return { form, submit, updateFormField, slugError } } From be4a89193a4da52548204345a394bdcb9bbe15da Mon Sep 17 00:00:00 2001 From: Ilya Y <75578537+ilya-bkv@users.noreply.github.com> Date: Mon, 13 Nov 2023 16:05:55 +0300 Subject: [PATCH 088/129] Userpic flow in profile settings (#311) Userpic flow update --- public/icons/user-image-black.svg | 8 +++ public/icons/user-image-gray.svg | 8 +++ public/locales/en/translation.json | 5 +- public/locales/ru/translation.json | 5 +- src/pages/profile/Settings.module.scss | 56 +++++++++++++++++++++ src/pages/profile/profileSettings.page.tsx | 58 ++++++++++++++++++---- 6 files changed, 128 insertions(+), 12 deletions(-) create mode 100644 public/icons/user-image-black.svg create mode 100644 public/icons/user-image-gray.svg diff --git a/public/icons/user-image-black.svg b/public/icons/user-image-black.svg new file mode 100644 index 00000000..2b7b10ef --- /dev/null +++ b/public/icons/user-image-black.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/public/icons/user-image-gray.svg b/public/icons/user-image-gray.svg new file mode 100644 index 00000000..a70784ec --- /dev/null +++ b/public/icons/user-image-gray.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/public/locales/en/translation.json b/public/locales/en/translation.json index 1b765ad0..d6eb744b 100644 --- a/public/locales/en/translation.json +++ b/public/locales/en/translation.json @@ -1,5 +1,4 @@ { - "subscribing...": "subscribing...", "About": "About", "About the project": "About the project", "Add a few topics so that the reader knows what your content is about and can find it on pages of topics that interest them. Topics can be swapped, the first topic becomes the title": "Add a few topics so that the reader knows what your content is about and can find it on pages of topics that interest them. Topics can be swapped, the first topic becomes the title", @@ -95,6 +94,7 @@ "Decline": "Decline", "Delete": "Delete", "Delete cover": "Delete cover", + "Delete userpic": "Delete userpic", "Description": "Description", "Discours": "Discours", "Discours is an intellectual environment, a web space and tools that allows authors to collaborate with readers and come together to co-create publications and media projects": "Discours is an intellectual environment, a web space and tools that allows authors to collaborate with readers and come together to co-create publications and media projects.
    We are convinced that one voice is good, but many is better. We create the most amazing stories together", @@ -151,6 +151,7 @@ "Help to edit": "Help to edit", "Here you can customize your profile the way you want.": "Here you can customize your profile the way you want.", "Here you can manage all your Discourse subscriptions": "Here you can manage all your Discourse subscriptions", + "Here you can upload your photo": "Here you can upload your photo", "Hide table of contents": "Hide table of contents", "Highlight": "Highlight", "Hooray! Welcome!": "Hooray! Welcome!", @@ -354,6 +355,7 @@ "Unnamed draft": "Unnamed draft", "Upload": "Upload", "Upload error": "Upload error", + "Upload userpic": "Upload userpic", "Upload video": "Upload video", "Uploading image": "Uploading image", "Username": "Username", @@ -439,6 +441,7 @@ "subscriber": "subscriber", "subscriber_rp": "subscriber", "subscribers": "subscribers", + "subscribing...": "subscribing...", "subscription": "subscription", "subscription_rp": "subscription", "subscriptions": "subscriptions", diff --git a/public/locales/ru/translation.json b/public/locales/ru/translation.json index 1ed9ca94..3640e6a3 100644 --- a/public/locales/ru/translation.json +++ b/public/locales/ru/translation.json @@ -1,5 +1,4 @@ { - "subscribing...": "Подписка...", "A short introduction to keep the reader interested": "Добавьте вступление, чтобы заинтересовать читателя", "About": "О себе", "About the project": "О проекте", @@ -98,6 +97,7 @@ "Decline": "Отмена", "Delete": "Удалить", "Delete cover": "Удалить обложку", + "Delete userpic": "Удалить аватар", "Description": "Описание", "Discours": "Дискурс", "Discours is an intellectual environment, a web space and tools that allows authors to collaborate with readers and come together to co-create publications and media projects": "Дискурс — это интеллектуальная среда, веб-пространство и инструменты, которые позволяют авторам сотрудничать с читателями и объединяться для совместного создания публикаций и медиапроектов.
    Мы убеждены, один голос хорошо, а много — лучше. Самые потрясающиe истории мы создаём вместе.", @@ -158,6 +158,7 @@ "Help to edit": "Помочь редактировать", "Here you can customize your profile the way you want.": "Здесь можно настроить свой профиль так, как вы хотите.", "Here you can manage all your Discourse subscriptions": "Здесь можно управлять всеми своими подписками на Дискурсе", + "Here you can upload your photo": "Здесь вы можете загрузить свою фотографию", "Hide table of contents": "Скрыть главление", "Highlight": "Подсветка", "Hooray! Welcome!": "Ура! Добро пожаловать!", @@ -372,6 +373,7 @@ "Unnamed draft": "Черновик без названия", "Upload": "Загрузить", "Upload error": "Ошибка загрузки", + "Upload userpic": "Загрузить аватар", "Upload video": "Загрузить видео", "Uploading image": "Загружаем изображение", "Username": "Имя пользователя", @@ -466,6 +468,7 @@ "subscriber": "подписчик", "subscriber_rp": "подписчика", "subscribers": "подписчиков", + "subscribing...": "Подписка...", "terms of use": "правилами пользования сайтом", "today": "сегодня", "topics": "темы", diff --git a/src/pages/profile/Settings.module.scss b/src/pages/profile/Settings.module.scss index 1bdb7520..4553b827 100644 --- a/src/pages/profile/Settings.module.scss +++ b/src/pages/profile/Settings.module.scss @@ -216,6 +216,62 @@ h5 { } } +.userpic { + @include font-size(1.2rem); + + position: relative; + width: 180px; + height: 180px; + border-radius: 50%; + overflow: hidden; + display: flex; + align-items: center; + justify-content: center; + flex-direction: column; + text-align: center; + gap: 1rem; + color: var(--black-300); + border: 1px solid var(--black-100); + cursor: pointer; + + img { + width: 100%; + border-radius: 50%; + } + + &.hasControls { + overflow: visible; + } + + .controls { + position: absolute; + right: -50px; + display: flex; + flex-direction: column; + gap: 1rem; + } + + .control { + width: 40px; + height: 40px; + border-radius: 50%; + background: var(--background-color); + border: 1px solid var(--black-100); + + img { + border-radius: unset; + } + + &:hover { + background: var(--background-color-invert); + + img { + filter: invert(1); + } + } + } +} + .socialInput { margin-top: 1rem; } diff --git a/src/pages/profile/profileSettings.page.tsx b/src/pages/profile/profileSettings.page.tsx index dccc7cc6..991892c7 100644 --- a/src/pages/profile/profileSettings.page.tsx +++ b/src/pages/profile/profileSettings.page.tsx @@ -1,6 +1,6 @@ import { PageLayout } from '../../components/_shared/PageLayout' import { ProfileSettingsNavigation } from '../../components/Nav/ProfileSettingsNavigation' -import { For, createSignal, Show, onMount, onCleanup, createEffect } from 'solid-js' +import { For, createSignal, Show, onMount, onCleanup, createEffect, Switch, Match } from 'solid-js' import deepEqual from 'fast-deep-equal' import { clsx } from 'clsx' import styles from './Settings.module.scss' @@ -20,6 +20,10 @@ import { AuthGuard } from '../../components/AuthGuard' import { handleImageUpload } from '../../utils/handleImageUpload' import { SocialNetworkInput } from '../../components/_shared/SocialNetworkInput' import { profileSocialLinks } from '../../utils/profileSocialLinks' +import { Icon } from '../../components/_shared/Icon' +import { Popover } from '../../components/_shared/Popover' +import { Image } from '../../components/_shared/Image' +import { Loading } from '../../components/_shared/Loading' export const ProfileSettingsPage = () => { const { t } = useLocalize() @@ -65,7 +69,7 @@ export const ProfileSettingsPage = () => { const { selectFiles } = createFileUploader({ multiple: false, accept: 'image/*' }) - const handleAvatarClick = async () => { + const handleUploadAvatar = async () => { selectFiles(async ([uploadFile]) => { try { setUploadError(false) @@ -136,14 +140,48 @@ export const ProfileSettingsPage = () => {

    {t('Here you can customize your profile the way you want.')}

    {t('Userpic')}

    -
    - +
    +
    + + + + + + {form.name} +
    + + {(triggerRef: (el) => void) => ( + + )} + + + {(triggerRef: (el) => void) => ( + + )} + +
    +
    + + + {t('Here you can upload your photo')} + +
    +
    {t('Upload error')}
    From 301fa4293c31c52a53ffc3eca57ef83210cccdf4 Mon Sep 17 00:00:00 2001 From: ilya-bkv Date: Mon, 13 Nov 2023 17:54:22 +0300 Subject: [PATCH 089/129] Add headers --- api/ssr.mjs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/api/ssr.mjs b/api/ssr.mjs index 0d471d1f..1c1817b8 100644 --- a/api/ssr.mjs +++ b/api/ssr.mjs @@ -1,5 +1,8 @@ import { renderPage } from 'vike/server' +export const config = { + runtime: 'edge' +} export default async function handler(req, res) { const { url, cookies } = req @@ -23,5 +26,6 @@ export default async function handler(req, res) { const { body, statusCode, contentType } = httpResponse res.statusCode = statusCode res.setHeader('Content-Type', contentType) + res.setHeader('Cache-Control', 's-maxage=1, stale-while-revalidate') res.end(body) } From 9b036b42599a3e7d59b9c7dfc31a2852765f4d05 Mon Sep 17 00:00:00 2001 From: ilya-bkv Date: Mon, 13 Nov 2023 18:01:04 +0300 Subject: [PATCH 090/129] revert runtime: 'edge' --- api/ssr.mjs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/api/ssr.mjs b/api/ssr.mjs index 1c1817b8..a8e82a7f 100644 --- a/api/ssr.mjs +++ b/api/ssr.mjs @@ -1,8 +1,8 @@ import { renderPage } from 'vike/server' -export const config = { - runtime: 'edge' -} +// export const config = { +// runtime: 'edge' +// } export default async function handler(req, res) { const { url, cookies } = req From a25255b02d07415255560345f5a392fdbb7498c9 Mon Sep 17 00:00:00 2001 From: ilya-bkv Date: Mon, 13 Nov 2023 18:10:39 +0300 Subject: [PATCH 091/129] test setHeader --- api/ssr.mjs | 1 + 1 file changed, 1 insertion(+) diff --git a/api/ssr.mjs b/api/ssr.mjs index a8e82a7f..051d583d 100644 --- a/api/ssr.mjs +++ b/api/ssr.mjs @@ -27,5 +27,6 @@ export default async function handler(req, res) { res.statusCode = statusCode res.setHeader('Content-Type', contentType) res.setHeader('Cache-Control', 's-maxage=1, stale-while-revalidate') + res.setHeader('Test', 'test=1') res.end(body) } From ecc1b8feecb1af9b7b09d042534b9361537362c9 Mon Sep 17 00:00:00 2001 From: ilya-bkv Date: Mon, 13 Nov 2023 18:29:46 +0300 Subject: [PATCH 092/129] test import --- api/ssr.mjs | 6 +++--- .../_shared/SolidSwiper/ArticleCardSwiper.tsx | 11 ++--------- src/components/_shared/SolidSwiper/ImageSwiper.tsx | 2 +- 3 files changed, 6 insertions(+), 13 deletions(-) diff --git a/api/ssr.mjs b/api/ssr.mjs index 051d583d..6e0c7e21 100644 --- a/api/ssr.mjs +++ b/api/ssr.mjs @@ -1,8 +1,8 @@ import { renderPage } from 'vike/server' -// export const config = { -// runtime: 'edge' -// } +export const config = { + runtime: 'edge' +} export default async function handler(req, res) { const { url, cookies } = req diff --git a/src/components/_shared/SolidSwiper/ArticleCardSwiper.tsx b/src/components/_shared/SolidSwiper/ArticleCardSwiper.tsx index bbfec7a1..82dd8492 100644 --- a/src/components/_shared/SolidSwiper/ArticleCardSwiper.tsx +++ b/src/components/_shared/SolidSwiper/ArticleCardSwiper.tsx @@ -1,6 +1,6 @@ -import { createSignal, For, Show } from 'solid-js' +import { For, Show } from 'solid-js' import { Icon } from '../Icon' -import { register } from 'swiper/element/bundle' +import { register } from 'swiper/element' import SwiperCore, { Manipulation, Navigation, Pagination } from 'swiper' import { SwiperRef } from './swiper' import { clsx } from 'clsx' @@ -18,14 +18,8 @@ register() SwiperCore.use([Pagination, Navigation, Manipulation]) export const ArticleCardSwiper = (props: Props) => { - const [slideIndex, setSlideIndex] = createSignal(0) - const mainSwipeRef: { current: SwiperRef } = { current: null } - const handleSlideChange = () => { - setSlideIndex(mainSwipeRef.current.swiper.activeIndex) - } - return (
    @@ -38,7 +32,6 @@ export const ArticleCardSwiper = (props: Props) => { ref={(el) => (mainSwipeRef.current = el)} centered-slides={true} observer={true} - onSlideChange={handleSlideChange} space-between={20} breakpoints={{ 576: { spaceBetween: 20, slidesPerView: 1.5 }, diff --git a/src/components/_shared/SolidSwiper/ImageSwiper.tsx b/src/components/_shared/SolidSwiper/ImageSwiper.tsx index 8b3a497c..8d51db03 100644 --- a/src/components/_shared/SolidSwiper/ImageSwiper.tsx +++ b/src/components/_shared/SolidSwiper/ImageSwiper.tsx @@ -3,7 +3,7 @@ import { MediaItem, UploadedFile } from '../../../pages/types' import { Icon } from '../Icon' import { Popover } from '../Popover' import { useLocalize } from '../../../context/localize' -import { register } from 'swiper/element/bundle' +import { register } from 'swiper/element' import { DropArea } from '../DropArea' import { createFileUploader } from '@solid-primitives/upload' import SwiperCore, { Manipulation, Navigation, Pagination } from 'swiper' From 0466eef16b748c33fa236d4ed3b81489efef2b45 Mon Sep 17 00:00:00 2001 From: ilya-bkv Date: Mon, 13 Nov 2023 18:35:07 +0300 Subject: [PATCH 093/129] test onMount --- .../_shared/SolidSwiper/ArticleCardSwiper.tsx | 13 ++++++------- src/components/_shared/SolidSwiper/ImageSwiper.tsx | 13 +++++++------ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/components/_shared/SolidSwiper/ArticleCardSwiper.tsx b/src/components/_shared/SolidSwiper/ArticleCardSwiper.tsx index 82dd8492..645abcb9 100644 --- a/src/components/_shared/SolidSwiper/ArticleCardSwiper.tsx +++ b/src/components/_shared/SolidSwiper/ArticleCardSwiper.tsx @@ -1,6 +1,6 @@ -import { For, Show } from 'solid-js' +import { For, onMount, Show } from 'solid-js' import { Icon } from '../Icon' -import { register } from 'swiper/element' +import { register } from 'swiper/element/bundle' import SwiperCore, { Manipulation, Navigation, Pagination } from 'swiper' import { SwiperRef } from './swiper' import { clsx } from 'clsx' @@ -13,13 +13,12 @@ type Props = { title?: string } -register() - -SwiperCore.use([Pagination, Navigation, Manipulation]) - export const ArticleCardSwiper = (props: Props) => { const mainSwipeRef: { current: SwiperRef } = { current: null } - + onMount(() => { + register() + SwiperCore.use([Pagination, Navigation, Manipulation]) + }) return (
    diff --git a/src/components/_shared/SolidSwiper/ImageSwiper.tsx b/src/components/_shared/SolidSwiper/ImageSwiper.tsx index 8d51db03..23a9f623 100644 --- a/src/components/_shared/SolidSwiper/ImageSwiper.tsx +++ b/src/components/_shared/SolidSwiper/ImageSwiper.tsx @@ -1,9 +1,9 @@ -import { createEffect, createSignal, For, Show, on } from 'solid-js' +import { createEffect, createSignal, For, Show, on, onMount } from 'solid-js' import { MediaItem, UploadedFile } from '../../../pages/types' import { Icon } from '../Icon' import { Popover } from '../Popover' import { useLocalize } from '../../../context/localize' -import { register } from 'swiper/element' +import { register } from 'swiper/element/bundle' import { DropArea } from '../DropArea' import { createFileUploader } from '@solid-primitives/upload' import SwiperCore, { Manipulation, Navigation, Pagination } from 'swiper' @@ -28,10 +28,6 @@ type Props = { onImageChange?: (index: number, value: MediaItem) => void } -register() - -SwiperCore.use([Pagination, Navigation, Manipulation]) - export const ImageSwiper = (props: Props) => { const { t } = useLocalize() const [loading, setLoading] = createSignal(false) @@ -139,6 +135,11 @@ export const ImageSwiper = (props: Props) => { handleSlideDescriptionChange(slideIndex(), 'body', slideBody()) } + onMount(() => { + register() + SwiperCore.use([Pagination, Navigation, Manipulation]) + }) + return (
    From 8ac7b104a802a4026042bbcede747452bebcdcbf Mon Sep 17 00:00:00 2001 From: Igor Lobanov Date: Mon, 13 Nov 2023 16:46:23 +0100 Subject: [PATCH 094/129] async swiper load --- src/components/_shared/SolidSwiper/ArticleCardSwiper.tsx | 5 +++-- src/components/_shared/SolidSwiper/ImageSwiper.tsx | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/components/_shared/SolidSwiper/ArticleCardSwiper.tsx b/src/components/_shared/SolidSwiper/ArticleCardSwiper.tsx index 645abcb9..8020c91b 100644 --- a/src/components/_shared/SolidSwiper/ArticleCardSwiper.tsx +++ b/src/components/_shared/SolidSwiper/ArticleCardSwiper.tsx @@ -1,6 +1,6 @@ import { For, onMount, Show } from 'solid-js' import { Icon } from '../Icon' -import { register } from 'swiper/element/bundle' + import SwiperCore, { Manipulation, Navigation, Pagination } from 'swiper' import { SwiperRef } from './swiper' import { clsx } from 'clsx' @@ -15,7 +15,8 @@ type Props = { export const ArticleCardSwiper = (props: Props) => { const mainSwipeRef: { current: SwiperRef } = { current: null } - onMount(() => { + onMount(async () => { + const { register } = await import('swiper/element/bundle') register() SwiperCore.use([Pagination, Navigation, Manipulation]) }) diff --git a/src/components/_shared/SolidSwiper/ImageSwiper.tsx b/src/components/_shared/SolidSwiper/ImageSwiper.tsx index 23a9f623..d22c5196 100644 --- a/src/components/_shared/SolidSwiper/ImageSwiper.tsx +++ b/src/components/_shared/SolidSwiper/ImageSwiper.tsx @@ -3,7 +3,6 @@ import { MediaItem, UploadedFile } from '../../../pages/types' import { Icon } from '../Icon' import { Popover } from '../Popover' import { useLocalize } from '../../../context/localize' -import { register } from 'swiper/element/bundle' import { DropArea } from '../DropArea' import { createFileUploader } from '@solid-primitives/upload' import SwiperCore, { Manipulation, Navigation, Pagination } from 'swiper' @@ -135,7 +134,8 @@ export const ImageSwiper = (props: Props) => { handleSlideDescriptionChange(slideIndex(), 'body', slideBody()) } - onMount(() => { + onMount(async () => { + const { register } = await import('swiper/element/bundle') register() SwiperCore.use([Pagination, Navigation, Manipulation]) }) From e82beb868ae769c7f28df3c878cf7ea6b25e655e Mon Sep 17 00:00:00 2001 From: Igor Lobanov Date: Mon, 13 Nov 2023 16:55:36 +0100 Subject: [PATCH 095/129] just-throttle and debounce replaced with throttle-debounce --- package-lock.json | 25 +++++++++++-------- package.json | 3 +-- .../NotificationsPanel/NotificationsPanel.tsx | 4 +-- .../TableOfContents/TableOfContents.tsx | 9 +++---- 4 files changed, 21 insertions(+), 20 deletions(-) diff --git a/package-lock.json b/package-lock.json index 809a2792..b1a5125b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,7 +13,6 @@ "i18next": "22.4.15", "i18next-icu": "2.3.0", "intl-messageformat": "10.5.3", - "just-throttle": "4.2.0", "mailgun.js": "8.2.1" }, "devDependencies": { @@ -76,7 +75,6 @@ "bootstrap": "5.3.2", "clsx": "2.0.0", "cross-env": "7.0.3", - "debounce": "1.2.1", "eslint": "8.53.0", "eslint-config-stylelint": "20.0.0", "eslint-import-resolver-typescript": "3.6.1", @@ -123,6 +121,7 @@ "stylelint-order": "6.0.3", "stylelint-scss": "5.3.0", "swiper": "9.4.1", + "throttle-debounce": "5.0.0", "typescript": "5.2.2", "typograf": "7.1.0", "uniqolor": "1.1.0", @@ -5102,6 +5101,15 @@ "throttle-debounce": "^3.0.1" } }, + "node_modules/@remirror/core-helpers/node_modules/throttle-debounce": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-3.0.1.tgz", + "integrity": "sha512-dTEWWNu6JmeVXY0ZYoPuH5cRIwc0MeGbJwah9KUNYSJwommQpCzTySTpEe8Gs1J23aeWEuAobe4Ag7EHVt/LOg==", + "dev": true, + "engines": { + "node": ">=10" + } + }, "node_modules/@remirror/types": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@remirror/types/-/types-1.0.1.tgz", @@ -13946,11 +13954,6 @@ "node": ">=4.0" } }, - "node_modules/just-throttle": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/just-throttle/-/just-throttle-4.2.0.tgz", - "integrity": "sha512-/iAZv1953JcExpvsywaPKjSzfTiCLqeguUTE6+VmK15mOcwxBx7/FHrVvS4WEErMR03TRazH8kcBSHqMagYIYg==" - }, "node_modules/kebab-case": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/kebab-case/-/kebab-case-1.0.2.tgz", @@ -18252,12 +18255,12 @@ "dev": true }, "node_modules/throttle-debounce": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-3.0.1.tgz", - "integrity": "sha512-dTEWWNu6JmeVXY0ZYoPuH5cRIwc0MeGbJwah9KUNYSJwommQpCzTySTpEe8Gs1J23aeWEuAobe4Ag7EHVt/LOg==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-5.0.0.tgz", + "integrity": "sha512-2iQTSgkkc1Zyk0MeVrt/3BvuOXYPl/R8Z0U2xxo9rjwNciaHDG3R+Lm6dh4EeUci49DanvBnuqI6jshoQQRGEg==", "dev": true, "engines": { - "node": ">=10" + "node": ">=12.22" } }, "node_modules/through": { diff --git a/package.json b/package.json index 6abc61e1..0378a2b7 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,6 @@ "i18next": "22.4.15", "i18next-icu": "2.3.0", "intl-messageformat": "10.5.3", - "just-throttle": "4.2.0", "mailgun.js": "8.2.1" }, "devDependencies": { @@ -97,7 +96,6 @@ "bootstrap": "5.3.2", "clsx": "2.0.0", "cross-env": "7.0.3", - "debounce": "1.2.1", "eslint": "8.53.0", "eslint-config-stylelint": "20.0.0", "eslint-import-resolver-typescript": "3.6.1", @@ -144,6 +142,7 @@ "stylelint-order": "6.0.3", "stylelint-scss": "5.3.0", "swiper": "9.4.1", + "throttle-debounce": "5.0.0", "typescript": "5.2.2", "typograf": "7.1.0", "uniqolor": "1.1.0", diff --git a/src/components/NotificationsPanel/NotificationsPanel.tsx b/src/components/NotificationsPanel/NotificationsPanel.tsx index 2618895f..30619e70 100644 --- a/src/components/NotificationsPanel/NotificationsPanel.tsx +++ b/src/components/NotificationsPanel/NotificationsPanel.tsx @@ -9,7 +9,7 @@ import { PAGE_SIZE, useNotifications } from '../../context/notifications' import { NotificationView } from './NotificationView' import { EmptyMessage } from './EmptyMessage' import { Button } from '../_shared/Button' -import throttle from 'just-throttle' +import { throttle } from 'throttle-debounce' import { useSession } from '../../context/session' type Props = { @@ -132,7 +132,7 @@ export const NotificationsPanel = (props: Props) => { setIsLoading(false) } } - const handleScrollThrottled = throttle(handleScroll, 50) + const handleScrollThrottled = throttle(50, handleScroll) onMount(() => { scrollContainerRef.current.addEventListener('scroll', handleScrollThrottled) diff --git a/src/components/TableOfContents/TableOfContents.tsx b/src/components/TableOfContents/TableOfContents.tsx index 1efcdd4e..d35601e9 100644 --- a/src/components/TableOfContents/TableOfContents.tsx +++ b/src/components/TableOfContents/TableOfContents.tsx @@ -2,11 +2,10 @@ import { For, Show, createSignal, createEffect, on, onMount, onCleanup } from 's import { clsx } from 'clsx' import { DEFAULT_HEADER_OFFSET } from '../../stores/router' import { useLocalize } from '../../context/localize' -import debounce from 'debounce' import { Icon } from '../_shared/Icon' import styles from './TableOfContents.module.scss' import { isDesktop } from '../../utils/media-query' -import throttle from 'just-throttle' +import { throttle, debounce } from 'throttle-debounce' interface Props { variant: 'article' | 'editor' @@ -49,12 +48,12 @@ export const TableOfContents = (props: Props) => { setAreHeadingsLoaded(true) } - const debouncedUpdateHeadings = debounce(updateHeadings, 500) + const debouncedUpdateHeadings = debounce(500, updateHeadings) - const updateActiveHeader = throttle(() => { + const updateActiveHeader = throttle(50, () => { const newActiveIndex = headings().findLastIndex((heading) => isInViewport(heading)) setActiveHeaderIndex(newActiveIndex) - }, 50) + }) createEffect( on( From 6da2e4f0e5112e5de90d351769a4b4a490c12c04 Mon Sep 17 00:00:00 2001 From: Igor Lobanov Date: Mon, 13 Nov 2023 17:48:04 +0100 Subject: [PATCH 096/129] html-to-json-parser removed --- .eslintrc.cjs | 1 + package-lock.json | 19 ------------------- package.json | 1 - .../EditorFloatingMenu/EditorFloatingMenu.tsx | 18 ++++++++++++------ 4 files changed, 13 insertions(+), 26 deletions(-) diff --git a/.eslintrc.cjs b/.eslintrc.cjs index e124309e..19c2c453 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -66,6 +66,7 @@ module.exports = { 'unicorn/consistent-function-scoping': 'warn', 'unicorn/no-array-callback-reference': 'warn', 'unicorn/no-array-method-this-argument': 'warn', + 'unicorn/no-for-loop': 'off', 'sonarjs/no-duplicate-string': ['warn', { threshold: 5 }], diff --git a/package-lock.json b/package-lock.json index b1a5125b..d84a4e43 100644 --- a/package-lock.json +++ b/package-lock.json @@ -88,7 +88,6 @@ "fast-deep-equal": "3.1.3", "graphql": "16.6.0", "graphql-tag": "2.12.6", - "html-to-json-parser": "1.1.0", "husky": "8.0.3", "hygen": "6.2.11", "i18next-http-backend": "2.2.0", @@ -10657,15 +10656,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/html-to-json-parser": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/html-to-json-parser/-/html-to-json-parser-1.1.0.tgz", - "integrity": "sha512-j6JiUBhIQkC+guahmh0VKwQRrnsROpUaRWAQyRlu5tp6atQg9ljeU70eBtpHSJwNALFNo//VOozvif7AQlfOtA==", - "dev": true, - "dependencies": { - "xmldom": "^0.6.0" - } - }, "node_modules/htmlparser2": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", @@ -19702,15 +19692,6 @@ } } }, - "node_modules/xmldom": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.6.0.tgz", - "integrity": "sha512-iAcin401y58LckRZ0TkI4k0VSM1Qg0KGSc3i8rU+xrxe19A/BN1zHyVSJY7uoutVlaTSzYyk/v5AmkewAP7jtg==", - "dev": true, - "engines": { - "node": ">=10.0.0" - } - }, "node_modules/y-prosemirror": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/y-prosemirror/-/y-prosemirror-1.2.1.tgz", diff --git a/package.json b/package.json index 0378a2b7..080e97c6 100644 --- a/package.json +++ b/package.json @@ -109,7 +109,6 @@ "fast-deep-equal": "3.1.3", "graphql": "16.6.0", "graphql-tag": "2.12.6", - "html-to-json-parser": "1.1.0", "husky": "8.0.3", "hygen": "6.2.11", "i18next-http-backend": "2.2.0", diff --git a/src/components/Editor/EditorFloatingMenu/EditorFloatingMenu.tsx b/src/components/Editor/EditorFloatingMenu/EditorFloatingMenu.tsx index cae2606c..3c03dfce 100644 --- a/src/components/Editor/EditorFloatingMenu/EditorFloatingMenu.tsx +++ b/src/components/Editor/EditorFloatingMenu/EditorFloatingMenu.tsx @@ -3,7 +3,6 @@ import type { Editor, JSONContent } from '@tiptap/core' import { Icon } from '../../_shared/Icon' import { InlineForm } from '../InlineForm' import styles from './EditorFloatingMenu.module.scss' -import HTMLParser from 'html-to-json-parser' import { useLocalize } from '../../../context/localize' import { Modal } from '../../Nav/Modal' import { Menu } from './Menu' @@ -20,10 +19,17 @@ type FloatingMenuProps = { } const embedData = async (data) => { - const result = (await HTMLParser(data, false)) as JSONContent - if ('type' in result && result.type === 'iframe') { - return result.attributes + const element = document.createRange().createContextualFragment(data) + const { attributes } = element.firstChild as HTMLIFrameElement + + const result: { src: string } = { src: '' } + + for (let i = 0; i < attributes.length; i++) { + const attribute = attributes[i] + result[attribute.name] = attribute.value } + + return result } export const EditorFloatingMenu = (props: FloatingMenuProps) => { @@ -39,8 +45,8 @@ export const EditorFloatingMenu = (props: FloatingMenuProps) => { } const validateEmbed = async (value) => { - const iframeData = (await HTMLParser(value, false)) as JSONContent - if (iframeData.type !== 'iframe') { + const element = document.createRange().createContextualFragment(value) + if (element.firstChild?.nodeName !== 'IFRAME') { return t('Error') } } From 80a9a4c9a55c08f254c2a2fd2d84e7ef03a77cad Mon Sep 17 00:00:00 2001 From: Ilya Y <75578537+ilya-bkv@users.noreply.github.com> Date: Mon, 13 Nov 2023 19:55:32 +0300 Subject: [PATCH 097/129] Update lightbox (#313) update_lightbox --- src/components/Article/Article.module.scss | 14 ++++---------- src/components/Article/FullArticle.tsx | 15 +++++++-------- .../_shared/Lightbox/Lightbox.module.scss | 6 ++++-- src/components/_shared/Lightbox/Lightbox.tsx | 8 +++++++- src/pages/profile/Settings.module.scss | 8 ++++++-- src/pages/profile/profileSettings.page.tsx | 11 ++++++++++- 6 files changed, 38 insertions(+), 24 deletions(-) diff --git a/src/components/Article/Article.module.scss b/src/components/Article/Article.module.scss index ed15b000..d2bc419d 100644 --- a/src/components/Article/Article.module.scss +++ b/src/components/Article/Article.module.scss @@ -23,22 +23,16 @@ img { } } -.shoutCover { - background-size: cover; - height: 0; - padding-bottom: 56.2%; +.articleContent { + img { + cursor: zoom-in; + } } .shoutBody { font-size: 1.6rem; line-height: 1.6; - img { - display: block; - margin-bottom: 0.5em; - cursor: zoom-in; - } - blockquote, blockquote[data-type='punchline'] { clear: both; diff --git a/src/components/Article/FullArticle.tsx b/src/components/Article/FullArticle.tsx index 39586bb4..ed19fece 100644 --- a/src/components/Article/FullArticle.tsx +++ b/src/components/Article/FullArticle.tsx @@ -28,6 +28,7 @@ import { AuthorBadge } from '../Author/AuthorBadge' import { getImageUrl } from '../../utils/getImageUrl' import { FeedArticlePopup } from '../Feed/FeedArticlePopup' import { Lightbox } from '../_shared/Lightbox' +import { Image } from '../_shared/Image' type Props = { article: Shout @@ -252,7 +253,10 @@ export const FullArticle = (props: Props) => { {props.article.title}
    -
    +
    {/*TODO: Check styles.shoutTopic*/}
    @@ -282,12 +286,7 @@ export const FullArticle = (props: Props) => { props.article.layout !== 'image' } > -
    + {props.article.title}
    @@ -328,7 +327,7 @@ export const FullArticle = (props: Props) => { -
    +
    }> diff --git a/src/components/_shared/Lightbox/Lightbox.module.scss b/src/components/_shared/Lightbox/Lightbox.module.scss index 834c8750..67075ab9 100644 --- a/src/components/_shared/Lightbox/Lightbox.module.scss +++ b/src/components/_shared/Lightbox/Lightbox.module.scss @@ -17,7 +17,8 @@ } .close { - position: absolute; + position: fixed; + z-index: 1001; top: 20px; right: 40px; font-size: 30px; @@ -29,12 +30,13 @@ .zoomControls { display: flex; - position: absolute; + position: fixed; bottom: 16px; left: 50%; height: 24px; gap: 1rem; transform: translateX(-50%); + z-index: 1001; .control { border-radius: 50%; diff --git a/src/components/_shared/Lightbox/Lightbox.tsx b/src/components/_shared/Lightbox/Lightbox.tsx index a90bf219..a9dee711 100644 --- a/src/components/_shared/Lightbox/Lightbox.tsx +++ b/src/components/_shared/Lightbox/Lightbox.tsx @@ -1,7 +1,8 @@ import { clsx } from 'clsx' import styles from './Lightbox.module.scss' -import { createSignal } from 'solid-js' +import { createSignal, onCleanup, onMount } from 'solid-js' import { Icon } from '../Icon' +import { useEscKeyDownHandler } from '../../../utils/useEscKeyDownHandler' type Props = { class?: string @@ -31,6 +32,8 @@ export const Lightbox = (props: Props) => { transition: 'transform 0.3s ease' }) + useEscKeyDownHandler(closeLightbox) + return (
    @@ -40,6 +43,9 @@ export const Lightbox = (props: Props) => { + diff --git a/src/pages/profile/Settings.module.scss b/src/pages/profile/Settings.module.scss index 4553b827..50473218 100644 --- a/src/pages/profile/Settings.module.scss +++ b/src/pages/profile/Settings.module.scss @@ -234,9 +234,12 @@ h5 { border: 1px solid var(--black-100); cursor: pointer; - img { - width: 100%; + .userpicImage { + width: 180px; + height: 180px; border-radius: 50%; + background-position: center; + background-size: contain; } &.hasControls { @@ -254,6 +257,7 @@ h5 { .control { width: 40px; height: 40px; + padding: 10px; border-radius: 50%; background: var(--background-color); border: 1px solid var(--black-100); diff --git a/src/pages/profile/profileSettings.page.tsx b/src/pages/profile/profileSettings.page.tsx index 991892c7..9eef5ad6 100644 --- a/src/pages/profile/profileSettings.page.tsx +++ b/src/pages/profile/profileSettings.page.tsx @@ -24,6 +24,7 @@ import { Icon } from '../../components/_shared/Icon' import { Popover } from '../../components/_shared/Popover' import { Image } from '../../components/_shared/Image' import { Loading } from '../../components/_shared/Loading' +import { getImageUrl } from '../../utils/getImageUrl' export const ProfileSettingsPage = () => { const { t } = useLocalize() @@ -150,7 +151,15 @@ export const ProfileSettingsPage = () => { - {form.name} +
    {(triggerRef: (el) => void) => ( From 6d0efd09a3b81ab23853aee839e3eaa0e7c3f37d Mon Sep 17 00:00:00 2001 From: Igor Lobanov Date: Mon, 13 Nov 2023 18:14:58 +0100 Subject: [PATCH 098/129] markdown support dropped --- package.json | 5 ---- .../Article/AudioPlayer/PlayerPlaylist.tsx | 5 ++-- src/components/Article/Comment/Comment.tsx | 3 +-- src/components/Article/FullArticle.tsx | 7 ++---- src/components/Article/MD.tsx | 24 ------------------- src/pages/profile/profileSettings.page.tsx | 1 - 6 files changed, 5 insertions(+), 40 deletions(-) delete mode 100644 src/components/Article/MD.tsx diff --git a/package.json b/package.json index 080e97c6..2f5c90e0 100644 --- a/package.json +++ b/package.json @@ -118,11 +118,6 @@ "lint-staged": "15.0.2", "loglevel": "1.8.1", "loglevel-plugin-prefix": "0.8.4", - "markdown-it": "13.0.1", - "markdown-it-container": "3.0.0", - "markdown-it-implicit-figures": "0.11.0", - "markdown-it-mark": "3.0.1", - "markdown-it-replace-link": "1.2.0", "nanostores": "0.7.4", "prettier": "3.0.3", "prettier-eslint": "16.1.2", diff --git a/src/components/Article/AudioPlayer/PlayerPlaylist.tsx b/src/components/Article/AudioPlayer/PlayerPlaylist.tsx index 7ce74f36..7f456f8b 100644 --- a/src/components/Article/AudioPlayer/PlayerPlaylist.tsx +++ b/src/components/Article/AudioPlayer/PlayerPlaylist.tsx @@ -6,7 +6,6 @@ import { Popover } from '../../_shared/Popover' import { Icon } from '../../_shared/Icon' import styles from './AudioPlayer.module.scss' import { GrowingTextarea } from '../../_shared/GrowingTextarea' -import MD from '../MD' import { MediaItem } from '../../../pages/types' import SimplifiedEditor from '../../Editor/SimplifiedEditor' @@ -146,12 +145,12 @@ export const PlayerPlaylist = (props: Props) => {
    - +
    - +
    diff --git a/src/components/Article/Comment/Comment.tsx b/src/components/Article/Comment/Comment.tsx index dc43c7ee..4bb7bc2f 100644 --- a/src/components/Article/Comment/Comment.tsx +++ b/src/components/Article/Comment/Comment.tsx @@ -2,7 +2,6 @@ import { Show, createMemo, createSignal, For, lazy, Suspense } from 'solid-js' import { clsx } from 'clsx' import { getPagePath } from '@nanostores/router' -import MD from '../MD' import { Userpic } from '../../Author/Userpic' import { CommentRatingControl } from '../CommentRatingControl' import { CommentDate } from '../CommentDate' @@ -171,7 +170,7 @@ export const Comment = (props: Props) => {
    - }> + }> {t('Loading')}

    }> { description={m.body} /> - +
    )} @@ -329,9 +328,7 @@ export const FullArticle = (props: Props) => {
    - }> - - +
    diff --git a/src/components/Article/MD.tsx b/src/components/Article/MD.tsx deleted file mode 100644 index 4dd6cd9c..00000000 --- a/src/components/Article/MD.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import MD from 'markdown-it' -import mdfig from 'markdown-it-implicit-figures' -import mdmark from 'markdown-it-mark' -import mdcustom from 'markdown-it-container' -import mdlinks from 'markdown-it-replace-link' -import { createMemo } from 'solid-js' - -const mit = MD({ - html: true, - linkify: true, - typographer: true -}) -mit.use(mdmark) -mit.use(mdcustom) -mit.use(mdfig, { - dataType: false, //
    - figcaption: true //
    alternative text
    -}) -mit.use(mdlinks) - -export default (props: { body: string }) => { - const body = createMemo(() => (props.body.startsWith('<') ? props.body : mit.render(props.body))) - return
    -} diff --git a/src/pages/profile/profileSettings.page.tsx b/src/pages/profile/profileSettings.page.tsx index 991892c7..fc1c51cb 100644 --- a/src/pages/profile/profileSettings.page.tsx +++ b/src/pages/profile/profileSettings.page.tsx @@ -11,7 +11,6 @@ import { useSession } from '../../context/session' import FloatingPanel from '../../components/_shared/FloatingPanel/FloatingPanel' import { useSnackbar } from '../../context/snackbar' import { useLocalize } from '../../context/localize' -import { Userpic } from '../../components/Author/Userpic' import { createStore } from 'solid-js/store' import { clone } from '../../utils/clone' import SimplifiedEditor from '../../components/Editor/SimplifiedEditor' From ffea32f0aba8ba59139ae9003d97362d0f695f88 Mon Sep 17 00:00:00 2001 From: Igor Lobanov Date: Mon, 13 Nov 2023 18:38:10 +0100 Subject: [PATCH 099/129] package-lock.json --- package-lock.json | 183 ++++++---------------------------------------- 1 file changed, 24 insertions(+), 159 deletions(-) diff --git a/package-lock.json b/package-lock.json index d84a4e43..573e7d43 100644 --- a/package-lock.json +++ b/package-lock.json @@ -97,11 +97,6 @@ "lint-staged": "15.0.2", "loglevel": "1.8.1", "loglevel-plugin-prefix": "0.8.4", - "markdown-it": "13.0.1", - "markdown-it-container": "3.0.0", - "markdown-it-implicit-figures": "0.11.0", - "markdown-it-mark": "3.0.1", - "markdown-it-replace-link": "1.2.0", "nanostores": "0.7.4", "prettier": "3.0.3", "prettier-eslint": "16.1.2", @@ -8294,78 +8289,6 @@ "node": ">=6.0.0" } }, - "node_modules/dom-serializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", - "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", - "dev": true, - "optional": true, - "dependencies": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.2", - "entities": "^4.2.0" - }, - "funding": { - "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" - } - }, - "node_modules/dom-serializer/node_modules/entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "dev": true, - "optional": true, - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/domelementtype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", - "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "optional": true - }, - "node_modules/domhandler": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", - "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", - "dev": true, - "optional": true, - "dependencies": { - "domelementtype": "^2.3.0" - }, - "engines": { - "node": ">= 4" - }, - "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" - } - }, - "node_modules/domutils": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", - "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", - "dev": true, - "optional": true, - "dependencies": { - "dom-serializer": "^2.0.0", - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3" - }, - "funding": { - "url": "https://github.com/fb55/domutils?sponsor=1" - } - }, "node_modules/dot-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", @@ -8419,9 +8342,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.579", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.579.tgz", - "integrity": "sha512-bJKvA+awBIzYR0xRced7PrQuRIwGQPpo6ZLP62GAShahU9fWpsNN2IP6BSP1BLDDSbxvBVRGAMWlvVVq3npmLA==", + "version": "1.4.581", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.581.tgz", + "integrity": "sha512-6uhqWBIapTJUxgPTCHH9sqdbxIMPt7oXl0VcAL1kOtlU6aECdcMncCrX5Z7sHQ/invtrC9jUQUef7+HhO8vVFw==", "dev": true }, "node_modules/emittery": { @@ -8473,6 +8396,7 @@ "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz", "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==", "dev": true, + "peer": true, "engines": { "node": ">=0.12" }, @@ -8565,9 +8489,9 @@ } }, "node_modules/es-module-lexer": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.3.1.tgz", - "integrity": "sha512-JUFAyicQV9mXc3YRxPnDlrfBKpqt6hUYzz9/boprUJHs4e4KVr3XwOF70doO6gwXUor6EWZJAyWAfKki84t20Q==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.4.1.tgz", + "integrity": "sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==", "dev": true }, "node_modules/es-set-tostringtag": { @@ -9108,9 +9032,9 @@ } }, "node_modules/eslint-plugin-n": { - "version": "16.3.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-16.3.0.tgz", - "integrity": "sha512-/XZLH5CUXGK3laz3xYFNza8ZxLCq8ZNW6MsVw5z3d5hc2AwZzi0fPiySFZHQTdVDOHGs2cGv91aqzWmgBdq2gQ==", + "version": "16.3.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-16.3.1.tgz", + "integrity": "sha512-w46eDIkxQ2FaTHcey7G40eD+FhTXOdKudDXPUO2n9WNcslze/i/HT2qJ3GXjHngYSGDISIgPNhwGtgoix4zeOw==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", @@ -9118,6 +9042,7 @@ "eslint-plugin-es-x": "^7.1.0", "get-tsconfig": "^4.7.0", "ignore": "^5.2.4", + "is-builtin-module": "^3.2.1", "is-core-module": "^2.12.1", "minimatch": "^3.1.2", "resolve": "^1.22.2", @@ -9801,9 +9726,9 @@ } }, "node_modules/flat-cache": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.1.1.tgz", - "integrity": "sha512-/qM2b3LUIaIgviBQovTLvijfyOQXPtSRnRK26ksj2J7rzPIecePUIpJsZ4T02Qg+xiAEKIs5K8dsHEd+VaKa/Q==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", "dev": true, "dependencies": { "flatted": "^3.2.9", @@ -9811,7 +9736,7 @@ "rimraf": "^3.0.2" }, "engines": { - "node": ">=12.0.0" + "node": "^10.12.0 || >=12.0.0" } }, "node_modules/flatted": { @@ -10656,39 +10581,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/htmlparser2": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", - "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", - "dev": true, - "funding": [ - "https://github.com/fb55/htmlparser2?sponsor=1", - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "optional": true, - "dependencies": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3", - "domutils": "^3.0.1", - "entities": "^4.4.0" - } - }, - "node_modules/htmlparser2/node_modules/entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "dev": true, - "optional": true, - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, "node_modules/http-proxy-agent": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.0.tgz", @@ -14063,6 +13955,7 @@ "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-4.0.1.tgz", "integrity": "sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw==", "dev": true, + "peer": true, "dependencies": { "uc.micro": "^1.0.1" } @@ -14978,10 +14871,11 @@ } }, "node_modules/markdown-it": { - "version": "13.0.1", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-13.0.1.tgz", - "integrity": "sha512-lTlxriVoy2criHP0JKRhO2VDG9c2ypWCsT237eDiLqi09rmbKoUetyGHq2uOIRoRS//kfoJckS0eUzzkDR+k2Q==", + "version": "13.0.2", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-13.0.2.tgz", + "integrity": "sha512-FtwnEuuK+2yVU7goGn/MJ0WBZMM9ZPgU9spqlFs7/A/pDIUNSOQZhUgOqYCficIuR2QaFnrt8LHqBWsbTAoI5w==", "dev": true, + "peer": true, "dependencies": { "argparse": "^2.0.1", "entities": "~3.0.1", @@ -14993,37 +14887,6 @@ "markdown-it": "bin/markdown-it.js" } }, - "node_modules/markdown-it-container": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/markdown-it-container/-/markdown-it-container-3.0.0.tgz", - "integrity": "sha512-y6oKTq4BB9OQuY/KLfk/O3ysFhB3IMYoIWhGJEidXt1NQFocFK2sA2t0NYZAMyMShAGL6x5OPIbrmXPIqaN9rw==", - "dev": true - }, - "node_modules/markdown-it-implicit-figures": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/markdown-it-implicit-figures/-/markdown-it-implicit-figures-0.11.0.tgz", - "integrity": "sha512-ed32u3O8pTEM3TKgeBTMKw8ce86L8u5L41CuLvGee3yevYOq+1BoxjI84m/f7RcUaATcKgXTgZwieadvOH4afg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/markdown-it-mark": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/markdown-it-mark/-/markdown-it-mark-3.0.1.tgz", - "integrity": "sha512-HyxjAu6BRsdt6Xcv6TKVQnkz/E70TdGXEFHRYBGLncRE9lBFwDNLVtFojKxjJWgJ+5XxUwLaHXy+2sGBbDn+4A==", - "dev": true - }, - "node_modules/markdown-it-replace-link": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/markdown-it-replace-link/-/markdown-it-replace-link-1.2.0.tgz", - "integrity": "sha512-tIsShJvQOYwTHjIPhE1SWo12HjOtpEqSQfVoApm3fuIkVcZrSE7zK3iW8kXcaJYasf8Ddf+VbH5fNXCzfejOrQ==", - "dev": true, - "optionalDependencies": { - "dom-serializer": "^2.0.0", - "htmlparser2": "^8.0.1" - } - }, "node_modules/mathml-tag-names": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz", @@ -15044,7 +14907,8 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==", - "dev": true + "dev": true, + "peer": true }, "node_modules/meow": { "version": "10.1.5", @@ -18567,7 +18431,8 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", - "dev": true + "dev": true, + "peer": true }, "node_modules/unbox-primitive": { "version": "1.0.2", From f2d7f1d895f1f9aae13c8fb74bb3f3e811394415 Mon Sep 17 00:00:00 2001 From: Igor Lobanov Date: Mon, 13 Nov 2023 18:58:30 +0100 Subject: [PATCH 100/129] test --- api/ssr.mjs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/api/ssr.mjs b/api/ssr.mjs index 6e0c7e21..4ece0f97 100644 --- a/api/ssr.mjs +++ b/api/ssr.mjs @@ -26,7 +26,6 @@ export default async function handler(req, res) { const { body, statusCode, contentType } = httpResponse res.statusCode = statusCode res.setHeader('Content-Type', contentType) - res.setHeader('Cache-Control', 's-maxage=1, stale-while-revalidate') - res.setHeader('Test', 'test=1') + // res.setHeader('Cache-Control', 's-maxage=1, stale-while-revalidate') res.end(body) } From 2465c835d457fe6ed1e0cf0832ee982a76fffb88 Mon Sep 17 00:00:00 2001 From: Igor Lobanov Date: Mon, 13 Nov 2023 19:15:38 +0100 Subject: [PATCH 101/129] test --- api/ssr.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/ssr.mjs b/api/ssr.mjs index 4ece0f97..1c1817b8 100644 --- a/api/ssr.mjs +++ b/api/ssr.mjs @@ -26,6 +26,6 @@ export default async function handler(req, res) { const { body, statusCode, contentType } = httpResponse res.statusCode = statusCode res.setHeader('Content-Type', contentType) - // res.setHeader('Cache-Control', 's-maxage=1, stale-while-revalidate') + res.setHeader('Cache-Control', 's-maxage=1, stale-while-revalidate') res.end(body) } From 9977d5482eb64089cc61997b632de9f0a102ef86 Mon Sep 17 00:00:00 2001 From: Igor Lobanov Date: Mon, 13 Nov 2023 19:25:11 +0100 Subject: [PATCH 102/129] test --- src/components/Nav/Snackbar.tsx | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/src/components/Nav/Snackbar.tsx b/src/components/Nav/Snackbar.tsx index 540e41bb..493124b9 100644 --- a/src/components/Nav/Snackbar.tsx +++ b/src/components/Nav/Snackbar.tsx @@ -4,6 +4,7 @@ import styles from './Snackbar.module.scss' import { Transition } from 'solid-transition-group' import { clsx } from 'clsx' import { Icon } from '../_shared/Icon' +import { isServer } from 'solid-js/web' export const Snackbar = () => { const { snackbarMessage } = useSnackbar() @@ -15,20 +16,22 @@ export const Snackbar = () => { [styles.success]: snackbarMessage()?.type === 'success' })} > - setTimeout(() => done(), 300)} - > - -
    - - - - {snackbarMessage().body} -
    -
    -
    + {!isServer && ( + setTimeout(() => done(), 300)} + > + +
    + + + + {snackbarMessage().body} +
    +
    +
    + )}
    ) } From 1a55a5bdb8877da8fbcb853e448dad699aba1584 Mon Sep 17 00:00:00 2001 From: kvakazyambra Date: Mon, 13 Nov 2023 21:28:21 +0300 Subject: [PATCH 103/129] Fixed error page style --- src/styles/FourOuFour.module.scss | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/styles/FourOuFour.module.scss b/src/styles/FourOuFour.module.scss index 09a87b79..683b078b 100644 --- a/src/styles/FourOuFour.module.scss +++ b/src/styles/FourOuFour.module.scss @@ -1,12 +1,11 @@ .errorPageWrapper { height: 100vh; - margin: -120px 0 -2em; - padding-top: 100px; + padding-top: 60px; } .errorPage { position: relative; - top: 35%; + top: 37%; transform: translateY(-50%); .image-link:hover { From b7d5260f8de61659b0ca4006cace0cf2ab7ad994 Mon Sep 17 00:00:00 2001 From: Igor Lobanov Date: Mon, 13 Nov 2023 19:32:23 +0100 Subject: [PATCH 104/129] testing-testing --- api/ssr.mjs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/api/ssr.mjs b/api/ssr.mjs index 1c1817b8..349cab37 100644 --- a/api/ssr.mjs +++ b/api/ssr.mjs @@ -23,9 +23,12 @@ export default async function handler(req, res) { return } - const { body, statusCode, contentType } = httpResponse + const { body, statusCode, headers } = httpResponse + + console.log('headers:', JSON.stringify(headers)) + res.statusCode = statusCode - res.setHeader('Content-Type', contentType) + res.setHeader('Content-Type', headers['Content-Type']) res.setHeader('Cache-Control', 's-maxage=1, stale-while-revalidate') res.end(body) } From 252d78b35deb2916617fbdb3395bdcd54a002623 Mon Sep 17 00:00:00 2001 From: kvakazyambra Date: Mon, 13 Nov 2023 21:37:19 +0300 Subject: [PATCH 105/129] Fixed swiper slide height --- src/components/Feed/ArticleCard/ArticleCard.module.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Feed/ArticleCard/ArticleCard.module.scss b/src/components/Feed/ArticleCard/ArticleCard.module.scss index 660df8ca..9ffcc750 100644 --- a/src/components/Feed/ArticleCard/ArticleCard.module.scss +++ b/src/components/Feed/ArticleCard/ArticleCard.module.scss @@ -403,7 +403,6 @@ } .shoutCardWithCover { - aspect-ratio: 16/9; width: 100%; @include media-breakpoint-down(xl) { @@ -413,6 +412,7 @@ } swiper-slide & { + aspect-ratio: 16/9; margin-bottom: 0; @include media-breakpoint-down(lg) { From 4d8e89201a20cdb75dada548c4befca0212f27bd Mon Sep 17 00:00:00 2001 From: Igor Lobanov Date: Mon, 13 Nov 2023 19:56:47 +0100 Subject: [PATCH 106/129] lint --- src/components/Article/Article.module.scss | 6 ++++-- src/components/Article/Comment/Comment.module.scss | 2 +- src/components/Author/AuthorBadge/AuthorBadge.tsx | 4 ++-- src/components/Author/AuthorCard/AuthorCard.tsx | 12 +++++++----- .../Editor/EditorFloatingMenu/EditorFloatingMenu.tsx | 2 +- .../SocialNetworkInput.module.scss | 2 ++ .../_shared/SolidSwiper/Swiper.module.scss | 10 +++++----- 7 files changed, 22 insertions(+), 16 deletions(-) diff --git a/src/components/Article/Article.module.scss b/src/components/Article/Article.module.scss index ed15b000..8216369c 100644 --- a/src/components/Article/Article.module.scss +++ b/src/components/Article/Article.module.scss @@ -75,6 +75,7 @@ img { &[data-float='left'], &[data-float='right'] { @include font-size(2.2rem); + line-height: 1.4; @include media-breakpoint-up(sm) { @@ -423,7 +424,7 @@ img { } .shoutStatsItemViews { - color: rgb(0 0 0 / 0.4); + color: rgb(0 0 0 / 40%); cursor: default; font-weight: normal; margin-left: auto; @@ -466,7 +467,8 @@ img { .shoutStatsItemAdditionalDataItem { font-weight: normal; display: inline-block; - //margin-left: 2rem; + + // margin-left: 2rem; margin-right: 0; margin-bottom: 0; cursor: default; diff --git a/src/components/Article/Comment/Comment.module.scss b/src/components/Article/Comment/Comment.module.scss index e16db64f..168ae67c 100644 --- a/src/components/Article/Comment/Comment.module.scss +++ b/src/components/Article/Comment/Comment.module.scss @@ -4,7 +4,7 @@ transition: background-color 0.3s; position: relative; list-style: none; - background: rgb(0 0 0 / 0.1); + background: rgb(0 0 0 / 10%); @include media-breakpoint-down(sm) { padding-right: 0; diff --git a/src/components/Author/AuthorBadge/AuthorBadge.tsx b/src/components/Author/AuthorBadge/AuthorBadge.tsx index 74b49154..5c9683f1 100644 --- a/src/components/Author/AuthorBadge/AuthorBadge.tsx +++ b/src/components/Author/AuthorBadge/AuthorBadge.tsx @@ -64,7 +64,7 @@ export const AuthorBadge = (props: Props) => { return isSubscribing() ? t('subscribing...') : t('Subscribe') }) - const unsubscribeValue = () => { + const unsubscribeValue = createMemo(() => { if (props.iconButtons) { return } @@ -75,7 +75,7 @@ export const AuthorBadge = (props: Props) => { {t('Unfollow')} ) - } + }) return (
    diff --git a/src/components/Author/AuthorCard/AuthorCard.tsx b/src/components/Author/AuthorCard/AuthorCard.tsx index 432bc5ef..62c7856b 100644 --- a/src/components/Author/AuthorCard/AuthorCard.tsx +++ b/src/components/Author/AuthorCard/AuthorCard.tsx @@ -97,20 +97,22 @@ export const AuthorCard = (props: Props) => { } }) - const followButtonText = () => { + const followButtonText = createMemo(() => { if (isSubscribing()) { return t('subscribing...') - } else if (subscribed()) { + } + + if (subscribed()) { return ( <> {t('Following')} {t('Unfollow')} ) - } else { - return t('Follow') } - } + + return t('Follow') + }) return (
    diff --git a/src/components/Editor/EditorFloatingMenu/EditorFloatingMenu.tsx b/src/components/Editor/EditorFloatingMenu/EditorFloatingMenu.tsx index 3c03dfce..eca9335a 100644 --- a/src/components/Editor/EditorFloatingMenu/EditorFloatingMenu.tsx +++ b/src/components/Editor/EditorFloatingMenu/EditorFloatingMenu.tsx @@ -1,5 +1,5 @@ import { createEffect, createSignal, Show } from 'solid-js' -import type { Editor, JSONContent } from '@tiptap/core' +import type { Editor } from '@tiptap/core' import { Icon } from '../../_shared/Icon' import { InlineForm } from '../InlineForm' import styles from './EditorFloatingMenu.module.scss' diff --git a/src/components/_shared/SocialNetworkInput/SocialNetworkInput.module.scss b/src/components/_shared/SocialNetworkInput/SocialNetworkInput.module.scss index 65401cdf..29728c4a 100644 --- a/src/components/_shared/SocialNetworkInput/SocialNetworkInput.module.scss +++ b/src/components/_shared/SocialNetworkInput/SocialNetworkInput.module.scss @@ -40,8 +40,10 @@ width: 54px; height: 54px; padding: 16px; + &:hover { background: var(--background-color-invert); + img { filter: invert(1); } diff --git a/src/components/_shared/SolidSwiper/Swiper.module.scss b/src/components/_shared/SolidSwiper/Swiper.module.scss index 648ca264..e953b565 100644 --- a/src/components/_shared/SolidSwiper/Swiper.module.scss +++ b/src/components/_shared/SolidSwiper/Swiper.module.scss @@ -38,8 +38,8 @@ } .container { - margin: auto; // max-width: 800px; + margin: auto; position: relative; padding: 24px 0; display: flex; @@ -177,12 +177,12 @@ } &.prev { - background-image: linear-gradient(to right, #000, rgb(0 0 0 / 0)); + background-image: linear-gradient(to right, #000, rgb(0 0 0 / 0%)); left: 0; } &.next { - background-image: linear-gradient(to left, #000, rgb(0 0 0 / 0)); + background-image: linear-gradient(to left, #000, rgb(0 0 0 / 0%)); justify-content: end; right: 0; } @@ -239,11 +239,11 @@ height: auto; &.prev { - left: -var(--navigation-reserve); + left: calc(0px - var(--navigation-reserve)); } &.next { - right: -var(--navigation-reserve); + right: calc(0px - var(--navigation-reserve)); } } From e3af5388df8b3703921ee1d83b74414fbc26ed65 Mon Sep 17 00:00:00 2001 From: Igor Lobanov Date: Mon, 13 Nov 2023 19:57:40 +0100 Subject: [PATCH 107/129] test --- api/ssr.mjs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/api/ssr.mjs b/api/ssr.mjs index 349cab37..62b2f5d6 100644 --- a/api/ssr.mjs +++ b/api/ssr.mjs @@ -1,8 +1,8 @@ import { renderPage } from 'vike/server' -export const config = { - runtime: 'edge' -} +// export const config = { +// runtime: 'edge' +// } export default async function handler(req, res) { const { url, cookies } = req @@ -26,6 +26,7 @@ export default async function handler(req, res) { const { body, statusCode, headers } = httpResponse console.log('headers:', JSON.stringify(headers)) + console.log('headers[0]:', JSON.stringify(headers[0])) res.statusCode = statusCode res.setHeader('Content-Type', headers['Content-Type']) From 137b3e917756080e58cfaa19e16909a2b67cd747 Mon Sep 17 00:00:00 2001 From: Igor Lobanov Date: Mon, 13 Nov 2023 20:21:01 +0100 Subject: [PATCH 108/129] oh help me glob --- api/ssr.mjs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/api/ssr.mjs b/api/ssr.mjs index 62b2f5d6..cfc1700c 100644 --- a/api/ssr.mjs +++ b/api/ssr.mjs @@ -25,11 +25,8 @@ export default async function handler(req, res) { const { body, statusCode, headers } = httpResponse - console.log('headers:', JSON.stringify(headers)) - console.log('headers[0]:', JSON.stringify(headers[0])) - res.statusCode = statusCode - res.setHeader('Content-Type', headers['Content-Type']) + headers.forEach(([name, value]) => res.setHeader(name, value)) res.setHeader('Cache-Control', 's-maxage=1, stale-while-revalidate') res.end(body) } From d29ad9a645c7a23b2cff08208af7958065e99aab Mon Sep 17 00:00:00 2001 From: Igor Lobanov Date: Mon, 13 Nov 2023 20:48:05 +0100 Subject: [PATCH 109/129] here we go again --- api/ssr.mjs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/api/ssr.mjs b/api/ssr.mjs index cfc1700c..c8317a35 100644 --- a/api/ssr.mjs +++ b/api/ssr.mjs @@ -1,8 +1,8 @@ import { renderPage } from 'vike/server' -// export const config = { -// runtime: 'edge' -// } +export const config = { + runtime: 'edge' +} export default async function handler(req, res) { const { url, cookies } = req From 3db5cea31d997bee52d1d701ae0db8c48a24b7a7 Mon Sep 17 00:00:00 2001 From: Igor Lobanov Date: Mon, 13 Nov 2023 20:52:35 +0100 Subject: [PATCH 110/129] test --- __checks__/discoursio-webapp.check.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/__checks__/discoursio-webapp.check.js b/__checks__/discoursio-webapp.check.js index b9550de3..939048be 100644 --- a/__checks__/discoursio-webapp.check.js +++ b/__checks__/discoursio-webapp.check.js @@ -15,7 +15,7 @@ const page = await browser.newPage() const targetUrl = process.env.ENVIRONMENT_URL || 'https://testing.discours.io' await checkUrl(page, targetUrl, 'main') -await checkUrl(page, `${targetUrl}/authors`, 'authors') -await checkUrl(page, `${targetUrl}/topics`, 'topics') +// await checkUrl(page, `${targetUrl}/authors`, 'authors') +// await checkUrl(page, `${targetUrl}/topics`, 'topics') await page.close() await browser.close() From cb263c68422d329ec6af4be1dcae6e3ebb387af0 Mon Sep 17 00:00:00 2001 From: Igor Lobanov Date: Mon, 13 Nov 2023 21:08:58 +0100 Subject: [PATCH 111/129] test --- __checks__/discoursio-webapp.check.js | 4 ++-- api/ssr.mjs | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/__checks__/discoursio-webapp.check.js b/__checks__/discoursio-webapp.check.js index 939048be..b9550de3 100644 --- a/__checks__/discoursio-webapp.check.js +++ b/__checks__/discoursio-webapp.check.js @@ -15,7 +15,7 @@ const page = await browser.newPage() const targetUrl = process.env.ENVIRONMENT_URL || 'https://testing.discours.io' await checkUrl(page, targetUrl, 'main') -// await checkUrl(page, `${targetUrl}/authors`, 'authors') -// await checkUrl(page, `${targetUrl}/topics`, 'topics') +await checkUrl(page, `${targetUrl}/authors`, 'authors') +await checkUrl(page, `${targetUrl}/topics`, 'topics') await page.close() await browser.close() diff --git a/api/ssr.mjs b/api/ssr.mjs index c8317a35..82b97524 100644 --- a/api/ssr.mjs +++ b/api/ssr.mjs @@ -26,7 +26,8 @@ export default async function handler(req, res) { const { body, statusCode, headers } = httpResponse res.statusCode = statusCode - headers.forEach(([name, value]) => res.setHeader(name, value)) + + // headers.forEach(([name, value]) => res.setHeader(name, value)) res.setHeader('Cache-Control', 's-maxage=1, stale-while-revalidate') res.end(body) } From a2c80432fd29567bb876c867347260100d9115be Mon Sep 17 00:00:00 2001 From: Igor Lobanov Date: Mon, 13 Nov 2023 21:14:53 +0100 Subject: [PATCH 112/129] test --- src/components/Nav/Snackbar.tsx | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/src/components/Nav/Snackbar.tsx b/src/components/Nav/Snackbar.tsx index 493124b9..540e41bb 100644 --- a/src/components/Nav/Snackbar.tsx +++ b/src/components/Nav/Snackbar.tsx @@ -4,7 +4,6 @@ import styles from './Snackbar.module.scss' import { Transition } from 'solid-transition-group' import { clsx } from 'clsx' import { Icon } from '../_shared/Icon' -import { isServer } from 'solid-js/web' export const Snackbar = () => { const { snackbarMessage } = useSnackbar() @@ -16,22 +15,20 @@ export const Snackbar = () => { [styles.success]: snackbarMessage()?.type === 'success' })} > - {!isServer && ( - setTimeout(() => done(), 300)} - > - -
    - - - - {snackbarMessage().body} -
    -
    -
    - )} + setTimeout(() => done(), 300)} + > + +
    + + + + {snackbarMessage().body} +
    +
    +
    ) } From 446ac598c5a9c4e6c2af2caab4c9b1b2e519a59f Mon Sep 17 00:00:00 2001 From: Igor Lobanov Date: Mon, 13 Nov 2023 21:23:40 +0100 Subject: [PATCH 113/129] test --- src/components/Nav/Header/Header.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/components/Nav/Header/Header.tsx b/src/components/Nav/Header/Header.tsx index 7dbe5026..088441a6 100644 --- a/src/components/Nav/Header/Header.tsx +++ b/src/components/Nav/Header/Header.tsx @@ -24,6 +24,7 @@ import { apiClient } from '../../../utils/apiClient' import { RANDOM_TOPICS_COUNT } from '../../Views/Home' import { Link } from './Link' import { Subscribe } from '../../_shared/Subscribe' +import { ShowOnlyOnClient } from '../../_shared/ShowOnlyOnClient' type Props = { title?: string @@ -527,8 +528,9 @@ export const Header = (props: Props) => {
    - - + + +
    ) From cf0ec8dcca09429fa1c74b46ae83e886f838c3b9 Mon Sep 17 00:00:00 2001 From: Igor Lobanov Date: Mon, 13 Nov 2023 21:57:04 +0100 Subject: [PATCH 114/129] something new --- api/edge-ssr.mjs | 32 ++++++++++++++++++++++++++++++++ api/ssr.mjs | 5 +---- vercel.json | 2 +- 3 files changed, 34 insertions(+), 5 deletions(-) create mode 100644 api/edge-ssr.mjs diff --git a/api/edge-ssr.mjs b/api/edge-ssr.mjs new file mode 100644 index 00000000..c810ed9b --- /dev/null +++ b/api/edge-ssr.mjs @@ -0,0 +1,32 @@ +import { renderPage } from 'vike/server' + +export const config = { + runtime: 'edge' +} +export default async function handler(request) { + const { url, cookies } = request + + const pageContext = await renderPage({ urlOriginal: url, cookies }) + + const { httpResponse, errorWhileRendering, is404 } = pageContext + + if (errorWhileRendering && !is404) { + console.error(errorWhileRendering) + return new Response('', { status: 500 }) + } + + if (!httpResponse) { + return new Response() + } + + const { body, statusCode, headers: headersArray } = httpResponse + + const headers = headersArray.reduce((acc, [name, value]) => { + acc[name] = value + return acc + }, {}) + + headers['Cache-Control'] = 's-maxage=1, stale-while-revalidate' + + return new Response(body, { status: statusCode, headers }) +} diff --git a/api/ssr.mjs b/api/ssr.mjs index 82b97524..b509f590 100644 --- a/api/ssr.mjs +++ b/api/ssr.mjs @@ -1,8 +1,5 @@ import { renderPage } from 'vike/server' -export const config = { - runtime: 'edge' -} export default async function handler(req, res) { const { url, cookies } = req @@ -27,7 +24,7 @@ export default async function handler(req, res) { res.statusCode = statusCode - // headers.forEach(([name, value]) => res.setHeader(name, value)) + headers.forEach(([name, value]) => res.setHeader(name, value)) res.setHeader('Cache-Control', 's-maxage=1, stale-while-revalidate') res.end(body) } diff --git a/vercel.json b/vercel.json index 3cd1f85e..ab03cf0b 100644 --- a/vercel.json +++ b/vercel.json @@ -2,7 +2,7 @@ "rewrites": [ { "source": "/((?!assets/).*)", - "destination": "/api/ssr.mjs" + "destination": "/api/edge-ssr.mjs" } ] } From aba1d89ead5b82f85803e2b0fad0e8f615dd1b30 Mon Sep 17 00:00:00 2001 From: Igor Lobanov Date: Mon, 13 Nov 2023 22:22:32 +0100 Subject: [PATCH 115/129] unified naming, unused code removed --- api/{edge-ssr.mjs => edge-ssr.js} | 0 api/ssr.mjs | 30 ------------------------------ vercel.json | 2 +- 3 files changed, 1 insertion(+), 31 deletions(-) rename api/{edge-ssr.mjs => edge-ssr.js} (100%) delete mode 100644 api/ssr.mjs diff --git a/api/edge-ssr.mjs b/api/edge-ssr.js similarity index 100% rename from api/edge-ssr.mjs rename to api/edge-ssr.js diff --git a/api/ssr.mjs b/api/ssr.mjs deleted file mode 100644 index b509f590..00000000 --- a/api/ssr.mjs +++ /dev/null @@ -1,30 +0,0 @@ -import { renderPage } from 'vike/server' - -export default async function handler(req, res) { - const { url, cookies } = req - - const pageContext = await renderPage({ urlOriginal: url, cookies }) - - const { httpResponse, errorWhileRendering, is404 } = pageContext - - if (errorWhileRendering && !is404) { - console.error(errorWhileRendering) - res.statusCode = 500 - res.end() - return - } - - if (!httpResponse) { - res.statusCode = 200 - res.end() - return - } - - const { body, statusCode, headers } = httpResponse - - res.statusCode = statusCode - - headers.forEach(([name, value]) => res.setHeader(name, value)) - res.setHeader('Cache-Control', 's-maxage=1, stale-while-revalidate') - res.end(body) -} diff --git a/vercel.json b/vercel.json index ab03cf0b..6a76165f 100644 --- a/vercel.json +++ b/vercel.json @@ -2,7 +2,7 @@ "rewrites": [ { "source": "/((?!assets/).*)", - "destination": "/api/edge-ssr.mjs" + "destination": "/api/edge-ssr.js" } ] } From e6e1189672608ec8c77fb1bc7d713db75b3b9223 Mon Sep 17 00:00:00 2001 From: Igor Lobanov Date: Mon, 13 Nov 2023 22:35:27 +0100 Subject: [PATCH 116/129] test --- api/edge-ssr.js | 1 + 1 file changed, 1 insertion(+) diff --git a/api/edge-ssr.js b/api/edge-ssr.js index c810ed9b..6ab18caf 100644 --- a/api/edge-ssr.js +++ b/api/edge-ssr.js @@ -27,6 +27,7 @@ export default async function handler(request) { }, {}) headers['Cache-Control'] = 's-maxage=1, stale-while-revalidate' + headers['TTTest'] = 'ttteeesssttt' return new Response(body, { status: statusCode, headers }) } From 8d2ae63e2535d32fe51e55b81afa4879355bef86 Mon Sep 17 00:00:00 2001 From: Igor Lobanov Date: Mon, 13 Nov 2023 22:56:02 +0100 Subject: [PATCH 117/129] debug code removed --- api/edge-ssr.js | 1 - 1 file changed, 1 deletion(-) diff --git a/api/edge-ssr.js b/api/edge-ssr.js index 6ab18caf..c810ed9b 100644 --- a/api/edge-ssr.js +++ b/api/edge-ssr.js @@ -27,7 +27,6 @@ export default async function handler(request) { }, {}) headers['Cache-Control'] = 's-maxage=1, stale-while-revalidate' - headers['TTTest'] = 'ttteeesssttt' return new Response(body, { status: statusCode, headers }) } From 37a8805b8a94efd55cd60625b4d5c73d1276aecd Mon Sep 17 00:00:00 2001 From: Ilya Y <75578537+ilya-bkv@users.noreply.github.com> Date: Tue, 14 Nov 2023 10:47:22 +0300 Subject: [PATCH 118/129] Fix/hydration (#315) hydration fix --------- Co-authored-by: Igor Lobanov --- .../Author/AuthorBadge/AuthorBadge.tsx | 27 ++++++++-------- src/components/Nav/Header/Header.tsx | 5 ++- src/components/Nav/Snackbar.tsx | 31 ++++++++++--------- 3 files changed, 33 insertions(+), 30 deletions(-) diff --git a/src/components/Author/AuthorBadge/AuthorBadge.tsx b/src/components/Author/AuthorBadge/AuthorBadge.tsx index 5c9683f1..83876f54 100644 --- a/src/components/Author/AuthorBadge/AuthorBadge.tsx +++ b/src/components/Author/AuthorBadge/AuthorBadge.tsx @@ -64,18 +64,7 @@ export const AuthorBadge = (props: Props) => { return isSubscribing() ? t('subscribing...') : t('Subscribe') }) - const unsubscribeValue = createMemo(() => { - if (props.iconButtons) { - return - } - - return ( - <> - {t('Following')} - {t('Unfollow')} - - ) - }) + const unsubscribeValue = () => {} return (
    @@ -142,7 +131,19 @@ export const AuthorBadge = (props: Props) => {
    - - - + + ) diff --git a/src/components/Nav/Snackbar.tsx b/src/components/Nav/Snackbar.tsx index 540e41bb..ac9b1091 100644 --- a/src/components/Nav/Snackbar.tsx +++ b/src/components/Nav/Snackbar.tsx @@ -4,6 +4,7 @@ import styles from './Snackbar.module.scss' import { Transition } from 'solid-transition-group' import { clsx } from 'clsx' import { Icon } from '../_shared/Icon' +import { ShowOnlyOnClient } from '../_shared/ShowOnlyOnClient' export const Snackbar = () => { const { snackbarMessage } = useSnackbar() @@ -15,20 +16,22 @@ export const Snackbar = () => { [styles.success]: snackbarMessage()?.type === 'success' })} > - setTimeout(() => done(), 300)} - > - -
    - - - - {snackbarMessage().body} -
    -
    -
    + + setTimeout(() => done(), 300)} + > + +
    + + + + {snackbarMessage().body} +
    +
    +
    +
    ) } From d90572e2430b25a492e6cb3ad981a0ba42c08036 Mon Sep 17 00:00:00 2001 From: Kosta <47947996+dobrodob@users.noreply.github.com> Date: Tue, 14 Nov 2023 12:45:44 +0200 Subject: [PATCH 119/129] Fix/meta (#314) * WIP * WIP * lint * package-lock.json * test * test * meta tags fixed * dynamic titles fix --------- Co-authored-by: Igor Lobanov --- .lintstagedrc | 5 +- .lintstagedrc.bak | 4 +- package-lock.json | 436 +++++++----------- package.json | 27 +- public/locales/en/translation.json | 2 + public/locales/ru/translation.json | 2 + src/components/App.tsx | 33 +- src/components/Article/FullArticle.tsx | 17 +- .../Author/AuthorBadge/AuthorBadge.tsx | 21 +- src/components/Nav/Header/Header.tsx | 1 - src/components/Views/Author/Author.tsx | 4 + src/components/Views/Edit.tsx | 23 +- src/components/Views/Topic.tsx | 4 + src/components/_shared/Lightbox/Lightbox.tsx | 2 +- src/components/_shared/PageLayout.tsx | 5 +- src/context/notifications.tsx | 2 +- src/pages/about/discussionRules.page.tsx | 4 +- src/pages/about/dogma.page.tsx | 7 +- src/pages/about/guide.page.tsx | 2 +- src/pages/about/help.page.tsx | 6 +- src/pages/about/manifest.page.tsx | 7 +- src/pages/about/partners.page.tsx | 4 +- src/pages/about/principles.page.tsx | 4 +- src/pages/about/projects.page.tsx | 4 +- src/pages/about/termsOfUse.page.tsx | 7 +- src/pages/about/thanks.page.tsx | 7 +- src/pages/allAuthors.page.server.ts | 2 +- src/pages/allAuthors.page.tsx | 5 +- src/pages/allTopics.page.server.ts | 2 +- src/pages/allTopics.page.tsx | 5 +- src/pages/article.page.server.ts | 2 +- src/pages/article.page.tsx | 5 +- src/pages/author.page.server.ts | 2 +- src/pages/author.page.tsx | 2 +- src/pages/connect.page.tsx | 20 +- src/pages/create.page.tsx | 3 +- src/pages/drafts.page.tsx | 5 +- src/pages/edit.page.tsx | 29 +- src/pages/expo/expo.page.server.ts | 2 +- src/pages/expo/expo.page.tsx | 9 +- src/pages/expo/expoLayout.page.server.ts | 2 +- src/pages/feed.page.tsx | 5 +- src/pages/fourOuFour.page.tsx | 5 +- src/pages/inbox.page.tsx | 5 +- src/pages/index.page.server.ts | 2 +- src/pages/index.page.tsx | 5 +- src/pages/profile/profileSecurity.page.tsx | 5 +- src/pages/profile/profileSettings.page.tsx | 3 +- .../profile/profileSubscriptions.page.tsx | 5 +- src/pages/search.page.server.ts | 2 +- src/pages/search.page.tsx | 15 +- src/pages/topic.page.server.ts | 2 +- src/pages/topic.page.tsx | 2 +- src/pages/types.ts | 3 + src/renderer/_default.page.client.tsx | 10 +- src/renderer/_default.page.server.tsx | 9 +- src/stores/router.ts | 13 +- 57 files changed, 387 insertions(+), 439 deletions(-) diff --git a/.lintstagedrc b/.lintstagedrc index 257ed088..272ddc54 100644 --- a/.lintstagedrc +++ b/.lintstagedrc @@ -1,4 +1,5 @@ { - "*.{js,mjs,ts,tsx,json,scss,css,html}": "prettier --write", - "package.json": "sort-package-json" + "*.{js,ts,tsx,json,scss,css,html}": "prettier --write", + "package.json": "sort-package-json", + "public/locales/**/*.json": "sort-json" } diff --git a/.lintstagedrc.bak b/.lintstagedrc.bak index 33269023..6de8a64b 100644 --- a/.lintstagedrc.bak +++ b/.lintstagedrc.bak @@ -1,6 +1,6 @@ { - "*.{js,mjs,ts,tsx,json,scss,css,html}": "prettier --write", + "*.{js,ts,tsx,json,scss,css,html}": "prettier --write", "package.json": "sort-package-json", "*.{scss,css}": "stylelint", - "*.{ts,tsx,js,mjs}": "eslint --fix" + "*.{ts,tsx,js}": "eslint --fix" } diff --git a/package-lock.json b/package-lock.json index 573e7d43..91e064fa 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,7 +16,7 @@ "mailgun.js": "8.2.1" }, "devDependencies": { - "@babel/core": "7.21.8", + "@babel/core": "7.23.3", "@graphql-codegen/cli": "5.0.0", "@graphql-codegen/typescript": "4.0.1", "@graphql-codegen/typescript-operations": "4.0.1", @@ -25,8 +25,8 @@ "@graphql-tools/url-loader": "7.17.18", "@graphql-typed-document-node/core": "3.2.0", "@hocuspocus/provider": "2.0.6", - "@nanostores/router": "0.8.3", - "@nanostores/solid": "0.3.2", + "@nanostores/router": "0.11.0", + "@nanostores/solid": "0.4.2", "@popperjs/core": "2.11.8", "@sentry/browser": "5.30.0", "@solid-primitives/media": "2.2.3", @@ -34,7 +34,7 @@ "@solid-primitives/share": "2.0.4", "@solid-primitives/storage": "1.3.9", "@solid-primitives/upload": "0.0.110", - "@solidjs/meta": "0.28.2", + "@solidjs/meta": "0.29.1", "@thisbeyond/solid-select": "0.14.0", "@tiptap/core": "2.0.3", "@tiptap/extension-blockquote": "2.0.3", @@ -65,10 +65,10 @@ "@tiptap/extension-text": "2.0.3", "@tiptap/extension-underline": "2.0.3", "@tiptap/extension-youtube": "2.0.3", - "@types/js-cookie": "3.0.5", - "@types/node": "20.8.10", - "@typescript-eslint/eslint-plugin": "6.9.1", - "@typescript-eslint/parser": "6.9.1", + "@types/js-cookie": "3.0.6", + "@types/node": "20.9.0", + "@typescript-eslint/eslint-plugin": "6.10.0", + "@typescript-eslint/parser": "6.10.0", "@urql/core": "3.2.2", "@urql/devtools": "2.0.3", "babel-preset-solid": "1.8.4", @@ -94,11 +94,11 @@ "javascript-time-ago": "2.5.9", "jest": "29.7.0", "js-cookie": "3.0.5", - "lint-staged": "15.0.2", + "lint-staged": "15.1.0", "loglevel": "1.8.1", "loglevel-plugin-prefix": "0.8.4", - "nanostores": "0.7.4", - "prettier": "3.0.3", + "nanostores": "0.9.5", + "prettier": "3.1.0", "prettier-eslint": "16.1.2", "prosemirror-history": "1.3.0", "prosemirror-trailing-node": "2.0.3", @@ -109,17 +109,18 @@ "solid-popper": "0.3.0", "solid-tiptap": "0.6.0", "solid-transition-group": "0.2.3", + "sort-json": "2.0.1", "sort-package-json": "2.6.0", "stylelint": "15.11.0", "stylelint-config-standard-scss": "11.1.0", "stylelint-order": "6.0.3", - "stylelint-scss": "5.3.0", + "stylelint-scss": "5.3.1", "swiper": "9.4.1", "throttle-debounce": "5.0.0", "typescript": "5.2.2", "typograf": "7.1.0", "uniqolor": "1.1.0", - "vike": "0.4.144", + "vike": "0.4.145", "vite": "4.5.0", "vite-plugin-mkcert": "1.16.0", "vite-plugin-sass-dts": "1.3.11", @@ -399,26 +400,26 @@ } }, "node_modules/@babel/core": { - "version": "7.21.8", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.21.8.tgz", - "integrity": "sha512-YeM22Sondbo523Sz0+CirSPnbj9bG3P0CdHcBZdqUuaeOaYEFbOLoGU7lebvGP6P5J/WE9wOn7u7C4J9HvS1xQ==", + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.3.tgz", + "integrity": "sha512-Jg+msLuNuCJDyBvFv5+OKOUjWMZgd85bKjbICd3zWrKAo+bJ49HJufi7CQE0q0uR8NGyO6xkCACScNqyjHSZew==", "dev": true, "dependencies": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.21.4", - "@babel/generator": "^7.21.5", - "@babel/helper-compilation-targets": "^7.21.5", - "@babel/helper-module-transforms": "^7.21.5", - "@babel/helpers": "^7.21.5", - "@babel/parser": "^7.21.8", - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.21.5", - "@babel/types": "^7.21.5", - "convert-source-map": "^1.7.0", + "@babel/code-frame": "^7.22.13", + "@babel/generator": "^7.23.3", + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helpers": "^7.23.2", + "@babel/parser": "^7.23.3", + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.3", + "@babel/types": "^7.23.3", + "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", - "json5": "^2.2.2", - "semver": "^6.3.0" + "json5": "^2.2.3", + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" @@ -3181,42 +3182,6 @@ "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, - "node_modules/@graphql-tools/graphql-tag-pluck/node_modules/@babel/core": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.3.tgz", - "integrity": "sha512-Jg+msLuNuCJDyBvFv5+OKOUjWMZgd85bKjbICd3zWrKAo+bJ49HJufi7CQE0q0uR8NGyO6xkCACScNqyjHSZew==", - "dev": true, - "dependencies": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.22.13", - "@babel/generator": "^7.23.3", - "@babel/helper-compilation-targets": "^7.22.15", - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helpers": "^7.23.2", - "@babel/parser": "^7.23.3", - "@babel/template": "^7.22.15", - "@babel/traverse": "^7.23.3", - "@babel/types": "^7.23.3", - "convert-source-map": "^2.0.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/@graphql-tools/graphql-tag-pluck/node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true - }, "node_modules/@graphql-tools/import": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/@graphql-tools/import/-/import-7.0.0.tgz", @@ -4474,12 +4439,6 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "node_modules/@jest/transform/node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true - }, "node_modules/@jest/transform/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -4706,36 +4665,6 @@ "node": "^12.16.0 || >=13.7.0" } }, - "node_modules/@linaria/utils/node_modules/@babel/core": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.3.tgz", - "integrity": "sha512-Jg+msLuNuCJDyBvFv5+OKOUjWMZgd85bKjbICd3zWrKAo+bJ49HJufi7CQE0q0uR8NGyO6xkCACScNqyjHSZew==", - "dev": true, - "dependencies": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.22.13", - "@babel/generator": "^7.23.3", - "@babel/helper-compilation-targets": "^7.22.15", - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helpers": "^7.23.2", - "@babel/parser": "^7.23.3", - "@babel/template": "^7.22.15", - "@babel/traverse": "^7.23.3", - "@babel/types": "^7.23.3", - "convert-source-map": "^2.0.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, "node_modules/@linaria/utils/node_modules/brace-expansion": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", @@ -4745,12 +4674,6 @@ "balanced-match": "^1.0.0" } }, - "node_modules/@linaria/utils/node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true - }, "node_modules/@linaria/utils/node_modules/minimatch": { "version": "9.0.3", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", @@ -4767,25 +4690,31 @@ } }, "node_modules/@nanostores/router": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/@nanostores/router/-/router-0.8.3.tgz", - "integrity": "sha512-AEGqyQQITIYgp232mIzwaG1wbP0yghCbEUi4ziy4kQaEfM8mRiaz/rrlnbDddd0MkwDZIWs3L3c3VodR5X9dUQ==", + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@nanostores/router/-/router-0.11.0.tgz", + "integrity": "sha512-QlcneDqXVIsQL3agOS59d9gJQ/9M3qyVOWVttARL5Xvpmovtq91oOYcQxKbLq9i7iitGs5yDJmabe/O3QjWddQ==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "engines": { - "node": "^14.0.0 || ^16.0.0 || >=18.0.0" + "node": "^16.0.0 || ^18.0.0 || >=20.0.0" }, "peerDependencies": { - "nanostores": "^0.7.0" + "nanostores": "^0.9.0" } }, "node_modules/@nanostores/solid": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@nanostores/solid/-/solid-0.3.2.tgz", - "integrity": "sha512-OH4m81Bls8NCH2ANzqEujPvzzzLlunm0e6Vpqy9mMgBYzOcqxWr3SrZgIVA7KhMsjftINwcpMN7/FKo2MQa1aQ==", + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@nanostores/solid/-/solid-0.4.2.tgz", + "integrity": "sha512-8v32+C9KdRbnvP4x4Oiw/CtL1tZwbRxYfmFsPIY9PXevCgxSFnicG6VnLLtNAR7F0kl8Ec7OROHO34Ffv0KDzg==", "dev": true, "peerDependencies": { - "nanostores": "^0.7.0", - "solid-js": ">=1.4.0" + "nanostores": ">=0.8.0", + "solid-js": "^1.6.0" } }, "node_modules/@nodelib/fs.scandir": { @@ -5412,12 +5341,12 @@ } }, "node_modules/@solidjs/meta": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@solidjs/meta/-/meta-0.28.2.tgz", - "integrity": "sha512-avlLgBPdk4KVxzRGFlYp/MIJo8B5jVgXPgk6OUnUP8km21Z+ovO+DUd7ZPA7ejv8PBdWi9GE3zCzw8RU2YuV2Q==", + "version": "0.29.1", + "resolved": "https://registry.npmjs.org/@solidjs/meta/-/meta-0.29.1.tgz", + "integrity": "sha512-qtrBYCnRRuzyvBg/u/SRO/2fM5r6DT1YKf+2W1RZhveMoeXHbZpWIrXjgpLFRHJLn6cqAGqrIzu42qS2o+1hKQ==", "dev": true, "peerDependencies": { - "solid-js": ">=1.4.0" + "solid-js": ">=1.8.4" } }, "node_modules/@thisbeyond/solid-select": { @@ -5934,9 +5863,9 @@ } }, "node_modules/@types/js-cookie": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@types/js-cookie/-/js-cookie-3.0.5.tgz", - "integrity": "sha512-dtLshqoiGRDHbHueIT9sjkd2F4tW1qPSX2xKAQK8p1e6pM+Z913GM1shv7dOqqasEMYbC5zEaClJomQe8OtQLA==", + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/js-cookie/-/js-cookie-3.0.6.tgz", + "integrity": "sha512-wkw9yd1kEXOPnvEeEV1Go1MmxtBJL0RR79aOTAApecWFVu7w0NNXNqhcWgvw2YgZDYadliXkl14pa3WXw5jlCQ==", "dev": true }, "node_modules/@types/js-yaml": { @@ -5970,9 +5899,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.8.10", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.10.tgz", - "integrity": "sha512-TlgT8JntpcbmKUFzjhsyhGfP2fsiz1Mv56im6enJ905xG1DAYesxJaeSbGqQmAw8OWPdhyJGhGSQGKRNJ45u9w==", + "version": "20.9.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.9.0.tgz", + "integrity": "sha512-nekiGu2NDb1BcVofVcEKMIwzlx4NjHlcjhoxxKBNLtz15Y1z7MYf549DFvkHSId02Ax6kGwWntIBPC3l/JZcmw==", "dev": true, "dependencies": { "undici-types": "~5.26.4" @@ -6039,16 +5968,16 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.9.1.tgz", - "integrity": "sha512-w0tiiRc9I4S5XSXXrMHOWgHgxbrBn1Ro+PmiYhSg2ZVdxrAJtQgzU5o2m1BfP6UOn7Vxcc6152vFjQfmZR4xEg==", + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.10.0.tgz", + "integrity": "sha512-uoLj4g2OTL8rfUQVx2AFO1hp/zja1wABJq77P6IclQs6I/m9GLrm7jCdgzZkvWdDCQf1uEvoa8s8CupsgWQgVg==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.9.1", - "@typescript-eslint/type-utils": "6.9.1", - "@typescript-eslint/utils": "6.9.1", - "@typescript-eslint/visitor-keys": "6.9.1", + "@typescript-eslint/scope-manager": "6.10.0", + "@typescript-eslint/type-utils": "6.10.0", + "@typescript-eslint/utils": "6.10.0", + "@typescript-eslint/visitor-keys": "6.10.0", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", @@ -6107,15 +6036,15 @@ "dev": true }, "node_modules/@typescript-eslint/parser": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.9.1.tgz", - "integrity": "sha512-C7AK2wn43GSaCUZ9do6Ksgi2g3mwFkMO3Cis96kzmgudoVaKyt62yNzJOktP0HDLb/iO2O0n2lBOzJgr6Q/cyg==", + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.10.0.tgz", + "integrity": "sha512-+sZwIj+s+io9ozSxIWbNB5873OSdfeBEH/FR0re14WLI6BaKuSOnnwCJ2foUiu8uXf4dRp1UqHP0vrZ1zXGrog==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "6.9.1", - "@typescript-eslint/types": "6.9.1", - "@typescript-eslint/typescript-estree": "6.9.1", - "@typescript-eslint/visitor-keys": "6.9.1", + "@typescript-eslint/scope-manager": "6.10.0", + "@typescript-eslint/types": "6.10.0", + "@typescript-eslint/typescript-estree": "6.10.0", + "@typescript-eslint/visitor-keys": "6.10.0", "debug": "^4.3.4" }, "engines": { @@ -6135,13 +6064,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.9.1.tgz", - "integrity": "sha512-38IxvKB6NAne3g/+MyXMs2Cda/Sz+CEpmm+KLGEM8hx/CvnSRuw51i8ukfwB/B/sESdeTGet1NH1Wj7I0YXswg==", + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.10.0.tgz", + "integrity": "sha512-TN/plV7dzqqC2iPNf1KrxozDgZs53Gfgg5ZHyw8erd6jd5Ta/JIEcdCheXFt9b1NYb93a1wmIIVW/2gLkombDg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.9.1", - "@typescript-eslint/visitor-keys": "6.9.1" + "@typescript-eslint/types": "6.10.0", + "@typescript-eslint/visitor-keys": "6.10.0" }, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -6152,13 +6081,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.9.1.tgz", - "integrity": "sha512-eh2oHaUKCK58qIeYp19F5V5TbpM52680sB4zNSz29VBQPTWIlE/hCj5P5B1AChxECe/fmZlspAWFuRniep1Skg==", + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.10.0.tgz", + "integrity": "sha512-wYpPs3hgTFblMYwbYWPT3eZtaDOjbLyIYuqpwuLBBqhLiuvJ+9sEp2gNRJEtR5N/c9G1uTtQQL5AhV0fEPJYcg==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "6.9.1", - "@typescript-eslint/utils": "6.9.1", + "@typescript-eslint/typescript-estree": "6.10.0", + "@typescript-eslint/utils": "6.10.0", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" }, @@ -6179,9 +6108,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.9.1.tgz", - "integrity": "sha512-BUGslGOb14zUHOUmDB2FfT6SI1CcZEJYfF3qFwBeUrU6srJfzANonwRYHDpLBuzbq3HaoF2XL2hcr01c8f8OaQ==", + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.10.0.tgz", + "integrity": "sha512-36Fq1PWh9dusgo3vH7qmQAj5/AZqARky1Wi6WpINxB6SkQdY5vQoT2/7rW7uBIsPDcvvGCLi4r10p0OJ7ITAeg==", "dev": true, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -6192,13 +6121,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.9.1.tgz", - "integrity": "sha512-U+mUylTHfcqeO7mLWVQ5W/tMLXqVpRv61wm9ZtfE5egz7gtnmqVIw9ryh0mgIlkKk9rZLY3UHygsBSdB9/ftyw==", + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.10.0.tgz", + "integrity": "sha512-ek0Eyuy6P15LJVeghbWhSrBCj/vJpPXXR+EpaRZqou7achUWL8IdYnMSC5WHAeTWswYQuP2hAZgij/bC9fanBg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.9.1", - "@typescript-eslint/visitor-keys": "6.9.1", + "@typescript-eslint/types": "6.10.0", + "@typescript-eslint/visitor-keys": "6.10.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -6252,17 +6181,17 @@ "dev": true }, "node_modules/@typescript-eslint/utils": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.9.1.tgz", - "integrity": "sha512-L1T0A5nFdQrMVunpZgzqPL6y2wVreSyHhKGZryS6jrEN7bD9NplVAyMryUhXsQ4TWLnZmxc2ekar/lSGIlprCA==", + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.10.0.tgz", + "integrity": "sha512-v+pJ1/RcVyRc0o4wAGux9x42RHmAjIGzPRo538Z8M1tVx6HOnoQBCX/NoadHQlZeC+QO2yr4nNSFWOoraZCAyg==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.9.1", - "@typescript-eslint/types": "6.9.1", - "@typescript-eslint/typescript-estree": "6.9.1", + "@typescript-eslint/scope-manager": "6.10.0", + "@typescript-eslint/types": "6.10.0", + "@typescript-eslint/typescript-estree": "6.10.0", "semver": "^7.5.4" }, "engines": { @@ -6310,12 +6239,12 @@ "dev": true }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.9.1.tgz", - "integrity": "sha512-MUaPUe/QRLEffARsmNfmpghuQkW436DvESW+h+M52w0coICHRfD6Np9/K6PdACwnrq1HmuLl+cSPZaJmeVPkSw==", + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.10.0.tgz", + "integrity": "sha512-xMGluxQIEtOM7bqFCo+rCMh5fqI+ZxV5RUUOa29iVPz1OgCZrtc7rFnz5cLUazlkPKYqX+75iuDq7m0HQ48nCg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.9.1", + "@typescript-eslint/types": "6.10.0", "eslint-visitor-keys": "^3.4.1" }, "engines": { @@ -7387,9 +7316,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001561", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001561.tgz", - "integrity": "sha512-NTt0DNoKe958Q0BE0j0c1V9jbUzhBxHIEJy7asmGrpE0yG63KTV7PLHPnK2E1O9RsQrQ081I3NLuXGS6zht3cw==", + "version": "1.0.30001562", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001562.tgz", + "integrity": "sha512-kfte3Hym//51EdX4239i+Rmp20EsLIYGdPkERegTgU19hQWCRhsRFGKHTliUlsry53tv17K7n077Kqa0WJU4ng==", "dev": true, "funding": [ { @@ -7807,9 +7736,9 @@ } }, "node_modules/convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "dev": true }, "node_modules/cosmiconfig": { @@ -8342,9 +8271,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.581", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.581.tgz", - "integrity": "sha512-6uhqWBIapTJUxgPTCHH9sqdbxIMPt7oXl0VcAL1kOtlU6aECdcMncCrX5Z7sHQ/invtrC9jUQUef7+HhO8vVFw==", + "version": "1.4.582", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.582.tgz", + "integrity": "sha512-89o0MGoocwYbzqUUjc+VNpeOFSOK9nIdC5wY4N+PVUarUK0MtjyTjks75AZS2bW4Kl8MdewdFsWaH0jLy+JNoA==", "dev": true }, "node_modules/emittery": { @@ -13680,9 +13609,9 @@ } }, "node_modules/jose": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/jose/-/jose-5.1.0.tgz", - "integrity": "sha512-H+RVqxA6apaJ0rcQYupKYhos7uosAiF42gUcWZiwhICWMphDULFj/CRr1R0tV/JCv9DEeJaSyYYpc9luHHNT4g==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/jose/-/jose-5.1.1.tgz", + "integrity": "sha512-bfB+lNxowY49LfrBO0ITUn93JbUhxUN8I11K6oI5hJu/G6PO6fEUddVLjqdD0cQ9SXIHWXuWh7eJYwZF7Z0N/g==", "dev": true, "funding": { "url": "https://github.com/sponsors/panva" @@ -13758,12 +13687,18 @@ "dev": true }, "node_modules/json-stable-stringify": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.2.tgz", - "integrity": "sha512-eunSSaEnxV12z+Z73y/j5N37/In40GK4GmsSy+tEHJMxknvqnA7/djeYtAgW0GsWHUfg+847WJjKaEylk2y09g==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.1.0.tgz", + "integrity": "sha512-zfA+5SuwYN2VWqN1/5HZaDzQKLJHaBVMZIIM+wuYjdptkaQsqzDdqjqf+lZZJUuJq1aanHiY8LhH8LmH+qBYJA==", "dev": true, "dependencies": { - "jsonify": "^0.0.1" + "call-bind": "^1.0.5", + "isarray": "^2.0.5", + "jsonify": "^0.0.1", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -13967,9 +13902,9 @@ "dev": true }, "node_modules/lint-staged": { - "version": "15.0.2", - "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-15.0.2.tgz", - "integrity": "sha512-vnEy7pFTHyVuDmCAIFKR5QDO8XLVlPFQQyujQ/STOxe40ICWqJ6knS2wSJ/ffX/Lw0rz83luRDh+ET7toN+rOw==", + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-15.1.0.tgz", + "integrity": "sha512-ZPKXWHVlL7uwVpy8OZ7YQjYDAuO5X4kMh0XgZvPNxLcCCngd0PO5jKQyy3+s4TL2EnHoIXIzP1422f/l3nZKMw==", "dev": true, "dependencies": { "chalk": "5.3.0", @@ -13981,7 +13916,7 @@ "micromatch": "4.0.5", "pidtree": "0.6.0", "string-argv": "0.3.2", - "yaml": "2.3.3" + "yaml": "2.3.4" }, "bin": { "lint-staged": "bin/lint-staged.js" @@ -14380,15 +14315,6 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/lint-staged/node_modules/yaml": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.3.tgz", - "integrity": "sha512-zw0VAJxgeZ6+++/su5AFoqBbZbrEakwu+X0M5HmcwUiBL7AzcuPKjj5we4xfQLp78LkEMpD0cOnUhmgOVy3KdQ==", - "dev": true, - "engines": { - "node": ">= 14" - } - }, "node_modules/listr2": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/listr2/-/listr2-4.0.5.tgz", @@ -15233,12 +15159,18 @@ } }, "node_modules/nanostores": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/nanostores/-/nanostores-0.7.4.tgz", - "integrity": "sha512-MBeUVt7NBcXqh7AGT+KSr3O0X/995CZsvcP2QEMP+PXFwb07qv3Vjyq+EX0yS8f12Vv3Tn2g/BvK/OZoMhJlOQ==", + "version": "0.9.5", + "resolved": "https://registry.npmjs.org/nanostores/-/nanostores-0.9.5.tgz", + "integrity": "sha512-Z+p+g8E7yzaWwOe5gEUB2Ox0rCEeXWYIZWmYvw/ajNYX8DlXdMvMDj8DWfM/subqPAcsf8l8Td4iAwO1DeIIRQ==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "engines": { - "node": "^14.0.0 || ^16.0.0 || >=18.0.0" + "node": "^16.0.0 || ^18.0.0 || >=20.0.0" } }, "node_modules/natural-compare": { @@ -16057,9 +15989,9 @@ } }, "node_modules/prettier": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.3.tgz", - "integrity": "sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.1.0.tgz", + "integrity": "sha512-TQLvXjq5IAibjh8EpBIkNKxO749UEWABoiIZehEPiY4GNpVdhaFKqSTu+QrlU6D2dPAfubRmtJTi4K4YkQ5eXw==", "dev": true, "bin": { "prettier": "bin/prettier.cjs" @@ -17321,6 +17253,38 @@ "solid-js": "^1.6.12" } }, + "node_modules/sort-json": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/sort-json/-/sort-json-2.0.1.tgz", + "integrity": "sha512-s8cs2bcsQCzo/P2T/uoU6Js4dS/jnX8+4xunziNoq9qmSpZNCrRIAIvp4avsz0ST18HycV4z/7myJ7jsHWB2XQ==", + "dev": true, + "dependencies": { + "detect-indent": "^5.0.0", + "detect-newline": "^2.1.0", + "minimist": "^1.2.0" + }, + "bin": { + "sort-json": "app/cmd.js" + } + }, + "node_modules/sort-json/node_modules/detect-indent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-5.0.0.tgz", + "integrity": "sha512-rlpvsxUtM0PQvy9iZe640/IWwWYyBsTApREbA1pHOpmOUIl9MkP/U4z7vTtg4Oaojvqhxt7sdufnT0EzGaR31g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/sort-json/node_modules/detect-newline": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-2.1.0.tgz", + "integrity": "sha512-CwffZFvlJffUg9zZA0uqrjQayUTC8ob94pnr5sFwaVv3IOmkfUHcWH+jXaQK3askE51Cqe8/9Ql/0uXNwqZ8Zg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/sort-object-keys": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/sort-object-keys/-/sort-object-keys-1.1.3.tgz", @@ -17817,12 +17781,12 @@ } }, "node_modules/stylelint-scss": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/stylelint-scss/-/stylelint-scss-5.3.0.tgz", - "integrity": "sha512-Sc7S1uWqStMc99NREsHNxpxHHFRvjo2pWILNl/UCwWO8PxhODK8qbJH0GHWIALxl6BD5rwJL4cSm4jk36hi6fg==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/stylelint-scss/-/stylelint-scss-5.3.1.tgz", + "integrity": "sha512-5I9ZDIm77BZrjOccma5WyW2nJEKjXDd4Ca8Kk+oBapSO4pewSlno3n+OyimcyVJJujQZkBN2D+xuMkIamSc6hA==", "dev": true, "dependencies": { - "known-css-properties": "^0.28.0", + "known-css-properties": "^0.29.0", "postcss-media-query-parser": "^0.2.3", "postcss-resolve-nested-selector": "^0.1.1", "postcss-selector-parser": "^6.0.13", @@ -17833,9 +17797,9 @@ } }, "node_modules/stylelint-scss/node_modules/known-css-properties": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.28.0.tgz", - "integrity": "sha512-9pSL5XB4J+ifHP0e0jmmC98OGC1nL8/JjS+fi6mnTlIf//yt/MfVLtKg7S6nCtj/8KTcWX7nRlY0XywoYY1ISQ==", + "version": "0.29.0", + "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.29.0.tgz", + "integrity": "sha512-Ne7wqW7/9Cz54PDt4I3tcV+hAyat8ypyOGzYRJQfdxnnjeWsTxt1cy8pjvvKeI5kfXuyvULyeeAvwvvtAX3ayQ==", "dev": true }, "node_modules/stylelint/node_modules/balanced-match": { @@ -18606,12 +18570,6 @@ "node": ">=10.12.0" } }, - "node_modules/v8-to-istanbul/node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true - }, "node_modules/validate-html-nesting": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/validate-html-nesting/-/validate-html-nesting-1.2.2.tgz", @@ -18638,13 +18596,13 @@ } }, "node_modules/vike": { - "version": "0.4.144", - "resolved": "https://registry.npmjs.org/vike/-/vike-0.4.144.tgz", - "integrity": "sha512-smvBXv33IhP5FHOvoBYZuir/Zip93AoBGqiIdmWHva1RYeQDFlXQMbs/YZ5HqFc7OrL8cL3K7iUsEC6t/pF+/Q==", + "version": "0.4.145", + "resolved": "https://registry.npmjs.org/vike/-/vike-0.4.145.tgz", + "integrity": "sha512-FPYM69bRC4ilzP2lLEzXxpa8Q3lxNKUtp1h6LaFh+lROzhf9e88TTXEnZTQi7iBUsiJqBjxm+fXUGkz6BOccnw==", "dev": true, "dependencies": { "@brillout/import": "0.2.3", - "@brillout/json-serializer": "^0.5.6", + "@brillout/json-serializer": "^0.5.8", "@brillout/picocolors": "^1.0.9", "@brillout/require-shim": "^0.1.2", "@brillout/vite-plugin-import-build": "^0.2.20", @@ -18792,42 +18750,6 @@ "vite": "^3.0.0 || ^4.0.0" } }, - "node_modules/vite-plugin-solid/node_modules/@babel/core": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.3.tgz", - "integrity": "sha512-Jg+msLuNuCJDyBvFv5+OKOUjWMZgd85bKjbICd3zWrKAo+bJ49HJufi7CQE0q0uR8NGyO6xkCACScNqyjHSZew==", - "dev": true, - "dependencies": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.22.13", - "@babel/generator": "^7.23.3", - "@babel/helper-compilation-targets": "^7.22.15", - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helpers": "^7.23.2", - "@babel/parser": "^7.23.3", - "@babel/template": "^7.22.15", - "@babel/traverse": "^7.23.3", - "@babel/types": "^7.23.3", - "convert-source-map": "^2.0.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/vite-plugin-solid/node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true - }, "node_modules/vite/node_modules/@esbuild/android-arm": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", diff --git a/package.json b/package.json index 2f5c90e0..d02dbb60 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "mailgun.js": "8.2.1" }, "devDependencies": { - "@babel/core": "7.21.8", + "@babel/core": "7.23.3", "@graphql-codegen/cli": "5.0.0", "@graphql-codegen/typescript": "4.0.1", "@graphql-codegen/typescript-operations": "4.0.1", @@ -46,8 +46,8 @@ "@graphql-tools/url-loader": "7.17.18", "@graphql-typed-document-node/core": "3.2.0", "@hocuspocus/provider": "2.0.6", - "@nanostores/router": "0.8.3", - "@nanostores/solid": "0.3.2", + "@nanostores/router": "0.11.0", + "@nanostores/solid": "0.4.2", "@popperjs/core": "2.11.8", "@sentry/browser": "5.30.0", "@solid-primitives/media": "2.2.3", @@ -55,7 +55,7 @@ "@solid-primitives/share": "2.0.4", "@solid-primitives/storage": "1.3.9", "@solid-primitives/upload": "0.0.110", - "@solidjs/meta": "0.28.2", + "@solidjs/meta": "0.29.1", "@thisbeyond/solid-select": "0.14.0", "@tiptap/core": "2.0.3", "@tiptap/extension-blockquote": "2.0.3", @@ -86,10 +86,10 @@ "@tiptap/extension-text": "2.0.3", "@tiptap/extension-underline": "2.0.3", "@tiptap/extension-youtube": "2.0.3", - "@types/js-cookie": "3.0.5", - "@types/node": "20.8.10", - "@typescript-eslint/eslint-plugin": "6.9.1", - "@typescript-eslint/parser": "6.9.1", + "@types/js-cookie": "3.0.6", + "@types/node": "20.9.0", + "@typescript-eslint/eslint-plugin": "6.10.0", + "@typescript-eslint/parser": "6.10.0", "@urql/core": "3.2.2", "@urql/devtools": "2.0.3", "babel-preset-solid": "1.8.4", @@ -115,11 +115,11 @@ "javascript-time-ago": "2.5.9", "jest": "29.7.0", "js-cookie": "3.0.5", - "lint-staged": "15.0.2", + "lint-staged": "15.1.0", "loglevel": "1.8.1", "loglevel-plugin-prefix": "0.8.4", - "nanostores": "0.7.4", - "prettier": "3.0.3", + "nanostores": "0.9.5", + "prettier": "3.1.0", "prettier-eslint": "16.1.2", "prosemirror-history": "1.3.0", "prosemirror-trailing-node": "2.0.3", @@ -130,17 +130,18 @@ "solid-popper": "0.3.0", "solid-tiptap": "0.6.0", "solid-transition-group": "0.2.3", + "sort-json": "2.0.1", "sort-package-json": "2.6.0", "stylelint": "15.11.0", "stylelint-config-standard-scss": "11.1.0", "stylelint-order": "6.0.3", - "stylelint-scss": "5.3.0", + "stylelint-scss": "5.3.1", "swiper": "9.4.1", "throttle-debounce": "5.0.0", "typescript": "5.2.2", "typograf": "7.1.0", "uniqolor": "1.1.0", - "vike": "0.4.144", + "vike": "0.4.145", "vite": "4.5.0", "vite-plugin-mkcert": "1.16.0", "vite-plugin-sass-dts": "1.3.11", diff --git a/public/locales/en/translation.json b/public/locales/en/translation.json index d6eb744b..35a11b7d 100644 --- a/public/locales/en/translation.json +++ b/public/locales/en/translation.json @@ -126,6 +126,7 @@ "FAQ": "Tips and suggestions", "Favorite": "Favorites", "Favorite topics": "Favorite topics", + "Feed": "Feed", "Feed settings": "Feed settings", "Feedback": "Feedback", "Fill email": "Fill email", @@ -168,6 +169,7 @@ "I know the password": "I know the password", "Image format not supported": "Image format not supported", "In bookmarks, you can save favorite discussions and materials that you want to return to": "In bookmarks, you can save favorite discussions and materials that you want to return to", + "Inbox": "Inbox", "Incut": "Incut", "Independant magazine with an open horizontal cooperation about culture, science and society": "Independant magazine with an open horizontal cooperation about culture, science and society", "Insert footnote": "Insert footnote", diff --git a/public/locales/ru/translation.json b/public/locales/ru/translation.json index 3640e6a3..a4daed51 100644 --- a/public/locales/ru/translation.json +++ b/public/locales/ru/translation.json @@ -130,6 +130,7 @@ "FAQ": "Советы и предложения", "Favorite": "Избранное", "Favorite topics": "Избранные темы", + "Feed": "Лента", "Feed settings": "Настройки ленты", "Feedback": "Обратная связь", "Fill email": "Введите почту", @@ -175,6 +176,7 @@ "I know the password": "Я знаю пароль!", "Image format not supported": "Тип изображения не поддерживается", "In bookmarks, you can save favorite discussions and materials that you want to return to": "В закладках можно сохранять избранные дискуссии и материалы, к которым хочется вернуться", + "Inbox": "Входящие", "Incut": "Подверстка", "Independant magazine with an open horizontal cooperation about culture, science and society": "Независимый журнал с открытой горизонтальной редакцией о культуре, науке и обществе", "Insert footnote": "Вставить сноску", diff --git a/src/components/App.tsx b/src/components/App.tsx index f5e054c5..2ad01f87 100644 --- a/src/components/App.tsx +++ b/src/components/App.tsx @@ -1,6 +1,3 @@ -// FIXME: breaks on vercel, research -// import 'solid-devtools' - import { hideModal, MODALS, showModal } from '../stores/ui' import { Component, createEffect, createMemo } from 'solid-js' import { ROUTES, useRouter } from '../stores/router' @@ -41,6 +38,7 @@ import { LocalizeProvider } from '../context/localize' import { ConfirmProvider } from '../context/confirm' import { EditorProvider } from '../context/editor' import { NotificationsProvider } from '../context/notifications' +import { Meta, MetaProvider } from '@solidjs/meta' // TODO: lazy load // const SomePage = lazy(() => import('./Pages/SomePage')) @@ -110,18 +108,21 @@ export const App = (props: PageProps) => { }) return ( - - - - - - - - - - - - - + + + + + + + + + + + + + + + + ) } diff --git a/src/components/Article/FullArticle.tsx b/src/components/Article/FullArticle.tsx index 6894d734..a4758800 100644 --- a/src/components/Article/FullArticle.tsx +++ b/src/components/Article/FullArticle.tsx @@ -1,5 +1,5 @@ import { createEffect, For, createMemo, onMount, Show, createSignal, onCleanup } from 'solid-js' -import { Title } from '@solidjs/meta' + import { clsx } from 'clsx' import { getPagePath } from '@nanostores/router' import type { Author, Shout } from '../../graphql/types.gen' @@ -28,6 +28,7 @@ import { getImageUrl } from '../../utils/getImageUrl' import { FeedArticlePopup } from '../Feed/FeedArticlePopup' import { Lightbox } from '../_shared/Lightbox' import { Image } from '../_shared/Image' +import article from '../Editor/extensions/Article' type Props = { article: Shout @@ -91,8 +92,13 @@ export const FullArticle = (props: Props) => { } return props.article.body }) - const media = createMemo(() => { - return JSON.parse(props.article.media || '[]') + + const media = createMemo(() => { + try { + return JSON.parse(props.article.media) + } catch { + return [] + } }) const commentsRef: { @@ -146,6 +152,10 @@ export const FullArticle = (props: Props) => { setIsReactionsLoaded(true) }) + onMount(() => { + document.title = props.article.title + }) + const clickHandlers = [] const documentClickHandlers = [] @@ -249,7 +259,6 @@ export const FullArticle = (props: Props) => { return ( <> - {props.article.title}
    { }) }, 'discussions') } - const subscribeValue = createMemo(() => { - if (props.iconButtons) { - return - } - return isSubscribing() ? t('subscribing...') : t('Subscribe') - }) - - const unsubscribeValue = () => {} return (
    @@ -118,7 +110,18 @@ export const AuthorBadge = (props: Props) => {
    diff --git a/src/components/Feed/Row5.tsx b/src/components/Feed/Row5.tsx index b3d07c52..eb564fc5 100644 --- a/src/components/Feed/Row5.tsx +++ b/src/components/Feed/Row5.tsx @@ -1,4 +1,5 @@ import type { Shout } from '../../graphql/types.gen' + import { ArticleCard } from './ArticleCard' export const Row5 = (props: { articles: Shout[]; nodate?: boolean }) => { diff --git a/src/components/Feed/RowShort.tsx b/src/components/Feed/RowShort.tsx index 1dc5fda2..2fb773e2 100644 --- a/src/components/Feed/RowShort.tsx +++ b/src/components/Feed/RowShort.tsx @@ -1,5 +1,7 @@ -import { For } from 'solid-js' import type { Shout } from '../../graphql/types.gen' + +import { For } from 'solid-js' + import { ArticleCard } from './ArticleCard' export default (props: { articles: Shout[] }) => ( @@ -16,7 +18,7 @@ export default (props: { articles: Shout[] }) => ( isWithCover: true, isBigTitle: true, isVertical: true, - nodate: true + nodate: true, }} />
    diff --git a/src/components/Feed/Sidebar/Sidebar.tsx b/src/components/Feed/Sidebar/Sidebar.tsx index a62441b1..04374e0b 100644 --- a/src/components/Feed/Sidebar/Sidebar.tsx +++ b/src/components/Feed/Sidebar/Sidebar.tsx @@ -1,14 +1,16 @@ +import { getPagePath } from '@nanostores/router' +import { clsx } from 'clsx' import { createSignal, For, Show } from 'solid-js' -import { Icon } from '../../_shared/Icon' + +import { useLocalize } from '../../../context/localize' +import { useSession } from '../../../context/session' +import { router, useRouter } from '../../../stores/router' import { useArticlesStore } from '../../../stores/zine/articles' import { useSeenStore } from '../../../stores/zine/seen' -import { useSession } from '../../../context/session' -import { useLocalize } from '../../../context/localize' -import styles from './Sidebar.module.scss' -import { clsx } from 'clsx' +import { Icon } from '../../_shared/Icon' import { Userpic } from '../../Author/Userpic' -import { getPagePath } from '@nanostores/router' -import { router, useRouter } from '../../../stores/router' + +import styles from './Sidebar.module.scss' export const Sidebar = () => { const { t } = useLocalize() @@ -33,7 +35,7 @@ export const Sidebar = () => { @@ -46,7 +48,7 @@ export const Sidebar = () => { @@ -59,7 +61,7 @@ export const Sidebar = () => { @@ -72,7 +74,7 @@ export const Sidebar = () => { @@ -85,7 +87,7 @@ export const Sidebar = () => { @@ -98,7 +100,7 @@ export const Sidebar = () => { diff --git a/src/components/Inbox/CreateModalContent.tsx b/src/components/Inbox/CreateModalContent.tsx index 07efd2e2..1a860da7 100644 --- a/src/components/Inbox/CreateModalContent.tsx +++ b/src/components/Inbox/CreateModalContent.tsx @@ -1,11 +1,14 @@ -import { createSignal, For, createEffect } from 'solid-js' -import styles from './CreateModalContent.module.scss' - -import InviteUser from './InviteUser' import type { Author } from '../../graphql/types.gen' -import { hideModal } from '../../stores/ui' + +import { createSignal, For, createEffect } from 'solid-js' + import { useInbox } from '../../context/inbox' import { useLocalize } from '../../context/localize' +import { hideModal } from '../../stores/ui' + +import InviteUser from './InviteUser' + +import styles from './CreateModalContent.module.scss' type inviteUser = Author & { selected: boolean } type Props = { @@ -46,7 +49,7 @@ const CreateModalContent = (props: Props) => { const handleClick = (user) => { setCollectionToInvite((userCollection) => { return userCollection.map((clickedUser) => - user.id === clickedUser.id ? { ...clickedUser, selected: !clickedUser.selected } : clickedUser + user.id === clickedUser.id ? { ...clickedUser, selected: !clickedUser.selected } : clickedUser, ) }) } diff --git a/src/components/Inbox/DialogAvatar.tsx b/src/components/Inbox/DialogAvatar.tsx index bb3382dc..875cdc98 100644 --- a/src/components/Inbox/DialogAvatar.tsx +++ b/src/components/Inbox/DialogAvatar.tsx @@ -1,8 +1,10 @@ -import { Show, createMemo } from 'solid-js' -import './DialogCard.module.scss' -import styles from './DialogAvatar.module.scss' import { clsx } from 'clsx' +import { Show, createMemo } from 'solid-js' + import { getImageUrl } from '../../utils/getImageUrl' +import './DialogCard.module.scss' + +import styles from './DialogAvatar.module.scss' type Props = { name: string @@ -25,7 +27,7 @@ const colors = [ '#668cff', '#c34cfe', '#e699ff', - '#6633ff' + '#6633ff', ] const getById = (letter: string) => @@ -42,7 +44,7 @@ const DialogAvatar = (props: Props) => { class={clsx(styles.DialogAvatar, props.class, { [styles.online]: props.online, [styles.bordered]: props.bordered, - [styles.small]: props.size === 'small' + [styles.small]: props.size === 'small', })} style={{ 'background-color': `${randomBg()}` }} > diff --git a/src/components/Inbox/DialogCard.tsx b/src/components/Inbox/DialogCard.tsx index 52465089..a3e0c4a4 100644 --- a/src/components/Inbox/DialogCard.tsx +++ b/src/components/Inbox/DialogCard.tsx @@ -1,12 +1,16 @@ -import { Show, Switch, Match, createMemo } from 'solid-js' -import DialogAvatar from './DialogAvatar' import type { ChatMember } from '../../graphql/types.gen' -import GroupDialogAvatar from './GroupDialogAvatar' + import { clsx } from 'clsx' -import styles from './DialogCard.module.scss' +import { Show, Switch, Match, createMemo } from 'solid-js' + import { useLocalize } from '../../context/localize' import { AuthorBadge } from '../Author/AuthorBadge' +import DialogAvatar from './DialogAvatar' +import GroupDialogAvatar from './GroupDialogAvatar' + +import styles from './DialogCard.module.scss' + type DialogProps = { online?: boolean message?: string @@ -22,14 +26,14 @@ type DialogProps = { const DialogCard = (props: DialogProps) => { const { t, formatTime } = useLocalize() const companions = createMemo( - () => props.members && props.members.filter((member) => member.id !== props.ownId) + () => props.members && props.members.filter((member) => member.id !== props.ownId), ) const names = createMemo( () => companions() ?.map((companion) => companion.name) - .join(', ') + .join(', '), ) return ( @@ -37,7 +41,7 @@ const DialogCard = (props: DialogProps) => {
    diff --git a/src/components/Inbox/DialogHeader.tsx b/src/components/Inbox/DialogHeader.tsx index 166b61a7..303c04ac 100644 --- a/src/components/Inbox/DialogHeader.tsx +++ b/src/components/Inbox/DialogHeader.tsx @@ -1,7 +1,9 @@ import type { Chat } from '../../graphql/types.gen' -import styles from './DialogHeader.module.scss' + import DialogCard from './DialogCard' +import styles from './DialogHeader.module.scss' + type DialogHeader = { chat: Chat ownId: number diff --git a/src/components/Inbox/GroupDialogAvatar.tsx b/src/components/Inbox/GroupDialogAvatar.tsx index 49df5ffe..dcd6dce9 100644 --- a/src/components/Inbox/GroupDialogAvatar.tsx +++ b/src/components/Inbox/GroupDialogAvatar.tsx @@ -1,10 +1,14 @@ -import { For } from 'solid-js' -import './DialogCard.module.scss' -import styles from './GroupDialogAvatar.module.scss' -import { clsx } from 'clsx' import type { ChatMember } from '../../graphql/types.gen' + +import { clsx } from 'clsx' +import { For } from 'solid-js' + import DialogAvatar from './DialogAvatar' +import './DialogCard.module.scss' + +import styles from './GroupDialogAvatar.module.scss' + type Props = { users: ChatMember[] } diff --git a/src/components/Inbox/InviteUser.tsx b/src/components/Inbox/InviteUser.tsx index 4fe85ed8..72d6b28c 100644 --- a/src/components/Inbox/InviteUser.tsx +++ b/src/components/Inbox/InviteUser.tsx @@ -1,8 +1,11 @@ -import styles from './InviteUser.module.scss' -import DialogAvatar from './DialogAvatar' import type { Author } from '../../graphql/types.gen' + import { Icon } from '../_shared/Icon' +import DialogAvatar from './DialogAvatar' + +import styles from './InviteUser.module.scss' + type DialogProps = { author: Author selected: boolean diff --git a/src/components/Inbox/Message.tsx b/src/components/Inbox/Message.tsx index c9a9df00..07bd66f0 100644 --- a/src/components/Inbox/Message.tsx +++ b/src/components/Inbox/Message.tsx @@ -1,12 +1,16 @@ -import { createSignal, Show } from 'solid-js' -import { clsx } from 'clsx' -import styles from './Message.module.scss' -import DialogAvatar from './DialogAvatar' import type { Message as MessageType, ChatMember } from '../../graphql/types.gen' + +import { clsx } from 'clsx' +import { createSignal, Show } from 'solid-js' + +import { useLocalize } from '../../context/localize' import { Icon } from '../_shared/Icon' + +import DialogAvatar from './DialogAvatar' import { MessageActionsPopup } from './MessageActionsPopup' import QuotedMessage from './QuotedMessage' -import { useLocalize } from '../../context/localize' + +import styles from './Message.module.scss' type Props = { content: MessageType diff --git a/src/components/Inbox/MessageActionsPopup.tsx b/src/components/Inbox/MessageActionsPopup.tsx index 9e0019bb..512f71cd 100644 --- a/src/components/Inbox/MessageActionsPopup.tsx +++ b/src/components/Inbox/MessageActionsPopup.tsx @@ -1,7 +1,9 @@ -import { createEffect, createSignal, For } from 'solid-js' import type { PopupProps } from '../_shared/Popup' -import { Popup } from '../_shared/Popup' + +import { createEffect, createSignal, For } from 'solid-js' + import { useLocalize } from '../../context/localize' +import { Popup } from '../_shared/Popup' export type MessageActionType = 'reply' | 'copy' | 'pin' | 'forward' | 'select' | 'delete' @@ -18,7 +20,7 @@ export const MessageActionsPopup = (props: MessageActionsPopupProps) => { { name: t('Pin'), action: 'pin' }, { name: t('Forward'), action: 'forward' }, { name: t('Select'), action: 'select' }, - { name: t('Delete'), action: 'delete' } + { name: t('Delete'), action: 'delete' }, ] createEffect(() => { if (props.actionSelect) props.actionSelect(selectedAction()) diff --git a/src/components/Inbox/MessagesFallback.tsx b/src/components/Inbox/MessagesFallback.tsx index e077f645..cbd29af2 100644 --- a/src/components/Inbox/MessagesFallback.tsx +++ b/src/components/Inbox/MessagesFallback.tsx @@ -1,4 +1,5 @@ import { Show } from 'solid-js' + import styles from './MessagesFallback.module.scss' type MessagesFallback = { diff --git a/src/components/Inbox/QuotedMessage.tsx b/src/components/Inbox/QuotedMessage.tsx index 605bff21..22c497cc 100644 --- a/src/components/Inbox/QuotedMessage.tsx +++ b/src/components/Inbox/QuotedMessage.tsx @@ -1,7 +1,9 @@ -import { Show } from 'solid-js' -import styles from './QuotedMessage.module.scss' -import { Icon } from '../_shared/Icon' import { clsx } from 'clsx' +import { Show } from 'solid-js' + +import { Icon } from '../_shared/Icon' + +import styles from './QuotedMessage.module.scss' type QuotedMessage = { body: string @@ -17,7 +19,7 @@ const QuotedMessage = (props: QuotedMessage) => { class={clsx(styles.QuotedMessage, { [styles.reply]: props.variant === 'reply', [styles.inline]: props.variant === 'inline', - [styles.own]: props.isOwn + [styles.own]: props.isOwn, })} > diff --git a/src/components/Inbox/Search.tsx b/src/components/Inbox/Search.tsx index 90ce7423..62bb4350 100644 --- a/src/components/Inbox/Search.tsx +++ b/src/components/Inbox/Search.tsx @@ -1,7 +1,9 @@ -import styles from './Search.module.scss' import { createSignal } from 'solid-js' + import { Icon } from '../_shared/Icon' +import styles from './Search.module.scss' + type Props = { placeholder: string onChange: (value: () => string) => void diff --git a/src/components/Nav/AuthModal/AuthModalHeader/AuthModalHeader.tsx b/src/components/Nav/AuthModal/AuthModalHeader/AuthModalHeader.tsx index 5aeff24a..80ad5330 100644 --- a/src/components/Nav/AuthModal/AuthModalHeader/AuthModalHeader.tsx +++ b/src/components/Nav/AuthModal/AuthModalHeader/AuthModalHeader.tsx @@ -1,9 +1,11 @@ -import styles from './AuthModalHeader.module.scss' import { Show } from 'solid-js' + import { useLocalize } from '../../../../context/localize' import { useRouter } from '../../../../stores/router' import { AuthModalSearchParams } from '../types' +import styles from './AuthModalHeader.module.scss' + type Props = { modalType: 'login' | 'register' } @@ -14,7 +16,7 @@ export const AuthModalHeader = (props: Props) => { const { source } = searchParams() const generateModalTextsFromSource = ( - modalType: 'login' | 'register' + modalType: 'login' | 'register', ): { title: string; description: string } => { const title = modalType === 'login' ? 'Welcome to Discours' : 'Create account' @@ -22,53 +24,53 @@ export const AuthModalHeader = (props: Props) => { case 'create': { return { title: t(`${title} to publish articles`), - description: '' + description: '', } } case 'bookmark': { return { title: t(`${title} to add to your bookmarks`), description: t( - 'In bookmarks, you can save favorite discussions and materials that you want to return to' - ) + 'In bookmarks, you can save favorite discussions and materials that you want to return to', + ), } } case 'discussions': { return { title: t(`${title} to participate in discussions`), description: t( - "You ll be able to participate in discussions, rate others' comments and learn about new responses" - ) + "You ll be able to participate in discussions, rate others' comments and learn about new responses", + ), } } case 'follow': { return { title: t(`${title} to subscribe`), description: t( - 'This way you ll be able to subscribe to authors, interesting topics and customize your feed' - ) + 'This way you ll be able to subscribe to authors, interesting topics and customize your feed', + ), } } case 'subscribe': { return { title: t(`${title} to subscribe to new publications`), description: t( - 'This way you ll be able to subscribe to authors, interesting topics and customize your feed' - ) + 'This way you ll be able to subscribe to authors, interesting topics and customize your feed', + ), } } case 'vote': { return { title: t(`${title} to vote`), description: t( - 'This way we ll realize that you re a real person and ll take your vote into account. And you ll see how others voted' - ) + 'This way we ll realize that you re a real person and ll take your vote into account. And you ll see how others voted', + ), } } default: { return { title: t(title), - description: '' + description: '', } } } diff --git a/src/components/Nav/AuthModal/EmailConfirm.tsx b/src/components/Nav/AuthModal/EmailConfirm.tsx index d9bf9828..fa57007c 100644 --- a/src/components/Nav/AuthModal/EmailConfirm.tsx +++ b/src/components/Nav/AuthModal/EmailConfirm.tsx @@ -1,18 +1,21 @@ -import styles from './AuthModal.module.scss' -import { clsx } from 'clsx' -import { hideModal } from '../../../stores/ui' -import { createMemo, createSignal, onMount, Show } from 'solid-js' -import { useRouter } from '../../../stores/router' import type { ConfirmEmailSearchParams } from './types' -import { ApiError } from '../../../utils/apiClient' -import { useSession } from '../../../context/session' + +import { clsx } from 'clsx' +import { createMemo, createSignal, onMount, Show } from 'solid-js' + import { useLocalize } from '../../../context/localize' +import { useSession } from '../../../context/session' +import { useRouter } from '../../../stores/router' +import { hideModal } from '../../../stores/ui' +import { ApiError } from '../../../utils/apiClient' + +import styles from './AuthModal.module.scss' export const EmailConfirm = () => { const { t } = useLocalize() const { session, - actions: { confirmEmail } + actions: { confirmEmail }, } = useSession() const [isTokenExpired, setIsTokenExpired] = createSignal(false) diff --git a/src/components/Nav/AuthModal/ForgotPasswordForm.tsx b/src/components/Nav/AuthModal/ForgotPasswordForm.tsx index 4d28d027..31c59da7 100644 --- a/src/components/Nav/AuthModal/ForgotPasswordForm.tsx +++ b/src/components/Nav/AuthModal/ForgotPasswordForm.tsx @@ -1,14 +1,18 @@ -import styles from './AuthModal.module.scss' +import type { AuthModalSearchParams } from './types' + import { clsx } from 'clsx' import { createSignal, JSX, Show } from 'solid-js' -import { useRouter } from '../../../stores/router' -import { email, setEmail } from './sharedLogic' -import type { AuthModalSearchParams } from './types' -import { ApiError } from '../../../utils/apiClient' -import { signSendLink } from '../../../stores/auth' + import { useLocalize } from '../../../context/localize' +import { signSendLink } from '../../../stores/auth' +import { useRouter } from '../../../stores/router' +import { ApiError } from '../../../utils/apiClient' import { validateEmail } from '../../../utils/validateEmail' +import { email, setEmail } from './sharedLogic' + +import styles from './AuthModal.module.scss' + type FormFields = { email: string } @@ -83,7 +87,7 @@ export const ForgotPasswordForm = () => {
    { onClick={(event) => { event.preventDefault() changeSearchParam({ - mode: 'register' + mode: 'register', }) }} > @@ -138,7 +142,7 @@ export const ForgotPasswordForm = () => { class={styles.authLink} onClick={() => changeSearchParam({ - mode: 'login' + mode: 'login', }) } > diff --git a/src/components/Nav/AuthModal/LoginForm.tsx b/src/components/Nav/AuthModal/LoginForm.tsx index f468d230..25f45594 100644 --- a/src/components/Nav/AuthModal/LoginForm.tsx +++ b/src/components/Nav/AuthModal/LoginForm.tsx @@ -1,19 +1,23 @@ -import styles from './AuthModal.module.scss' -import { clsx } from 'clsx' -import { SocialProviders } from './SocialProviders' -import { ApiError } from '../../../utils/apiClient' -import { createSignal, Show } from 'solid-js' -import { email, setEmail } from './sharedLogic' -import { useRouter } from '../../../stores/router' import type { AuthModalSearchParams } from './types' -import { hideModal } from '../../../stores/ui' -import { useSession } from '../../../context/session' -import { signSendLink } from '../../../stores/auth' -import { validateEmail } from '../../../utils/validateEmail' -import { useSnackbar } from '../../../context/snackbar' + +import { clsx } from 'clsx' +import { createSignal, Show } from 'solid-js' + import { useLocalize } from '../../../context/localize' +import { useSession } from '../../../context/session' +import { useSnackbar } from '../../../context/snackbar' +import { signSendLink } from '../../../stores/auth' +import { useRouter } from '../../../stores/router' +import { hideModal } from '../../../stores/ui' +import { ApiError } from '../../../utils/apiClient' +import { validateEmail } from '../../../utils/validateEmail' import { Icon } from '../../_shared/Icon' + import { AuthModalHeader } from './AuthModalHeader' +import { email, setEmail } from './sharedLogic' +import { SocialProviders } from './SocialProviders' + +import styles from './AuthModal.module.scss' type FormFields = { email: string @@ -36,11 +40,11 @@ export const LoginForm = () => { const authFormRef: { current: HTMLFormElement } = { current: null } const { - actions: { showSnackbar } + actions: { showSnackbar }, } = useSnackbar() const { - actions: { signIn } + actions: { signIn }, } = useSession() const { changeSearchParam } = useRouter() @@ -144,7 +148,7 @@ export const LoginForm = () => {
    {
    { class="link" onClick={() => changeSearchParam({ - mode: 'forgot-password' + mode: 'forgot-password', }) } > @@ -215,7 +219,7 @@ export const LoginForm = () => { class={styles.authLink} onClick={() => changeSearchParam({ - mode: 'register' + mode: 'register', }) } > diff --git a/src/components/Nav/AuthModal/RegisterForm.tsx b/src/components/Nav/AuthModal/RegisterForm.tsx index 152c0ad5..d2f9c9f2 100644 --- a/src/components/Nav/AuthModal/RegisterForm.tsx +++ b/src/components/Nav/AuthModal/RegisterForm.tsx @@ -1,20 +1,24 @@ -import { Show, createSignal } from 'solid-js' -import type { JSX } from 'solid-js' -import styles from './AuthModal.module.scss' -import { clsx } from 'clsx' -import { SocialProviders } from './SocialProviders' -import { ApiError } from '../../../utils/apiClient' -import { email, setEmail } from './sharedLogic' -import { useRouter } from '../../../stores/router' import type { AuthModalSearchParams } from './types' -import { hideModal } from '../../../stores/ui' -import { checkEmail, useEmailChecks } from '../../../stores/emailChecks' -import { register } from '../../../stores/auth' +import type { JSX } from 'solid-js' + +import { clsx } from 'clsx' +import { Show, createSignal } from 'solid-js' + import { useLocalize } from '../../../context/localize' +import { register } from '../../../stores/auth' +import { checkEmail, useEmailChecks } from '../../../stores/emailChecks' +import { useRouter } from '../../../stores/router' +import { hideModal } from '../../../stores/ui' +import { ApiError } from '../../../utils/apiClient' import { validateEmail } from '../../../utils/validateEmail' -import { AuthModalHeader } from './AuthModalHeader' import { Icon } from '../../_shared/Icon' +import { AuthModalHeader } from './AuthModalHeader' +import { email, setEmail } from './sharedLogic' +import { SocialProviders } from './SocialProviders' + +import styles from './AuthModal.module.scss' + type FormFields = { fullName: string email: string @@ -126,7 +130,7 @@ export const RegisterForm = () => { await register({ name: cleanName, email: cleanEmail, - password: password() + password: password(), }) setIsSuccess(true) @@ -156,7 +160,7 @@ export const RegisterForm = () => {
    {
    { onClick={(event) => { event.preventDefault() changeSearchParam({ - mode: 'login' + mode: 'login', }) }} > @@ -211,7 +215,7 @@ export const RegisterForm = () => {
    { class={styles.authLink} onClick={() => changeSearchParam({ - mode: 'login' + mode: 'login', }) } > diff --git a/src/components/Nav/AuthModal/SocialProviders.tsx b/src/components/Nav/AuthModal/SocialProviders.tsx index e23f9dfa..f80f593c 100644 --- a/src/components/Nav/AuthModal/SocialProviders.tsx +++ b/src/components/Nav/AuthModal/SocialProviders.tsx @@ -1,9 +1,9 @@ -import { Icon } from '../../_shared/Icon' +import { useLocalize } from '../../../context/localize' import { hideModal } from '../../../stores/ui' +import { apiBaseUrl } from '../../../utils/config' +import { Icon } from '../../_shared/Icon' import styles from './SocialProviders.module.scss' -import { apiBaseUrl } from '../../../utils/config' -import { useLocalize } from '../../../context/localize' type Provider = 'facebook' | 'google' | 'vk' | 'github' diff --git a/src/components/Nav/AuthModal/index.tsx b/src/components/Nav/AuthModal/index.tsx index 7a2a8e27..0823d5b3 100644 --- a/src/components/Nav/AuthModal/index.tsx +++ b/src/components/Nav/AuthModal/index.tsx @@ -1,22 +1,26 @@ -import { Dynamic } from 'solid-js/web' -import { Show, Component, createEffect, createMemo } from 'solid-js' -import { hideModal } from '../../../stores/ui' -import { useRouter } from '../../../stores/router' -import { clsx } from 'clsx' -import styles from './AuthModal.module.scss' -import { LoginForm } from './LoginForm' -import { isMobile } from '../../../utils/media-query' -import { RegisterForm } from './RegisterForm' -import { ForgotPasswordForm } from './ForgotPasswordForm' -import { EmailConfirm } from './EmailConfirm' import type { AuthModalMode, AuthModalSearchParams } from './types' + +import { clsx } from 'clsx' +import { Show, Component, createEffect, createMemo } from 'solid-js' +import { Dynamic } from 'solid-js/web' + import { useLocalize } from '../../../context/localize' +import { useRouter } from '../../../stores/router' +import { hideModal } from '../../../stores/ui' +import { isMobile } from '../../../utils/media-query' + +import { EmailConfirm } from './EmailConfirm' +import { ForgotPasswordForm } from './ForgotPasswordForm' +import { LoginForm } from './LoginForm' +import { RegisterForm } from './RegisterForm' + +import styles from './AuthModal.module.scss' const AUTH_MODAL_MODES: Record = { login: LoginForm, register: RegisterForm, 'forgot-password': ForgotPasswordForm, - 'confirm-email': EmailConfirm + 'confirm-email': EmailConfirm, } export const AuthModal = () => { @@ -40,7 +44,7 @@ export const AuthModal = () => {
    @@ -54,7 +58,7 @@ export const AuthModal = () => {

    {t(`Join the global community of authors!`)}

    {t( - 'Get to know the most intelligent people of our time, edit and discuss the articles, share your expertise, rate and decide what to publish in the magazine' + 'Get to know the most intelligent people of our time, edit and discuss the articles, share your expertise, rate and decide what to publish in the magazine', )} .  {t('New stories every day and even more!')} @@ -77,7 +81,7 @@ export const AuthModal = () => {

    diff --git a/src/components/Nav/ConfirmModal/ConfirmModal.tsx b/src/components/Nav/ConfirmModal/ConfirmModal.tsx index 63f6a767..767eb535 100644 --- a/src/components/Nav/ConfirmModal/ConfirmModal.tsx +++ b/src/components/Nav/ConfirmModal/ConfirmModal.tsx @@ -1,6 +1,7 @@ import { useConfirm } from '../../../context/confirm' import { useLocalize } from '../../../context/localize' import { Button } from '../../_shared/Button' + import styles from './ConfirmModal.module.scss' export const ConfirmModal = () => { @@ -8,7 +9,7 @@ export const ConfirmModal = () => { const { confirmMessage, - actions: { resolveConfirm } + actions: { resolveConfirm }, } = useConfirm() return ( diff --git a/src/components/Nav/Confirmed.tsx b/src/components/Nav/Confirmed.tsx index 09adf3c2..fe615284 100644 --- a/src/components/Nav/Confirmed.tsx +++ b/src/components/Nav/Confirmed.tsx @@ -1,5 +1,6 @@ import './Confirmed.scss' import { onMount } from 'solid-js' + import { useLocalize } from '../../context/localize' export const Confirmed = (props: { token?: string }) => { diff --git a/src/components/Nav/Header/Header.tsx b/src/components/Nav/Header/Header.tsx index 7dbe5026..0c1a8087 100644 --- a/src/components/Nav/Header/Header.tsx +++ b/src/components/Nav/Header/Header.tsx @@ -1,29 +1,28 @@ -import { Show, createSignal, createEffect, onMount, onCleanup, For } from 'solid-js' -import { getPagePath, redirectPage } from '@nanostores/router' -import { clsx } from 'clsx' - -import { Modal } from '../Modal' -import { AuthModal } from '../AuthModal' -import { HeaderAuth } from '../HeaderAuth' -import { ConfirmModal } from '../ConfirmModal' -import { getShareUrl, SharePopup } from '../../Article/SharePopup' -import { Snackbar } from '../Snackbar' -import { Icon } from '../../_shared/Icon' import type { Topic } from '../../../graphql/types.gen' -import { useModalStore } from '../../../stores/ui' -import { router, ROUTES, useRouter } from '../../../stores/router' - -import { getDescription } from '../../../utils/meta' +import { getPagePath, redirectPage } from '@nanostores/router' +import { clsx } from 'clsx' +import { Show, createSignal, createEffect, onMount, onCleanup, For } from 'solid-js' import { useLocalize } from '../../../context/localize' import { useSession } from '../../../context/session' +import { router, ROUTES, useRouter } from '../../../stores/router' +import { useModalStore } from '../../../stores/ui' +import { apiClient } from '../../../utils/apiClient' +import { getDescription } from '../../../utils/meta' +import { Icon } from '../../_shared/Icon' +import { Subscribe } from '../../_shared/Subscribe' +import { getShareUrl, SharePopup } from '../../Article/SharePopup' +import { RANDOM_TOPICS_COUNT } from '../../Views/Home' +import { AuthModal } from '../AuthModal' +import { ConfirmModal } from '../ConfirmModal' +import { HeaderAuth } from '../HeaderAuth' +import { Modal } from '../Modal' +import { Snackbar } from '../Snackbar' + +import { Link } from './Link' import styles from './Header.module.scss' -import { apiClient } from '../../../utils/apiClient' -import { RANDOM_TOPICS_COUNT } from '../../Views/Home' -import { Link } from './Link' -import { Subscribe } from '../../_shared/Subscribe' type Props = { title?: string @@ -47,7 +46,7 @@ export const Header = (props: Props) => { const { modal } = useModalStore() const { page } = useRouter() const { - actions: { requireAuthentication } + actions: { requireAuthentication }, } = useSession() const { searchParams } = useRouter() @@ -167,7 +166,7 @@ export const Header = (props: Props) => { [styles.headerScrolledTop]: !getIsScrollingBottom() && getIsScrolled(), [styles.headerScrolledBottom]: (getIsScrollingBottom() && getIsScrolled() && !isProfilePopupVisible()) || isSharePopupVisible(), - [styles.headerWithTitle]: Boolean(props.title) + [styles.headerWithTitle]: Boolean(props.title), }} > {

    diff --git a/src/components/Nav/Header/Link.tsx b/src/components/Nav/Header/Link.tsx index bbad79b9..67cf5318 100644 --- a/src/components/Nav/Header/Link.tsx +++ b/src/components/Nav/Header/Link.tsx @@ -1,8 +1,10 @@ -import styles from './Header.module.scss' -import { router, ROUTES, useRouter } from '../../../stores/router' -import { clsx } from 'clsx' -import { ConditionalWrapper } from '../../_shared/ConditionalWrapper' import { getPagePath } from '@nanostores/router' +import { clsx } from 'clsx' + +import { router, ROUTES, useRouter } from '../../../stores/router' +import { ConditionalWrapper } from '../../_shared/ConditionalWrapper' + +import styles from './Header.module.scss' type Props = { onMouseOver: (event?: MouseEvent, time?: number) => void diff --git a/src/components/Nav/HeaderAuth.tsx b/src/components/Nav/HeaderAuth.tsx index 1ca47d3b..f1784d9a 100644 --- a/src/components/Nav/HeaderAuth.tsx +++ b/src/components/Nav/HeaderAuth.tsx @@ -1,19 +1,22 @@ -import styles from './Header/Header.module.scss' -import { clsx } from 'clsx' -import { router, useRouter } from '../../stores/router' -import { Icon } from '../_shared/Icon' -import { createMemo, createSignal, onCleanup, onMount, Show } from 'solid-js' -import { ProfilePopup } from './ProfilePopup' -import { Userpic } from '../Author/Userpic' -import { showModal } from '../../stores/ui' -import { ShowOnlyOnClient } from '../_shared/ShowOnlyOnClient' -import { useSession } from '../../context/session' -import { useLocalize } from '../../context/localize' import { getPagePath } from '@nanostores/router' -import { Button } from '../_shared/Button' +import { clsx } from 'clsx' +import { createMemo, createSignal, onCleanup, onMount, Show } from 'solid-js' + import { useEditorContext } from '../../context/editor' -import { Popover } from '../_shared/Popover' +import { useLocalize } from '../../context/localize' import { useNotifications } from '../../context/notifications' +import { useSession } from '../../context/session' +import { router, useRouter } from '../../stores/router' +import { showModal } from '../../stores/ui' +import { Button } from '../_shared/Button' +import { Icon } from '../_shared/Icon' +import { Popover } from '../_shared/Popover' +import { ShowOnlyOnClient } from '../_shared/ShowOnlyOnClient' +import { Userpic } from '../Author/Userpic' + +import { ProfilePopup } from './ProfilePopup' + +import styles from './Header/Header.module.scss' type Props = { setIsProfilePopupVisible: (value: boolean) => void @@ -32,12 +35,12 @@ export const HeaderAuth = (props: Props) => { const { session, isSessionLoaded, isAuthenticated } = useSession() const { unreadNotificationsCount, - actions: { showNotificationsPanel } + actions: { showNotificationsPanel }, } = useNotifications() const { form, - actions: { toggleEditorPanel, saveShout, publishShout } + actions: { toggleEditorPanel, saveShout, publishShout }, } = useEditorContext() const handleBellIconClick = (event: Event) => { @@ -158,7 +161,7 @@ export const HeaderAuth = (props: Props) => { {renderIconedButton({ value: t('Save'), icon: 'save', - action: handleSaveButtonClick + action: handleSaveButtonClick, })}
    @@ -166,7 +169,7 @@ export const HeaderAuth = (props: Props) => { {renderIconedButton({ value: t('Publish'), icon: 'publish', - action: handlePublishButtonClick + action: handlePublishButtonClick, })}
    diff --git a/src/components/Nav/Modal/Modal.tsx b/src/components/Nav/Modal/Modal.tsx index 0b6e1415..a1fe5380 100644 --- a/src/components/Nav/Modal/Modal.tsx +++ b/src/components/Nav/Modal/Modal.tsx @@ -1,13 +1,15 @@ -import { createEffect, createMemo, createSignal, Show } from 'solid-js' import type { JSX } from 'solid-js' + +import { redirectPage } from '@nanostores/router' import { clsx } from 'clsx' +import { createEffect, createMemo, createSignal, Show } from 'solid-js' + +import { router } from '../../../stores/router' import { hideModal, useModalStore } from '../../../stores/ui' import { useEscKeyDownHandler } from '../../../utils/useEscKeyDownHandler' +import { Icon } from '../../_shared/Icon' import styles from './Modal.module.scss' -import { redirectPage } from '@nanostores/router' -import { router } from '../../../stores/router' -import { Icon } from '../../_shared/Icon' interface Props { name: string @@ -50,7 +52,7 @@ export const Modal = (props: Props) => { [styles.narrow]: props.variant === 'narrow', ['col-auto col-md-20 offset-md-2 col-lg-14 offset-lg-5']: props.variant === 'medium', [styles.noPadding]: props.noPadding, - [styles.maxHeight]: props.maxHeight + [styles.maxHeight]: props.maxHeight, })} onClick={(event) => event.stopPropagation()} > diff --git a/src/components/Nav/Modal/Opener.tsx b/src/components/Nav/Modal/Opener.tsx index b13e0007..a56d7f69 100644 --- a/src/components/Nav/Modal/Opener.tsx +++ b/src/components/Nav/Modal/Opener.tsx @@ -1,5 +1,6 @@ -import type { JSX } from 'solid-js/jsx-runtime' import type { ModalType } from '../../../stores/ui' +import type { JSX } from 'solid-js/jsx-runtime' + import { showModal } from '../../../stores/ui' export default (props: { name: ModalType; children: JSX.Element }) => { diff --git a/src/components/Nav/ProfilePopup.tsx b/src/components/Nav/ProfilePopup.tsx index 6e6efba5..3427fd52 100644 --- a/src/components/Nav/ProfilePopup.tsx +++ b/src/components/Nav/ProfilePopup.tsx @@ -1,17 +1,20 @@ -import { useSession } from '../../context/session' import type { PopupProps } from '../_shared/Popup' -import { Popup } from '../_shared/Popup' -import styles from '../_shared/Popup/Popup.module.scss' + import { getPagePath } from '@nanostores/router' -import { router } from '../../stores/router' + import { useLocalize } from '../../context/localize' +import { useSession } from '../../context/session' +import { router } from '../../stores/router' +import { Popup } from '../_shared/Popup' + +import styles from '../_shared/Popup/Popup.module.scss' type ProfilePopupProps = Omit export const ProfilePopup = (props: ProfilePopupProps) => { const { user, - actions: { signOut } + actions: { signOut }, } = useSession() const { t } = useLocalize() diff --git a/src/components/Nav/ProfileSettingsNavigation/ProfileSettingsNavigation.tsx b/src/components/Nav/ProfileSettingsNavigation/ProfileSettingsNavigation.tsx index 76e96c85..228f0b0a 100644 --- a/src/components/Nav/ProfileSettingsNavigation/ProfileSettingsNavigation.tsx +++ b/src/components/Nav/ProfileSettingsNavigation/ProfileSettingsNavigation.tsx @@ -1,8 +1,10 @@ -import styles from './ProfileSettingsNavigation.module.scss' import { clsx } from 'clsx' + import { useLocalize } from '../../../context/localize' import { useRouter } from '../../../stores/router' +import styles from './ProfileSettingsNavigation.module.scss' + export const ProfileSettingsNavigation = () => { const { t } = useLocalize() const { page } = useRouter() diff --git a/src/components/Nav/Snackbar.tsx b/src/components/Nav/Snackbar.tsx index ac9b1091..59bbc634 100644 --- a/src/components/Nav/Snackbar.tsx +++ b/src/components/Nav/Snackbar.tsx @@ -1,11 +1,13 @@ -import { Show } from 'solid-js' -import { useSnackbar } from '../../context/snackbar' -import styles from './Snackbar.module.scss' -import { Transition } from 'solid-transition-group' import { clsx } from 'clsx' +import { Show } from 'solid-js' +import { Transition } from 'solid-transition-group' + +import { useSnackbar } from '../../context/snackbar' import { Icon } from '../_shared/Icon' import { ShowOnlyOnClient } from '../_shared/ShowOnlyOnClient' +import styles from './Snackbar.module.scss' + export const Snackbar = () => { const { snackbarMessage } = useSnackbar() @@ -13,7 +15,7 @@ export const Snackbar = () => {
    diff --git a/src/components/Nav/Topics/Topics.tsx b/src/components/Nav/Topics/Topics.tsx index 11662329..2248a639 100644 --- a/src/components/Nav/Topics/Topics.tsx +++ b/src/components/Nav/Topics/Topics.tsx @@ -1,9 +1,11 @@ -import { Icon } from '../../_shared/Icon' -import { useLocalize } from '../../../context/localize' -import styles from './Topics.module.scss' -import { clsx } from 'clsx' -import { router, useRouter } from '../../../stores/router' import { getPagePath } from '@nanostores/router' +import { clsx } from 'clsx' + +import { useLocalize } from '../../../context/localize' +import { router, useRouter } from '../../../stores/router' +import { Icon } from '../../_shared/Icon' + +import styles from './Topics.module.scss' export const Topics = () => { const { t } = useLocalize() diff --git a/src/components/NotificationsPanel/EmptyMessage/EmptyMessage.tsx b/src/components/NotificationsPanel/EmptyMessage/EmptyMessage.tsx index 855009ff..39e0e597 100644 --- a/src/components/NotificationsPanel/EmptyMessage/EmptyMessage.tsx +++ b/src/components/NotificationsPanel/EmptyMessage/EmptyMessage.tsx @@ -1,7 +1,9 @@ import { clsx } from 'clsx' -import styles from './EmptyMessage.module.scss' + import { useLocalize } from '../../../context/localize' +import styles from './EmptyMessage.module.scss' + export const EmptyMessage = () => { const { t } = useLocalize() diff --git a/src/components/NotificationsPanel/NotificationView/NotificationView.tsx b/src/components/NotificationsPanel/NotificationView/NotificationView.tsx index ae5b1dd9..5751884b 100644 --- a/src/components/NotificationsPanel/NotificationView/NotificationView.tsx +++ b/src/components/NotificationsPanel/NotificationView/NotificationView.tsx @@ -1,15 +1,18 @@ -import { clsx } from 'clsx' import type { Notification } from '../../../graphql/types.gen' -import { createMemo, createSignal, onMount, Show } from 'solid-js' -import { NotificationType } from '../../../graphql/types.gen' -import { getPagePath, openPage } from '@nanostores/router' -import { router, useRouter } from '../../../stores/router' -import { useNotifications } from '../../../context/notifications' -import { useLocalize } from '../../../context/localize' import type { ArticlePageSearchParams } from '../../Article/FullArticle' -import { TimeAgo } from '../../_shared/TimeAgo' -import styles from './NotificationView.module.scss' + +import { getPagePath, openPage } from '@nanostores/router' +import { clsx } from 'clsx' +import { createMemo, createSignal, onMount, Show } from 'solid-js' + +import { useLocalize } from '../../../context/localize' +import { useNotifications } from '../../../context/notifications' +import { NotificationType } from '../../../graphql/types.gen' +import { router, useRouter } from '../../../stores/router' import { GroupAvatar } from '../../_shared/GroupAvatar' +import { TimeAgo } from '../../_shared/TimeAgo' + +import styles from './NotificationView.module.scss' type Props = { notification: Notification @@ -36,7 +39,7 @@ type NotificationData = { export const NotificationView = (props: Props) => { const { - actions: { markNotificationAsRead, hideNotificationsPanel } + actions: { markNotificationAsRead, hideNotificationsPanel }, } = useNotifications() const { changeSearchParam } = useRouter() @@ -89,7 +92,7 @@ export const NotificationView = (props: Props) => { return ( <> {t('NotificationNewCommentText1', { - commentsCount: props.notification.occurrences + commentsCount: props.notification.occurrences, })}{' '} {shoutTitle} @@ -99,7 +102,7 @@ export const NotificationView = (props: Props) => { {lastUser().name} {' '} {t('NotificationNewCommentText3', { - restUsersCount: data().users.length - 1 + restUsersCount: data().users.length - 1, })} ) @@ -108,7 +111,7 @@ export const NotificationView = (props: Props) => { return ( <> {t('NotificationNewReplyText1', { - commentsCount: props.notification.occurrences + commentsCount: props.notification.occurrences, })}{' '} {shoutTitle} @@ -118,7 +121,7 @@ export const NotificationView = (props: Props) => { {lastUser().name} {' '} {t('NotificationNewReplyText3', { - restUsersCount: data().users.length - 1 + restUsersCount: data().users.length - 1, })} ) @@ -158,7 +161,7 @@ export const NotificationView = (props: Props) => {
    diff --git a/src/components/NotificationsPanel/NotificationsPanel.tsx b/src/components/NotificationsPanel/NotificationsPanel.tsx index 30619e70..72ed3780 100644 --- a/src/components/NotificationsPanel/NotificationsPanel.tsx +++ b/src/components/NotificationsPanel/NotificationsPanel.tsx @@ -1,16 +1,19 @@ import { clsx } from 'clsx' -import styles from './NotificationsPanel.module.scss' +import { createEffect, createMemo, createSignal, For, on, onCleanup, onMount, Show } from 'solid-js' +import { throttle } from 'throttle-debounce' + +import { useLocalize } from '../../context/localize' +import { PAGE_SIZE, useNotifications } from '../../context/notifications' +import { useSession } from '../../context/session' import { useEscKeyDownHandler } from '../../utils/useEscKeyDownHandler' import { useOutsideClickHandler } from '../../utils/useOutsideClickHandler' -import { useLocalize } from '../../context/localize' -import { Icon } from '../_shared/Icon' -import { createEffect, createMemo, createSignal, For, on, onCleanup, onMount, Show } from 'solid-js' -import { PAGE_SIZE, useNotifications } from '../../context/notifications' -import { NotificationView } from './NotificationView' -import { EmptyMessage } from './EmptyMessage' import { Button } from '../_shared/Button' -import { throttle } from 'throttle-debounce' -import { useSession } from '../../context/session' +import { Icon } from '../_shared/Icon' + +import { EmptyMessage } from './EmptyMessage' +import { NotificationView } from './NotificationView' + +import styles from './NotificationsPanel.module.scss' type Props = { isOpen: boolean @@ -51,20 +54,20 @@ export const NotificationsPanel = (props: Props) => { unreadNotificationsCount, loadedNotificationsCount, totalNotificationsCount, - actions: { loadNotifications, markAllNotificationsAsRead } + actions: { loadNotifications, markAllNotificationsAsRead }, } = useNotifications() const handleHide = () => { props.onClose() } const panelRef: { current: HTMLDivElement } = { - current: null + current: null, } useOutsideClickHandler({ containerRef: panelRef, predicate: () => props.isOpen, - handler: () => handleHide() + handler: () => handleHide(), }) let windowScrollTop = 0 @@ -150,14 +153,14 @@ export const NotificationsPanel = (props: Props) => { await loadNextPage() setIsLoading(false) } - } - ) + }, + ), ) return (
    (panelRef.current = el)} class={styles.panel}> diff --git a/src/components/TableOfContents/TableOfContents.tsx b/src/components/TableOfContents/TableOfContents.tsx index d35601e9..23632214 100644 --- a/src/components/TableOfContents/TableOfContents.tsx +++ b/src/components/TableOfContents/TableOfContents.tsx @@ -1,12 +1,14 @@ -import { For, Show, createSignal, createEffect, on, onMount, onCleanup } from 'solid-js' import { clsx } from 'clsx' -import { DEFAULT_HEADER_OFFSET } from '../../stores/router' -import { useLocalize } from '../../context/localize' -import { Icon } from '../_shared/Icon' -import styles from './TableOfContents.module.scss' -import { isDesktop } from '../../utils/media-query' +import { For, Show, createSignal, createEffect, on, onMount, onCleanup } from 'solid-js' import { throttle, debounce } from 'throttle-debounce' +import { useLocalize } from '../../context/localize' +import { DEFAULT_HEADER_OFFSET } from '../../stores/router' +import { isDesktop } from '../../utils/media-query' +import { Icon } from '../_shared/Icon' + +import styles from './TableOfContents.module.scss' + interface Props { variant: 'article' | 'editor' parentSelector: string @@ -23,7 +25,7 @@ const scrollToHeader = (element) => { top: element.getBoundingClientRect().top - document.body.getBoundingClientRect().top - - DEFAULT_HEADER_OFFSET + DEFAULT_HEADER_OFFSET, }) } @@ -43,7 +45,7 @@ export const TableOfContents = (props: Props) => { const updateHeadings = () => { setHeadings( // eslint-disable-next-line unicorn/prefer-spread - Array.from(document.querySelector(props.parentSelector).querySelectorAll('h2, h3, h4')) + Array.from(document.querySelector(props.parentSelector).querySelectorAll('h2, h3, h4')), ) setAreHeadingsLoaded(true) } @@ -58,8 +60,8 @@ export const TableOfContents = (props: Props) => { createEffect( on( () => props.body, - () => debouncedUpdateHeadings() - ) + () => debouncedUpdateHeadings(), + ), ) onMount(() => { @@ -75,7 +77,7 @@ export const TableOfContents = (props: Props) => { >
    @@ -92,7 +94,7 @@ export const TableOfContents = (props: Props) => { class={clsx(styles.TableOfContentsHeadingsItem, { [styles.TableOfContentsHeadingsItemH3]: h.nodeName === 'H3', [styles.TableOfContentsHeadingsItemH4]: h.nodeName === 'H4', - [styles.active]: index() === activeHeaderIndex() + [styles.active]: index() === activeHeaderIndex(), })} innerHTML={h.textContent} onClick={(e) => { @@ -111,9 +113,9 @@ export const TableOfContents = (props: Props) => { class={clsx( styles.TableOfContentsPrimaryButton, { - [styles.TableOfContentsPrimaryButtonLefted]: props.variant === 'editor' && !isVisible() + [styles.TableOfContentsPrimaryButtonLefted]: props.variant === 'editor' && !isVisible(), }, - 'd-none d-xl-block' + 'd-none d-xl-block', )} onClick={(e) => { e.preventDefault() @@ -149,9 +151,9 @@ export const TableOfContents = (props: Props) => { class={clsx( styles.TableOfContentsPrimaryButton, { - [styles.TableOfContentsPrimaryButtonLefted]: props.variant === 'editor' && !isVisible() + [styles.TableOfContentsPrimaryButtonLefted]: props.variant === 'editor' && !isVisible(), }, - 'd-xl-none' + 'd-xl-none', )} onClick={(e) => { e.preventDefault() diff --git a/src/components/Topic/Card.tsx b/src/components/Topic/Card.tsx index 7dab0cf0..584aaed5 100644 --- a/src/components/Topic/Card.tsx +++ b/src/components/Topic/Card.tsx @@ -1,19 +1,20 @@ -import { createMemo, createSignal, Show } from 'solid-js' import type { Topic } from '../../graphql/types.gen' -import { FollowingEntity } from '../../graphql/types.gen' -import { follow, unfollow } from '../../stores/zine/common' import { clsx } from 'clsx' -import { useSession } from '../../context/session' -import { ShowOnlyOnClient } from '../_shared/ShowOnlyOnClient' -import { Icon } from '../_shared/Icon' +import { createMemo, createSignal, Show } from 'solid-js' + import { useLocalize } from '../../context/localize' -import { CardTopic } from '../Feed/CardTopic' -import { CheckButton } from '../_shared/CheckButton' +import { useSession } from '../../context/session' +import { FollowingEntity } from '../../graphql/types.gen' +import { follow, unfollow } from '../../stores/zine/common' import { capitalize } from '../../utils/capitalize' +import { Button } from '../_shared/Button' +import { CheckButton } from '../_shared/CheckButton' +import { Icon } from '../_shared/Icon' +import { ShowOnlyOnClient } from '../_shared/ShowOnlyOnClient' +import { CardTopic } from '../Feed/CardTopic' import styles from './Card.module.scss' -import { Button } from '../_shared/Button' import stylesButton from '../_shared/Button/Button.module.scss' interface TopicProps { @@ -38,7 +39,7 @@ export const TopicCard = (props: TopicProps) => { const { subscriptions, isSessionLoaded, - actions: { loadSubscriptions, requireAuthentication } + actions: { loadSubscriptions, requireAuthentication }, } = useSession() const [isSubscribing, setIsSubscribing] = createSignal(false) @@ -89,7 +90,7 @@ export const TopicCard = (props: TopicProps) => { classList={{ row: !props.subscribeButtonBottom, [styles.topicCompact]: props.compact, - [styles.topicInRow]: props.isTopicInRow + [styles.topicInRow]: props.isTopicInRow, }} >
    { [clsx('col-sm-18 col-md-24 col-lg-14 col-xl-15', styles.topicDetails)]: props.isNarrow, [clsx('col-24 col-sm-17 col-md-18', styles.topicDetails)]: props.compact, [clsx('col-sm-17 col-md-18', styles.topicDetails)]: - !props.subscribeButtonBottom && !props.isNarrow && !props.compact + !props.subscribeButtonBottom && !props.isNarrow && !props.compact, }} > @@ -132,7 +133,7 @@ export const TopicCard = (props: TopicProps) => { classList={{ 'col-sm-6 col-md-24 col-lg-10 col-xl-9': props.isNarrow, 'col-24 col-sm-7 col-md-6': props.compact, - 'col-sm-7 col-md-6': !props.subscribeButtonBottom && !props.isNarrow && !props.compact + 'col-sm-7 col-md-6': !props.subscribeButtonBottom && !props.isNarrow && !props.compact, }} > @@ -151,7 +152,7 @@ export const TopicCard = (props: TopicProps) => { isSubscribeButton={true} class={clsx(styles.actionButton, { [styles.isSubscribing]: isSubscribing(), - [stylesButton.subscribed]: subscribed() + [stylesButton.subscribed]: subscribed(), })} disabled={isSubscribing()} /> diff --git a/src/components/Topic/FloorHeader.tsx b/src/components/Topic/FloorHeader.tsx index 6f8557de..84977c26 100644 --- a/src/components/Topic/FloorHeader.tsx +++ b/src/components/Topic/FloorHeader.tsx @@ -1,7 +1,9 @@ import type { Topic } from '../../graphql/types.gen' -import { Icon } from '../_shared/Icon' -import './FloorHeader.scss' + import { useLocalize } from '../../context/localize' +import { Icon } from '../_shared/Icon' + +import './FloorHeader.scss' export default (props: { topic: Topic; color: string }) => { const { t } = useLocalize() diff --git a/src/components/Topic/Full.tsx b/src/components/Topic/Full.tsx index 9ce2a389..0109b464 100644 --- a/src/components/Topic/Full.tsx +++ b/src/components/Topic/Full.tsx @@ -1,14 +1,16 @@ -import { createMemo, Show } from 'solid-js' import type { Topic } from '../../graphql/types.gen' -import { FollowingEntity } from '../../graphql/types.gen' -import styles from './Full.module.scss' -import { follow, unfollow } from '../../stores/zine/common' import { clsx } from 'clsx' -import { useSession } from '../../context/session' +import { createMemo, Show } from 'solid-js' + import { useLocalize } from '../../context/localize' +import { useSession } from '../../context/session' +import { FollowingEntity } from '../../graphql/types.gen' +import { follow, unfollow } from '../../stores/zine/common' import { Button } from '../_shared/Button' +import styles from './Full.module.scss' + type Props = { topic: Topic } @@ -16,13 +18,13 @@ type Props = { export const FullTopic = (props: Props) => { const { subscriptions, - actions: { requireAuthentication, loadSubscriptions } + actions: { requireAuthentication, loadSubscriptions }, } = useSession() const { t } = useLocalize() const subscribed = createMemo(() => - subscriptions().topics.some((topic) => topic.slug === props.topic?.slug) + subscriptions().topics.some((topic) => topic.slug === props.topic?.slug), ) const handleSubscribe = (really: boolean) => { diff --git a/src/components/Topic/TopicBadge/TopicBadge.tsx b/src/components/Topic/TopicBadge/TopicBadge.tsx index 3387a2e8..9ad6da66 100644 --- a/src/components/Topic/TopicBadge/TopicBadge.tsx +++ b/src/components/Topic/TopicBadge/TopicBadge.tsx @@ -1,13 +1,15 @@ import { clsx } from 'clsx' -import styles from './TopicBadge.module.scss' -import { FollowingEntity, Topic } from '../../../graphql/types.gen' import { createMemo, createSignal, Show } from 'solid-js' -import { Button } from '../../_shared/Button' -import { useSession } from '../../../context/session' + import { useLocalize } from '../../../context/localize' +import { useSession } from '../../../context/session' +import { FollowingEntity, Topic } from '../../../graphql/types.gen' import { follow, unfollow } from '../../../stores/zine/common' -import { CheckButton } from '../../_shared/CheckButton' import { getImageUrl } from '../../../utils/getImageUrl' +import { Button } from '../../_shared/Button' +import { CheckButton } from '../../_shared/CheckButton' + +import styles from './TopicBadge.module.scss' type Props = { topic: Topic @@ -20,11 +22,11 @@ export const TopicBadge = (props: Props) => { const { isAuthenticated, subscriptions, - actions: { loadSubscriptions } + actions: { loadSubscriptions }, } = useSession() const subscribed = createMemo(() => - subscriptions().topics.some((topic) => topic.slug === props.topic.slug) + subscriptions().topics.some((topic) => topic.slug === props.topic.slug), ) const subscribe = async (really = true) => { @@ -45,7 +47,7 @@ export const TopicBadge = (props: Props) => { class={clsx(styles.picture, { [styles.withImage]: props.topic.pic })} style={ props.topic.pic && { - 'background-image': `url('${getImageUrl(props.topic.pic, { width: 40, height: 40 })}')` + 'background-image': `url('${getImageUrl(props.topic.pic, { width: 40, height: 40 })}')`, } } /> diff --git a/src/components/Views/AllAuthors.tsx b/src/components/Views/AllAuthors.tsx index 4bd74962..6d01a23f 100644 --- a/src/components/Views/AllAuthors.tsx +++ b/src/components/Views/AllAuthors.tsx @@ -1,12 +1,14 @@ -import { createEffect, createMemo, createSignal, For, Show } from 'solid-js' import type { Author } from '../../graphql/types.gen' -import { setAuthorsSort, useAuthorsStore } from '../../stores/zine/authors' -import { useRouter } from '../../stores/router' + import { clsx } from 'clsx' -import { SearchField } from '../_shared/SearchField' -import { scrollHandler } from '../../utils/scroll' +import { createEffect, createMemo, createSignal, For, Show } from 'solid-js' + import { useLocalize } from '../../context/localize' +import { useRouter } from '../../stores/router' +import { setAuthorsSort, useAuthorsStore } from '../../stores/zine/authors' import { dummyFilter } from '../../utils/dummyFilter' +import { scrollHandler } from '../../utils/scroll' +import { SearchField } from '../_shared/SearchField' import { AuthorBadge } from '../Author/AuthorBadge' import styles from './AllAuthors.module.scss' @@ -28,7 +30,7 @@ export const AllAuthorsView = (props: AllAuthorsViewProps) => { const { searchParams, changeSearchParam } = useRouter() const { sortedAuthors } = useAuthorsStore({ authors: props.authors, - sortBy: searchParams().by || 'shouts' + sortBy: searchParams().by || 'shouts', }) const [searchQuery, setSearchQuery] = createSignal('') @@ -36,7 +38,7 @@ export const AllAuthorsView = (props: AllAuthorsViewProps) => { createEffect(() => { if (!searchParams().by) { changeSearchParam({ - by: 'shouts' + by: 'shouts', }) } }) @@ -64,7 +66,7 @@ export const AllAuthorsView = (props: AllAuthorsViewProps) => { acc[letter].push(author) return acc }, - {} as { [letter: string]: Author[] } + {} as { [letter: string]: Author[] }, ) }) @@ -88,7 +90,7 @@ export const AllAuthorsView = (props: AllAuthorsViewProps) => {
    • {t('By shouts')} diff --git a/src/components/Views/AllTopics.tsx b/src/components/Views/AllTopics.tsx index decf7abe..c440f4f5 100644 --- a/src/components/Views/AllTopics.tsx +++ b/src/components/Views/AllTopics.tsx @@ -1,15 +1,16 @@ -import { createEffect, createMemo, createSignal, For, Show } from 'solid-js' import type { Topic } from '../../graphql/types.gen' -import { setTopicsSort, useTopicsStore } from '../../stores/zine/topics' -import { useRouter } from '../../stores/router' -import { TopicCard } from '../Topic/Card' import { clsx } from 'clsx' -import { useSession } from '../../context/session' -import { SearchField } from '../_shared/SearchField' -import { scrollHandler } from '../../utils/scroll' +import { createEffect, createMemo, createSignal, For, Show } from 'solid-js' + import { useLocalize } from '../../context/localize' +import { useSession } from '../../context/session' +import { useRouter } from '../../stores/router' +import { setTopicsSort, useTopicsStore } from '../../stores/zine/topics' import { dummyFilter } from '../../utils/dummyFilter' +import { scrollHandler } from '../../utils/scroll' +import { SearchField } from '../_shared/SearchField' +import { TopicCard } from '../Topic/Card' import styles from './AllTopics.module.scss' @@ -31,7 +32,7 @@ export const AllTopicsView = (props: AllTopicsViewProps) => { const { sortedTopics } = useTopicsStore({ topics: props.topics, - sortBy: searchParams().by || 'shouts' + sortBy: searchParams().by || 'shouts', }) const { subscriptions } = useSession() @@ -39,7 +40,7 @@ export const AllTopicsView = (props: AllTopicsViewProps) => { createEffect(() => { if (!searchParams().by) { changeSearchParam({ - by: 'shouts' + by: 'shouts', }) } }) @@ -57,7 +58,7 @@ export const AllTopicsView = (props: AllTopicsViewProps) => { acc[letter].push(topic) return acc }, - {} as { [letter: string]: Topic[] } + {} as { [letter: string]: Topic[] }, ) }) diff --git a/src/components/Views/Author/Author.tsx b/src/components/Views/Author/Author.tsx index d5123465..a0463ffc 100644 --- a/src/components/Views/Author/Author.tsx +++ b/src/components/Views/Author/Author.tsx @@ -1,23 +1,26 @@ -import { Show, createMemo, createSignal, Switch, onMount, For, Match, createEffect } from 'solid-js' import type { Author, Shout, Topic } from '../../../graphql/types.gen' + +import { getPagePath } from '@nanostores/router' +import { clsx } from 'clsx' +import { Show, createMemo, createSignal, Switch, onMount, For, Match, createEffect } from 'solid-js' + +import { useLocalize } from '../../../context/localize' +import { router, useRouter } from '../../../stores/router' +import { loadShouts, useArticlesStore } from '../../../stores/zine/articles' +import { useAuthorsStore } from '../../../stores/zine/authors' +import { apiClient } from '../../../utils/apiClient' +import { restoreScrollPosition, saveScrollPosition } from '../../../utils/scroll' +import { splitToPages } from '../../../utils/splitToPages' +import { Loading } from '../../_shared/Loading' +import { Comment } from '../../Article/Comment' +import { AuthorCard } from '../../Author/AuthorCard' +import { AuthorRatingControl } from '../../Author/AuthorRatingControl' import { Row1 } from '../../Feed/Row1' import { Row2 } from '../../Feed/Row2' import { Row3 } from '../../Feed/Row3' -import { useAuthorsStore } from '../../../stores/zine/authors' -import { loadShouts, useArticlesStore } from '../../../stores/zine/articles' -import { router, useRouter } from '../../../stores/router' -import { restoreScrollPosition, saveScrollPosition } from '../../../utils/scroll' -import { splitToPages } from '../../../utils/splitToPages' + import styles from './Author.module.scss' import stylesArticle from '../../Article/Article.module.scss' -import { clsx } from 'clsx' -import { AuthorCard } from '../../Author/AuthorCard' -import { apiClient } from '../../../utils/apiClient' -import { Comment } from '../../Article/Comment' -import { useLocalize } from '../../../context/localize' -import { AuthorRatingControl } from '../../Author/AuthorRatingControl' -import { getPagePath } from '@nanostores/router' -import { Loading } from '../../_shared/Loading' type Props = { shouts: Shout[] @@ -47,7 +50,7 @@ export const AuthorView = (props: Props) => { try { const [getAuthors, getTopics] = await Promise.all([ apiClient.getAuthorFollowingUsers({ slug: props.authorSlug }), - apiClient.getAuthorFollowingTopics({ slug: props.authorSlug }) + apiClient.getAuthorFollowingTopics({ slug: props.authorSlug }), ]) const authors = getAuthors const topics = getTopics @@ -90,7 +93,7 @@ export const AuthorView = (props: Props) => { const { hasMore } = await loadShouts({ filters: { author: props.authorSlug }, limit: LOAD_MORE_PAGE_SIZE, - offset: sortedArticles().length + offset: sortedArticles().length, }) setIsLoadMoreButtonVisible(hasMore) restoreScrollPosition() @@ -106,7 +109,7 @@ export const AuthorView = (props: Props) => { // }) const pages = createMemo(() => - splitToPages(sortedArticles(), PRERENDERED_ARTICLES_COUNT, LOAD_MORE_PAGE_SIZE) + splitToPages(sortedArticles(), PRERENDERED_ARTICLES_COUNT, LOAD_MORE_PAGE_SIZE), ) const [commented, setCommented] = createSignal([]) @@ -115,7 +118,7 @@ export const AuthorView = (props: Props) => { if (getPage().route === 'authorComments') { try { const data = await apiClient.getReactionsBy({ - by: { comment: true, createdBy: props.authorSlug } + by: { comment: true, createdBy: props.authorSlug }, }) setCommented(data) } catch (error) { diff --git a/src/components/Views/DraftsView/DraftsView.tsx b/src/components/Views/DraftsView/DraftsView.tsx index d98efe08..7eda20d1 100644 --- a/src/components/Views/DraftsView/DraftsView.tsx +++ b/src/components/Views/DraftsView/DraftsView.tsx @@ -1,13 +1,15 @@ +import { openPage } from '@nanostores/router' import { clsx } from 'clsx' -import styles from './DraftsView.module.scss' import { createSignal, For, onMount, Show } from 'solid-js' -import { Draft } from '../../Draft' + +import { useEditorContext } from '../../../context/editor' import { useSession } from '../../../context/session' import { Shout } from '../../../graphql/types.gen' -import { apiClient } from '../../../utils/apiClient' -import { useEditorContext } from '../../../context/editor' -import { openPage } from '@nanostores/router' import { router } from '../../../stores/router' +import { apiClient } from '../../../utils/apiClient' +import { Draft } from '../../Draft' + +import styles from './DraftsView.module.scss' export const DraftsView = () => { const { isAuthenticated, isSessionLoaded } = useSession() @@ -24,7 +26,7 @@ export const DraftsView = () => { }) const { - actions: { publishShoutById, deleteShout } + actions: { publishShoutById, deleteShout }, } = useEditorContext() const handleDraftDelete = (shout: Shout) => { diff --git a/src/components/Views/Edit.tsx b/src/components/Views/Edit.tsx index c7168333..501c5c06 100644 --- a/src/components/Views/Edit.tsx +++ b/src/components/Views/Edit.tsx @@ -1,30 +1,33 @@ -import { Accessor, createMemo, createSignal, onCleanup, onMount, Show } from 'solid-js' -import { useLocalize } from '../../context/localize' -import { clsx } from 'clsx' - import type { Shout, Topic } from '../../graphql/types.gen' -import { useRouter } from '../../stores/router' -import { ShoutForm, useEditorContext } from '../../context/editor' -import { Editor, Panel } from '../Editor' -import { Icon } from '../_shared/Icon' -import styles from './Edit.module.scss' -import { GrowingTextarea } from '../_shared/GrowingTextarea' -import { VideoUploader } from '../Editor/VideoUploader' -import { AudioUploader } from '../Editor/AudioUploader' -import { slugify } from '../../utils/slugify' -import { ImageSwiper } from '../_shared/SolidSwiper' -import { DropArea } from '../_shared/DropArea' -import { LayoutType, MediaItem } from '../../pages/types' -import { clone } from '../../utils/clone' + +import { clsx } from 'clsx' import deepEqual from 'fast-deep-equal' -import { AutoSaveNotice } from '../Editor/AutoSaveNotice' -import { PublishSettings } from './PublishSettings' +import { Accessor, createMemo, createSignal, onCleanup, onMount, Show } from 'solid-js' import { createStore } from 'solid-js/store' -import SimplifiedEditor from '../Editor/SimplifiedEditor' -import { isDesktop } from '../../utils/media-query' -import { TableOfContents } from '../TableOfContents' + +import { ShoutForm, useEditorContext } from '../../context/editor' +import { useLocalize } from '../../context/localize' +import { LayoutType, MediaItem } from '../../pages/types' +import { useRouter } from '../../stores/router' +import { clone } from '../../utils/clone' import { getImageUrl } from '../../utils/getImageUrl' +import { isDesktop } from '../../utils/media-query' +import { slugify } from '../../utils/slugify' +import { DropArea } from '../_shared/DropArea' +import { GrowingTextarea } from '../_shared/GrowingTextarea' +import { Icon } from '../_shared/Icon' import { Popover } from '../_shared/Popover' +import { ImageSwiper } from '../_shared/SolidSwiper' +import { Editor, Panel } from '../Editor' +import { AudioUploader } from '../Editor/AudioUploader' +import { AutoSaveNotice } from '../Editor/AutoSaveNotice' +import SimplifiedEditor from '../Editor/SimplifiedEditor' +import { VideoUploader } from '../Editor/VideoUploader' +import { TableOfContents } from '../TableOfContents' + +import { PublishSettings } from './PublishSettings' + +import styles from './Edit.module.scss' type Props = { shout: Shout @@ -33,7 +36,7 @@ type Props = { export const MAX_HEADER_LIMIT = 100 export const EMPTY_TOPIC: Topic = { id: -1, - slug: '' + slug: '', } const AUTO_SAVE_INTERVAL = 5000 @@ -41,7 +44,7 @@ const handleScrollTopButtonClick = (e) => { e.preventDefault() window.scrollTo({ top: 0, - behavior: 'smooth' + behavior: 'smooth', }) } @@ -54,7 +57,7 @@ export const EditView = (props: Props) => { const { form, formErrors, - actions: { setForm, setFormErrors, saveDraft, saveDraftToLocalStorage, getDraftFromLocalStorage } + actions: { setForm, setFormErrors, saveDraft, saveDraftToLocalStorage, getDraftFromLocalStorage }, } = useEditorContext() const shoutTopics = props.shout.topics || [] @@ -75,7 +78,7 @@ export const EditView = (props: Props) => { body: props.shout.body, coverImageUrl: props.shout.cover, media: props.shout.media, - layout: props.shout.layout + layout: props.shout.layout, }) } @@ -106,7 +109,7 @@ export const EditView = (props: Props) => { const handleBeforeUnload = (event) => { if (!deepEqual(prevForm, form)) { event.returnValue = t( - `There are unsaved changes in your publishing settings. Are you sure you want to leave the page without saving?` + `There are unsaved changes in your publishing settings. Are you sure you want to leave the page without saving?`, ) } } @@ -145,7 +148,7 @@ export const EditView = (props: Props) => { const [baseAudioFields, setBaseAudioFields] = createSignal({ artist: '', date: '', - genre: '' + genre: '', }) const handleBaseFieldsChange = (key, value) => { @@ -219,7 +222,7 @@ export const EditView = (props: Props) => {
      - - - hideModal()} /> - - @@ -369,6 +381,12 @@ const SimplifiedEditor = (props: Props) => { ref={(el) => (textBubbleMenuRef.current = el)} /> + (linkBubbleMenuRef.current = el)} + onClose={() => setShouldShowLinkBubbleMenu(false)} + />
    ) } diff --git a/src/stores/ui.ts b/src/stores/ui.ts index b4edecd2..aa555272 100644 --- a/src/stores/ui.ts +++ b/src/stores/ui.ts @@ -21,7 +21,6 @@ export type ModalType = | 'simplifiedEditorUploadImage' | 'uploadCoverImage' | 'editorInsertLink' - | 'simplifiedEditorInsertLink' | 'followers' | 'following' @@ -37,7 +36,6 @@ export const MODALS: Record = { simplifiedEditorUploadImage: 'simplifiedEditorUploadImage', uploadCoverImage: 'uploadCoverImage', editorInsertLink: 'editorInsertLink', - simplifiedEditorInsertLink: 'simplifiedEditorInsertLink', followers: 'followers', following: 'following', } From 1772be044c97bbb3b060f5b5bf93e7146b600814 Mon Sep 17 00:00:00 2001 From: Ilya Y <75578537+ilya-bkv@users.noreply.github.com> Date: Wed, 15 Nov 2023 20:52:05 +0300 Subject: [PATCH 124/129] notification seen fix (#319) Co-authored-by: Igor Lobanov --- package-lock.json | 16 ++++++++-------- package.json | 4 ++-- src/context/notifications.tsx | 2 ++ 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/package-lock.json b/package-lock.json index 91e064fa..b1e5a7ef 100644 --- a/package-lock.json +++ b/package-lock.json @@ -86,7 +86,7 @@ "eslint-plugin-sonarjs": "0.23.0", "eslint-plugin-unicorn": "49.0.0", "fast-deep-equal": "3.1.3", - "graphql": "16.6.0", + "graphql": "16.8.1", "graphql-tag": "2.12.6", "husky": "8.0.3", "hygen": "6.2.11", @@ -120,7 +120,7 @@ "typescript": "5.2.2", "typograf": "7.1.0", "uniqolor": "1.1.0", - "vike": "0.4.145", + "vike": "0.4.146", "vite": "4.5.0", "vite-plugin-mkcert": "1.16.0", "vite-plugin-sass-dts": "1.3.11", @@ -10070,9 +10070,9 @@ "dev": true }, "node_modules/graphql": { - "version": "16.6.0", - "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.6.0.tgz", - "integrity": "sha512-KPIBPDlW7NxrbT/eh4qPXz5FiFdL5UbaA0XUNz2Rp3Z3hqBSkbj0GVjwFDztsWVauZUWsbKHgMg++sk8UX0bkw==", + "version": "16.8.1", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.8.1.tgz", + "integrity": "sha512-59LZHPdGZVh695Ud9lRzPBVTtlX9ZCV150Er2W43ro37wVof0ctenSaskPPjN7lVTIN8mSZt8PHUNKZuNQUuxw==", "dev": true, "engines": { "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0" @@ -18596,9 +18596,9 @@ } }, "node_modules/vike": { - "version": "0.4.145", - "resolved": "https://registry.npmjs.org/vike/-/vike-0.4.145.tgz", - "integrity": "sha512-FPYM69bRC4ilzP2lLEzXxpa8Q3lxNKUtp1h6LaFh+lROzhf9e88TTXEnZTQi7iBUsiJqBjxm+fXUGkz6BOccnw==", + "version": "0.4.146", + "resolved": "https://registry.npmjs.org/vike/-/vike-0.4.146.tgz", + "integrity": "sha512-1vaktcDy/eitSzVaUppKJWu+6vfwxKC4kV6uzAqj3RIK+WgteH3vF6IMZ0jnjjzCpeDRCIByN8PF4c0CtzRfHA==", "dev": true, "dependencies": { "@brillout/import": "0.2.3", diff --git a/package.json b/package.json index d02dbb60..3ce3e90e 100644 --- a/package.json +++ b/package.json @@ -107,7 +107,7 @@ "eslint-plugin-sonarjs": "0.23.0", "eslint-plugin-unicorn": "49.0.0", "fast-deep-equal": "3.1.3", - "graphql": "16.6.0", + "graphql": "16.8.1", "graphql-tag": "2.12.6", "husky": "8.0.3", "hygen": "6.2.11", @@ -141,7 +141,7 @@ "typescript": "5.2.2", "typograf": "7.1.0", "uniqolor": "1.1.0", - "vike": "0.4.145", + "vike": "0.4.146", "vite": "4.5.0", "vite-plugin-mkcert": "1.16.0", "vite-plugin-sass-dts": "1.3.11", diff --git a/src/context/notifications.tsx b/src/context/notifications.tsx index 1a96ed94..1a53ba49 100644 --- a/src/context/notifications.tsx +++ b/src/context/notifications.tsx @@ -81,6 +81,8 @@ export const NotificationsProvider = (props: { children: JSX.Element }) => { const markNotificationAsRead = async (notification: Notification) => { await apiClient.markNotificationAsRead(notification.id) + setNotificationEntities(notification.id, 'seen', true) + setUnreadNotificationsCount((oldCount) => oldCount - 1) } const markAllNotificationsAsRead = async () => { await apiClient.markAllNotificationsAsRead() From df983e1c60349c368441a4d619e95727fe073397 Mon Sep 17 00:00:00 2001 From: kvakazyambra Date: Wed, 15 Nov 2023 23:27:43 +0300 Subject: [PATCH 125/129] Feed sidebar style fixes --- src/components/Feed/Sidebar/Sidebar.module.scss | 10 +++++----- src/components/Feed/Sidebar/Sidebar.tsx | 4 ++-- src/components/Views/Feed.module.scss | 9 +-------- 3 files changed, 8 insertions(+), 15 deletions(-) diff --git a/src/components/Feed/Sidebar/Sidebar.module.scss b/src/components/Feed/Sidebar/Sidebar.module.scss index 040096a5..5f936e92 100644 --- a/src/components/Feed/Sidebar/Sidebar.module.scss +++ b/src/components/Feed/Sidebar/Sidebar.module.scss @@ -19,11 +19,12 @@ align-items: center; display: flex; position: relative; + } - @include media-breakpoint-up(md) { - overflow: hidden; - text-overflow: ellipsis; - } + .sidebarItemNameLabel { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; } .userpic { @@ -109,7 +110,6 @@ display: inline-block; line-height: 1; height: 2.4rem; - margin-bottom: 0.2rem; margin-right: 0.8rem; min-width: 2.4rem; text-align: center; diff --git a/src/components/Feed/Sidebar/Sidebar.tsx b/src/components/Feed/Sidebar/Sidebar.tsx index 04374e0b..eecf8b45 100644 --- a/src/components/Feed/Sidebar/Sidebar.tsx +++ b/src/components/Feed/Sidebar/Sidebar.tsx @@ -131,7 +131,7 @@ export const Sidebar = () => { >
    - {author.name} +
    {author.name}
    @@ -146,7 +146,7 @@ export const Sidebar = () => { >
    - {topic.title} +
    {topic.title}
    diff --git a/src/components/Views/Feed.module.scss b/src/components/Views/Feed.module.scss index e5c22e58..7fa3da81 100644 --- a/src/components/Views/Feed.module.scss +++ b/src/components/Views/Feed.module.scss @@ -8,8 +8,7 @@ } .feedNavigation { - @include font-size(1.6rem); - + @include font-size(1.4rem); font-weight: 500; h4 { @@ -34,12 +33,6 @@ margin: 0 0 1rem; white-space: nowrap; width: 100%; - - a, - strong { - display: flex; - justify-content: space-between; - } } a { From 08636979bc9902f3be4b5ce3f2d25934427be73a Mon Sep 17 00:00:00 2001 From: kvakazyambra Date: Thu, 16 Nov 2023 00:51:32 +0300 Subject: [PATCH 126/129] Feed sidebar style fixes --- .../TableOfContents/TableOfContents.tsx | 4 +- src/components/Views/StaticPage.tsx | 32 ++ src/pages/about/guide.page.tsx | 496 ++++++++---------- src/pages/about/help.page.tsx | 268 ++++------ src/pages/about/manifest.page.tsx | 302 +++++------ src/styles/help.scss | 13 +- 6 files changed, 505 insertions(+), 610 deletions(-) create mode 100644 src/components/Views/StaticPage.tsx diff --git a/src/components/TableOfContents/TableOfContents.tsx b/src/components/TableOfContents/TableOfContents.tsx index 23632214..0fa245dd 100644 --- a/src/components/TableOfContents/TableOfContents.tsx +++ b/src/components/TableOfContents/TableOfContents.tsx @@ -45,7 +45,9 @@ export const TableOfContents = (props: Props) => { const updateHeadings = () => { setHeadings( // eslint-disable-next-line unicorn/prefer-spread - Array.from(document.querySelector(props.parentSelector).querySelectorAll('h2, h3, h4')), + Array.from( + document.querySelector(props.parentSelector).querySelectorAll('h1, h2, h3, h4'), + ), ) setAreHeadingsLoaded(true) } diff --git a/src/components/Views/StaticPage.tsx b/src/components/Views/StaticPage.tsx new file mode 100644 index 00000000..1b276679 --- /dev/null +++ b/src/components/Views/StaticPage.tsx @@ -0,0 +1,32 @@ +import { PageLayout } from '../_shared/PageLayout' +import { TableOfContents } from '../TableOfContents' +import { JSX } from 'solid-js' + +export const StaticPage = (props: { + title: string + children: JSX.Element + layoutChildren: JSX.Element +}) => { + let articleBodyElement: HTMLElement | undefined + + return ( + + {props.layoutChildren} +
    +
    +
    + {props.children} +
    + +
    + +
    +
    +
    +
    + ) +} diff --git a/src/pages/about/guide.page.tsx b/src/pages/about/guide.page.tsx index 9c4d26a7..8df422bf 100644 --- a/src/pages/about/guide.page.tsx +++ b/src/pages/about/guide.page.tsx @@ -1,291 +1,241 @@ import { Meta } from '@solidjs/meta' -import { createSignal, Show } from 'solid-js' -import { Icon } from '../../components/_shared/Icon' -import { PageLayout } from '../../components/_shared/PageLayout' import { useLocalize } from '../../context/localize' +import { StaticPage } from '../../components/Views/StaticPage' export const GuidePage = () => { const { t } = useLocalize() const title = t('How it works') - const [indexExpanded, setIndexExpanded] = createSignal(true) - - const toggleIndexExpanded = () => setIndexExpanded((oldExpanded) => !oldExpanded) - return ( - - - - - - - - -
    -
    -
    - + + + + + + + + + + } + > +

    + Как устроен Дискурс +

    - - - -
    +
    +

    Как стать автором журнала

    +

    + Дискурс объединяет журналистов, активистов, музыкантов, художников, фотографов, режиссеров, + философов, ученых и других замечательных людей. Каждый может прислать{' '} + свой материал в журнал. Формат и тематика не имеют значения, единственное, что + важно — хороший ли материал. Если сообщество + поддержит вашу публикацию, она выйдет в журнале и станет доступна тысячам наших + читателей. +

    +
    -
    -

    - Как устроен Дискурс -

    +

    Как проходит голосование

    +

    + Все присылаемые в Дискурс материалы попадают в  + «Редакцию». Это внутренний раздел сайта, где участники сообщества + решают, что будет опубликовано в Дискурсе. Как только работа получает одобрение как минимум + пятерых авторов открытой редакции, она немедленно публикуется в журнале. Если же материал + набирает более 20% голосов «против», он не выходит и может быть + отправлен на доработку. Жестких сроков рассмотрения материалов у нас нет, иногда это + занимает час, иногда месяц, обычно — несколько дней. +

    +
    +

    + Как только сообщество поддержит публикацию, вы получите приглашение в интернет-редакцию + и сможете голосовать за новые материалы. +

    +
    -

    - Дискурс — независимый журнал о культуре, науке, искусстве и обществе - с  - открытой редакцией. У нас нет главного редактора, инвестора - и вообще никого, кто бы принимал единоличные решения. Вместо традиционных иерархий - Дискурс основан на принципах прямой демократии: в нашем горизонтальном сообществе - все редакционные вопросы решаются открытым голосованием авторов журнала. Вот как это работает. -

    -

    Как устроен сайт Дискурса

    -

    Дискурс состоит из четырех основных разделов:

    -
      -
    • -

      - Темы -  — у нас публикуются исследования, обзоры, эссе, интервью, репортажи, - аналитика и другие материалы о культуре, науке, искусстве и обществе. -

      -
    • -
    • -

      - Искусство -  — здесь, например, представлены художественные произведения: литература, - живопись, музыка, фотографии, видео. Этот раздел помогает прозвучать новому искусству, - которое создают российские художники, писатели, режиссёры и музыканты. -

      -
    • - {/* -
    • -

      - События — в этом разделе - публикуются самые важные, по мнению редакции, культурные - события России — выставки, лекции, концерты, кинопоказы, фестивали, - художественные и политические акции. Напишите нам - на почту, если вы - хотите разместить объявление. Мы делаем это - на безвозмездной основе. -

      -
    • -
    • -

      - Редакция — - это внутренний раздел, где появляются новые материалы, которые присылают - в редакцию. Здесь авторы обсуждают, редактируют и оценивают - публикации, определяя таким образом содержание журнала. -

      -
    • - */} -
    -

    - Материалы в Дискурсе объединяются по темам - — ключевым словам, которые располагаются в конце материалов и связывают - материалы по жанрам (например, интервью,{' '} - репортажи, эссе,{' '} - ликбезы - ), по тематике (кино,{' '} - философия, история,{' '} - абсурдизм, секс и т.д.) или - в серии (как «Законы мира» или « - За линией Маннергейма - »). Темы объединяют сотни публикаций, помогают ориентироваться в журнале - и следить за интересными материалами. -

    +

    Как мы делаем тексты друг друга лучше

    +

    + Дискурс — журнал с совместным редактированием. Совершенствовать тексты нам помогает{' '} + система ремарок. Вы можете выделить часть текста в любой статье и оставить + к ней замечание, вопрос или предложение — автор текста получит совет на почту + и сможет его учесть. Так мы устраняем опечатки, неточности и советуем друг другу, как + сделать тексты качественнее и интереснее. +

    +

    + Среди участников сообщества есть профессиональные редакторы, которые помогают авторам делать тексты + лучше. Если вашему материалу потребуется доработка, они помогут отредактировать текст, подобрать + иллюстрации, придумать заголовок и красиво сверстать публикацию. Если вы хотите обсудить + текст, прежде чем загрузить материал в интернет-редакцию — разместите его + в google-документе, откройте доступ к редактированию по ссылке и напишите нам + на  + + welcome@discours.io + + . +

    +

    + Если у вас возникают трудности с тем, чтобы подобрать к своему материалу иллюстрации, + тоже пишите на  + + почту + + — наши коллеги-художники могут вам помочь{' '} + + в режиме совместного редактирования + + . +

    -
    -

    Как стать автором журнала

    -

    - Дискурс объединяет журналистов, активистов, музыкантов, художников, фотографов, режиссеров, - философов, ученых и других замечательных людей. Каждый может{' '} - прислать свой материал в журнал. Формат и тематика - не имеют значения, единственное, что важно —{' '} - хороший ли материал. Если сообщество - поддержит вашу публикацию, она выйдет в журнале и станет доступна тысячам наших - читателей. -

    -
    +

    Что сообщество дает авторам

    +
      +
    • +

      + Право определять, каким будет журнал. Дискурс — это общественная + институция, созданная людьми и ради людей, функционирующая на условиях прямой + демократии. Авторы публикуют статьи и художественные проекты, участвуют в обсуждениях, + голосуют за работы коллег и таким образом вносят свой вклад в развитие проекта, + определяя содержание и направление журнала. +

      +
    • +
    • +

      + Возможность обратиться к широкой аудитории. Дискурс читают десятки тысяч + людей, и с каждым днем их становится больше. +

      +
    • +
    • +

      + Поддержка редакции. Дискурс предоставляет авторам аккредитацию + на мероприятия, базу контактов, юридическую поддержку, ознакомление с книжными, кино- + и музыкальными новинками до их выхода в свет. Если что-то из этого вам + понадобится, пишите на почту{' '} + + welcome@discours.io + +  — поможем. +

      +
    • +
    • +

      + Пресс-карты для корреспондентов. Три опубликованные статьи позволяют авторам + Дискурса получить официальные удостоверения журналистов (пресс-карты) на следующий год. + Пресс-карты удостоверяют, что вы журналист и можете пользоваться всеми теми правами, + которые гарантирует Закон о СМИ. Кроме того, многие культурные институции (музеи, галереи + и др.) предоставляют журналистам право свободного входа. +

      +
    • +
    • +

      + Помощь сотен специалистов в разных областях. В основе Дискурса лежит + идея совместного редактирования. Участники редакционного сообщества — несколько сотен + журналистов, исследователей, художников, литераторов из разных стран — изучают + материалы друг друга до публикации и помогают сделать их качественнее + и интереснее. Так, в редакции нередко складываются творческие союзы: например, авторов + текстов и художников, создающих для них иллюстрации. +

      +
    • +
    • +

      + Пространство общения полное выдающихся людей. Дискурс — большое + живое сообщество интеллектуалов, разбросанных по всему земному шару. Вступив + в редакцию, вы сможете познакомиться со множеством интересных людей, которые + определяют повестку завтрашнего дня, вдохновляют окружающих, создают новое и изучают + старое, ищут знания и готовы ими делиться, чтобы менять мир в соответствии + со своими идеалами. +

      +
    • +
    -

    Как проходит голосование

    -

    - Все присылаемые в Дискурс материалы попадают в  - «Редакцию». Это внутренний раздел сайта, где участники сообщества - решают, что будет опубликовано в Дискурсе. Как только работа получает одобрение как - минимум пятерых авторов открытой редакции, она немедленно публикуется в журнале. - Если же материал набирает более 20% голосов «против», - он не выходит и может быть отправлен на доработку. Жестких сроков - рассмотрения материалов у нас нет, иногда это занимает час, иногда месяц, - обычно — несколько дней. -

    -
    -

    - Как только сообщество поддержит публикацию, вы получите приглашение - в интернет-редакцию и сможете голосовать за новые материалы. -

    -
    - -

    Как мы делаем тексты друг друга лучше

    -

    - Дискурс — журнал с совместным редактированием. Совершенствовать тексты нам - помогает система ремарок. Вы можете выделить часть текста в любой статье - и оставить к ней замечание, вопрос или предложение — автор текста получит - совет на почту и сможет его учесть. Так мы устраняем опечатки, неточности - и советуем друг другу, как сделать тексты качественнее и интереснее. -

    -

    - Среди участников сообщества есть профессиональные редакторы, которые помогают авторам делать - тексты лучше. Если вашему материалу потребуется доработка, они помогут отредактировать текст, - подобрать иллюстрации, придумать заголовок и красиво сверстать публикацию. Если - вы хотите обсудить текст, прежде чем загрузить материал в интернет-редакцию — - разместите его в google-документе, откройте доступ к редактированию по ссылке - и напишите нам на  - - welcome@discours.io - - . -

    -

    - Если у вас возникают трудности с тем, чтобы подобрать к своему материалу - иллюстрации, тоже пишите на  - - почту - - — наши коллеги-художники могут вам помочь{' '} - - в режиме совместного редактирования - - . -

    - -

    Что сообщество дает авторам

    -
      -
    • -

      - Право определять, каким будет журнал. Дискурс — это - общественная институция, созданная людьми и ради людей, функционирующая - на условиях прямой демократии. Авторы публикуют статьи и художественные проекты, - участвуют в обсуждениях, голосуют за работы коллег и таким образом вносят - свой вклад в развитие проекта, определяя содержание и направление журнала. -

      -
    • -
    • -

      - Возможность обратиться к широкой аудитории. Дискурс читают десятки - тысяч людей, и с каждым днем их становится больше. -

      -
    • -
    • -

      - Поддержка редакции. Дискурс предоставляет авторам аккредитацию - на мероприятия, базу контактов, юридическую поддержку, ознакомление с книжными, - кино- и музыкальными новинками до их выхода в свет. Если что-то - из этого вам понадобится, пишите на почту{' '} - - welcome@discours.io - -  — поможем. -

      -
    • -
    • -

      - Пресс-карты для корреспондентов. Три опубликованные статьи позволяют - авторам Дискурса получить официальные удостоверения журналистов (пресс-карты) - на следующий год. Пресс-карты удостоверяют, что вы журналист и можете - пользоваться всеми теми правами, которые гарантирует Закон о СМИ. Кроме того, многие - культурные институции (музеи, галереи и др.) предоставляют журналистам право - свободного входа. -

      -
    • -
    • -

      - Помощь сотен специалистов в разных областях. В основе Дискурса - лежит идея совместного редактирования. Участники редакционного сообщества — - несколько сотен журналистов, исследователей, художников, литераторов из разных стран - — изучают материалы друг друга до публикации и помогают сделать - их качественнее и интереснее. Так, в редакции нередко складываются - творческие союзы: например, авторов текстов и художников, создающих для них - иллюстрации. -

      -
    • -
    • -

      - Пространство общения полное выдающихся людей. Дискурс — - большое живое сообщество интеллектуалов, разбросанных по всему земному шару. Вступив - в редакцию, вы сможете познакомиться со множеством интересных людей, - которые определяют повестку завтрашнего дня, вдохновляют окружающих, создают новое - и изучают старое, ищут знания и готовы ими делиться, чтобы менять мир - в соответствии со своими идеалами. -

      -
    • -
    - -

    Как быть в курсе

    -

    - За свежими публикациями Дискурса можно следить не только на сайте, - но и на страницах в  - - Фейсбуке - - ,{' '} - - ВКонтакте - {' '} - и  - - Телеграме - - . А ещё раз в месяц мы отправляем почтовую рассылку{' '} - с дайджестом лучших материалов. -

    -

    - Если вы хотите сотрудничать, что-то обсудить или предложить — пожалуйста, пишите - на  - - welcome@discours.io - - . Мы обязательно ответим. -

    -
    -
    -
    -
    +

    Как быть в курсе

    +

    + За свежими публикациями Дискурса можно следить не только на сайте, + но и на страницах в  + + Фейсбуке + + ,{' '} + + ВКонтакте + {' '} + и  + + Телеграме + + . А ещё раз в месяц мы отправляем почтовую рассылку{' '} + с дайджестом лучших материалов. +

    +

    + Если вы хотите сотрудничать, что-то обсудить или предложить — пожалуйста, пишите на  + + welcome@discours.io + + . Мы обязательно ответим. +

    + ) } diff --git a/src/pages/about/help.page.tsx b/src/pages/about/help.page.tsx index 87e29026..34b9cec3 100644 --- a/src/pages/about/help.page.tsx +++ b/src/pages/about/help.page.tsx @@ -1,171 +1,127 @@ import { Meta } from '@solidjs/meta' -import { createSignal, Show } from 'solid-js' -import { Icon } from '../../components/_shared/Icon' -import { PageLayout } from '../../components/_shared/PageLayout' import { Donate } from '../../components/Discours/Donate' import { useLocalize } from '../../context/localize' +import { StaticPage } from '../../components/Views/StaticPage' export const HelpPage = () => { - const [indexExpanded, setIndexExpanded] = createSignal(true) - const { t } = useLocalize() - const toggleIndexExpanded = () => setIndexExpanded((oldExpanded) => !oldExpanded) - // TODO: l10n return ( - - - + + + + + } + > +

    + Как вы можете поддержать Дискурс? +

    - {/*Благодарим!*/} - -
    -
    - - -
    -

    - Как вы можете поддержать Дискурс? -

    - -

    - Дискурс — уникальное независимое издание с горизонтальной редакцией, - существующее в интересах своих читателей. Ваша поддержка действительно много - значит — не только для редакции Дискурса, но и для сохранения - свободной мысли и некоммерческого искусства в нашем обществе. -

    -

    - Дискурс существует на добровольных началах. Никакой медиахолдинг, фонд или - государственная структура не финансирует нас — благодаря этому мы можем - писать о том, что важно, а не о том, что выгодно. Сообщество наших - волонтеров ежедневно трудится, чтобы рассказывать вам интересные, не освещенные другими - изданиями истории — но мы не сможем делать это без вашей помощи. - Пожертвования читателей составляют основу нашего бюджета и позволяют нам существовать. -

    -

    - Если вам нравится то, что мы делаем и вы хотите, чтобы Дискурс - продолжался, пожалуйста, поддержите проект. -

    -
    -
    - -
    -
    -

    На что пойдут деньги?

    -

    - Ваши пожертвования пойдут на оплату серверов, содержание офиса, зарплату редакции - и налоги, оплату юридического сопровождения и труда бухгалтера, совершенствование - сайта, аренду помещения для открытой редакции, на печать альманаха Дискурс с лучшими - текстами авторов за полгода, а также на другие редакционные и технические - расходы. -

    -

    Ваша помощь позволит нам

    -
      -
    • -

      Оставаться бесплатным изданием.

      -

      - Мы делаем открытый журнал для всех желающих, а также собираем искусство лучших - авторов по всему миру. Ваша поддержка позволяет нам становиться лучше. -

      -
    • -
    • -

      Создавать еще больше контента.

      -

      - Каждый день к нам присоединяются новые люди, и чем больше нас становится, тем - больше мы творим и строже оцениваем результаты творчества друг друга. - В результате повышается и количество, и качество контента. Каждый день мы - трудимся, чтобы открывать нашим читателям новые грани окружающего мира. -

      -
    • -
    • -

      Развивать форматы и расширять деятельность Дискурса.

      -

      - Мы создаем различные спецпроекты и регулярно проводим необычные мероприятия. - Мы хотим приносить пользу человечеству всеми возможными способами. -

      -
    • -
    • -

      Модернизировать сайт.

      -

      - Мы совершенствуем платформу и стараемся сделать проект максимально удобным для - вас. Мы работаем над мобильной версией, новым дизайном, фукционалом, системой - регистрации, навигации и рекомендаций, которые сделают наше общение еще - увлекательней. -

      -
    • -
    • -

      Выпускать альманах.

      -

      - Выпускать раз в полугодие печатный альманах Дискурс с 33 лучшими текстами - сайта. -

      -
    • -
    • -

      Захватить весь мир

      -

      и принести «Дискурс» в каждый дом.

      -
    • -
    -

    Войдите в попечительский совет Дискурса

    -

    - Вы хотите сделать крупное пожертвование? Станьте попечителем Дискурса — - - напишите нам - - , мы будем рады единомышленникам. -

    -

    Как ещё можно поддержать Дискурс?

    -

    - Есть много других способов поддержать Дискурс и труд наших авторов. Например, - вы можете периодически рассказывать о проекте своим друзьям в соцсетях, - делиться хорошими материалами или — что еще лучше — публиковать свои - статьи в «Дискурсе». Но главное, что вы можете сделать для - Дискурса, — читать нас. Мы вкладываем в журнал душу, и внимание каждого - читателя убеждает нас в правильности выбранного пути. Не переключайтесь. -

    -

    - Если вы хотите помочь проекту, но у вас возникли вопросы, напишите нам письмо - по адресу{' '} - - welcome@discours.io - - . -

    -
    +

    + Дискурс — уникальное независимое издание с горизонтальной редакцией, существующее + в интересах своих читателей. Ваша поддержка действительно много значит — + не только для редакции Дискурса, но и для сохранения свободной мысли + и некоммерческого искусства в нашем обществе. +

    +

    + Дискурс существует на добровольных началах. Никакой медиахолдинг, фонд или государственная + структура не финансирует нас — благодаря этому мы можем писать о том, что + важно, а не о том, что выгодно. Сообщество наших волонтеров ежедневно трудится, чтобы + рассказывать вам интересные, не освещенные другими изданиями истории — + но мы не сможем делать это без вашей помощи. Пожертвования читателей составляют + основу нашего бюджета и позволяют нам существовать. +

    +

    + Если вам нравится то, что мы делаем и вы хотите, чтобы Дискурс продолжался, + пожалуйста, поддержите проект. +

    +
    +
    +
    -
    -
    +
    +

    На что пойдут деньги?

    +

    + Ваши пожертвования пойдут на оплату серверов, содержание офиса, зарплату редакции + и налоги, оплату юридического сопровождения и труда бухгалтера, совершенствование сайта, + аренду помещения для открытой редакции, на печать альманаха Дискурс с лучшими текстами + авторов за полгода, а также на другие редакционные и технические расходы. +

    +

    Ваша помощь позволит нам

    +
      +
    • +

      Оставаться бесплатным изданием.

      +

      + Мы делаем открытый журнал для всех желающих, а также собираем искусство лучших авторов + по всему миру. Ваша поддержка позволяет нам становиться лучше. +

      +
    • +
    • +

      Создавать еще больше контента.

      +

      + Каждый день к нам присоединяются новые люди, и чем больше нас становится, тем больше + мы творим и строже оцениваем результаты творчества друг друга. В результате + повышается и количество, и качество контента. Каждый день мы трудимся, чтобы открывать + нашим читателям новые грани окружающего мира. +

      +
    • +
    • +

      Развивать форматы и расширять деятельность Дискурса.

      +

      + Мы создаем различные спецпроекты и регулярно проводим необычные мероприятия. + Мы хотим приносить пользу человечеству всеми возможными способами. +

      +
    • +
    • +

      Модернизировать сайт.

      +

      + Мы совершенствуем платформу и стараемся сделать проект максимально удобным для вас. + Мы работаем над мобильной версией, новым дизайном, фукционалом, системой регистрации, + навигации и рекомендаций, которые сделают наше общение еще увлекательней. +

      +
    • +
    • +

      Выпускать альманах.

      +

      + Выпускать раз в полугодие печатный альманах Дискурс с 33 лучшими текстами сайта. +

      +
    • +
    • +

      Захватить весь мир

      +

      и принести «Дискурс» в каждый дом.

      +
    • +
    +

    Войдите в попечительский совет Дискурса

    +

    + Вы хотите сделать крупное пожертвование? Станьте попечителем Дискурса —{' '} + + напишите нам + + , мы будем рады единомышленникам. +

    +

    Как ещё можно поддержать Дискурс?

    +

    + Есть много других способов поддержать Дискурс и труд наших авторов. Например, вы можете + периодически рассказывать о проекте своим друзьям в соцсетях, делиться хорошими + материалами или — что еще лучше — публиковать свои статьи + в «Дискурсе». Но главное, что вы можете сделать для Дискурса, — + читать нас. Мы вкладываем в журнал душу, и внимание каждого читателя убеждает нас + в правильности выбранного пути. Не переключайтесь. +

    +

    + Если вы хотите помочь проекту, но у вас возникли вопросы, напишите нам письмо + по адресу{' '} + + welcome@discours.io + + . +

    + ) } diff --git a/src/pages/about/manifest.page.tsx b/src/pages/about/manifest.page.tsx index 6b4ab838..f2a0c6bd 100644 --- a/src/pages/about/manifest.page.tsx +++ b/src/pages/about/manifest.page.tsx @@ -1,198 +1,146 @@ -import { createSignal, Show } from 'solid-js' - -import { Icon } from '../../components/_shared/Icon' -import { PageLayout } from '../../components/_shared/PageLayout' import { Subscribe } from '../../components/_shared/Subscribe' import { Feedback } from '../../components/Discours/Feedback' import { Modal } from '../../components/Nav/Modal' import Opener from '../../components/Nav/Modal/Opener' import { useLocalize } from '../../context/localize' +import { StaticPage } from '../../components/Views/StaticPage' export const ManifestPage = () => { - const [indexExpanded, setIndexExpanded] = createSignal(true) - const { t } = useLocalize() - const toggleIndexExpanded = () => setIndexExpanded((oldExpanded) => !oldExpanded) - return ( - - - - - - - -
    -
    -
    - + + + + + + + + + } + > +

    + Манифест +

    - - - -
    +

    + Как участвовать в самиздате +

    -
    -

    - Манифест -

    +

    + Дискурс создается открытым сообществом энтузиастов новой независимой + журналистики. Участвовать в открытой редакции и помогать журналу можно следующими + способами: +

    +
    + +

    Предлагать материалы

    +
    +

    + Создавайте свои статьи и художественные работы — лучшие из + них будут опубликованы в журнале. Дискурс — некоммерческое издание, авторы + публикуются в журнале на общественных началах, получая при этом{' '} + поддержку редакции, право голоса, множество других возможностей + и читателей по всему миру. +

    +
    -

    - Дискурс — независимый художественно-аналитический журнал с горизонтальной - редакцией, основанный на принципах свободы слова, прямой демократии и совместного - редактирования. Дискурс создаётся открытым медиасообществом ученых, журналистов, музыкантов, - писателей, предпринимателей, философов, инженеров, художников и специалистов - со всего мира, объединившихся, чтобы вместе делать общий журнал и объяснять - с разных точек зрения мозаичную картину современности. -

    -

    - Мы пишем о культуре, науке и обществе, рассказываем о новых идеях - и современном искусстве, публикуем статьи, исследования, репортажи, интервью людей, чью - прямую речь стоит услышать, и работы художников из разных стран — - от фильмов и музыки до живописи и фотографии. Помогая друг другу делать - публикации качественнее и общим голосованием выбирая лучшие материалы для журнала, - мы создаём новую горизонтальную журналистику, чтобы честно рассказывать о важном - и интересном. -

    -

    - Редакция Дискурса открыта для всех: у нас нет цензуры, запретных тем - и идеологических рамок. Каждый может прислать материал{' '} - в журнал и  - присоединиться к редакции. Предоставляя трибуну для - независимой журналистики и художественных проектов, мы помогаем людям рассказывать - свои истории так, чтобы они были услышаны. Мы убеждены: чем больше голосов будет звучать - на Дискурсе, тем громче в полифонии мнений будет слышна истина. -

    +
    + + + +

    + Дискурс существует на пожертвования читателей. Если вам нравится журнал, пожалуйста,{' '} + поддержите нашу работу. Ваши пожертвования пойдут на выпуск новых + материалов, оплату серверов, труда программистов, дизайнеров и редакторов. +

    +
    -

    - Как участвовать в самиздате -

    +
    + +

    Сотрудничать с журналом

    +
    +

    + Мы всегда открыты для сотрудничества и рады единомышленникам. Если вы хотите помогать журналу + с редактурой, корректурой, иллюстрациями, переводами, версткой, подкастами, мероприятиями, + фандрайзингом или как-то ещё — скорее пишите нам на  + welcome@discours.io. +

    +

    + Если вы представляете некоммерческую организацию и хотите сделать с нами совместный + проект, получить информационную поддержку или предложить другую форму сотрудничества —{' '} + пишите. +

    +

    + Если вы разработчик и хотите помогать с развитием сайта Дискурса,{' '} + присоединяйтесь к IT-команде самиздата. Открытый + код платформы для независимой журналистики, а также всех наших спецпроектов + и медиаинструментов находится{' '} + в свободном доступе на GitHub. +

    +
    -

    - Дискурс создается открытым сообществом энтузиастов новой - независимой журналистики. Участвовать в открытой редакции и помогать журналу можно - следующими способами: -

    -
    - -

    Предлагать материалы

    -
    -

    - Создавайте свои статьи и художественные работы — - лучшие из них будут опубликованы в журнале. Дискурс — некоммерческое - издание, авторы публикуются в журнале на общественных началах, получая при этом{' '} - поддержку редакции, право голоса, множество других - возможностей и читателей по всему миру. -

    -
    +
    + +

    Как еще можно помочь

    +
    +

    + Советуйте Дискурс друзьям и знакомым. Обсуждайте и распространяйте наши + публикации — все материалы открытой редакции можно читать и перепечатывать + бесплатно. Подпишитесь на самиздат ВКонтакте, в  + Фейсбуке и в  + Телеграме, а также на  + рассылку лучших материалов, чтобы не пропустить ничего + интересного. +

    +

    + Рассказывайте о впечатлениях{' '} + от материалов открытой редакции, делитесь идеями, + интересными темами, о которых хотели бы узнать больше, и историями, которые нужно + рассказать. +

    +
    -
    - - - -

    - Дискурс существует на пожертвования читателей. Если вам нравится журнал, пожалуйста,{' '} - поддержите нашу работу. Ваши пожертвования пойдут на выпуск - новых материалов, оплату серверов, труда программистов, дизайнеров и редакторов. -

    -
    +

    + Будем на связи +

    -
    - -

    Сотрудничать с журналом

    -
    -

    - Мы всегда открыты для сотрудничества и рады единомышленникам. Если вы хотите помогать - журналу с редактурой, корректурой, иллюстрациями, переводами, версткой, подкастами, - мероприятиями, фандрайзингом или как-то ещё — скорее пишите нам на  - welcome@discours.io. -

    -

    - Если вы представляете некоммерческую организацию и хотите сделать с нами - совместный проект, получить информационную поддержку или предложить другую форму - сотрудничества — пишите. -

    -

    - Если вы разработчик и хотите помогать с развитием сайта Дискурса,{' '} - присоединяйтесь к IT-команде самиздата. - Открытый код платформы для независимой журналистики, а также всех наших спецпроектов - и медиаинструментов находится{' '} - в свободном доступе на GitHub. -

    -
    - -
    - -

    Как еще можно помочь

    -
    -

    - Советуйте Дискурс друзьям и знакомым. Обсуждайте и распространяйте наши - публикации — все материалы открытой редакции можно читать и перепечатывать - бесплатно. Подпишитесь на самиздат ВКонтакте, - в Фейсбуке и в  - Телеграме, а также на  - рассылку лучших материалов, чтобы не пропустить - ничего интересного. -

    -

    - Рассказывайте о впечатлениях{' '} - от материалов открытой редакции, делитесь идеями, - интересными темами, о которых хотели бы узнать больше, и историями, которые нужно - рассказать. -

    -
    - -

    - Будем на связи -

    - -

    - Если вы хотите предложить материал, сотрудничать, рассказать о проблеме, которую нужно - осветить, сообщить об ошибке или баге, что-то обсудить, уточнить или посоветовать, - пожалуйста, напишите нам здесь или на почту{' '} - welcome@discours.io. Мы обязательно ответим - и постараемся реализовать все хорошие задумки. -

    -
    -
    -
    -
    +

    + Если вы хотите предложить материал, сотрудничать, рассказать о проблеме, которую нужно + осветить, сообщить об ошибке или баге, что-то обсудить, уточнить или посоветовать, пожалуйста,{' '} + напишите нам здесь или на почту{' '} + welcome@discours.io. Мы обязательно ответим + и постараемся реализовать все хорошие задумки. +

    + ) } diff --git a/src/styles/help.scss b/src/styles/help.scss index 05711076..e39ef129 100644 --- a/src/styles/help.scss +++ b/src/styles/help.scss @@ -48,12 +48,13 @@ } } -.btn { +.donate-form .btn { cursor: pointer; flex: 1; padding: 5px 10px; text-align: center; white-space: nowrap; + transform: none !important; @include media-breakpoint-down(sm) { &:last-of-type { @@ -81,6 +82,7 @@ } .donate-buttons-container { + align-items: center; display: flex; flex: 1; justify-content: space-between; @@ -119,15 +121,20 @@ } .send-btn { - border: 1px solid #000; + border: 2px solid #000; background-color: #000; - color: #fff; + color: #fff !important; display: block; font-weight: 700; line-height: 1.8; letter-spacing: 0.05em; text-transform: uppercase; width: 100%; + + &:hover { + background-color: #fff !important; + color: #000 !important; + } } .payment-choose { From 3ad0e222d2b9c49acbf939a60408dea402c76caf Mon Sep 17 00:00:00 2001 From: kvakazyambra Date: Thu, 16 Nov 2023 00:56:31 +0300 Subject: [PATCH 127/129] Fixed params type --- src/components/Views/StaticPage.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/components/Views/StaticPage.tsx b/src/components/Views/StaticPage.tsx index 1b276679..7abdd003 100644 --- a/src/components/Views/StaticPage.tsx +++ b/src/components/Views/StaticPage.tsx @@ -23,7 +23,11 @@ export const StaticPage = (props: {
    - +
    From a9a16ce8b15d35811990bff36dc3023e3cef67df Mon Sep 17 00:00:00 2001 From: kvakazyambra Date: Thu, 16 Nov 2023 01:21:04 +0300 Subject: [PATCH 128/129] Convert donate form styles to css module --- .../Discours/Donate.module.scss} | 54 +++++-------------- src/components/Discours/Donate.tsx | 38 ++++++++----- src/components/Views/StaticPage.tsx | 3 +- src/pages/about/guide.page.tsx | 2 +- src/pages/about/help.page.tsx | 2 +- src/pages/about/manifest.page.tsx | 2 +- 6 files changed, 41 insertions(+), 60 deletions(-) rename src/{styles/help.scss => components/Discours/Donate.module.scss} (77%) diff --git a/src/styles/help.scss b/src/components/Discours/Donate.module.scss similarity index 77% rename from src/styles/help.scss rename to src/components/Discours/Donate.module.scss index e39ef129..010d164d 100644 --- a/src/styles/help.scss +++ b/src/components/Discours/Donate.module.scss @@ -1,6 +1,6 @@ -.donate-form input, -.donate-form label, -.donate-form .btn { +.donateForm input, +.donateForm label, +.donateForm .btn { font-family: Muller, Arial, Helvetica, sans-serif; border: solid 1px #595959; border-radius: 3px; @@ -10,7 +10,7 @@ text-align: center; } -.donate-form input { +.donateForm input { &::-webkit-outer-spin-button, &::-webkit-inner-spin-button { appearance: none; @@ -48,7 +48,7 @@ } } -.donate-form .btn { +.donateForm .btn { cursor: pointer; flex: 1; padding: 5px 10px; @@ -63,7 +63,7 @@ } } -.btn-group { +.btnGroup { input { &:first-child + .btn { border-top-right-radius: 0; @@ -76,12 +76,12 @@ } } - .payment-type { + .paymentType { width: 50%; } } -.donate-buttons-container { +.donateButtonsContainer { align-items: center; display: flex; flex: 1; @@ -113,14 +113,14 @@ } } -.donate-input { +.donateInput { @include media-breakpoint-down(sm) { flex: 1 100%; margin: 0 !important; } } -.send-btn { +.sendBtn { border: 2px solid #000; background-color: #000; color: #fff !important; @@ -137,40 +137,10 @@ } } -.payment-choose { +.paymentChoose { display: flex; } -.form-group:not(:first-child) { +.formGroup:not(:first-child) { margin-top: 20px; } - -.discours-help .modalwrap__inner { - max-width: 500px; -} - -/* - -.payment-form { -padding: 0 !important; - -.button { - display: block; - padding-bottom: 1.5rem; - padding-top: 1.5rem; - width: 100%; -} -} - -.delimiter-container { -position: relative; -} - -.delimiter { -left: 100%; -line-height: 1; -position: absolute; -top: 50%; -transform: translate(-50%, calc(-50% - 0.8rem)); -} -*/ diff --git a/src/components/Discours/Donate.tsx b/src/components/Discours/Donate.tsx index 71ab5dd7..a1b445d5 100644 --- a/src/components/Discours/Donate.tsx +++ b/src/components/Discours/Donate.tsx @@ -1,10 +1,12 @@ -import '../../styles/help.scss' +import { clsx } from 'clsx' import { createSignal, onMount } from 'solid-js' import { useLocalize } from '../../context/localize' import { useSnackbar } from '../../context/snackbar' import { showModal } from '../../stores/ui' +import styles from './Donate.module.scss' + export const Donate = () => { const { t } = useLocalize() const once = '' @@ -119,27 +121,27 @@ export const Donate = () => { } return ( - + -
    -