recursive comments
This commit is contained in:
parent
8efde302a6
commit
0cd5dd1498
|
@ -1,33 +1,34 @@
|
||||||
import styles from './Comment.module.scss'
|
import styles from './Comment.module.scss'
|
||||||
import type { JSX } from 'solid-js/jsx-runtime'
|
|
||||||
import { Icon } from '../_shared/Icon'
|
import { Icon } from '../_shared/Icon'
|
||||||
import { AuthorCard } from '../Author/Card'
|
import { AuthorCard } from '../Author/Card'
|
||||||
import { Show, createMemo, createSignal, createEffect } from 'solid-js'
|
import { Show, createMemo, createSignal, For } from 'solid-js'
|
||||||
import { clsx } from 'clsx'
|
import { clsx } from 'clsx'
|
||||||
import type { Author, Reaction as Point } from '../../graphql/types.gen'
|
import type { Author, Reaction } from '../../graphql/types.gen'
|
||||||
import { t } from '../../utils/intl'
|
import { t } from '../../utils/intl'
|
||||||
import { createReaction, updateReaction, deleteReaction } from '../../stores/zine/reactions'
|
import { deleteReaction } from '../../stores/zine/reactions'
|
||||||
import MD from './MD'
|
import MD from './MD'
|
||||||
import { formatDate } from '../../utils'
|
import { formatDate } from '../../utils'
|
||||||
import { SharePopup } from './SharePopup'
|
import { SharePopup } from './SharePopup'
|
||||||
import stylesHeader from '../Nav/Header.module.scss'
|
import stylesHeader from '../Nav/Header.module.scss'
|
||||||
import Userpic from '../Author/Userpic'
|
import Userpic from '../Author/Userpic'
|
||||||
import { apiClient } from '../../utils/apiClient'
|
import { apiClient } from '../../utils/apiClient'
|
||||||
import { ReactionKind } from '../../graphql/types.gen'
|
import { useSession } from '../../context/session'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
level?: number
|
level: number
|
||||||
comment: Partial<Point>
|
comment: Reaction
|
||||||
canEdit?: boolean
|
|
||||||
compact?: boolean
|
compact?: boolean
|
||||||
children?: JSX.Element[]
|
reactions: Reaction[]
|
||||||
parent?: number
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default (props: Props) => {
|
export const Comment = (props: Props) => {
|
||||||
const [isReplyVisible, setIsReplyVisible] = createSignal(false)
|
const [isReplyVisible, setIsReplyVisible] = createSignal(false)
|
||||||
const [postMessageText, setPostMessageText] = createSignal('')
|
const [postMessageText, setPostMessageText] = createSignal('')
|
||||||
|
|
||||||
|
const { session } = useSession()
|
||||||
|
|
||||||
|
const canEdit = createMemo(() => props.comment.createdBy?.slug === session()?.user?.slug)
|
||||||
|
|
||||||
const comment = createMemo(() => props.comment)
|
const comment = createMemo(() => props.comment)
|
||||||
const body = createMemo(() => (comment().body || '').trim())
|
const body = createMemo(() => (comment().body || '').trim())
|
||||||
const remove = () => {
|
const remove = () => {
|
||||||
|
@ -43,7 +44,7 @@ export default (props: Props) => {
|
||||||
// await createReaction({
|
// await createReaction({
|
||||||
await apiClient.createReaction({
|
await apiClient.createReaction({
|
||||||
kind: 7,
|
kind: 7,
|
||||||
replyTo: props.parent,
|
replyTo: props.comment.id,
|
||||||
body: postMessageText(),
|
body: postMessageText(),
|
||||||
shout: comment().shout.id
|
shout: comment().shout.id
|
||||||
})
|
})
|
||||||
|
@ -95,7 +96,7 @@ export default (props: Props) => {
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class={styles.commentBody}
|
class={styles.commentBody}
|
||||||
contenteditable={props.canEdit}
|
contenteditable={canEdit()}
|
||||||
id={'comment-' + (comment().id || '')}
|
id={'comment-' + (comment().id || '')}
|
||||||
>
|
>
|
||||||
<MD body={body()} />
|
<MD body={body()} />
|
||||||
|
@ -111,7 +112,7 @@ export default (props: Props) => {
|
||||||
{t('Reply')}
|
{t('Reply')}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<Show when={props.canEdit}>
|
<Show when={canEdit()}>
|
||||||
{/*FIXME implement edit comment modal*/}
|
{/*FIXME implement edit comment modal*/}
|
||||||
{/*<button*/}
|
{/*<button*/}
|
||||||
{/* class={clsx(styles.commentControl, styles.commentControlEdit)}*/}
|
{/* class={clsx(styles.commentControl, styles.commentControlEdit)}*/}
|
||||||
|
@ -169,9 +170,11 @@ export default (props: Props) => {
|
||||||
</Show>
|
</Show>
|
||||||
</div>
|
</div>
|
||||||
</Show>
|
</Show>
|
||||||
<Show when={props.children}>
|
<ul>
|
||||||
<ul>{props.children}</ul>
|
<For each={props.reactions.filter((r) => r.replyTo === props.comment.id)}>
|
||||||
</Show>
|
{(reaction) => <Comment reactions={props.reactions} comment={reaction} level={props.level + 1} />}
|
||||||
|
</For>
|
||||||
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { For, Show, createMemo, createSignal, onMount, createEffect } from 'solid-js'
|
import { For, Show, createMemo, createSignal, onMount, createEffect } from 'solid-js'
|
||||||
import { useSession } from '../../context/session'
|
import { useSession } from '../../context/session'
|
||||||
import Comment from './Comment'
|
import { Comment } from './Comment'
|
||||||
import { t } from '../../utils/intl'
|
import { t } from '../../utils/intl'
|
||||||
import { showModal } from '../../stores/ui'
|
import { showModal } from '../../stores/ui'
|
||||||
import styles from '../../styles/Article.module.scss'
|
import styles from '../../styles/Article.module.scss'
|
||||||
|
@ -10,10 +10,6 @@ import { clsx } from 'clsx'
|
||||||
import { byCreated, byStat } from '../../utils/sortby'
|
import { byCreated, byStat } from '../../utils/sortby'
|
||||||
import { Loading } from '../Loading'
|
import { Loading } from '../Loading'
|
||||||
|
|
||||||
type NestedReaction = {
|
|
||||||
children: Reaction[] | []
|
|
||||||
} & Reaction
|
|
||||||
|
|
||||||
const ARTICLE_COMMENTS_PAGE_SIZE = 50
|
const ARTICLE_COMMENTS_PAGE_SIZE = 50
|
||||||
const MAX_COMMENT_LEVEL = 6
|
const MAX_COMMENT_LEVEL = 6
|
||||||
|
|
||||||
|
@ -106,18 +102,8 @@ export const CommentsTree = (props: { shoutSlug: string }) => {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ul class={styles.comments}>
|
<ul class={styles.comments}>
|
||||||
<For each={nestComments(reactions().reverse())}>
|
<For each={reactions().filter((r) => !r.replyTo)}>
|
||||||
{(reaction: NestedReaction) => (
|
{(reaction) => <Comment level={0} reactions={reactions()} comment={reaction} />}
|
||||||
<Comment
|
|
||||||
comment={reaction}
|
|
||||||
parent={reaction.id}
|
|
||||||
level={getCommentLevel(reaction)}
|
|
||||||
canEdit={reaction?.createdBy?.slug === session()?.user?.slug}
|
|
||||||
children={(reaction.children || []).map((r) => {
|
|
||||||
return <Comment comment={r} parent={reaction.id} />
|
|
||||||
})}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</For>
|
</For>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { ArticleCard } from '../Feed/Card'
|
||||||
import { AuthorCard } from '../Author/Card'
|
import { AuthorCard } from '../Author/Card'
|
||||||
import { t } from '../../utils/intl'
|
import { t } from '../../utils/intl'
|
||||||
import { FeedSidebar } from '../Feed/Sidebar'
|
import { FeedSidebar } from '../Feed/Sidebar'
|
||||||
import CommentCard from '../Article/Comment'
|
import { Comment as CommentCard } from '../Article/Comment'
|
||||||
import { loadShouts, useArticlesStore } from '../../stores/zine/articles'
|
import { loadShouts, useArticlesStore } from '../../stores/zine/articles'
|
||||||
import { useReactionsStore } from '../../stores/zine/reactions'
|
import { useReactionsStore } from '../../stores/zine/reactions'
|
||||||
import { useAuthorsStore } from '../../stores/zine/authors'
|
import { useAuthorsStore } from '../../stores/zine/authors'
|
||||||
|
@ -128,7 +128,8 @@ export const FeedView = () => {
|
||||||
<section class="feed-comments">
|
<section class="feed-comments">
|
||||||
<h4>{t('Comments')}</h4>
|
<h4>{t('Comments')}</h4>
|
||||||
<For each={topComments()}>
|
<For each={topComments()}>
|
||||||
{(comment) => <CommentCard comment={comment} compact={true} />}
|
{/*FIXME: different components/better comment props*/}
|
||||||
|
{(comment) => <CommentCard comment={comment} level={0} reactions={[]} compact={true} />}
|
||||||
</For>
|
</For>
|
||||||
</section>
|
</section>
|
||||||
<Show when={topTopics().length > 0}>
|
<Show when={topTopics().length > 0}>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user