subs-refactoring
This commit is contained in:
parent
bec333f7c3
commit
79f94876f0
|
@ -423,14 +423,14 @@
|
||||||
"subscriber": "subscriber",
|
"subscriber": "subscriber",
|
||||||
"subscriber_rp": "subscriber",
|
"subscriber_rp": "subscriber",
|
||||||
"subscribers": "subscribers",
|
"subscribers": "subscribers",
|
||||||
"SubscriberWithCount": "{count, plural, =0 {no followers} one {{count} follower} other {{count} followers}}",
|
"FollowersWithCount": "{count, plural, =0 {no followers} one {{count} follower} other {{count} followers}}",
|
||||||
"subscribing...": "subscribing...",
|
"subscribing...": "subscribing...",
|
||||||
"subscription": "subscription",
|
"subscription": "subscription",
|
||||||
"Subscription": "Subscription",
|
"Subscription": "Subscription",
|
||||||
"subscription_rp": "subscription",
|
"subscription_rp": "subscription",
|
||||||
"subscriptions": "subscriptions",
|
"subscriptions": "subscriptions",
|
||||||
"Subscriptions": "Subscriptions",
|
"Subscriptions": "Subscriptions",
|
||||||
"SubscriptionWithCount": "{count, plural, =0 {no subscriptions} one {{count} subscription} other {{count} subscriptions}}",
|
"FollowsWithCount": "{count, plural, =0 {no subscriptions} one {{count} subscription} other {{count} subscriptions}}",
|
||||||
"Substrate": "Substrate",
|
"Substrate": "Substrate",
|
||||||
"Success": "Success",
|
"Success": "Success",
|
||||||
"Successfully authorized": "Authorization successful",
|
"Successfully authorized": "Authorization successful",
|
||||||
|
|
|
@ -451,11 +451,11 @@
|
||||||
"subscriber": "подписчик",
|
"subscriber": "подписчик",
|
||||||
"subscriber_rp": "подписчика",
|
"subscriber_rp": "подписчика",
|
||||||
"subscribers": "подписчиков",
|
"subscribers": "подписчиков",
|
||||||
"SubscriberWithCount": "{count, plural, =0 {нет подписчиков} one {{count} подписчик} few {{count} подписчика} other {{count} подписчиков}}",
|
"FollowersWithCount": "{count, plural, =0 {нет подписчиков} one {{count} подписчик} few {{count} подписчика} other {{count} подписчиков}}",
|
||||||
"subscribing...": "Подписка...",
|
"subscribing...": "Подписка...",
|
||||||
"Subscription": "Подписка",
|
"Subscription": "Подписка",
|
||||||
"Subscriptions": "Подписки",
|
"Subscriptions": "Подписки",
|
||||||
"SubscriptionWithCount": "{count, plural, =0 {нет подписок} one {{count} подписка} few {{count} подписки} other {{count} подписок}}",
|
"FollowsWithCount": "{count, plural, =0 {нет подписок} one {{count} подписка} few {{count} подписки} other {{count} подписок}}",
|
||||||
"Substrate": "Подложка",
|
"Substrate": "Подложка",
|
||||||
"Success": "Успешно",
|
"Success": "Успешно",
|
||||||
"Successfully authorized": "Авторизация успешна",
|
"Successfully authorized": "Авторизация успешна",
|
||||||
|
|
|
@ -31,16 +31,7 @@ export const AudioPlayer = (props: Props) => {
|
||||||
const [isPlaying, setIsPlaying] = createSignal(false)
|
const [isPlaying, setIsPlaying] = createSignal(false)
|
||||||
|
|
||||||
const currentTack = createMemo(() => props.media[currentTrackIndex()])
|
const currentTack = createMemo(() => props.media[currentTrackIndex()])
|
||||||
|
createEffect(on(currentTrackIndex, () => setCurrentTrackDuration(0), { defer: true }))
|
||||||
createEffect(
|
|
||||||
on(
|
|
||||||
() => currentTrackIndex(),
|
|
||||||
() => {
|
|
||||||
setCurrentTrackDuration(0)
|
|
||||||
},
|
|
||||||
{ defer: true },
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
const handlePlayMedia = async (trackIndex: number) => {
|
const handlePlayMedia = async (trackIndex: number) => {
|
||||||
setIsPlaying(!isPlaying() || trackIndex !== currentTrackIndex())
|
setIsPlaying(!isPlaying() || trackIndex !== currentTrackIndex())
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { openPage } from '@nanostores/router'
|
import { openPage } from '@nanostores/router'
|
||||||
import { clsx } from 'clsx'
|
import { clsx } from 'clsx'
|
||||||
import { Match, Show, Switch, createEffect, createMemo, createSignal } from 'solid-js'
|
import { Match, Show, Switch, createEffect, createMemo, createSignal, on } from 'solid-js'
|
||||||
|
|
||||||
import { useFollowing } from '../../../context/following'
|
import { useFollowing } from '../../../context/following'
|
||||||
import { useLocalize } from '../../../context/localize'
|
import { useLocalize } from '../../../context/localize'
|
||||||
|
@ -34,17 +34,19 @@ export const AuthorBadge = (props: Props) => {
|
||||||
const { author, requireAuthentication } = useSession()
|
const { author, requireAuthentication } = useSession()
|
||||||
const { follow, unfollow, follows, following } = useFollowing()
|
const { follow, unfollow, follows, following } = useFollowing()
|
||||||
const [isMobileView, setIsMobileView] = createSignal(false)
|
const [isMobileView, setIsMobileView] = createSignal(false)
|
||||||
const [isFollowed, setIsFollowed] = createSignal<boolean>()
|
const [isFollowed, setIsFollowed] = createSignal<boolean>(
|
||||||
|
follows?.authors?.some((authorEntity) => authorEntity.id === props.author?.id),
|
||||||
createEffect(() => {
|
)
|
||||||
if (!(follows && props.author)) return
|
createEffect(() => setIsMobileView(!mediaMatches.sm))
|
||||||
const followed = follows?.authors?.some((authorEntity) => authorEntity.id === props.author?.id)
|
createEffect(
|
||||||
setIsFollowed(followed)
|
on(
|
||||||
})
|
[() => follows?.authors, () => props.author, following],
|
||||||
|
([followingAuthors, currentAuthor, _]) => {
|
||||||
createEffect(() => {
|
setIsFollowed(followingAuthors?.some((followedAuthor) => followedAuthor.id === currentAuthor?.id))
|
||||||
setIsMobileView(!mediaMatches.sm)
|
},
|
||||||
})
|
{ defer: true },
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
const { changeSearchParams } = useRouter()
|
const { changeSearchParams } = useRouter()
|
||||||
const { t, formatDate, lang } = useLocalize()
|
const { t, formatDate, lang } = useLocalize()
|
||||||
|
@ -132,7 +134,7 @@ export const AuthorBadge = (props: Props) => {
|
||||||
<Show when={props.author.slug !== author()?.slug && !props.nameOnly}>
|
<Show when={props.author.slug !== author()?.slug && !props.nameOnly}>
|
||||||
<div class={styles.actions}>
|
<div class={styles.actions}>
|
||||||
<FollowingButton
|
<FollowingButton
|
||||||
action={() => handleFollowClick()}
|
action={handleFollowClick}
|
||||||
isFollowed={isFollowed()}
|
isFollowed={isFollowed()}
|
||||||
actionMessageType={following()?.slug === props.author.slug ? following().type : undefined}
|
actionMessageType={following()?.slug === props.author.slug ? following().type : undefined}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -429,7 +429,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.subscribersContainer {
|
.followersContainer {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
font-size: 1.4rem;
|
font-size: 1.4rem;
|
||||||
|
@ -440,7 +440,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.subscribers {
|
.followers {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
|
@ -456,7 +456,7 @@
|
||||||
margin-right: 0;
|
margin-right: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.subscribersItem {
|
.followersItem {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
&:nth-child(1) {
|
&:nth-child(1) {
|
||||||
|
@ -473,7 +473,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.subscribersCounter {
|
.followsCounter {
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
margin-left: 1rem;
|
margin-left: 1rem;
|
||||||
}
|
}
|
||||||
|
@ -481,7 +481,7 @@
|
||||||
&:hover {
|
&:hover {
|
||||||
background: none !important;
|
background: none !important;
|
||||||
|
|
||||||
.subscribersCounter {
|
.followsCounter {
|
||||||
background: var(--background-color-invert);
|
background: var(--background-color-invert);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ import styles from './AuthorCard.module.scss'
|
||||||
type Props = {
|
type Props = {
|
||||||
author: Author
|
author: Author
|
||||||
followers?: Author[]
|
followers?: Author[]
|
||||||
following?: Array<Author | Topic>
|
flatFollows?: Array<Author | Topic>
|
||||||
}
|
}
|
||||||
export const AuthorCard = (props: Props) => {
|
export const AuthorCard = (props: Props) => {
|
||||||
const { t, lang } = useLocalize()
|
const { t, lang } = useLocalize()
|
||||||
|
@ -39,7 +39,7 @@ export const AuthorCard = (props: Props) => {
|
||||||
const { follow, unfollow, follows, following } = useFollowing()
|
const { follow, unfollow, follows, following } = useFollowing()
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
setAuthorSubs(props.following)
|
setAuthorSubs(props.flatFollows)
|
||||||
})
|
})
|
||||||
|
|
||||||
createEffect(() => {
|
createEffect(() => {
|
||||||
|
@ -71,15 +71,15 @@ export const AuthorCard = (props: Props) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
createEffect(() => {
|
createEffect(() => {
|
||||||
if (props.following) {
|
if (props.flatFollows) {
|
||||||
if (followsFilter() === 'authors') {
|
if (followsFilter() === 'authors') {
|
||||||
setAuthorSubs(props.following.filter((s) => 'name' in s))
|
setAuthorSubs(props.flatFollows.filter((s) => 'name' in s))
|
||||||
} else if (followsFilter() === 'topics') {
|
} else if (followsFilter() === 'topics') {
|
||||||
setAuthorSubs(props.following.filter((s) => 'title' in s))
|
setAuthorSubs(props.flatFollows.filter((s) => 'title' in s))
|
||||||
} else if (followsFilter() === 'communities') {
|
} else if (followsFilter() === 'communities') {
|
||||||
setAuthorSubs(props.following.filter((s) => 'title' in s))
|
setAuthorSubs(props.flatFollows.filter((s) => 'title' in s))
|
||||||
} else {
|
} else {
|
||||||
setAuthorSubs(props.following)
|
setAuthorSubs(props.flatFollows)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -108,6 +108,73 @@ export const AuthorCard = (props: Props) => {
|
||||||
return t('Follow')
|
return t('Follow')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const FollowersModalView = () => (
|
||||||
|
<>
|
||||||
|
<h2>{t('Followers')}</h2>
|
||||||
|
<div class={styles.listWrapper}>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-24">
|
||||||
|
<For each={props.followers}>{(follower: Author) => <AuthorBadge author={follower} />}</For>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
|
||||||
|
const FollowingModalView = () => (
|
||||||
|
<>
|
||||||
|
<h2>{t('Subscriptions')}</h2>
|
||||||
|
<ul class="view-switcher">
|
||||||
|
<li
|
||||||
|
class={clsx({
|
||||||
|
'view-switcher__item--selected': followsFilter() === 'all',
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
<button type="button" onClick={() => setFollowsFilter('all')}>
|
||||||
|
{t('All')}
|
||||||
|
</button>
|
||||||
|
<span class="view-switcher__counter">{props.flatFollows.length}</span>
|
||||||
|
</li>
|
||||||
|
<li
|
||||||
|
class={clsx({
|
||||||
|
'view-switcher__item--selected': followsFilter() === 'authors',
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
<button type="button" onClick={() => setFollowsFilter('authors')}>
|
||||||
|
{t('Authors')}
|
||||||
|
</button>
|
||||||
|
<span class="view-switcher__counter">{props.flatFollows.filter((s) => 'name' in s).length}</span>
|
||||||
|
</li>
|
||||||
|
<li
|
||||||
|
class={clsx({
|
||||||
|
'view-switcher__item--selected': followsFilter() === 'topics',
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
<button type="button" onClick={() => setFollowsFilter('topics')}>
|
||||||
|
{t('Topics')}
|
||||||
|
</button>
|
||||||
|
<span class="view-switcher__counter">{props.flatFollows.filter((s) => 'title' in s).length}</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<br />
|
||||||
|
<div class={styles.listWrapper}>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-24">
|
||||||
|
<For each={authorSubs()}>
|
||||||
|
{(subscription) =>
|
||||||
|
isAuthor(subscription) ? (
|
||||||
|
<AuthorBadge author={subscription} subscriptionsMode={true} />
|
||||||
|
) : (
|
||||||
|
<TopicBadge topic={subscription} subscriptionsMode={true} />
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</For>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div class={clsx(styles.author, 'row')}>
|
<div class={clsx(styles.author, 'row')}>
|
||||||
<div class="col-md-5">
|
<div class="col-md-5">
|
||||||
|
@ -125,35 +192,30 @@ export const AuthorCard = (props: Props) => {
|
||||||
<Show when={props.author.bio}>
|
<Show when={props.author.bio}>
|
||||||
<div class={styles.authorAbout} innerHTML={props.author.bio} />
|
<div class={styles.authorAbout} innerHTML={props.author.bio} />
|
||||||
</Show>
|
</Show>
|
||||||
<Show when={props.followers?.length > 0 || props.following?.length > 0}>
|
<Show when={props.followers?.length > 0 || props.flatFollows?.length > 0}>
|
||||||
<div class={styles.subscribersContainer}>
|
<div class={styles.followersContainer}>
|
||||||
<Show when={props.followers && props.followers.length > 0}>
|
<Show when={props.followers && props.followers.length > 0}>
|
||||||
<a href="?m=followers" class={styles.subscribers}>
|
<a href="?m=followers" class={styles.followers}>
|
||||||
<For each={props.followers.slice(0, 3)}>
|
<For each={props.followers.slice(0, 3)}>
|
||||||
{(f) => (
|
{(f) => (
|
||||||
<Userpic size={'XS'} name={f.name} userpic={f.pic} class={styles.subscribersItem} />
|
<Userpic size={'XS'} name={f.name} userpic={f.pic} class={styles.followersItem} />
|
||||||
)}
|
)}
|
||||||
</For>
|
</For>
|
||||||
<div class={styles.subscribersCounter}>
|
<div class={styles.followsCounter}>
|
||||||
{t('SubscriberWithCount', {
|
{t('FollowersWithCount', {
|
||||||
count: props.followers.length ?? 0,
|
count: props.followers.length ?? 0,
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
</Show>
|
</Show>
|
||||||
|
|
||||||
<Show when={props.following && props.following.length > 0}>
|
<Show when={props.flatFollows?.length > 0}>
|
||||||
<a href="?m=following" class={styles.subscribers}>
|
<a href="?m=following" class={styles.followers}>
|
||||||
<For each={props.following.slice(0, 3)}>
|
<For each={props.flatFollows.slice(0, 3)}>
|
||||||
{(f) => {
|
{(f) => {
|
||||||
if ('name' in f) {
|
if ('name' in f) {
|
||||||
return (
|
return (
|
||||||
<Userpic
|
<Userpic size={'XS'} name={f.name} userpic={f.pic} class={styles.followersItem} />
|
||||||
size={'XS'}
|
|
||||||
name={f.name}
|
|
||||||
userpic={f.pic}
|
|
||||||
class={styles.subscribersItem}
|
|
||||||
/>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,7 +225,7 @@ export const AuthorCard = (props: Props) => {
|
||||||
size={'XS'}
|
size={'XS'}
|
||||||
name={f.title}
|
name={f.title}
|
||||||
userpic={f.pic}
|
userpic={f.pic}
|
||||||
class={styles.subscribersItem}
|
class={styles.followersItem}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -171,9 +233,9 @@ export const AuthorCard = (props: Props) => {
|
||||||
return null
|
return null
|
||||||
}}
|
}}
|
||||||
</For>
|
</For>
|
||||||
<div class={styles.subscribersCounter}>
|
<div class={styles.followsCounter}>
|
||||||
{t('SubscriptionWithCount', {
|
{t('FollowsWithCount', {
|
||||||
count: props?.following.length ?? 0,
|
count: props?.flatFollows.length ?? 0,
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
|
@ -251,77 +313,12 @@ export const AuthorCard = (props: Props) => {
|
||||||
</ShowOnlyOnClient>
|
</ShowOnlyOnClient>
|
||||||
<Show when={props.followers}>
|
<Show when={props.followers}>
|
||||||
<Modal variant="medium" isResponsive={true} name="followers" maxHeight>
|
<Modal variant="medium" isResponsive={true} name="followers" maxHeight>
|
||||||
<>
|
<FollowersModalView />
|
||||||
<h2>{t('Followers')}</h2>
|
|
||||||
<div class={styles.listWrapper}>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-24">
|
|
||||||
<For each={props.followers}>
|
|
||||||
{(follower: Author) => <AuthorBadge author={follower} />}
|
|
||||||
</For>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
</Modal>
|
</Modal>
|
||||||
</Show>
|
</Show>
|
||||||
<Show when={props.following}>
|
<Show when={props.flatFollows}>
|
||||||
<Modal variant="medium" isResponsive={true} name="following" maxHeight>
|
<Modal variant="medium" isResponsive={true} name="following" maxHeight>
|
||||||
<>
|
<FollowingModalView />
|
||||||
<h2>{t('Subscriptions')}</h2>
|
|
||||||
<ul class="view-switcher">
|
|
||||||
<li
|
|
||||||
class={clsx({
|
|
||||||
'view-switcher__item--selected': followsFilter() === 'all',
|
|
||||||
})}
|
|
||||||
>
|
|
||||||
<button type="button" onClick={() => setFollowsFilter('all')}>
|
|
||||||
{t('All')}
|
|
||||||
</button>
|
|
||||||
<span class="view-switcher__counter">{props.following.length}</span>
|
|
||||||
</li>
|
|
||||||
<li
|
|
||||||
class={clsx({
|
|
||||||
'view-switcher__item--selected': followsFilter() === 'authors',
|
|
||||||
})}
|
|
||||||
>
|
|
||||||
<button type="button" onClick={() => setFollowsFilter('authors')}>
|
|
||||||
{t('Authors')}
|
|
||||||
</button>
|
|
||||||
<span class="view-switcher__counter">
|
|
||||||
{props.following.filter((s) => 'name' in s).length}
|
|
||||||
</span>
|
|
||||||
</li>
|
|
||||||
<li
|
|
||||||
class={clsx({
|
|
||||||
'view-switcher__item--selected': followsFilter() === 'topics',
|
|
||||||
})}
|
|
||||||
>
|
|
||||||
<button type="button" onClick={() => setFollowsFilter('topics')}>
|
|
||||||
{t('Topics')}
|
|
||||||
</button>
|
|
||||||
<span class="view-switcher__counter">
|
|
||||||
{props.following.filter((s) => 'title' in s).length}
|
|
||||||
</span>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<br />
|
|
||||||
<div class={styles.listWrapper}>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-24">
|
|
||||||
<For each={authorSubs()}>
|
|
||||||
{(subscription) =>
|
|
||||||
isAuthor(subscription) ? (
|
|
||||||
<AuthorBadge author={subscription} subscriptionsMode={true} />
|
|
||||||
) : (
|
|
||||||
<TopicBadge topic={subscription} subscriptionsMode={true} />
|
|
||||||
)
|
|
||||||
}
|
|
||||||
</For>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
</Modal>
|
</Modal>
|
||||||
</Show>
|
</Show>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -63,18 +63,8 @@ export const PasswordField = (props: Props) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
createEffect(
|
createEffect(on(error, (er) => er && props.errorMessage?.(er), { defer: true }))
|
||||||
on(
|
createEffect(() => setError(props.setError))
|
||||||
() => error(),
|
|
||||||
() => {
|
|
||||||
props.errorMessage?.(error())
|
|
||||||
},
|
|
||||||
{ defer: true },
|
|
||||||
),
|
|
||||||
)
|
|
||||||
createEffect(() => {
|
|
||||||
setError(props.setError)
|
|
||||||
})
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div class={clsx(styles.PassportField, props.class)}>
|
<div class={clsx(styles.PassportField, props.class)}>
|
||||||
|
|
|
@ -62,7 +62,7 @@ export const TableOfContents = (props: Props) => {
|
||||||
createEffect(
|
createEffect(
|
||||||
on(
|
on(
|
||||||
() => props.body,
|
() => props.body,
|
||||||
() => debouncedUpdateHeadings(),
|
(_) => debouncedUpdateHeadings(),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -40,65 +40,19 @@ const LOAD_MORE_PAGE_SIZE = 9
|
||||||
export const AuthorView = (props: Props) => {
|
export const AuthorView = (props: Props) => {
|
||||||
const { t } = useLocalize()
|
const { t } = useLocalize()
|
||||||
const { followers: myFollowers, follows: myFollows } = useFollowing()
|
const { followers: myFollowers, follows: myFollows } = useFollowing()
|
||||||
const { session, author: me } = useSession()
|
const { author: me } = useSession()
|
||||||
const { sortedArticles } = useArticlesStore({ shouts: props.shouts })
|
const { sortedArticles } = useArticlesStore({ shouts: props.shouts })
|
||||||
const { page: getPage, searchParams } = useRouter()
|
const { page: getPage, searchParams } = useRouter()
|
||||||
const [isLoadMoreButtonVisible, setIsLoadMoreButtonVisible] = createSignal(false)
|
const [isLoadMoreButtonVisible, setIsLoadMoreButtonVisible] = createSignal(false)
|
||||||
const [isBioExpanded, setIsBioExpanded] = createSignal(false)
|
const [isBioExpanded, setIsBioExpanded] = createSignal(false)
|
||||||
const [author, setAuthor] = createSignal<Author>()
|
const [author, setAuthor] = createSignal<Author>(props.author)
|
||||||
const [followers, setFollowers] = createSignal([])
|
const [followers, setFollowers] = createSignal([])
|
||||||
const [following, changeFollowing] = createSignal<Array<Author | Topic>>([]) // flat AuthorFollowsResult
|
const [following, changeFollowing] = createSignal<Array<Author | Topic>>([]) // flat AuthorFollowsResult
|
||||||
const [showExpandBioControl, setShowExpandBioControl] = createSignal(false)
|
const [showExpandBioControl, setShowExpandBioControl] = createSignal(false)
|
||||||
const [commented, setCommented] = createSignal<Reaction[]>()
|
const [commented, setCommented] = createSignal<Reaction[]>()
|
||||||
const modal = MODALS[searchParams().m]
|
const modal = MODALS[searchParams().m]
|
||||||
|
|
||||||
const [sessionChecked, setSessionChecked] = createSignal(false)
|
// пагинация загрузки ленты постов
|
||||||
createEffect(
|
|
||||||
on(
|
|
||||||
[() => sessionChecked(), () => props.authorSlug, () => session()?.user?.app_data?.profile?.slug],
|
|
||||||
([checked, slug, mySlug]) => {
|
|
||||||
if (!checked && slug && mySlug === slug) {
|
|
||||||
setSessionChecked(true)
|
|
||||||
const appdata = session()?.user.app_data
|
|
||||||
if (appdata) {
|
|
||||||
console.info('preloaded my own profile')
|
|
||||||
setFollowers(myFollowers())
|
|
||||||
setAuthor(me())
|
|
||||||
const { authors, topics } = myFollows
|
|
||||||
changeFollowing([...authors, ...topics])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{ defer: true },
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
const bioContainerRef: { current: HTMLDivElement } = { current: null }
|
|
||||||
const bioWrapperRef: { current: HTMLDivElement } = { current: null }
|
|
||||||
|
|
||||||
const fetchData = async (slug: string) => {
|
|
||||||
try {
|
|
||||||
const [followsResult, followersResult, authorResult] = await Promise.all([
|
|
||||||
apiClient.getAuthorFollows({ slug }),
|
|
||||||
apiClient.getAuthorFollowers({ slug }),
|
|
||||||
loadAuthor({ slug }),
|
|
||||||
])
|
|
||||||
console.info('[components.Author] data loaded')
|
|
||||||
setAuthor(authorResult)
|
|
||||||
setFollowers(followersResult || [])
|
|
||||||
const { authors, topics } = followsResult
|
|
||||||
changeFollowing([...(authors || []), ...(topics || [])])
|
|
||||||
} catch (error) {
|
|
||||||
console.error('[components.Author] fetch error', error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const checkBioHeight = () => {
|
|
||||||
if (bioContainerRef.current) {
|
|
||||||
setShowExpandBioControl(bioContainerRef.current.offsetHeight > bioWrapperRef.current.offsetHeight)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const loadMore = async () => {
|
const loadMore = async () => {
|
||||||
saveScrollPosition()
|
saveScrollPosition()
|
||||||
const { hasMore } = await loadShouts({
|
const { hasMore } = await loadShouts({
|
||||||
|
@ -110,36 +64,72 @@ export const AuthorView = (props: Props) => {
|
||||||
restoreScrollPosition()
|
restoreScrollPosition()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// загружает профиль и подписки
|
||||||
|
const [isFetching, setIsFetching] = createSignal(false)
|
||||||
|
const fetchData = async (slug) => {
|
||||||
|
setIsFetching(true)
|
||||||
|
const authorResult = await loadAuthor({ slug })
|
||||||
|
setAuthor(authorResult)
|
||||||
|
console.info(`[Author] profile for @${slug} fetched`)
|
||||||
|
|
||||||
|
const followsResult = await apiClient.getAuthorFollows({ slug })
|
||||||
|
const { authors, topics } = followsResult
|
||||||
|
changeFollowing([...(authors || []), ...(topics || [])])
|
||||||
|
console.info(`[Author] follows for @${slug} fetched`)
|
||||||
|
|
||||||
|
const followersResult = await apiClient.getAuthorFollowers({ slug })
|
||||||
|
setFollowers(followersResult || [])
|
||||||
|
console.info(`[Author] followers for @${slug} fetched`)
|
||||||
|
setIsFetching(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
// проверяет не собственный ли это профиль, иначе - загружает
|
||||||
|
createEffect(
|
||||||
|
on([() => me(), () => props.authorSlug], ([myProfile, slug]) => {
|
||||||
|
const my = slug && myProfile?.slug === slug
|
||||||
|
if (my) {
|
||||||
|
console.debug('[Author] my profile precached')
|
||||||
|
myProfile && setAuthor(myProfile)
|
||||||
|
setFollowers(myFollowers() || [])
|
||||||
|
changeFollowing([...(myFollows?.authors || []), ...(myFollows?.topics || [])])
|
||||||
|
} else if (slug && !isFetching()) {
|
||||||
|
fetchData(slug)
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
{ defer: true },
|
||||||
|
)
|
||||||
|
|
||||||
|
// догружает ленту и комментарии
|
||||||
|
createEffect(
|
||||||
|
on(author, async (profile) => {
|
||||||
|
if (!commented() && profile) {
|
||||||
|
await loadMore()
|
||||||
|
|
||||||
|
const ccc = await apiClient.getReactionsBy({
|
||||||
|
by: { comment: true, created_by: profile.id },
|
||||||
|
})
|
||||||
|
setCommented(ccc)
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
|
||||||
|
const bioContainerRef: { current: HTMLDivElement } = { current: null }
|
||||||
|
const bioWrapperRef: { current: HTMLDivElement } = { current: null }
|
||||||
|
const checkBioHeight = () => {
|
||||||
|
if (bioContainerRef.current) {
|
||||||
|
setShowExpandBioControl(bioContainerRef.current.offsetHeight > bioWrapperRef.current.offsetHeight)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
if (!modal) hideModal()
|
if (!modal) hideModal()
|
||||||
fetchData(props.authorSlug)
|
|
||||||
checkBioHeight()
|
checkBioHeight()
|
||||||
loadMore()
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const pages = createMemo<Shout[][]>(() =>
|
const pages = createMemo<Shout[][]>(() =>
|
||||||
splitToPages(sortedArticles(), PRERENDERED_ARTICLES_COUNT, LOAD_MORE_PAGE_SIZE),
|
splitToPages(sortedArticles(), PRERENDERED_ARTICLES_COUNT, LOAD_MORE_PAGE_SIZE),
|
||||||
)
|
)
|
||||||
|
|
||||||
const fetchComments = async (commenter: Author) => {
|
|
||||||
const data = await apiClient.getReactionsBy({
|
|
||||||
by: { comment: true, created_by: commenter.id },
|
|
||||||
})
|
|
||||||
setCommented(data)
|
|
||||||
}
|
|
||||||
|
|
||||||
const authorSlug = createMemo(() => author()?.slug)
|
|
||||||
createEffect(
|
|
||||||
on(
|
|
||||||
() => authorSlug(),
|
|
||||||
() => {
|
|
||||||
fetchData(authorSlug())
|
|
||||||
fetchComments(author())
|
|
||||||
},
|
|
||||||
{ defer: true },
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
const ogImage = createMemo(() =>
|
const ogImage = createMemo(() =>
|
||||||
author()?.pic
|
author()?.pic
|
||||||
? getImageUrl(author()?.pic, { width: 1200 })
|
? getImageUrl(author()?.pic, { width: 1200 })
|
||||||
|
@ -168,7 +158,7 @@ export const AuthorView = (props: Props) => {
|
||||||
<Show when={author()} fallback={<Loading />}>
|
<Show when={author()} fallback={<Loading />}>
|
||||||
<>
|
<>
|
||||||
<div class={styles.authorHeader}>
|
<div class={styles.authorHeader}>
|
||||||
<AuthorCard author={author()} followers={followers() || []} following={following() || []} />
|
<AuthorCard author={author()} followers={followers() || []} flatFollows={following() || []} />
|
||||||
</div>
|
</div>
|
||||||
<div class={clsx(styles.groupControls, 'row')}>
|
<div class={clsx(styles.groupControls, 'row')}>
|
||||||
<div class="col-md-16">
|
<div class="col-md-16">
|
||||||
|
|
|
@ -143,16 +143,20 @@ export const FeedView = (props: Props) => {
|
||||||
Promise.all([loadTopComments()]).finally(() => setIsRightColumnLoaded(true))
|
Promise.all([loadTopComments()]).finally(() => setIsRightColumnLoaded(true))
|
||||||
})
|
})
|
||||||
|
|
||||||
createEffect(() => {
|
createEffect(
|
||||||
if (session()?.access_token && !unratedArticles()) {
|
on(
|
||||||
loadUnratedArticles()
|
[() => session(), unratedArticles],
|
||||||
}
|
([s, seen]) => {
|
||||||
})
|
if (s?.access_token && !(seen?.length > 0)) loadUnratedArticles()
|
||||||
|
},
|
||||||
|
{ defer: true },
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
createEffect(
|
createEffect(
|
||||||
on(
|
on(
|
||||||
() => page().route + searchParams().by + searchParams().period + searchParams().visibility,
|
[page, searchParams],
|
||||||
() => {
|
(_, _p) => {
|
||||||
resetSortedArticles()
|
resetSortedArticles()
|
||||||
loadMore()
|
loadMore()
|
||||||
},
|
},
|
||||||
|
|
|
@ -136,9 +136,7 @@ export const InboxView = (props: Props) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
createEffect(
|
createEffect(
|
||||||
on(
|
on(messages, () => {
|
||||||
() => messages(),
|
|
||||||
() => {
|
|
||||||
if (!messagesContainerRef.current) {
|
if (!messagesContainerRef.current) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -149,8 +147,7 @@ export const InboxView = (props: Props) => {
|
||||||
top: messagesContainerRef.current.scrollHeight,
|
top: messagesContainerRef.current.scrollHeight,
|
||||||
behavior: 'smooth',
|
behavior: 'smooth',
|
||||||
})
|
})
|
||||||
},
|
}),
|
||||||
),
|
|
||||||
{ defer: true },
|
{ defer: true },
|
||||||
)
|
)
|
||||||
const handleScrollMessageContainer = () => {
|
const handleScrollMessageContainer = () => {
|
||||||
|
|
|
@ -87,13 +87,7 @@ export const TopicView = (props: Props) => {
|
||||||
loadReactedTopMonthArticles(topic()?.slug)
|
loadReactedTopMonthArticles(topic()?.slug)
|
||||||
}
|
}
|
||||||
|
|
||||||
createEffect(
|
createEffect(on(topic, loadRandom, { defer: true }))
|
||||||
on(
|
|
||||||
() => topic(),
|
|
||||||
() => loadRandom(),
|
|
||||||
{ defer: true },
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
const title = createMemo(
|
const title = createMemo(
|
||||||
() =>
|
() =>
|
||||||
|
|
|
@ -66,7 +66,7 @@ export const InviteMembers = (props: Props) => {
|
||||||
|
|
||||||
createEffect(
|
createEffect(
|
||||||
on(
|
on(
|
||||||
() => sortedAuthors(),
|
sortedAuthors,
|
||||||
(currentAuthors) => {
|
(currentAuthors) => {
|
||||||
setAuthorsToInvite(currentAuthors.map((author) => ({ ...author, selected: false })))
|
setAuthorsToInvite(currentAuthors.map((author) => ({ ...author, selected: false })))
|
||||||
},
|
},
|
||||||
|
|
|
@ -129,8 +129,8 @@ export const Lightbox = (props: Props) => {
|
||||||
|
|
||||||
createEffect(
|
createEffect(
|
||||||
on(
|
on(
|
||||||
() => zoomLevel(),
|
zoomLevel,
|
||||||
() => {
|
(_) => {
|
||||||
clearTimeout(fadeTimer)
|
clearTimeout(fadeTimer)
|
||||||
|
|
||||||
fadeTimer = setTimeout(() => {
|
fadeTimer = setTimeout(() => {
|
||||||
|
|
|
@ -61,7 +61,7 @@ export const EditorSwiper = (props: Props) => {
|
||||||
createEffect(
|
createEffect(
|
||||||
on(
|
on(
|
||||||
() => props.images.length,
|
() => props.images.length,
|
||||||
() => {
|
(_) => {
|
||||||
mainSwipeRef.current?.swiper.update()
|
mainSwipeRef.current?.swiper.update()
|
||||||
thumbSwipeRef.current?.swiper.update()
|
thumbSwipeRef.current?.swiper.update()
|
||||||
},
|
},
|
||||||
|
|
|
@ -45,7 +45,7 @@ export const ImageSwiper = (props: Props) => {
|
||||||
createEffect(
|
createEffect(
|
||||||
on(
|
on(
|
||||||
() => props.images.length,
|
() => props.images.length,
|
||||||
() => {
|
(_) => {
|
||||||
mainSwipeRef.current?.swiper.update()
|
mainSwipeRef.current?.swiper.update()
|
||||||
thumbSwipeRef.current?.swiper.update()
|
thumbSwipeRef.current?.swiper.update()
|
||||||
},
|
},
|
||||||
|
|
|
@ -94,21 +94,14 @@ export const FollowingProvider = (props: { children: JSX.Element }) => {
|
||||||
|
|
||||||
createEffect(
|
createEffect(
|
||||||
on(
|
on(
|
||||||
() => author(),
|
() => session()?.user.app_data,
|
||||||
(a) => {
|
(appdata) => {
|
||||||
if (a?.id) {
|
|
||||||
try {
|
|
||||||
const appdata = session()?.user.app_data
|
|
||||||
if (appdata) {
|
if (appdata) {
|
||||||
const { authors, followers, topics } = appdata
|
const { authors, followers, topics } = appdata
|
||||||
setFollows({ authors, topics })
|
setFollows({ authors, topics })
|
||||||
setFollowers(followers)
|
setFollowers(followers)
|
||||||
if (!authors) fetchData()
|
if (!authors) fetchData()
|
||||||
}
|
}
|
||||||
} catch (e) {
|
|
||||||
console.error(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
|
@ -96,15 +96,15 @@ export const SessionProvider = (props: {
|
||||||
// handle auth state callback
|
// handle auth state callback
|
||||||
createEffect(
|
createEffect(
|
||||||
on(
|
on(
|
||||||
() => searchParams()?.state,
|
searchParams,
|
||||||
(state) => {
|
(params) => {
|
||||||
if (state) {
|
if (params?.state) {
|
||||||
setOauthState((_s) => state)
|
setOauthState((_s) => params?.state)
|
||||||
const scope = searchParams()?.scope
|
const scope = params?.scope
|
||||||
? searchParams()?.scope?.toString().split(' ')
|
? params?.scope?.toString().split(' ')
|
||||||
: ['openid', 'profile', 'email']
|
: ['openid', 'profile', 'email']
|
||||||
if (scope) console.info(`[context.session] scope: ${scope}`)
|
if (scope) console.info(`[context.session] scope: ${scope}`)
|
||||||
const url = searchParams()?.redirect_uri || searchParams()?.redirectURL || window.location.href
|
const url = params?.redirect_uri || params?.redirectURL || window.location.href
|
||||||
setConfig((c: ConfigType) => ({ ...c, redirectURL: url.split('?')[0] }))
|
setConfig((c: ConfigType) => ({ ...c, redirectURL: url.split('?')[0] }))
|
||||||
changeSearchParams({ mode: 'confirm-email', m: 'auth' }, true)
|
changeSearchParams({ mode: 'confirm-email', m: 'auth' }, true)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import type { PageProps } from './types'
|
import type { PageProps } from './types'
|
||||||
|
|
||||||
import { Show, createEffect, createMemo, createSignal, on, onCleanup, onMount } from 'solid-js'
|
import { Show, createEffect, createMemo, createSignal, on, onCleanup } from 'solid-js'
|
||||||
|
|
||||||
import { AuthorView, PRERENDERED_ARTICLES_COUNT } from '../components/Views/Author'
|
import { AuthorView, PRERENDERED_ARTICLES_COUNT } from '../components/Views/Author'
|
||||||
import { Loading } from '../components/_shared/Loading'
|
import { Loading } from '../components/_shared/Loading'
|
||||||
|
@ -20,38 +20,19 @@ export const AuthorPage = (props: PageProps) => {
|
||||||
Boolean(props.authorShouts) && Boolean(props.author) && props.author.slug === slug(),
|
Boolean(props.authorShouts) && Boolean(props.author) && props.author.slug === slug(),
|
||||||
)
|
)
|
||||||
|
|
||||||
const preload = () => {
|
|
||||||
return Promise.all([
|
|
||||||
loadShouts({
|
|
||||||
filters: { author: slug(), featured: false },
|
|
||||||
limit: PRERENDERED_ARTICLES_COUNT,
|
|
||||||
}),
|
|
||||||
loadAuthor({ slug: slug() }),
|
|
||||||
])
|
|
||||||
}
|
|
||||||
|
|
||||||
onMount(async () => {
|
|
||||||
if (isLoaded()) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
resetSortedArticles()
|
|
||||||
await preload()
|
|
||||||
|
|
||||||
setIsLoaded(true)
|
|
||||||
})
|
|
||||||
|
|
||||||
createEffect(
|
createEffect(
|
||||||
on(
|
on(slug, async (s) => {
|
||||||
() => slug(),
|
if (s) {
|
||||||
async () => {
|
|
||||||
setIsLoaded(false)
|
setIsLoaded(false)
|
||||||
resetSortedArticles()
|
resetSortedArticles()
|
||||||
await preload()
|
await loadShouts({
|
||||||
|
filters: { author: s, featured: false },
|
||||||
|
limit: PRERENDERED_ARTICLES_COUNT,
|
||||||
|
})
|
||||||
|
await loadAuthor({ slug: s })
|
||||||
setIsLoaded(true)
|
setIsLoaded(true)
|
||||||
},
|
}
|
||||||
{ defer: true },
|
}),
|
||||||
),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
onCleanup(() => resetSortedArticles())
|
onCleanup(() => resetSortedArticles())
|
||||||
|
|
|
@ -12,10 +12,9 @@ import { LayoutType } from '../types'
|
||||||
export const ExpoPage = (props: PageProps) => {
|
export const ExpoPage = (props: PageProps) => {
|
||||||
const { t } = useLocalize()
|
const { t } = useLocalize()
|
||||||
const { page } = useRouter()
|
const { page } = useRouter()
|
||||||
const getLayout = createMemo<LayoutType>(() => page().params['layout'] as LayoutType)
|
const layout = createMemo(() => page().params['layout'] as LayoutType)
|
||||||
|
const title = createMemo(() => {
|
||||||
const getTitle = () => {
|
switch (layout()) {
|
||||||
switch (getLayout()) {
|
|
||||||
case 'audio': {
|
case 'audio': {
|
||||||
return t('Audio')
|
return t('Audio')
|
||||||
}
|
}
|
||||||
|
@ -32,22 +31,14 @@ export const ExpoPage = (props: PageProps) => {
|
||||||
return t('Art')
|
return t('Art')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
|
|
||||||
createEffect(
|
createEffect(on(title, (t) => (document.title = t), { defer: true }))
|
||||||
on(
|
|
||||||
() => getLayout(),
|
|
||||||
() => {
|
|
||||||
document.title = getTitle()
|
|
||||||
},
|
|
||||||
{ defer: true },
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PageLayout withPadding={true} zeroBottomPadding={true} title={getTitle()}>
|
<PageLayout withPadding={true} zeroBottomPadding={true} title={title()}>
|
||||||
<Topics />
|
<Topics />
|
||||||
<Expo shouts={props.expoShouts} layout={getLayout()} />
|
<Expo shouts={props.expoShouts} layout={layout()} />
|
||||||
</PageLayout>
|
</PageLayout>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,20 +25,9 @@ const handleMyFeedLoadShouts = (options: LoadShoutsOptions) => {
|
||||||
|
|
||||||
export const FeedPage = () => {
|
export const FeedPage = () => {
|
||||||
const { t } = useLocalize()
|
const { t } = useLocalize()
|
||||||
|
|
||||||
onCleanup(() => resetSortedArticles())
|
|
||||||
|
|
||||||
const { page } = useRouter()
|
const { page } = useRouter()
|
||||||
|
createEffect(on(page, (_) => resetSortedArticles(), { defer: true }))
|
||||||
createEffect(
|
onCleanup(() => resetSortedArticles())
|
||||||
on(
|
|
||||||
() => page().route,
|
|
||||||
() => {
|
|
||||||
resetSortedArticles()
|
|
||||||
},
|
|
||||||
{ defer: true },
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PageLayout title={t('Feed')}>
|
<PageLayout title={t('Feed')}>
|
||||||
|
|
|
@ -44,10 +44,10 @@ export const ProfileSecurityPage = () => {
|
||||||
createEffect(
|
createEffect(
|
||||||
on(
|
on(
|
||||||
() => session()?.user?.email,
|
() => session()?.user?.email,
|
||||||
() => {
|
(email) => {
|
||||||
setFormData((prevData) => ({
|
setFormData((prevData) => ({
|
||||||
...prevData,
|
...prevData,
|
||||||
['email']: session()?.user?.email,
|
email,
|
||||||
}))
|
}))
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|
|
@ -37,19 +37,17 @@ export const TopicPage = (props: PageProps) => {
|
||||||
})
|
})
|
||||||
|
|
||||||
createEffect(
|
createEffect(
|
||||||
on(
|
on(slug, async (s) => {
|
||||||
() => slug(),
|
if (s) {
|
||||||
async () => {
|
|
||||||
setIsLoaded(false)
|
setIsLoaded(false)
|
||||||
resetSortedArticles()
|
resetSortedArticles()
|
||||||
await preload()
|
await preload()
|
||||||
setIsLoaded(true)
|
setIsLoaded(true)
|
||||||
},
|
}
|
||||||
{ defer: true },
|
}),
|
||||||
),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
onCleanup(() => resetSortedArticles())
|
onCleanup(resetSortedArticles)
|
||||||
|
|
||||||
const usePrerenderedData = props.topic?.slug === slug()
|
const usePrerenderedData = props.topic?.slug === slug()
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ const cssModuleHMR = () => {
|
||||||
modules.forEach((module) => {
|
modules.forEach((module) => {
|
||||||
if (module.id.includes('.scss') || module.id.includes('.css')) {
|
if (module.id.includes('.scss') || module.id.includes('.css')) {
|
||||||
module.isSelfAccepting = true
|
module.isSelfAccepting = true
|
||||||
module.accept()
|
// module.accept()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue
Block a user