comments-view-fix
This commit is contained in:
parent
a2999e3851
commit
7a2043f223
|
@ -63,7 +63,7 @@ const scrollTo = (el: HTMLElement) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const imgSrcRegExp = /<img[^>]+src\s*=\s*["']([^"']+)["']/gi
|
const imgSrcRegExp = /<img[^>]+src\s*=\s*["']([^"']+)["']/gi
|
||||||
const COMMENTS_PER_PAGE = 30
|
export const COMMENTS_PER_PAGE = 30
|
||||||
const VOTES_PER_PAGE = 50
|
const VOTES_PER_PAGE = 50
|
||||||
|
|
||||||
export const FullArticle = (props: Props) => {
|
export const FullArticle = (props: Props) => {
|
||||||
|
|
|
@ -30,6 +30,7 @@ import styles from './Author.module.scss'
|
||||||
type AuthorViewProps = {
|
type AuthorViewProps = {
|
||||||
authorSlug: string
|
authorSlug: string
|
||||||
shouts: Shout[]
|
shouts: Shout[]
|
||||||
|
comments: Reaction[]
|
||||||
author?: Author
|
author?: Author
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,7 +57,7 @@ export const AuthorView = (props: AuthorViewProps) => {
|
||||||
const [followers, setFollowers] = createSignal<Author[]>([] as Author[])
|
const [followers, setFollowers] = createSignal<Author[]>([] as Author[])
|
||||||
const [following, changeFollowing] = createSignal<Array<Author | Topic>>([] as Array<Author | Topic>) // flat AuthorFollowsResult
|
const [following, changeFollowing] = createSignal<Array<Author | Topic>>([] as 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[]>(props.comments || [])
|
||||||
const [followersLoaded, setFollowersLoaded] = createSignal(false)
|
const [followersLoaded, setFollowersLoaded] = createSignal(false)
|
||||||
const [followingsLoaded, setFollowingsLoaded] = createSignal(false)
|
const [followingsLoaded, setFollowingsLoaded] = createSignal(false)
|
||||||
|
|
||||||
|
@ -64,36 +65,41 @@ export const AuthorView = (props: AuthorViewProps) => {
|
||||||
const me = createMemo<Author>(() => session()?.user?.app_data?.profile as Author)
|
const me = createMemo<Author>(() => session()?.user?.app_data?.profile as Author)
|
||||||
|
|
||||||
// Объединенный эффект для загрузки автора и его подписок
|
// Объединенный эффект для загрузки автора и его подписок
|
||||||
createEffect(async () => {
|
createEffect(
|
||||||
const meData = session()?.user?.app_data?.profile as Author
|
on(
|
||||||
const slug = props.authorSlug
|
() => session()?.user?.app_data?.profile,
|
||||||
|
async (meData?: Author) => {
|
||||||
|
const slug = props.authorSlug
|
||||||
|
|
||||||
if (slug && meData?.slug === slug) {
|
if (slug && meData?.slug === slug) {
|
||||||
setAuthor(meData)
|
setAuthor(meData)
|
||||||
setFollowers(myFollowers() || [])
|
setFollowers(myFollowers() || [])
|
||||||
setFollowersLoaded(true)
|
setFollowersLoaded(true)
|
||||||
changeFollowing([...(myFollows?.topics || []), ...(myFollows?.authors || [])])
|
changeFollowing([...(myFollows?.topics || []), ...(myFollows?.authors || [])])
|
||||||
} else if (slug && !author()) {
|
} else if (slug && !author()) {
|
||||||
await loadAuthor({ slug })
|
await loadAuthor({ slug })
|
||||||
const foundAuthor = authorsEntities()[slug]
|
const foundAuthor = authorsEntities()[slug]
|
||||||
setAuthor(foundAuthor)
|
setAuthor(foundAuthor)
|
||||||
|
|
||||||
if (foundAuthor) {
|
if (foundAuthor) {
|
||||||
const followsResp = await client()
|
const followsResp = await client()
|
||||||
?.query(getAuthorFollowsQuery, { slug: foundAuthor.slug })
|
?.query(getAuthorFollowsQuery, { slug: foundAuthor.slug })
|
||||||
.toPromise()
|
.toPromise()
|
||||||
const follows = followsResp?.data?.get_author_followers || {}
|
const follows = followsResp?.data?.get_author_followers || {}
|
||||||
changeFollowing([...(follows?.authors || []), ...(follows?.topics || [])])
|
changeFollowing([...(follows?.authors || []), ...(follows?.topics || [])])
|
||||||
setFollowingsLoaded(true)
|
setFollowingsLoaded(true)
|
||||||
|
|
||||||
const followersResp = await client()
|
const followersResp = await client()
|
||||||
?.query(getAuthorFollowersQuery, { slug: foundAuthor.slug })
|
?.query(getAuthorFollowersQuery, { slug: foundAuthor.slug })
|
||||||
.toPromise()
|
.toPromise()
|
||||||
setFollowers(followersResp?.data?.get_author_followers || [])
|
setFollowers(followersResp?.data?.get_author_followers || [])
|
||||||
setFollowersLoaded(true)
|
setFollowersLoaded(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
},
|
||||||
|
{}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
// Обработка биографии
|
// Обработка биографии
|
||||||
let bioContainerRef: HTMLDivElement
|
let bioContainerRef: HTMLDivElement
|
||||||
|
@ -138,7 +144,7 @@ export const AuthorView = (props: AuthorViewProps) => {
|
||||||
)
|
)
|
||||||
|
|
||||||
const { feedByAuthor, addFeed } = useFeed()
|
const { feedByAuthor, addFeed } = useFeed()
|
||||||
const [sortedFeed, setSortedFeed] = createSignal<Shout[]>([])
|
const [sortedFeed, setSortedFeed] = createSignal<Shout[]>(props.shouts || [])
|
||||||
const [loadMoreHidden, setLoadMoreHidden] = createSignal(false)
|
const [loadMoreHidden, setLoadMoreHidden] = createSignal(false)
|
||||||
const loadMore = async () => {
|
const loadMore = async () => {
|
||||||
saveScrollPosition()
|
saveScrollPosition()
|
||||||
|
@ -166,7 +172,9 @@ export const AuthorView = (props: AuthorViewProps) => {
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
const [loadMoreCommentsHidden, setLoadMoreCommentsHidden] = createSignal(false)
|
const [loadMoreCommentsHidden, setLoadMoreCommentsHidden] = createSignal(
|
||||||
|
Boolean(props.author?.stat && props.author?.stat?.comments === 0)
|
||||||
|
)
|
||||||
const { commentsByAuthor, addReactions } = useReactions()
|
const { commentsByAuthor, addReactions } = useReactions()
|
||||||
const loadMoreComments = async () => {
|
const loadMoreComments = async () => {
|
||||||
if (!author()) return [] as LoadMoreItems
|
if (!author()) return [] as LoadMoreItems
|
||||||
|
@ -188,16 +196,14 @@ export const AuthorView = (props: AuthorViewProps) => {
|
||||||
|
|
||||||
createEffect(() => setCurrentTab(params.tab))
|
createEffect(() => setCurrentTab(params.tab))
|
||||||
|
|
||||||
|
createEffect(
|
||||||
|
on([author, commentsByAuthor], ([a, ccc]) => a && ccc && ccc[a.id] && setCommented(ccc[a.id]), {})
|
||||||
|
)
|
||||||
|
|
||||||
createEffect(
|
createEffect(
|
||||||
on(
|
on(
|
||||||
[author, commentsByAuthor],
|
[author, commented],
|
||||||
([a, ccc]) => {
|
([a, ccc]) => a && ccc && setLoadMoreCommentsHidden((ccc || []).length === a.stat?.comments)
|
||||||
if (a && ccc && ccc[a.id]) {
|
|
||||||
setCommented(ccc[a.id])
|
|
||||||
setLoadMoreCommentsHidden(ccc[a.id]?.length === a.stat?.comments)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{}
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { RouteSectionProps, createAsync } from '@solidjs/router'
|
import { RouteSectionProps, createAsync } from '@solidjs/router'
|
||||||
import { ErrorBoundary, Suspense, createEffect, createSignal, on } from 'solid-js'
|
import { ErrorBoundary, Suspense, createEffect, createSignal, on } from 'solid-js'
|
||||||
|
import { COMMENTS_PER_PAGE } from '~/components/Article/FullArticle'
|
||||||
import { AuthorView } from '~/components/Views/Author'
|
import { AuthorView } from '~/components/Views/Author'
|
||||||
import { FourOuFourView } from '~/components/Views/FourOuFour'
|
import { FourOuFourView } from '~/components/Views/FourOuFour'
|
||||||
import { Loading } from '~/components/_shared/Loading'
|
import { Loading } from '~/components/_shared/Loading'
|
||||||
|
@ -8,11 +9,13 @@ import { useAuthors } from '~/context/authors'
|
||||||
import { SHOUTS_PER_PAGE } from '~/context/feed'
|
import { SHOUTS_PER_PAGE } from '~/context/feed'
|
||||||
import { useLocalize } from '~/context/localize'
|
import { useLocalize } from '~/context/localize'
|
||||||
import { ReactionsProvider } from '~/context/reactions'
|
import { ReactionsProvider } from '~/context/reactions'
|
||||||
import { loadAuthors, loadShouts, loadTopics } from '~/graphql/api/public'
|
import { loadAuthors, loadReactions, loadShouts, loadTopics } from '~/graphql/api/public'
|
||||||
import {
|
import {
|
||||||
Author,
|
Author,
|
||||||
LoadShoutsOptions,
|
LoadShoutsOptions,
|
||||||
QueryLoad_Authors_ByArgs,
|
QueryLoad_Authors_ByArgs,
|
||||||
|
QueryLoad_Reactions_ByArgs,
|
||||||
|
Reaction,
|
||||||
Shout,
|
Shout,
|
||||||
Topic
|
Topic
|
||||||
} from '~/graphql/schema/core.gen'
|
} from '~/graphql/schema/core.gen'
|
||||||
|
@ -24,6 +27,16 @@ const fetchAuthorShouts = async (slug: string, offset?: number) => {
|
||||||
return await shoutsLoader()
|
return await shoutsLoader()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const fetchAuthorComments = async (slug: string, offset?: number) => {
|
||||||
|
const opts: QueryLoad_Reactions_ByArgs = {
|
||||||
|
by: { comment: true, author: slug },
|
||||||
|
limit: COMMENTS_PER_PAGE,
|
||||||
|
offset
|
||||||
|
}
|
||||||
|
const shoutsLoader = loadReactions(opts)
|
||||||
|
return await shoutsLoader()
|
||||||
|
}
|
||||||
|
|
||||||
const fetchAllTopics = async () => {
|
const fetchAllTopics = async () => {
|
||||||
const topicsFetcher = loadTopics()
|
const topicsFetcher = loadTopics()
|
||||||
return await topicsFetcher()
|
return await topicsFetcher()
|
||||||
|
@ -47,7 +60,12 @@ export const route = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export type AuthorPageProps = { articles?: Shout[]; author?: Author; topics?: Topic[] }
|
export type AuthorPageProps = {
|
||||||
|
articles?: Shout[]
|
||||||
|
author?: Author
|
||||||
|
topics?: Topic[]
|
||||||
|
comments?: Reaction[]
|
||||||
|
}
|
||||||
|
|
||||||
export default function AuthorPage(props: RouteSectionProps<AuthorPageProps>) {
|
export default function AuthorPage(props: RouteSectionProps<AuthorPageProps>) {
|
||||||
const { t } = useLocalize()
|
const { t } = useLocalize()
|
||||||
|
@ -109,6 +127,11 @@ export default function AuthorPage(props: RouteSectionProps<AuthorPageProps>) {
|
||||||
async () => (props.data.articles as Shout[]) || (await fetchAuthorShouts(props.params.slug, 0))
|
async () => (props.data.articles as Shout[]) || (await fetchAuthorShouts(props.params.slug, 0))
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// author's comments
|
||||||
|
const authorComments = createAsync(
|
||||||
|
async () => (props.data.comments as Reaction[]) || (await fetchAuthorComments(props.params.slug, 0))
|
||||||
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ErrorBoundary fallback={(_err) => <FourOuFourView />}>
|
<ErrorBoundary fallback={(_err) => <FourOuFourView />}>
|
||||||
<Suspense fallback={<Loading />}>
|
<Suspense fallback={<Loading />}>
|
||||||
|
@ -124,6 +147,7 @@ export default function AuthorPage(props: RouteSectionProps<AuthorPageProps>) {
|
||||||
author={author() as Author}
|
author={author() as Author}
|
||||||
authorSlug={props.params.slug}
|
authorSlug={props.params.slug}
|
||||||
shouts={authorShouts() || []}
|
shouts={authorShouts() || []}
|
||||||
|
comments={authorComments() || []}
|
||||||
/>
|
/>
|
||||||
</ReactionsProvider>
|
</ReactionsProvider>
|
||||||
</PageLayout>
|
</PageLayout>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user