pre recursive comments
This commit is contained in:
parent
28ed42fc29
commit
95d6d789fa
|
@ -31,24 +31,33 @@ export default {
|
|||
Query: {
|
||||
items: async (parent, args, { models }) => {
|
||||
return await models.$queryRaw(`
|
||||
SELECT id, "created_at" as "createdAt", title, url, text, "userId", ltree2text("path") AS "path"
|
||||
SELECT id, "created_at" as "createdAt", title, url, text,
|
||||
"userId", nlevel(path)-1 AS depth, ltree2text("path") AS "path"
|
||||
FROM "Item"
|
||||
WHERE "parentId" IS NULL
|
||||
ORDER BY "path"`)
|
||||
WHERE "parentId" IS NULL`)
|
||||
},
|
||||
item: async (parent, { id }, { models }) => {
|
||||
const res = await models.$queryRaw(`
|
||||
SELECT id, "created_at" as "createdAt", title, url, text, "parentId", "userId", ltree2text("path") AS "path"
|
||||
SELECT id, "created_at" as "createdAt", title, url, text,
|
||||
"parentId", "userId", nlevel(path)-1 AS depth, ltree2text("path") AS "path"
|
||||
FROM "Item"
|
||||
WHERE id = ${id}
|
||||
ORDER BY "path"`)
|
||||
WHERE id = ${id}`)
|
||||
return res.length ? res[0] : null
|
||||
},
|
||||
ncomments: async (parent, { parentId }, { models }) => {
|
||||
comments: async (parent, { parentId }, { models }) => {
|
||||
return await models.$queryRaw(`
|
||||
SELECT id, "created_at" as "createdAt", title, url, text, "userId", ltree2text("path") AS "path"
|
||||
SELECT id, "created_at" as "createdAt", text, "parentId",
|
||||
"userId", nlevel(path)-1 AS depth, ltree2text("path") AS "path"
|
||||
FROM "Item"
|
||||
WHERE path <@ (SELECT path FROM "Item" where id = ${parentId}) AND id != ${parentId}
|
||||
ORDER BY "path"`)
|
||||
},
|
||||
root: async (parent, { id }, { models }) => {
|
||||
const res = await models.$queryRaw(`
|
||||
SELECT id, title
|
||||
FROM "Item"
|
||||
WHERE id = (SELECT ltree2text(subltree(path, 0, 1))::integer FROM "Item" WHERE id = ${id})`)
|
||||
return res.length ? res[0] : null
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -87,24 +96,11 @@ export default {
|
|||
Item: {
|
||||
user: async (item, args, { models }) =>
|
||||
await models.user.findUnique({ where: { id: item.userId } }),
|
||||
depth: async (item, args, { models }) => {
|
||||
if (item.path) {
|
||||
return item.path.split('.').length - 1
|
||||
}
|
||||
|
||||
// as the result of a mutation, path is not populated
|
||||
const [{ path }] = await models.$queryRaw`
|
||||
SELECT ltree2text("path") AS "path"
|
||||
FROM "Item"
|
||||
WHERE id = ${item.id}`
|
||||
|
||||
return path.split('.').length - 1
|
||||
},
|
||||
ncomments: async (item, args, { models }) => {
|
||||
const [{ count }] = await models.$queryRaw`
|
||||
SELECT count(*)
|
||||
FROM "Item"
|
||||
WHERE path <@ text2ltree(${item.id}) AND id != ${item.id}`
|
||||
WHERE path <@ text2ltree(${item.path}) AND id != ${item.id}`
|
||||
return count
|
||||
},
|
||||
sats: () => 0
|
||||
|
|
|
@ -4,7 +4,8 @@ export default gql`
|
|||
extend type Query {
|
||||
items: [Item!]!
|
||||
item(id: ID!): Item
|
||||
ncomments(id: ID!): [Item!]!
|
||||
comments(parentId: ID!): [Item!]!
|
||||
root(id: ID!): Item
|
||||
}
|
||||
|
||||
extend type Mutation {
|
||||
|
|
|
@ -5,6 +5,7 @@ import Text from './text'
|
|||
import Link from 'next/link'
|
||||
import Reply from './reply'
|
||||
import { useState } from 'react'
|
||||
import { gql, useQuery } from '@apollo/client'
|
||||
|
||||
function timeSince (timeStamp) {
|
||||
const now = new Date()
|
||||
|
@ -26,8 +27,42 @@ function timeSince (timeStamp) {
|
|||
}
|
||||
}
|
||||
|
||||
export default function Comment ({ item, children }) {
|
||||
const [reply, setReply] = useState(false)
|
||||
function Parent ({ item }) {
|
||||
const { data } = useQuery(
|
||||
gql`{
|
||||
root(id: ${item.id}) {
|
||||
id
|
||||
title
|
||||
}
|
||||
}`
|
||||
)
|
||||
|
||||
const ParentFrag = () => (
|
||||
<>
|
||||
<span> \ </span>
|
||||
<Link href={`/items/${item.parentId}`} passHref>
|
||||
<a className='text-reset'>parent</a>
|
||||
</Link>
|
||||
</>
|
||||
)
|
||||
|
||||
if (!data) {
|
||||
return <ParentFrag />
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{data.root.id !== item.parentId && <ParentFrag />}
|
||||
<span> \ </span>
|
||||
<Link href={`/items/${data.root.id}`} passHref>
|
||||
<a className='text-reset'>{data.root.title}</a>
|
||||
</Link>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default function Comment ({ item, children, replyOpen, includeParent }) {
|
||||
const [reply, setReply] = useState(replyOpen)
|
||||
|
||||
return (
|
||||
<>
|
||||
|
@ -43,7 +78,10 @@ export default function Comment ({ item, children }) {
|
|||
<span> \ </span>
|
||||
<span>{item.sats} sats</span>
|
||||
<span> \ </span>
|
||||
<span>{item.ncomments} replies</span>
|
||||
<Link href={`/items/${item.id}`} passHref>
|
||||
<a className='text-reset'>{item.ncomments} replies</a>
|
||||
</Link>
|
||||
{includeParent && <Parent item={item} />}
|
||||
</div>
|
||||
<div className={styles.text}>
|
||||
<Text>{item.text}</Text>
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
import { useQuery, gql } from '@apollo/client'
|
||||
import Comment from './comment'
|
||||
|
||||
export default function Comments ({ parentId, baseDepth }) {
|
||||
const { data } = useQuery(
|
||||
gql`{
|
||||
comments(parentId: ${parentId}) {
|
||||
id
|
||||
createdAt
|
||||
text
|
||||
user {
|
||||
name
|
||||
}
|
||||
depth
|
||||
sats
|
||||
ncomments
|
||||
}
|
||||
}`
|
||||
)
|
||||
|
||||
if (!data) return null
|
||||
|
||||
return (
|
||||
<div className='mt-5'>
|
||||
{data.comments.map(item => (
|
||||
<div
|
||||
key={item.id} className='mt-2'
|
||||
style={{ marginLeft: `${42 * (item.depth - baseDepth - 1)}px` }}
|
||||
>
|
||||
<Comment item={item} />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
}
|
|
@ -37,7 +37,9 @@ export default function Item ({ item, children }) {
|
|||
<div className={styles.other}>
|
||||
<span>{item.sats} sats</span>
|
||||
<span> \ </span>
|
||||
<span>{item.ncomments} comments</span>
|
||||
<Link href={`/items/${item.id}`} passHref>
|
||||
<a className='text-reset'>{item.ncomments} comments</a>
|
||||
</Link>
|
||||
<span> \ </span>
|
||||
<Link href={`/@${item.user.name}`} passHref>
|
||||
<a>@{item.user.name}</a>
|
||||
|
@ -50,11 +52,6 @@ export default function Item ({ item, children }) {
|
|||
{children && (
|
||||
<div className={styles.children}>
|
||||
{children}
|
||||
{item.comments
|
||||
? item.comments.map((item) => (
|
||||
<Item key={item.id} item={item} />
|
||||
))
|
||||
: null}
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
|
|
|
@ -5,6 +5,7 @@ import ApolloClient from '../../api/client'
|
|||
import Reply from '../../components/reply'
|
||||
import Comment from '../../components/comment'
|
||||
import Text from '../../components/text'
|
||||
import Comments from '../../components/comments'
|
||||
|
||||
export async function getServerSideProps ({ params }) {
|
||||
const { error, data: { item } } = await ApolloClient.query({
|
||||
|
@ -20,6 +21,7 @@ export async function getServerSideProps ({ params }) {
|
|||
user {
|
||||
name
|
||||
}
|
||||
depth
|
||||
sats
|
||||
ncomments
|
||||
}
|
||||
|
@ -43,9 +45,7 @@ export default function FullItem ({ item }) {
|
|||
return (
|
||||
<Layout>
|
||||
{item.parentId
|
||||
? (
|
||||
<Comment item={item} />
|
||||
)
|
||||
? <Comment item={item} replyOpen includeParent />
|
||||
: (
|
||||
<>
|
||||
<Item item={item}>
|
||||
|
@ -54,6 +54,7 @@ export default function FullItem ({ item }) {
|
|||
</Item>
|
||||
</>
|
||||
)}
|
||||
<Comments parentId={item.id} baseDepth={item.depth} />
|
||||
</Layout>
|
||||
)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue