From 21e9fc00da348c4016d20e6fcff2e089840b10b3 Mon Sep 17 00:00:00 2001 From: Ilya Y <75578537+ilya-bkv@users.noreply.github.com> Date: Sat, 3 Feb 2024 10:56:11 +0300 Subject: [PATCH] Feature/refactoring subscriptions (#392) refactoring Author page and Top Authors subscribe logic --- .../Author/AuthorBadge/AuthorBadge.tsx | 41 ++++++++++----- .../Author/AuthorCard/AuthorCard.tsx | 41 ++++++++++----- src/components/Feed/Beside.tsx | 18 ++++++- src/components/Views/Author/Author.tsx | 51 +++++++------------ src/components/Views/Home.tsx | 3 +- src/stores/zine/articles.ts | 2 +- 6 files changed, 94 insertions(+), 62 deletions(-) diff --git a/src/components/Author/AuthorBadge/AuthorBadge.tsx b/src/components/Author/AuthorBadge/AuthorBadge.tsx index 2c90471b..a8456166 100644 --- a/src/components/Author/AuthorBadge/AuthorBadge.tsx +++ b/src/components/Author/AuthorBadge/AuthorBadge.tsx @@ -1,6 +1,6 @@ import { openPage } from '@nanostores/router' import { clsx } from 'clsx' -import { createEffect, createMemo, createSignal, Match, Show, Switch } from 'solid-js' +import { createEffect, createMemo, createSignal, Match, on, Show, Switch } from 'solid-js' import { useFollowing } from '../../../context/following' import { useLocalize } from '../../../context/localize' @@ -8,6 +8,7 @@ import { useMediaQuery } from '../../../context/mediaQuery' import { useSession } from '../../../context/session' import { Author, FollowingEntity } from '../../../graphql/schema/core.gen' import { router, useRouter } from '../../../stores/router' +import { resetSortedArticles } from '../../../stores/zine/articles' import { isCyrillic } from '../../../utils/cyrillic' import { translit } from '../../../utils/ru2en' import { Button } from '../../_shared/Button' @@ -19,6 +20,10 @@ import { Userpic } from '../Userpic' import styles from './AuthorBadge.module.scss' import stylesButton from '../../_shared/Button/Button.module.scss' +type FollowedInfo = { + value?: boolean + loaded?: boolean +} type Props = { author: Author minimizeSubscribeButton?: boolean @@ -28,20 +33,22 @@ type Props = { inviteView?: boolean onInvite?: (id: number) => void selected?: boolean + isFollowed?: FollowedInfo } export const AuthorBadge = (props: Props) => { const { mediaMatches } = useMediaQuery() + const { + author, + actions: { requireAuthentication }, + } = useSession() + const [isMobileView, setIsMobileView] = createSignal(false) - const [followed, setFollowed] = createSignal(false) + const [isFollowed, setIsFollowed] = createSignal() createEffect(() => { setIsMobileView(!mediaMatches.sm) }) - const { - author, - actions: { requireAuthentication }, - } = useSession() const { setFollowing } = useFollowing() const { changeSearchParams } = useRouter() const { t, formatDate, lang } = useLocalize() @@ -68,10 +75,20 @@ export const AuthorBadge = (props: Props) => { return props.author.name }) + createEffect( + on( + () => props.isFollowed, + () => { + setIsFollowed(props.isFollowed.value) + }, + { defer: true }, + ), + ) + const handleFollowClick = () => { - const value = !followed() + const value = !isFollowed() requireAuthentication(() => { - setFollowed(value) + setIsFollowed(value) setFollowing(FollowingEntity.Author, props.author.slug, value) }, 'subscribe') } @@ -123,10 +140,10 @@ export const AuthorBadge = (props: Props) => {
} + fallback={} > { isSubscribeButton={true} class={clsx(styles.actionButton, { [styles.iconed]: props.iconButtons, - [stylesButton.subscribed]: followed(), + [stylesButton.subscribed]: isFollowed(), })} /> } @@ -165,7 +182,7 @@ export const AuthorBadge = (props: Props) => { isSubscribeButton={true} class={clsx(styles.actionButton, { [styles.iconed]: props.iconButtons, - [stylesButton.subscribed]: followed(), + [stylesButton.subscribed]: isFollowed(), })} /> diff --git a/src/components/Author/AuthorCard/AuthorCard.tsx b/src/components/Author/AuthorCard/AuthorCard.tsx index 336d908f..d7cc72e6 100644 --- a/src/components/Author/AuthorCard/AuthorCard.tsx +++ b/src/components/Author/AuthorCard/AuthorCard.tsx @@ -2,7 +2,7 @@ import type { Author, Community } from '../../../graphql/schema/core.gen' import { openPage, redirectPage } from '@nanostores/router' import { clsx } from 'clsx' -import { createEffect, createMemo, createSignal, For, onMount, Show } from 'solid-js' +import { createEffect, createMemo, createSignal, For, on, onMount, Show } from 'solid-js' import { useFollowing } from '../../../context/following' import { useLocalize } from '../../../context/localize' @@ -36,11 +36,24 @@ export const AuthorCard = (props: Props) => { isSessionLoaded, actions: { requireAuthentication }, } = useSession() + const [authorSubs, setAuthorSubs] = createSignal>([]) const [subscriptionFilter, setSubscriptionFilter] = createSignal('all') + const [isFollowed, setIsFollowed] = createSignal() const isProfileOwner = createMemo(() => author()?.slug === props.author.slug) - const [followed, setFollowed] = createSignal() + const isSubscribed = () => props.followers?.some((entity) => entity.id === author()?.id) + createEffect( + on( + () => props.followers, + () => { + setIsFollowed(isSubscribed()) + }, + { defer: true }, + ), + ) + const { setFollowing } = useFollowing() + const name = createMemo(() => { if (lang() !== 'ru' && isCyrillic(props.author.name)) { if (props.author.name === 'Дискурс') { @@ -82,15 +95,15 @@ export const AuthorCard = (props: Props) => { }) const handleFollowClick = () => { - const value = !followed() + const value = !isFollowed() requireAuthentication(() => { - setFollowed(value) + setIsFollowed(value) setFollowing(FollowingEntity.Author, props.author.slug, value) }, 'subscribe') } const followButtonText = createMemo(() => { - if (followed()) { + if (isFollowed()) { return ( <> {t('Following')} @@ -198,14 +211,16 @@ export const AuthorCard = (props: Props) => { when={isProfileOwner()} fallback={
-