fix nested comment sorting
This commit is contained in:
parent
19835aef5f
commit
8ab018af88
@ -482,9 +482,6 @@ export default {
|
|||||||
LIMIT 3`
|
LIMIT 3`
|
||||||
}, similar)
|
}, similar)
|
||||||
},
|
},
|
||||||
comments: async (parent, { id, sort }, { me, models }) => {
|
|
||||||
return comments(me, models, id, sort)
|
|
||||||
},
|
|
||||||
auctionPosition: async (parent, { id, sub, bid }, { models, me }) => {
|
auctionPosition: async (parent, { id, sub, bid }, { models, me }) => {
|
||||||
const createdAt = id ? (await getItem(parent, { id }, { models, me })).createdAt : new Date()
|
const createdAt = id ? (await getItem(parent, { id }, { models, me })).createdAt : new Date()
|
||||||
let where
|
let where
|
||||||
@ -848,12 +845,11 @@ export default {
|
|||||||
}
|
}
|
||||||
return await models.user.findUnique({ where: { id: item.fwdUserId } })
|
return await models.user.findUnique({ where: { id: item.fwdUserId } })
|
||||||
},
|
},
|
||||||
comments: async (item, args, { me, models }) => {
|
comments: async (item, { sort }, { me, models }) => {
|
||||||
if (item.comments) {
|
if (item.comments) return item.comments
|
||||||
return item.comments
|
if (item.ncomments === 0) return []
|
||||||
}
|
|
||||||
|
|
||||||
return comments(me, models, item.id, defaultCommentSort(item.pinId, item.bioId, item.createdAt))
|
return comments(me, models, item.id, sort || defaultCommentSort(item.pinId, item.bioId, item.createdAt))
|
||||||
},
|
},
|
||||||
wvotes: async (item) => {
|
wvotes: async (item) => {
|
||||||
return item.weightedVotes - item.weightedDownVotes
|
return item.weightedVotes - item.weightedDownVotes
|
||||||
|
@ -4,7 +4,6 @@ export default gql`
|
|||||||
extend type Query {
|
extend type Query {
|
||||||
items(sub: String, sort: String, type: String, cursor: String, name: String, when: String, by: String, limit: Int): Items
|
items(sub: String, sort: String, type: String, cursor: String, name: String, when: String, by: String, limit: Int): Items
|
||||||
item(id: ID!): Item
|
item(id: ID!): Item
|
||||||
comments(id: ID!, sort: String): [Item!]!
|
|
||||||
pageTitleAndUnshorted(url: String!): TitleUnshorted
|
pageTitleAndUnshorted(url: String!): TitleUnshorted
|
||||||
dupes(url: String!): [Item!]
|
dupes(url: String!): [Item!]
|
||||||
related(cursor: String, title: String, id: ID, minMatch: String, limit: Int): Items
|
related(cursor: String, title: String, id: ID, minMatch: String, limit: Int): Items
|
||||||
@ -99,7 +98,7 @@ export default gql`
|
|||||||
freebie: Boolean!
|
freebie: Boolean!
|
||||||
paidImgLink: Boolean
|
paidImgLink: Boolean
|
||||||
ncomments: Int!
|
ncomments: Int!
|
||||||
comments: [Item!]!
|
comments(sort: String): [Item!]!
|
||||||
path: String
|
path: String
|
||||||
position: Int
|
position: Int
|
||||||
prior: Int
|
prior: Int
|
||||||
|
@ -1,20 +1,17 @@
|
|||||||
import { gql, useApolloClient, useLazyQuery } from '@apollo/client'
|
|
||||||
import { 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'
|
||||||
import Nav from 'react-bootstrap/Nav'
|
import Nav from 'react-bootstrap/Nav'
|
||||||
import Navbar from 'react-bootstrap/Navbar'
|
import Navbar from 'react-bootstrap/Navbar'
|
||||||
import { COMMENTS_QUERY } from '../fragments/items'
|
|
||||||
import { COMMENTS } from '../fragments/comments'
|
|
||||||
import { abbrNum } from '../lib/format'
|
import { abbrNum } from '../lib/format'
|
||||||
import { defaultCommentSort } from '../lib/item'
|
import { defaultCommentSort } from '../lib/item'
|
||||||
|
import { useRouter } from 'next/router'
|
||||||
|
|
||||||
export function CommentsHeader ({ handleSort, pinned, bio, parentCreatedAt, commentSats }) {
|
export function CommentsHeader ({ handleSort, pinned, bio, parentCreatedAt, commentSats }) {
|
||||||
const [sort, setSort] = useState(defaultCommentSort(pinned, bio, parentCreatedAt))
|
const router = useRouter()
|
||||||
|
const sort = router.query.sort || defaultCommentSort(pinned, bio, parentCreatedAt)
|
||||||
|
|
||||||
const getHandleClick = sort => {
|
const getHandleClick = sort => {
|
||||||
return () => {
|
return () => {
|
||||||
setSort(sort)
|
|
||||||
handleSort(sort)
|
handleSort(sort)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -63,45 +60,24 @@ export function CommentsHeader ({ handleSort, pinned, bio, parentCreatedAt, comm
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default function Comments ({ parentId, pinned, bio, parentCreatedAt, commentSats, comments, ...props }) {
|
export default function Comments ({ parentId, pinned, bio, parentCreatedAt, commentSats, comments, ...props }) {
|
||||||
const client = useApolloClient()
|
const router = useRouter()
|
||||||
|
|
||||||
const [loading, setLoading] = useState()
|
|
||||||
const [getComments] = useLazyQuery(COMMENTS_QUERY, {
|
|
||||||
fetchPolicy: 'cache-first',
|
|
||||||
onCompleted: data => {
|
|
||||||
client.writeFragment({
|
|
||||||
id: `Item:${parentId}`,
|
|
||||||
fragment: gql`
|
|
||||||
${COMMENTS}
|
|
||||||
fragment Comments on Item {
|
|
||||||
comments {
|
|
||||||
...CommentsRecursive
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
fragmentName: 'Comments',
|
|
||||||
data: {
|
|
||||||
comments: data.comments
|
|
||||||
}
|
|
||||||
})
|
|
||||||
setLoading(false)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{comments.length
|
{comments?.length > 0
|
||||||
? <CommentsHeader
|
? <CommentsHeader
|
||||||
commentSats={commentSats} parentCreatedAt={parentCreatedAt}
|
commentSats={commentSats} parentCreatedAt={parentCreatedAt}
|
||||||
pinned={pinned} bio={bio} handleSort={sort => {
|
pinned={pinned} bio={bio} handleSort={sort => {
|
||||||
setLoading(true)
|
const query = router.query
|
||||||
getComments({ variables: { id: parentId, sort } })
|
delete query.nodata
|
||||||
|
router.push({
|
||||||
|
pathname: router.pathname,
|
||||||
|
query: { ...router.query, sort }
|
||||||
|
}, router.asPath, { scroll: false })
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
: null}
|
: null}
|
||||||
{loading
|
{comments.map(item => (
|
||||||
? <CommentsSkeleton />
|
|
||||||
: comments.map(item => (
|
|
||||||
<Comment depth={1} key={item.id} item={item} {...props} />
|
<Comment depth={1} key={item.id} item={item} {...props} />
|
||||||
))}
|
))}
|
||||||
</>
|
</>
|
||||||
|
@ -178,11 +178,9 @@ export default function ItemFull ({ item, bio, rank, ...props }) {
|
|||||||
{item.parentId
|
{item.parentId
|
||||||
? <Comment topLevel item={item} replyOpen includeParent noComments {...props} />
|
? <Comment topLevel item={item} replyOpen includeParent noComments {...props} />
|
||||||
: (
|
: (
|
||||||
<div className='mt-1'>{
|
<div>{bio
|
||||||
bio
|
|
||||||
? <BioItem item={item} {...props} />
|
? <BioItem item={item} {...props} />
|
||||||
: <TopLevelItem item={item} {...props} />
|
: <TopLevelItem item={item} {...props} />}
|
||||||
}
|
|
||||||
</div>)}
|
</div>)}
|
||||||
{item.comments &&
|
{item.comments &&
|
||||||
<div className={styles.comments}>
|
<div className={styles.comments}>
|
||||||
|
@ -19,8 +19,8 @@ export default function TopHeader ({ sub, cat }) {
|
|||||||
|
|
||||||
if (typeof query.by !== 'undefined') {
|
if (typeof query.by !== 'undefined') {
|
||||||
if (query.by === '' ||
|
if (query.by === '' ||
|
||||||
(what === 'stackers' && !USER_SORTS.includes(query.by)) ||
|
(what === 'stackers' && (query.by === 'stacked' || !USER_SORTS.includes(query.by))) ||
|
||||||
(what !== 'stackers' && !ITEM_SORTS.includes(query.by))) {
|
(what !== 'stackers' && (query.by === 'votes' || !ITEM_SORTS.includes(query.by)))) {
|
||||||
delete query.by
|
delete query.by
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -49,6 +49,7 @@ export const COMMENTS_ITEM_EXT_FIELDS = gql`
|
|||||||
}
|
}
|
||||||
}`
|
}`
|
||||||
|
|
||||||
|
// we only get the first COMMENT_DEPTH_LIMIT comments
|
||||||
export const COMMENTS = gql`
|
export const COMMENTS = gql`
|
||||||
${COMMENT_FIELDS}
|
${COMMENT_FIELDS}
|
||||||
|
|
||||||
@ -72,54 +73,6 @@ export const COMMENTS = gql`
|
|||||||
...CommentFields
|
...CommentFields
|
||||||
comments {
|
comments {
|
||||||
...CommentFields
|
...CommentFields
|
||||||
comments {
|
|
||||||
...CommentFields
|
|
||||||
comments {
|
|
||||||
...CommentFields
|
|
||||||
comments {
|
|
||||||
...CommentFields
|
|
||||||
comments {
|
|
||||||
...CommentFields
|
|
||||||
comments {
|
|
||||||
...CommentFields
|
|
||||||
comments {
|
|
||||||
...CommentFields
|
|
||||||
comments {
|
|
||||||
...CommentFields
|
|
||||||
comments {
|
|
||||||
...CommentFields
|
|
||||||
comments {
|
|
||||||
...CommentFields
|
|
||||||
comments {
|
|
||||||
...CommentFields
|
|
||||||
comments {
|
|
||||||
...CommentFields
|
|
||||||
comments {
|
|
||||||
...CommentFields
|
|
||||||
comments {
|
|
||||||
...CommentFields
|
|
||||||
comments {
|
|
||||||
...CommentFields
|
|
||||||
comments {
|
|
||||||
...CommentFields
|
|
||||||
comments {
|
|
||||||
...CommentFields
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -116,41 +116,21 @@ export const ITEM = gql`
|
|||||||
}
|
}
|
||||||
}`
|
}`
|
||||||
|
|
||||||
export const COMMENTS_QUERY = gql`
|
|
||||||
${COMMENTS}
|
|
||||||
|
|
||||||
query Comments($id: ID!, $sort: String) {
|
|
||||||
comments(id: $id, sort: $sort) {
|
|
||||||
...CommentsRecursive
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
export const ITEM_FULL = gql`
|
export const ITEM_FULL = gql`
|
||||||
${ITEM_FULL_FIELDS}
|
${ITEM_FULL_FIELDS}
|
||||||
${POLL_FIELDS}
|
${POLL_FIELDS}
|
||||||
${COMMENTS}
|
${COMMENTS}
|
||||||
query Item($id: ID!) {
|
query Item($id: ID!, $sort: String) {
|
||||||
item(id: $id) {
|
item(id: $id) {
|
||||||
...ItemFullFields
|
...ItemFullFields
|
||||||
prior
|
prior
|
||||||
...PollFields
|
...PollFields
|
||||||
comments {
|
comments(sort: $sort) {
|
||||||
...CommentsRecursive
|
...CommentsRecursive
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}`
|
}`
|
||||||
|
|
||||||
export const ITEM_WITH_COMMENTS = gql`
|
|
||||||
${ITEM_FULL_FIELDS}
|
|
||||||
${COMMENTS}
|
|
||||||
fragment ItemWithComments on Item {
|
|
||||||
...ItemFullFields
|
|
||||||
comments {
|
|
||||||
...CommentsRecursive
|
|
||||||
}
|
|
||||||
}`
|
|
||||||
|
|
||||||
export const RELATED_ITEMS = gql`
|
export const RELATED_ITEMS = gql`
|
||||||
${ITEM_FIELDS}
|
${ITEM_FIELDS}
|
||||||
query Related($title: String, $id: ID, $cursor: String, $limit: Int) {
|
query Related($title: String, $id: ID, $cursor: String, $limit: Int) {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { gql } from '@apollo/client'
|
import { gql } from '@apollo/client'
|
||||||
import { COMMENTS_ITEM_EXT_FIELDS } from './comments'
|
import { COMMENTS, COMMENTS_ITEM_EXT_FIELDS } from './comments'
|
||||||
import { ITEM_FIELDS, ITEM_WITH_COMMENTS } from './items'
|
import { ITEM_FIELDS, ITEM_FULL_FIELDS } from './items'
|
||||||
|
|
||||||
export const ME = gql`
|
export const ME = gql`
|
||||||
{
|
{
|
||||||
@ -174,12 +174,16 @@ export const TOP_COWBOYS = gql`
|
|||||||
|
|
||||||
export const USER_FULL = gql`
|
export const USER_FULL = gql`
|
||||||
${USER_FIELDS}
|
${USER_FIELDS}
|
||||||
${ITEM_WITH_COMMENTS}
|
${ITEM_FULL_FIELDS}
|
||||||
query User($name: String!) {
|
${COMMENTS}
|
||||||
|
query User($name: String!, $sort: String) {
|
||||||
user(name: $name) {
|
user(name: $name) {
|
||||||
...UserFields
|
...UserFields
|
||||||
bio {
|
bio {
|
||||||
...ItemWithComments
|
...ItemFullFields
|
||||||
|
comments(sort: $sort) {
|
||||||
|
...CommentsRecursive
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}`
|
}`
|
||||||
|
@ -3,9 +3,9 @@ import { dayPivot } from './time'
|
|||||||
|
|
||||||
export const defaultCommentSort = (pinned, bio, createdAt) => {
|
export const defaultCommentSort = (pinned, bio, createdAt) => {
|
||||||
// pins sort by recent
|
// pins sort by recent
|
||||||
if (pinned || bio) return 'recent'
|
if (pinned) return 'recent'
|
||||||
// old items sort by top
|
// old items (that aren't bios) sort by top
|
||||||
if (new Date(createdAt) < dayPivot(new Date(), -OLD_ITEM_DAYS)) return 'top'
|
if (!bio && new Date(createdAt) < dayPivot(new Date(), -OLD_ITEM_DAYS)) return 'top'
|
||||||
// everything else sorts by hot
|
// everything else sorts by hot
|
||||||
return 'hot'
|
return 'hot'
|
||||||
}
|
}
|
||||||
|
@ -97,7 +97,7 @@ export default function User ({ ssrData }) {
|
|||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const me = useMe()
|
const me = useMe()
|
||||||
|
|
||||||
const { data } = useQuery(USER_FULL, { variables: { name: router.query.name } })
|
const { data } = useQuery(USER_FULL, { variables: { ...router.query } })
|
||||||
if (!data && !ssrData) return <PageLoading />
|
if (!data && !ssrData) return <PageLoading />
|
||||||
|
|
||||||
const { user } = data || ssrData
|
const { user } = data || ssrData
|
||||||
|
@ -39,6 +39,8 @@ function MyApp ({ Component, pageProps: { session, ...props } }) {
|
|||||||
// this nodata var will get passed to the server on back/foward and
|
// this nodata var will get passed to the server on back/foward and
|
||||||
// 1. prevent data from reloading and 2. perserve scroll
|
// 1. prevent data from reloading and 2. perserve scroll
|
||||||
// (2) is not possible while intercepting nav with beforePopState
|
// (2) is not possible while intercepting nav with beforePopState
|
||||||
|
if (router.query.nodata) return
|
||||||
|
|
||||||
router.replace({
|
router.replace({
|
||||||
pathname: router.pathname,
|
pathname: router.pathname,
|
||||||
query: { ...router.query, nodata: true }
|
query: { ...router.query, nodata: true }
|
||||||
@ -48,7 +50,7 @@ function MyApp ({ Component, pageProps: { session, ...props } }) {
|
|||||||
throw e
|
throw e
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}, [router.asPath])
|
}, [router.pathname, router.query])
|
||||||
|
|
||||||
/*
|
/*
|
||||||
If we are on the client, we populate the apollo cache with the
|
If we are on the client, we populate the apollo cache with the
|
||||||
|
@ -12,7 +12,7 @@ export const getServerSideProps = getGetServerSideProps(ITEM_FULL, null,
|
|||||||
export default function Item ({ ssrData }) {
|
export default function Item ({ ssrData }) {
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
|
||||||
const { data } = useQuery(ITEM_FULL, { variables: { id: router.query.id } })
|
const { data } = useQuery(ITEM_FULL, { variables: { ...router.query } })
|
||||||
if (!data && !ssrData) return <PageLoading />
|
if (!data && !ssrData) return <PageLoading />
|
||||||
|
|
||||||
const { item } = data || ssrData
|
const { item } = data || ssrData
|
||||||
|
Loading…
x
Reference in New Issue
Block a user