From f0f51438c407544b00a8f0d6bac08f25d4195394 Mon Sep 17 00:00:00 2001 From: keyan Date: Mon, 12 Jun 2023 17:15:20 -0500 Subject: [PATCH] add top posts/comments to subs --- api/resolvers/item.js | 17 ++++++---- api/typeDefs/item.js | 4 +-- components/header.js | 4 +-- components/top-header.js | 8 +++-- fragments/subs.js | 49 ++++++++++++++++++++++++++++ pages/~/[sub]/top/comments/[when].js | 25 ++++++++++++++ pages/~/[sub]/top/posts/[when].js | 25 ++++++++++++++ 7 files changed, 119 insertions(+), 13 deletions(-) create mode 100644 pages/~/[sub]/top/comments/[when].js create mode 100644 pages/~/[sub]/top/posts/[when].js diff --git a/api/resolvers/item.js b/api/resolvers/item.js index afa40c03..8a8ebb5e 100644 --- a/api/resolvers/item.js +++ b/api/resolvers/item.js @@ -226,8 +226,9 @@ export default { return count }, - topItems: async (parent, { cursor, sort, when }, { me, models }) => { + topItems: async (parent, { sub, cursor, sort, when }, { me, models }) => { const decodedCursor = decodeCursor(cursor) + const subArr = sub ? [sub] : [] const items = await itemQueryWithMeta({ me, models, @@ -236,35 +237,39 @@ export default { FROM "Item" WHERE "parentId" IS NULL AND "Item".created_at <= $1 AND "pinId" IS NULL AND "deletedAt" IS NULL + ${subClause(sub, 3)} ${topClause(when)} ${await filterClause(me, models)} ${await topOrderClause(sort, me, models)} OFFSET $2 LIMIT ${LIMIT}`, orderBy: await topOrderClause(sort, me, models) - }, decodedCursor.time, decodedCursor.offset) + }, decodedCursor.time, decodedCursor.offset, ...subArr) return { cursor: items.length === LIMIT ? nextCursorEncoded(decodedCursor) : null, items } }, - topComments: async (parent, { cursor, sort, when }, { me, models }) => { + topComments: async (parent, { sub, cursor, sort, when }, { me, models }) => { const decodedCursor = decodeCursor(cursor) + const subArr = sub ? [sub] : [] const comments = await itemQueryWithMeta({ me, models, query: ` ${SELECT} FROM "Item" - WHERE "parentId" IS NOT NULL - AND "Item".created_at <= $1 AND "deletedAt" IS NULL + JOIN "Item" root ON "Item"."rootId" = root.id + WHERE "Item"."parentId" IS NOT NULL + AND "Item".created_at <= $1 AND "Item"."deletedAt" IS NULL + ${subClause(sub, 3, 'root')} ${topClause(when)} ${await filterClause(me, models)} ${await topOrderClause(sort, me, models)} OFFSET $2 LIMIT ${LIMIT}`, orderBy: await topOrderClause(sort, me, models) - }, decodedCursor.time, decodedCursor.offset) + }, decodedCursor.time, decodedCursor.offset, ...subArr) return { cursor: comments.length === LIMIT ? nextCursorEncoded(decodedCursor) : null, comments diff --git a/api/typeDefs/item.js b/api/typeDefs/item.js index 665df122..d31c75e8 100644 --- a/api/typeDefs/item.js +++ b/api/typeDefs/item.js @@ -18,8 +18,8 @@ export default gql` outlawedItems(cursor: String): Items borderlandItems(cursor: String): Items freebieItems(cursor: String): Items - topItems(cursor: String, sort: String, when: String): Items - topComments(cursor: String, sort: String, when: String): Comments + topItems(cursor: String, sub: String, sort: String, when: String): Items + topComments(cursor: String, sub: String, sort: String, when: String): Comments } type TitleUnshorted { diff --git a/components/header.js b/components/header.js index 3e0dd8af..ac905f14 100644 --- a/components/header.js +++ b/components/header.js @@ -239,9 +239,9 @@ export default function Header ({ sub }) { recent - {!prefix && + {sub !== 'jobs' && - + top } diff --git a/components/top-header.js b/components/top-header.js index 5d3cae8d..abcdb3e7 100644 --- a/components/top-header.js +++ b/components/top-header.js @@ -4,7 +4,7 @@ import { Form, Select } from './form' const USER_SORTS = ['stacked', 'spent', 'comments', 'posts', 'referrals'] const ITEM_SORTS = ['votes', 'comments', 'sats'] -export default function TopHeader ({ cat }) { +export default function TopHeader ({ sub, cat }) { const router = useRouter() const top = async values => { @@ -17,6 +17,8 @@ export default function TopHeader ({ cat }) { return } + const prefix = sub ? `/~${sub}` : '' + if (typeof query.sort !== 'undefined') { if (query.sort === '' || (what === 'users' && !USER_SORTS.includes(query.sort)) || @@ -26,7 +28,7 @@ export default function TopHeader ({ cat }) { } await router.push({ - pathname: `/top/${what}/${when || 'day'}`, + pathname: `${prefix}/top/${what}/${when || 'day'}`, query }) } @@ -49,7 +51,7 @@ export default function TopHeader ({ cat }) { onChange={(formik, e) => top({ ...formik?.values, what: e.target.value })} name='what' size='sm' - items={['posts', 'comments', 'users', 'cowboys']} + items={router?.query?.sub ? ['posts', 'comments'] : ['posts', 'comments', 'users', 'cowboys']} /> {cat !== 'cowboys' && <> diff --git a/fragments/subs.js b/fragments/subs.js index f7fda523..ce18a749 100644 --- a/fragments/subs.js +++ b/fragments/subs.js @@ -40,6 +40,55 @@ export const SUB_ITEMS = gql` } ` +export const SUB_TOP_ITEMS = gql` + ${SUB_FIELDS} + ${ITEM_FIELDS} + + query SubTopItems($sub: String!, $sort: String, $cursor: String, $when: String) { + sub(name: $sub) { + ...SubFields + } + topItems(sub: $sub, sort: $sort, cursor: $cursor, when: $when) { + cursor + items { + ...ItemFields + }, + pins { + ...ItemFields + } + } + }` + +export const SUB_TOP_COMMENTS = gql` + ${SUB_FIELDS} + ${COMMENT_FIELDS} + + query SubTopComments($sub: String!, $sort: String, $cursor: String, $when: String = "day") { + sub(name: $sub) { + ...SubFields + } + topComments(sub: $sub, sort: $sort, cursor: $cursor, when: $when) { + cursor + comments { + ...CommentFields + root { + id + title + bounty + bountyPaidTo + subName + user { + name + streak + hideCowboyHat + id + } + } + } + } + } +` + export const SUB_SEARCH = gql` ${SUB_FIELDS} ${ITEM_FIELDS} diff --git a/pages/~/[sub]/top/comments/[when].js b/pages/~/[sub]/top/comments/[when].js new file mode 100644 index 00000000..a1584c20 --- /dev/null +++ b/pages/~/[sub]/top/comments/[when].js @@ -0,0 +1,25 @@ +import Layout from '../../../../../components/layout' +import { useRouter } from 'next/router' +import { getGetServerSideProps } from '../../../../../api/ssrApollo' +import TopHeader from '../../../../../components/top-header' +import { SUB_TOP_COMMENTS } from '../../../../../fragments/subs' +import CommentsFlat from '../../../../../components/comments-flat' + +export const getServerSideProps = getGetServerSideProps(SUB_TOP_COMMENTS, undefined, data => !data.sub) + +export default function Index ({ data: { sub, topComments: { comments, cursor } } }) { + const router = useRouter() + + return ( + + + data.topComments} + variables={{ sub: sub?.name, sort: router.query.sort, when: router.query.when }} + includeParent noReply + /> + + ) +} diff --git a/pages/~/[sub]/top/posts/[when].js b/pages/~/[sub]/top/posts/[when].js new file mode 100644 index 00000000..a62baacf --- /dev/null +++ b/pages/~/[sub]/top/posts/[when].js @@ -0,0 +1,25 @@ +import Layout from '../../../../../components/layout' +import Items from '../../../../../components/items' +import { useRouter } from 'next/router' +import { getGetServerSideProps } from '../../../../../api/ssrApollo' +import TopHeader from '../../../../../components/top-header' +import { SUB_TOP_ITEMS } from '../../../../../fragments/subs' + +export const getServerSideProps = getGetServerSideProps(SUB_TOP_ITEMS, undefined, + data => !data.sub) + +export default function Index ({ data: { sub, topItems: { items, cursor } } }) { + const router = useRouter() + + return ( + + + data.topItems} + variables={{ sub: sub?.name, sort: router.query.sort, when: router.query.when }} rank + /> + + ) +}