limit displayed comment depth
This commit is contained in:
parent
35b533c572
commit
cef8a33267
|
@ -2,7 +2,7 @@ import itemStyles from './item.module.css'
|
||||||
import styles from './comment.module.css'
|
import styles from './comment.module.css'
|
||||||
import Text from './text'
|
import Text from './text'
|
||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
import Reply from './reply'
|
import Reply, { ReplyOnAnotherPage } from './reply'
|
||||||
import { useEffect, useRef, useState } from 'react'
|
import { useEffect, useRef, useState } from 'react'
|
||||||
import { timeSince } from '../lib/time'
|
import { timeSince } from '../lib/time'
|
||||||
import UpVote from './upvote'
|
import UpVote from './upvote'
|
||||||
|
@ -11,7 +11,7 @@ import EyeClose from '../svgs/eye-close-line.svg'
|
||||||
import { useRouter } from 'next/router'
|
import { useRouter } from 'next/router'
|
||||||
import CommentEdit from './comment-edit'
|
import CommentEdit from './comment-edit'
|
||||||
import Countdown from './countdown'
|
import Countdown from './countdown'
|
||||||
import { NOFOLLOW_LIMIT } from '../lib/constants'
|
import { COMMENT_DEPTH_LIMIT, NOFOLLOW_LIMIT } from '../lib/constants'
|
||||||
import { ignoreClick } from '../lib/clicks'
|
import { ignoreClick } from '../lib/clicks'
|
||||||
|
|
||||||
function Parent ({ item, rootText }) {
|
function Parent ({ item, rootText }) {
|
||||||
|
@ -53,10 +53,17 @@ export function CommentFlat ({ item, ...props }) {
|
||||||
if (ignoreClick(e)) {
|
if (ignoreClick(e)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
router.push({
|
if (item.path.split('.').length > COMMENT_DEPTH_LIMIT + 1) {
|
||||||
pathname: '/items/[id]',
|
router.push({
|
||||||
query: { id: item.root.id, commentId: item.id }
|
pathname: '/items/[id]',
|
||||||
}, `/items/${item.root.id}`)
|
query: { id: item.parentId, commentId: item.id }
|
||||||
|
}, `/items/${item.parentId}`)
|
||||||
|
} else {
|
||||||
|
router.push({
|
||||||
|
pathname: '/items/[id]',
|
||||||
|
query: { id: item.root.id, commentId: item.id }
|
||||||
|
}, `/items/${item.root.id}`)
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Comment item={item} {...props} />
|
<Comment item={item} {...props} />
|
||||||
|
@ -66,7 +73,7 @@ export function CommentFlat ({ item, ...props }) {
|
||||||
|
|
||||||
export default function Comment ({
|
export default function Comment ({
|
||||||
item, children, replyOpen, includeParent,
|
item, children, replyOpen, includeParent,
|
||||||
rootText, noComments, noReply, truncate
|
rootText, noComments, noReply, truncate, depth
|
||||||
}) {
|
}) {
|
||||||
const [edit, setEdit] = useState()
|
const [edit, setEdit] = useState()
|
||||||
const [collapse, setCollapse] = useState(false)
|
const [collapse, setCollapse] = useState(false)
|
||||||
|
@ -89,6 +96,8 @@ export default function Comment ({
|
||||||
setCollapse(localStorage.getItem(`commentCollapse:${item.id}`))
|
setCollapse(localStorage.getItem(`commentCollapse:${item.id}`))
|
||||||
}, [item])
|
}, [item])
|
||||||
|
|
||||||
|
const bottomedOut = depth === COMMENT_DEPTH_LIMIT
|
||||||
|
|
||||||
const op = item.root.user.name === item.user.name
|
const op = item.root.user.name === item.user.name
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -171,20 +180,40 @@ export default function Comment ({
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className={`${styles.children}`}>
|
{bottomedOut
|
||||||
{!noReply &&
|
? <DepthLimit item={item} />
|
||||||
<Reply
|
: (
|
||||||
parentId={item.id} meComments={item.meComments} replyOpen={replyOpen}
|
<div className={`${styles.children}`}>
|
||||||
/>}
|
{!noReply &&
|
||||||
{children}
|
<Reply
|
||||||
<div className={`${styles.comments} ml-sm-1 ml-md-3`}>
|
depth={depth + 1} parentId={item.id} meComments={item.meComments} replyOpen={replyOpen}
|
||||||
{item.comments && !noComments
|
/>}
|
||||||
? item.comments.map((item) => (
|
{children}
|
||||||
<Comment key={item.id} item={item} />
|
<div className={`${styles.comments} ml-sm-1 ml-md-3`}>
|
||||||
))
|
{item.comments && !noComments
|
||||||
: null}
|
? item.comments.map((item) => (
|
||||||
</div>
|
<Comment depth={depth + 1} key={item.id} item={item} />
|
||||||
</div>
|
))
|
||||||
|
: null}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function DepthLimit ({ item }) {
|
||||||
|
if (item.ncomments > 0) {
|
||||||
|
return (
|
||||||
|
<Link href={`/items/${item.id}`} passHref>
|
||||||
|
<a className='d-block p-3 font-weight-bold text-muted w-100 text-center'>view replies</a>
|
||||||
|
</Link>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={`${styles.children}`}>
|
||||||
|
<ReplyOnAnotherPage parentId={item.id} />
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { gql, useApolloClient, useLazyQuery, useQuery } from '@apollo/client'
|
import { gql, useApolloClient, useLazyQuery } from '@apollo/client'
|
||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
import Comment, { CommentSkeleton } from './comment'
|
import Comment, { CommentSkeleton } from './comment'
|
||||||
import styles from './header.module.css'
|
import styles from './header.module.css'
|
||||||
|
@ -89,7 +89,7 @@ export default function Comments ({ parentId, comments, ...props }) {
|
||||||
{loading
|
{loading
|
||||||
? <CommentsSkeleton />
|
? <CommentsSkeleton />
|
||||||
: comments.map(item => (
|
: comments.map(item => (
|
||||||
<Comment key={item.id} item={item} {...props} />
|
<Comment depth={1} key={item.id} item={item} {...props} />
|
||||||
))}
|
))}
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
|
@ -98,14 +98,3 @@ export default function Comments ({ parentId, comments, ...props }) {
|
||||||
export function CommentsSkeleton () {
|
export function CommentsSkeleton () {
|
||||||
return <CommentSkeleton skeletonChildren={7} />
|
return <CommentSkeleton skeletonChildren={7} />
|
||||||
}
|
}
|
||||||
|
|
||||||
export function CommentsQuery ({ query, ...props }) {
|
|
||||||
const { error, data } = useQuery(query)
|
|
||||||
|
|
||||||
if (error) return <div>Failed to load!</div>
|
|
||||||
if (!data) {
|
|
||||||
return <CommentsSkeleton />
|
|
||||||
}
|
|
||||||
|
|
||||||
return <Comments comments={data.comments} {...props} />
|
|
||||||
}
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ import { timeSince } from '../lib/time'
|
||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
import Check from '../svgs/check-double-line.svg'
|
import Check from '../svgs/check-double-line.svg'
|
||||||
import HandCoin from '../svgs/hand-coin-fill.svg'
|
import HandCoin from '../svgs/hand-coin-fill.svg'
|
||||||
|
import { COMMENT_DEPTH_LIMIT } from '../lib/constants'
|
||||||
|
|
||||||
// TODO: oh man, this is a mess ... each notification type should just be a component ...
|
// TODO: oh man, this is a mess ... each notification type should just be a component ...
|
||||||
function Notification ({ n }) {
|
function Notification ({ n }) {
|
||||||
|
@ -31,10 +32,17 @@ function Notification ({ n }) {
|
||||||
} else if (n.__typename === 'Invitification') {
|
} else if (n.__typename === 'Invitification') {
|
||||||
router.push('/invites')
|
router.push('/invites')
|
||||||
} else if (!n.item.title) {
|
} else if (!n.item.title) {
|
||||||
router.push({
|
if (n.item.path.split('.').length > COMMENT_DEPTH_LIMIT + 1) {
|
||||||
pathname: '/items/[id]',
|
router.push({
|
||||||
query: { id: n.item.root.id, commentId: n.item.id }
|
pathname: '/items/[id]',
|
||||||
}, `/items/${n.item.root.id}`)
|
query: { id: n.item.parentId, commentId: n.item.id }
|
||||||
|
}, `/items/${n.item.parentId}`)
|
||||||
|
} else {
|
||||||
|
router.push({
|
||||||
|
pathname: '/items/[id]',
|
||||||
|
query: { id: n.item.root.id, commentId: n.item.id }
|
||||||
|
}, `/items/${n.item.root.id}`)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
router.push({
|
router.push({
|
||||||
pathname: '/items/[id]',
|
pathname: '/items/[id]',
|
||||||
|
|
|
@ -8,11 +8,20 @@ import ActionTooltip from './action-tooltip'
|
||||||
import TextareaAutosize from 'react-textarea-autosize'
|
import TextareaAutosize from 'react-textarea-autosize'
|
||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
import Info from './info'
|
import Info from './info'
|
||||||
|
import Link from 'next/link'
|
||||||
|
|
||||||
export const CommentSchema = Yup.object({
|
export const CommentSchema = Yup.object({
|
||||||
text: Yup.string().required('required').trim()
|
text: Yup.string().required('required').trim()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
export function ReplyOnAnotherPage ({ parentId }) {
|
||||||
|
return (
|
||||||
|
<Link href={`/items/${parentId}`}>
|
||||||
|
<a className={`${styles.replyButtons} text-muted`}>reply on another page</a>
|
||||||
|
</Link>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
export default function Reply ({ parentId, meComments, onSuccess, replyOpen }) {
|
export default function Reply ({ parentId, meComments, onSuccess, replyOpen }) {
|
||||||
const [reply, setReply] = useState(replyOpen)
|
const [reply, setReply] = useState(replyOpen)
|
||||||
const me = useMe()
|
const me = useMe()
|
||||||
|
|
|
@ -15,6 +15,7 @@ export const COMMENT_FIELDS = gql`
|
||||||
boost
|
boost
|
||||||
meSats
|
meSats
|
||||||
meComments
|
meComments
|
||||||
|
path
|
||||||
mine
|
mine
|
||||||
ncomments
|
ncomments
|
||||||
root {
|
root {
|
||||||
|
|
|
@ -19,6 +19,7 @@ export const ITEM_FIELDS = gql`
|
||||||
sats
|
sats
|
||||||
upvotes
|
upvotes
|
||||||
boost
|
boost
|
||||||
|
path
|
||||||
meSats
|
meSats
|
||||||
ncomments
|
ncomments
|
||||||
maxBid
|
maxBid
|
||||||
|
|
|
@ -9,3 +9,4 @@ export const UPLOAD_TYPES_ALLOW = [
|
||||||
'image/jpeg',
|
'image/jpeg',
|
||||||
'image/webp'
|
'image/webp'
|
||||||
]
|
]
|
||||||
|
export const COMMENT_DEPTH_LIMIT = 10
|
||||||
|
|
Loading…
Reference in New Issue