author-feed-debug
This commit is contained in:
parent
1a9529d9fc
commit
01e7dec615
8
.vscode/launch.json
vendored
8
.vscode/launch.json
vendored
|
@ -1,16 +1,14 @@
|
|||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
|
||||
{
|
||||
"name": "Launch Brave against localhost",
|
||||
"name": "Launch browser against localhost",
|
||||
"type": "chrome",
|
||||
"request": "launch",
|
||||
"url": "http://localhost:3000",
|
||||
"url": "https://localhost:3000",
|
||||
"webRoot": "${workspaceFolder}/src",
|
||||
"sourceMaps": true,
|
||||
"trace": true,
|
||||
"runtimeExecutable": "/Applications/Brave Browser.app/Contents/MacOS/Brave Browser"
|
||||
"trace": true
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
import { clsx } from 'clsx'
|
||||
import { For, Show, createMemo, createSignal, lazy, onMount } from 'solid-js'
|
||||
|
||||
import { useFeed } from '~/context/feed'
|
||||
import { useLocalize } from '~/context/localize'
|
||||
import { useReactions } from '~/context/reactions'
|
||||
import { COMMENTS_PER_PAGE, useReactions } from '~/context/reactions'
|
||||
import { useSession } from '~/context/session'
|
||||
import {
|
||||
QueryLoad_Reactions_ByArgs,
|
||||
Reaction,
|
||||
ReactionKind,
|
||||
ReactionSort,
|
||||
|
@ -26,12 +24,11 @@ const SimplifiedEditor = lazy(() => import('../Editor/SimplifiedEditor'))
|
|||
type Props = {
|
||||
shout: Shout
|
||||
}
|
||||
const COMMENTS_PER_PAGE = 50
|
||||
|
||||
export const CommentsTree = (props: Props) => {
|
||||
const { session } = useSession()
|
||||
const { t } = useLocalize()
|
||||
const { reactionEntities, createReaction, loadReactionsBy, addReactions } = useReactions()
|
||||
const { reactionEntities, createReaction, loadShoutComments } = useReactions()
|
||||
const { seen } = useFeed()
|
||||
const [commentsOrder, setCommentsOrder] = createSignal<ReactionSort>(ReactionSort.Newest)
|
||||
const [onlyNew, setOnlyNew] = createSignal(false)
|
||||
|
@ -83,13 +80,7 @@ export const CommentsTree = (props: Props) => {
|
|||
setCommentsLoading(true)
|
||||
const next = pagination() + 1
|
||||
const offset = next * COMMENTS_PER_PAGE
|
||||
const opts: QueryLoad_Reactions_ByArgs = {
|
||||
by: { comment: true, shout: props.shout.slug },
|
||||
limit: COMMENTS_PER_PAGE,
|
||||
offset
|
||||
}
|
||||
const rrr = await loadReactionsBy(opts)
|
||||
rrr && addReactions(rrr)
|
||||
const rrr = await loadShoutComments(props.shout.id, COMMENTS_PER_PAGE, offset)
|
||||
rrr && setPagination(next)
|
||||
setCommentsLoading(false)
|
||||
return rrr as LoadMoreItems
|
||||
|
|
|
@ -3,10 +3,10 @@ import { clsx } from 'clsx'
|
|||
import { Show, createEffect, createMemo, createSignal, on } from 'solid-js'
|
||||
import { byCreated } from '~/lib/sort'
|
||||
import { useLocalize } from '../../context/localize'
|
||||
import { useReactions } from '../../context/reactions'
|
||||
import { RATINGS_PER_PAGE, useReactions } from '../../context/reactions'
|
||||
import { useSession } from '../../context/session'
|
||||
import { useSnackbar } from '../../context/ui'
|
||||
import { QueryLoad_Reactions_ByArgs, Reaction, ReactionKind, Shout } from '../../graphql/schema/core.gen'
|
||||
import { Reaction, ReactionKind, Shout } from '../../graphql/schema/core.gen'
|
||||
import { Icon } from '../_shared/Icon'
|
||||
import { InlineLoader } from '../_shared/InlineLoader'
|
||||
import { LoadMoreItems, LoadMoreWrapper } from '../_shared/LoadMoreWrapper'
|
||||
|
@ -26,8 +26,7 @@ export const RatingControl = (props: RatingControlProps) => {
|
|||
const [_, changeSearchParams] = useSearchParams()
|
||||
const snackbar = useSnackbar()
|
||||
const { session } = useSession()
|
||||
const { addReactions } = useReactions()
|
||||
const { reactionEntities, reactionsByShout, createReaction, deleteReaction, loadReactionsBy } =
|
||||
const { reactionEntities, reactionsByShout, createReaction, deleteReaction, loadShoutRatings, loadCommentRatings } =
|
||||
useReactions()
|
||||
const [myRate, setMyRate] = createSignal<Reaction | undefined>()
|
||||
const [ratingReactions, setRatingReactions] = createSignal<Reaction[]>([])
|
||||
|
@ -70,12 +69,13 @@ export const RatingControl = (props: RatingControlProps) => {
|
|||
// rating change
|
||||
const handleRatingChange = async (isUpvote: boolean) => {
|
||||
setIsLoading(true)
|
||||
let error = ''
|
||||
try {
|
||||
if (isUpvoted()) {
|
||||
await deleteRating(ReactionKind.Like)
|
||||
} else if (isDownvoted()) {
|
||||
await deleteRating(ReactionKind.Dislike)
|
||||
} else {
|
||||
if (isUpvoted() && isUpvote) return
|
||||
if (isDownvoted() && !isUpvote) return
|
||||
if (isUpvoted() && !isUpvote) error = (await deleteRating(ReactionKind.Like))?.error || ''
|
||||
if (isDownvoted() && isUpvote) error = (await deleteRating(ReactionKind.Dislike))?.error || ''
|
||||
if (!(isUpvoted() || isDownvoted())) {
|
||||
props.comment?.shout.id &&
|
||||
(await createReaction({
|
||||
reaction: {
|
||||
|
@ -85,13 +85,8 @@ export const RatingControl = (props: RatingControlProps) => {
|
|||
}
|
||||
}))
|
||||
}
|
||||
} catch {
|
||||
snackbar?.showSnackbar({ type: 'error', body: t('Error') })
|
||||
}
|
||||
|
||||
if (props.comment?.shout.slug) {
|
||||
const rrr = await loadReactionsBy({ by: { shout: props.comment.shout.slug } })
|
||||
addReactions(rrr)
|
||||
} catch(err) {
|
||||
snackbar?.showSnackbar({ type: 'error', body: `${t('Error')}: ${error || err || ''}` })
|
||||
}
|
||||
setIsLoading(false)
|
||||
}
|
||||
|
@ -138,16 +133,12 @@ export const RatingControl = (props: RatingControlProps) => {
|
|||
: []
|
||||
)
|
||||
const loadMoreReactions = async () => {
|
||||
if (!(props.shout?.id || props.comment?.id)) return [] as LoadMoreItems
|
||||
setRatingLoading(true)
|
||||
const next = ratingPage() + 1
|
||||
const offset = VOTERS_PER_PAGE * next
|
||||
const opts: QueryLoad_Reactions_ByArgs = {
|
||||
by: { rating: true, shout: props.shout?.slug },
|
||||
limit: VOTERS_PER_PAGE,
|
||||
offset
|
||||
}
|
||||
const rrr = await loadReactionsBy(opts)
|
||||
rrr && addReactions(rrr)
|
||||
const offset = RATINGS_PER_PAGE * next
|
||||
const loader = props.comment ? loadCommentRatings : loadShoutRatings
|
||||
const rrr = await loader(props.shout?.id || 0, RATINGS_PER_PAGE, offset)
|
||||
rrr && setRatingPage(next)
|
||||
setRatingLoading(false)
|
||||
return rrr as LoadMoreItems
|
||||
|
|
|
@ -61,7 +61,7 @@ export const AuthorView = (props: AuthorViewProps) => {
|
|||
on(
|
||||
[() => session()?.user?.app_data?.profile, () => props.authorSlug || ''],
|
||||
async ([me, slug]) => {
|
||||
console.debug('check if my profile')
|
||||
console.debug('[AuthorView] checking if my profile')
|
||||
const my = slug && me?.slug === slug
|
||||
if (my) {
|
||||
console.debug('[Author] my profile precached')
|
||||
|
@ -86,7 +86,7 @@ export const AuthorView = (props: AuthorViewProps) => {
|
|||
() => authorsEntities()[props.author?.slug || props.authorSlug || ''],
|
||||
async (found) => {
|
||||
if (!found) return
|
||||
setAuthor(found)
|
||||
console.debug('[AuthorView] ')
|
||||
console.info(`[Author] profile for @${found.slug} fetched`)
|
||||
const followsResp = await query(getAuthorFollowsQuery, { slug: found.slug }).toPromise()
|
||||
const follows = followsResp?.data?.get_author_followers || {}
|
||||
|
@ -96,6 +96,7 @@ export const AuthorView = (props: AuthorViewProps) => {
|
|||
setFollowers(followersResp?.data?.get_author_followers || [])
|
||||
console.info(`[Author] followers for @${found.slug} fetched`)
|
||||
setIsFetching(false)
|
||||
setTimeout(() => setAuthor(found), 1)
|
||||
},
|
||||
{ defer: true }
|
||||
)
|
||||
|
@ -123,7 +124,37 @@ export const AuthorView = (props: AuthorViewProps) => {
|
|||
(tab) => tab && console.log('[views.Author] profile tab switched')
|
||||
)
|
||||
)
|
||||
const AuthorFeed = () => (
|
||||
<Show when={Array.isArray(props.shouts) && props.shouts.length > 0 && props.shouts[0]}>
|
||||
<Row1 article={props.shouts?.[0] as Shout} noauthor={true} nodate={true} />
|
||||
|
||||
<Show when={props.shouts?.length || 0}>
|
||||
<Show when={props.shouts?.length === 1}>
|
||||
<Row1 article={props.shouts?.[0] as Shout} noauthor={true} nodate={true} />
|
||||
</Show>
|
||||
<Show when={props.shouts?.length === 2}>
|
||||
<Row2 articles={props.shouts as Shout[]} isEqual={true} noauthor={true} nodate={true} />
|
||||
</Show>
|
||||
<Show when={props.shouts?.length === 3}>
|
||||
<Row3 articles={props.shouts as Shout[]} noauthor={true} nodate={true} />
|
||||
</Show>
|
||||
<Show when={props.shouts && props.shouts.length > 3}>
|
||||
<For each={pages()}>
|
||||
{(page) => (
|
||||
<>
|
||||
<Row1 article={page[0]} noauthor={true} nodate={true} />
|
||||
<Row2 articles={page.slice(1, 3)} isEqual={true} noauthor={true} />
|
||||
<Row1 article={page[3]} noauthor={true} nodate={true} />
|
||||
<Row2 articles={page.slice(4, 6)} isEqual={true} noauthor={true} />
|
||||
<Row1 article={page[6]} noauthor={true} nodate={true} />
|
||||
<Row2 articles={page.slice(7, 9)} isEqual={true} noauthor={true} />
|
||||
</>
|
||||
)}
|
||||
</For>
|
||||
</Show>
|
||||
</Show>
|
||||
</Show>
|
||||
)
|
||||
return (
|
||||
<div class={styles.authorPage}>
|
||||
<div class="wide-container">
|
||||
|
@ -229,34 +260,8 @@ export const AuthorView = (props: AuthorViewProps) => {
|
|||
</div>
|
||||
</Show>
|
||||
|
||||
<Show when={Array.isArray(props.shouts) && props.shouts.length > 0 && props.shouts[0]}>
|
||||
<Row1 article={props.shouts?.[0] as Shout} noauthor={true} nodate={true} />
|
||||
<AuthorFeed />
|
||||
|
||||
<Show when={props.shouts && props.shouts.length > 1}>
|
||||
<Switch>
|
||||
<Match when={props.shouts && props.shouts.length === 2}>
|
||||
<Row2 articles={props.shouts as Shout[]} isEqual={true} noauthor={true} nodate={true} />
|
||||
</Match>
|
||||
<Match when={props.shouts && props.shouts.length === 3}>
|
||||
<Row3 articles={props.shouts as Shout[]} noauthor={true} nodate={true} />
|
||||
</Match>
|
||||
<Match when={props.shouts && props.shouts.length > 3}>
|
||||
<For each={pages()}>
|
||||
{(page) => (
|
||||
<>
|
||||
<Row1 article={page[0]} noauthor={true} nodate={true} />
|
||||
<Row2 articles={page.slice(1, 3)} isEqual={true} noauthor={true} />
|
||||
<Row1 article={page[3]} noauthor={true} nodate={true} />
|
||||
<Row2 articles={page.slice(4, 6)} isEqual={true} noauthor={true} />
|
||||
<Row1 article={page[6]} noauthor={true} nodate={true} />
|
||||
<Row2 articles={page.slice(7, 9)} isEqual={true} noauthor={true} />
|
||||
</>
|
||||
)}
|
||||
</For>
|
||||
</Match>
|
||||
</Switch>
|
||||
</Show>
|
||||
</Show>
|
||||
</Match>
|
||||
</Switch>
|
||||
</div>
|
||||
|
|
|
@ -5,6 +5,7 @@ import { Author, Reaction, Shout } from '~/graphql/schema/core.gen'
|
|||
import { byCreated } from '~/lib/sort'
|
||||
import { SortFunction } from '~/types/common'
|
||||
import { restoreScrollPosition, saveScrollPosition } from '~/utils/scroll'
|
||||
import { Loading } from './Loading'
|
||||
|
||||
export type LoadMoreItems = Shout[] | Author[] | Reaction[]
|
||||
|
||||
|
@ -52,11 +53,11 @@ export const LoadMoreWrapper = (props: LoadMoreProps) => {
|
|||
return (
|
||||
<>
|
||||
{props.children}
|
||||
<Show when={isLoadMoreButtonVisible() && !props.hidden}>
|
||||
<Show when={isLoading()}><Loading /></Show>
|
||||
<Show when={isLoadMoreButtonVisible() && !props.hidden && !isLoading()}>
|
||||
<div class="load-more-container">
|
||||
<Button
|
||||
onClick={loadItems}
|
||||
disabled={isLoading()}
|
||||
value={t('Load more')}
|
||||
title={`${items().length} ${t('loaded')}`}
|
||||
/>
|
||||
|
|
|
@ -2,7 +2,7 @@ import type { JSX } from 'solid-js'
|
|||
|
||||
import { createContext, onCleanup, useContext } from 'solid-js'
|
||||
import { createStore, reconcile } from 'solid-js/store'
|
||||
import { loadReactions } from '~/graphql/api/public'
|
||||
import { loadCommentRatings, loadReactions, loadShoutComments, loadShoutRatings } from '~/graphql/api/public'
|
||||
import createReactionMutation from '~/graphql/mutation/core/reaction-create'
|
||||
import destroyReactionMutation from '~/graphql/mutation/core/reaction-destroy'
|
||||
import updateReactionMutation from '~/graphql/mutation/core/reaction-update'
|
||||
|
@ -17,10 +17,16 @@ import { useGraphQL } from './graphql'
|
|||
import { useLocalize } from './localize'
|
||||
import { useSnackbar } from './ui'
|
||||
|
||||
export const COMMENTS_PER_PAGE = 50
|
||||
export const RATINGS_PER_PAGE = 100
|
||||
|
||||
type ReactionsContextType = {
|
||||
reactionEntities: Record<number, Reaction>
|
||||
reactionsByShout: Record<string, Reaction[]>
|
||||
loadReactionsBy: (args: QueryLoad_Reactions_ByArgs) => Promise<Reaction[]>
|
||||
loadShoutComments: (shout: number, limit?: number, offset?: number) => Promise<Reaction[]>
|
||||
loadShoutRatings: (shout: number, limit?: number, offset?: number) => Promise<Reaction[]>
|
||||
loadCommentRatings: (comment: number, limit?: number, offset?: number) => Promise<Reaction[]>
|
||||
createReaction: (reaction: MutationCreate_ReactionArgs) => Promise<void>
|
||||
updateReaction: (reaction: MutationUpdate_ReactionArgs) => Promise<Reaction>
|
||||
deleteReaction: (id: number) => Promise<{ error: string } | null>
|
||||
|
@ -63,6 +69,30 @@ export const ReactionsProvider = (props: { children: JSX.Element }) => {
|
|||
return result
|
||||
}
|
||||
|
||||
const loadShoutRatingsAdding = async (shout: number, limit = RATINGS_PER_PAGE, offset = 0): Promise<Reaction[]> => {
|
||||
const fetcher = await loadShoutRatings({ shout, limit, offset })
|
||||
const result = (await fetcher()) || []
|
||||
console.debug('[context.reactions] shout ratings loaded', result)
|
||||
result && addReactions(result)
|
||||
return result
|
||||
}
|
||||
|
||||
const loadCommentRatingsAdding = async (comment: number, limit = RATINGS_PER_PAGE, offset = 0): Promise<Reaction[]> => {
|
||||
const fetcher = await loadCommentRatings({ comment, limit, offset })
|
||||
const result = (await fetcher()) || []
|
||||
console.debug('[context.reactions] shout ratings loaded', result)
|
||||
result && addReactions(result)
|
||||
return result
|
||||
}
|
||||
|
||||
const loadShoutCommentsAdding = async (shout: number, limit = COMMENTS_PER_PAGE, offset = 0): Promise<Reaction[]> => {
|
||||
const fetcher = await loadShoutComments({ shout, limit, offset })
|
||||
const result = (await fetcher()) || []
|
||||
console.debug('[context.reactions] shout comments loaded', result)
|
||||
result && addReactions(result)
|
||||
return result
|
||||
}
|
||||
|
||||
const createReaction = async (input: MutationCreate_ReactionArgs): Promise<void> => {
|
||||
const resp = await mutation(createReactionMutation, input).toPromise()
|
||||
const { error, reaction } = resp?.data?.create_reaction || {}
|
||||
|
@ -122,6 +152,9 @@ export const ReactionsProvider = (props: { children: JSX.Element }) => {
|
|||
|
||||
const actions = {
|
||||
loadReactionsBy,
|
||||
loadShoutComments: loadShoutCommentsAdding,
|
||||
loadShoutRatings: loadShoutRatingsAdding,
|
||||
loadCommentRatings: loadCommentRatingsAdding,
|
||||
createReaction,
|
||||
updateReaction,
|
||||
deleteReaction,
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
import { cache } from '@solidjs/router'
|
||||
import { defaultClient } from '~/context/graphql'
|
||||
import loadShoutCommentsQuery from '~/graphql/query/core/article-comments-load'
|
||||
import getShoutQuery from '~/graphql/query/core/article-load'
|
||||
import loadShoutRatingsQuery from '~/graphql/query/core/article-ratings-load'
|
||||
import loadShoutsByQuery from '~/graphql/query/core/articles-load-by'
|
||||
import loadShoutsSearchQuery from '~/graphql/query/core/articles-load-search'
|
||||
import getAuthorQuery from '~/graphql/query/core/author-by'
|
||||
import loadAuthorsAllQuery from '~/graphql/query/core/authors-all'
|
||||
import loadAuthorsByQuery from '~/graphql/query/core/authors-load-by'
|
||||
import loadCommentRatingsQuery from '~/graphql/query/core/comment-ratings-load'
|
||||
import loadReactionsByQuery from '~/graphql/query/core/reactions-load-by'
|
||||
import loadFollowersByTopicQuery from '~/graphql/query/core/topic-followers'
|
||||
import loadTopicsQuery from '~/graphql/query/core/topics-all'
|
||||
|
@ -16,6 +19,7 @@ import {
|
|||
QueryGet_ShoutArgs,
|
||||
QueryLoad_Authors_ByArgs,
|
||||
QueryLoad_Reactions_ByArgs,
|
||||
QueryLoad_Shout_RatingsArgs,
|
||||
QueryLoad_Shouts_SearchArgs,
|
||||
Reaction,
|
||||
Shout,
|
||||
|
@ -57,16 +61,39 @@ export const loadShouts = (options: LoadShoutsOptions) => {
|
|||
}, `shouts-${filter}-${page}`)
|
||||
}
|
||||
|
||||
export const loadShoutComments = (options: QueryLoad_Shout_RatingsArgs) => {
|
||||
const page = `${options.offset || 0}-${(options.limit||1) + (options.offset || 0)}`
|
||||
return cache(async () => {
|
||||
const resp = await defaultClient.query(loadShoutCommentsQuery, options).toPromise()
|
||||
const result = resp?.data?.load_reactions_by
|
||||
if (result) return result as Reaction[]
|
||||
}, `shout-${options.shout}-comments-${page}`)
|
||||
}
|
||||
|
||||
export const loadShoutRatings = (options: QueryLoad_Shout_RatingsArgs) => {
|
||||
const page = `${options.offset || 0}-${(options.limit||1) + (options.offset || 0)}`
|
||||
return cache(async () => {
|
||||
const resp = await defaultClient.query(loadShoutRatingsQuery, options).toPromise()
|
||||
const result = resp?.data?.load_reactions_by
|
||||
if (result) return result as Reaction[]
|
||||
}, `shout-${options.shout}-ratings-${page}`)
|
||||
}
|
||||
|
||||
// biome-ignore lint/suspicious/noExplicitAny: FIXME: wait backend
|
||||
export const loadCommentRatings = (options: any) => {
|
||||
const page = `${options.offset || 0}-${(options.limit||1) + (options.offset || 0)}`
|
||||
return cache(async () => {
|
||||
const resp = await defaultClient.query(loadCommentRatingsQuery, options).toPromise()
|
||||
const result = resp?.data?.load_reactions_by
|
||||
if (result) return result as Reaction[]
|
||||
}, `comment-${options.comment}-ratings-${page}`)
|
||||
}
|
||||
|
||||
export const loadReactions = (options: QueryLoad_Reactions_ByArgs) => {
|
||||
if (!options.by) {
|
||||
console.debug(options)
|
||||
throw new Error('[api] wrong loadReactions call')
|
||||
}
|
||||
const kind = options.by?.comment ? 'comments' : options.by?.rating ? 'votes' : 'reactions'
|
||||
const allorone = options.by?.shout ? `shout-${options.by.shout}` : 'all'
|
||||
const page = `${options.offset || 0}-${(options?.limit || 0) + (options.offset || 0)}`
|
||||
const filter = new URLSearchParams(options.by as Record<string, string>)
|
||||
// console.debug(options)
|
||||
return cache(async () => {
|
||||
const resp = await defaultClient.query(loadReactionsByQuery, options).toPromise()
|
||||
const result = resp?.data?.load_reactions_by
|
||||
|
@ -75,7 +102,6 @@ export const loadReactions = (options: QueryLoad_Reactions_ByArgs) => {
|
|||
}
|
||||
|
||||
export const getShout = (options: QueryGet_ShoutArgs) => {
|
||||
// console.debug('[lib.api] get shout options', options)
|
||||
return cache(
|
||||
async () => {
|
||||
const resp = await defaultClient.query(getShoutQuery, { ...options }).toPromise()
|
||||
|
|
29
src/graphql/query/core/article-comments-load.ts
Normal file
29
src/graphql/query/core/article-comments-load.ts
Normal file
|
@ -0,0 +1,29 @@
|
|||
import { gql } from '@urql/core'
|
||||
|
||||
export default gql`
|
||||
query LoadReactions($shout: Int!, $limit: Int, $offset: Int) {
|
||||
load_shout_comments(shout: $shout, limit: $limit, offset: $offset) {
|
||||
id
|
||||
kind
|
||||
body
|
||||
reply_to
|
||||
shout {
|
||||
id
|
||||
slug
|
||||
title
|
||||
}
|
||||
created_by {
|
||||
id
|
||||
name
|
||||
slug
|
||||
pic
|
||||
created_at
|
||||
}
|
||||
created_at
|
||||
updated_at
|
||||
stat {
|
||||
rating
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
29
src/graphql/query/core/article-ratings-load.ts
Normal file
29
src/graphql/query/core/article-ratings-load.ts
Normal file
|
@ -0,0 +1,29 @@
|
|||
import { gql } from '@urql/core'
|
||||
|
||||
export default gql`
|
||||
query LoadReactions($shout: Int!, $limit: Int, $offset: Int) {
|
||||
load_shout_ratings(shout: $shout, limit: $limit, offset: $offset) {
|
||||
id
|
||||
kind
|
||||
body
|
||||
reply_to
|
||||
shout {
|
||||
id
|
||||
slug
|
||||
title
|
||||
}
|
||||
created_by {
|
||||
id
|
||||
name
|
||||
slug
|
||||
pic
|
||||
created_at
|
||||
}
|
||||
created_at
|
||||
updated_at
|
||||
stat {
|
||||
rating
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
29
src/graphql/query/core/comment-ratings-load.ts
Normal file
29
src/graphql/query/core/comment-ratings-load.ts
Normal file
|
@ -0,0 +1,29 @@
|
|||
import { gql } from '@urql/core'
|
||||
|
||||
export default gql`
|
||||
query LoadReactions($comment: Int!, $limit: Int, $offset: Int) {
|
||||
load_comment_ratings(comment: $comment, limit: $limit, offset: $offset) {
|
||||
id
|
||||
kind
|
||||
body
|
||||
reply_to
|
||||
shout {
|
||||
id
|
||||
slug
|
||||
title
|
||||
}
|
||||
created_by {
|
||||
id
|
||||
name
|
||||
slug
|
||||
pic
|
||||
created_at
|
||||
}
|
||||
created_at
|
||||
updated_at
|
||||
stat {
|
||||
rating
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
|
@ -1,5 +1,5 @@
|
|||
import { RouteSectionProps } from '@solidjs/router'
|
||||
import { ErrorBoundary, createEffect, createMemo, createSignal, on } from 'solid-js'
|
||||
import { RouteSectionProps, createAsync } from '@solidjs/router'
|
||||
import { ErrorBoundary, createEffect, createMemo } from 'solid-js'
|
||||
import { AuthorView } from '~/components/Views/Author'
|
||||
import { FourOuFourView } from '~/components/Views/FourOuFour'
|
||||
import { LoadMoreItems, LoadMoreWrapper } from '~/components/_shared/LoadMoreWrapper'
|
||||
|
@ -33,6 +33,7 @@ const fetchAllTopics = async () => {
|
|||
const fetchAuthor = async (slug: string) => {
|
||||
const authorFetcher = loadAuthors({ by: { slug }, limit: 1, offset: 0 } as QueryLoad_Authors_ByArgs)
|
||||
const aaa = await authorFetcher()
|
||||
console.debug(aaa)
|
||||
return aaa?.[0]
|
||||
}
|
||||
|
||||
|
@ -50,11 +51,17 @@ export const route = {
|
|||
export type AuthorPageProps = { articles?: Shout[]; author?: Author; topics?: Topic[] }
|
||||
|
||||
export default function AuthorPage(props: RouteSectionProps<AuthorPageProps>) {
|
||||
const { addAuthor, authorsEntities } = useAuthors()
|
||||
const [author, setAuthor] = createSignal<Author | undefined>(undefined)
|
||||
|
||||
const { authorsEntities } = useAuthors()
|
||||
const { addFeed, feedByAuthor } = useFeed()
|
||||
const { t } = useLocalize()
|
||||
const author = createAsync(async() => props.data.author || authorsEntities()[props.params.slug] || await fetchAuthor(props.params.slug))
|
||||
const shoutsByAuthor = createMemo(() => feedByAuthor()[props.params.slug])
|
||||
const title = createMemo(() => `${author()?.name || ''}`)
|
||||
const cover = createMemo(() =>
|
||||
author()?.pic
|
||||
? getImageUrl(author()?.pic || '', { width: 1200 })
|
||||
: getImageUrl('production/image/logo_image.png')
|
||||
)
|
||||
|
||||
createEffect(() => {
|
||||
if (author()) {
|
||||
|
@ -67,32 +74,8 @@ export default function AuthorPage(props: RouteSectionProps<AuthorPageProps>) {
|
|||
}
|
||||
})
|
||||
|
||||
const cover = createMemo(() =>
|
||||
author()?.pic
|
||||
? getImageUrl(author()?.pic || '', { width: 1200 })
|
||||
: getImageUrl('production/image/logo_image.png')
|
||||
)
|
||||
|
||||
// author shouts
|
||||
const { addFeed, feedByAuthor } = useFeed()
|
||||
const shoutsByAuthor = createMemo(() => feedByAuthor()[props.params.slug])
|
||||
|
||||
createEffect(
|
||||
on(
|
||||
[() => props.params.slug || '', author],
|
||||
async ([slug, profile]) => {
|
||||
if (!profile) {
|
||||
const loadedAuthor = authorsEntities()[slug] || (await fetchAuthor(slug))
|
||||
if (loadedAuthor) {
|
||||
addAuthor(loadedAuthor)
|
||||
setAuthor(loadedAuthor)
|
||||
}
|
||||
}
|
||||
},
|
||||
{ defer: true }
|
||||
)
|
||||
)
|
||||
|
||||
const loadAuthorShoutsMore = async (offset: number) => {
|
||||
const loadedShouts = await fetchAuthorShouts(props.params.slug, offset)
|
||||
loadedShouts && addFeed(loadedShouts)
|
||||
|
|
|
@ -125,7 +125,7 @@ export default (props: RouteSectionProps<{ shouts: Shout[]; topics: Topic[] }>)
|
|||
key="feed"
|
||||
desc="Independent media project about culture, science, art and society with horizontal editing"
|
||||
>
|
||||
<LoadMoreWrapper loadFunction={loadMoreFeed} pageSize={AUTHORS_PER_PAGE}>
|
||||
<LoadMoreWrapper loadFunction={loadMoreFeed} pageSize={AUTHORS_PER_PAGE} hidden={!feed()}>
|
||||
<ReactionsProvider>
|
||||
<Feed shouts={feed() || (shouts() as Shout[])} order={order() as FeedProps['order']} />
|
||||
</ReactionsProvider>
|
||||
|
|
Loading…
Reference in New Issue
Block a user