From c82c82bb7b46294c9f34d92065a5d7d774b414ae Mon Sep 17 00:00:00 2001 From: keyan Date: Mon, 26 Apr 2021 19:55:48 -0500 Subject: [PATCH] mostly clientside render --- api/resolvers/item.js | 21 ++++----- api/typeDefs/item.js | 1 - components/comment.js | 4 +- components/comments.js | 38 +++++++++------- components/item.js | 7 ++- components/reply.js | 13 +++++- components/reply.module.css | 16 +++++++ pages/[username]/comments.js | 8 ++-- pages/items/[id].js | 86 ++++++++++++++++++++---------------- styles/globals.scss | 4 +- 10 files changed, 119 insertions(+), 79 deletions(-) diff --git a/api/resolvers/item.js b/api/resolvers/item.js index 2c1ab296..b96c93cb 100644 --- a/api/resolvers/item.js +++ b/api/resolvers/item.js @@ -28,14 +28,6 @@ export default { WHERE "userId" = ${userId} AND "parentId" IS NULL ORDER BY created_at`) }, - comments: async (parent, { parentId }, { models }) => { - const flat = await models.$queryRaw(` - ${SELECT} - FROM "Item" - WHERE path <@ (SELECT path FROM "Item" where id = ${parentId}) AND id != ${parentId} - ORDER BY "path"`) - return nestComments(flat, parentId)[0] - }, userComments: async (parent, { userId }, { models }) => { return await models.$queryRaw(` ${SELECT} @@ -119,6 +111,14 @@ export default { WHERE path <@ text2ltree(${item.path}) AND id != ${item.id}` return count }, + comments: async (item, args, { models }) => { + const flat = await models.$queryRaw(` + ${SELECT} + FROM "Item" + WHERE path <@ (SELECT path FROM "Item" where id = ${item.id}) AND id != ${item.id} + ORDER BY "path"`) + return nestComments(flat, item.id)[0] + }, sats: async (item, args, { models }) => { const { sum: { sats } } = await models.vote.aggregate({ sum: { @@ -158,11 +158,6 @@ const createItem = async (parent, { title, text, url, parentId }, { me, models } title, url, text, - item: { - connect: { - - } - }, user: { connect: { name: me.name diff --git a/api/typeDefs/item.js b/api/typeDefs/item.js index c07f7bcb..c2b44725 100644 --- a/api/typeDefs/item.js +++ b/api/typeDefs/item.js @@ -6,7 +6,6 @@ export default gql` recent: [Item!]! item(id: ID!): Item userItems(userId: ID!): [Item!] - comments(parentId: ID!): [Item!]! userComments(userId: ID!): [Item!] root(id: ID!): Item } diff --git a/components/comment.js b/components/comment.js index b76dfdbe..870082f9 100644 --- a/components/comment.js +++ b/components/comment.js @@ -42,7 +42,7 @@ function Parent ({ item }) { ) } -export default function Comment ({ item, children, replyOpen, includeParent, cacheId, noReply }) { +export default function Comment ({ item, children, replyOpen, includeParent, cacheId, noComments, noReply }) { const [reply, setReply] = useState(replyOpen) return ( @@ -82,7 +82,7 @@ export default function Comment ({ item, children, replyOpen, includeParent, cac {reply && setReply(replyOpen || false)} cacheId={cacheId} />} {children}
- {item.comments + {item.comments && !noComments ? item.comments.map((item) => ( )) diff --git a/components/comments.js b/components/comments.js index c9e7b60b..b1b82e9c 100644 --- a/components/comments.js +++ b/components/comments.js @@ -1,23 +1,31 @@ import { useQuery } from '@apollo/client' import Comment, { CommentSkeleton } from './comment' -export default function Comments ({ query, ...props }) { - const { loading, error, data } = useQuery(query) - - if (error) return
Failed to load!
- if (loading) { - const comments = new Array(3).fill(null) - - return comments.map((_, i) => ( -
- -
- )) - } - - return data.comments.map(item => ( +export default function Comments ({ comments, ...props }) { + return comments.map(item => (
)) } + +export function CommentsSkeleton () { + const comments = new Array(3).fill(null) + + return comments.map((_, i) => ( +
+ +
+ )) +} + +export function CommentsQuery ({ query, ...props }) { + const { loading, error, data } = useQuery(query) + + if (error) return
Failed to load!
+ if (loading) { + return + } + + return +} diff --git a/components/item.js b/components/item.js index 1badb1cc..8f37dabc 100644 --- a/components/item.js +++ b/components/item.js @@ -45,7 +45,7 @@ export default function Item ({ item, rank, children }) { ) } -export function ItemSkeleton ({ rank }) { +export function ItemSkeleton ({ rank, children }) { return ( <> {rank && @@ -66,6 +66,11 @@ export function ItemSkeleton ({ rank }) {
+ {children && ( +
+ {children} +
+ )} ) } diff --git a/components/reply.js b/components/reply.js index 72780cc1..b6923ac6 100644 --- a/components/reply.js +++ b/components/reply.js @@ -8,7 +8,7 @@ export const CommentSchema = Yup.object({ text: Yup.string().required('required').trim() }) -export default function Reply ({ parentId, onSuccess, cacheId }) { +export default function Reply ({ parentId, onSuccess }) { const [createComment] = useMutation( gql` ${COMMENTS} @@ -22,7 +22,7 @@ export default function Reply ({ parentId, onSuccess, cacheId }) { }`, { update (cache, { data: { createComment } }) { cache.modify({ - id: cacheId || `Item:${parentId}`, + id: `Item:${parentId}`, fields: { comments (existingCommentRefs = []) { const newCommentRef = cache.writeFragment({ @@ -67,3 +67,12 @@ export default function Reply ({ parentId, onSuccess, cacheId }) { ) } + +export function ReplySkeleton () { + return ( +
+
+
+
+ ) +} diff --git a/components/reply.module.css b/components/reply.module.css index 4d060507..9fbca204 100644 --- a/components/reply.module.css +++ b/components/reply.module.css @@ -1,4 +1,20 @@ .reply { max-width: 600px; margin-top: 1rem; +} + +.skeleton .input { + background-color: grey; + width: 100%; + border-radius: .4rem; + height: 115px; + margin-bottom: 1rem; +} + +.skeleton .button { + background-color: grey; + border-radius: .4rem; + margin-top: .25rem; + width: 71px; + height: 38px; } \ No newline at end of file diff --git a/pages/[username]/comments.js b/pages/[username]/comments.js index bdf50afd..129e3ea2 100644 --- a/pages/[username]/comments.js +++ b/pages/[username]/comments.js @@ -1,12 +1,12 @@ import Layout from '../../components/layout' -import Comments from '../../components/comments' +import { CommentsQuery } from '../../components/comments' import { COMMENT_FIELDS } from '../../fragments/comments' import { gql } from '@apollo/client' import ApolloClient from '../../api/client' import UserHeader from '../../components/user-header' -export async function getServerSideProps ({ params }) { - const { error, data: { user } } = await ApolloClient.query({ +export async function getServerSideProps ({ req, params }) { + const { error, data: { user } } = await (await ApolloClient(req)).query({ query: gql`{ user(name: "${params.username}") { @@ -46,7 +46,7 @@ export default function User ({ user }) { return ( - + ) } diff --git a/pages/items/[id].js b/pages/items/[id].js index 66442be0..62c5c6d6 100644 --- a/pages/items/[id].js +++ b/pages/items/[id].js @@ -1,64 +1,72 @@ -import Item from '../../components/item' +import Item, { ItemSkeleton } from '../../components/item' import Layout from '../../components/layout' -import ApolloClient from '../../api/client' -import Reply from '../../components/reply' +import Reply, { ReplySkeleton } from '../../components/reply' import Comment from '../../components/comment' import Text from '../../components/text' -import Comments from '../../components/comments' +import Comments, { CommentsSkeleton } from '../../components/comments' import { COMMENTS } from '../../fragments/comments' import { ITEM_FIELDS } from '../../fragments/items' -import { gql } from '@apollo/client' - -export async function getServerSideProps ({ req, params }) { - const { error, data: { item } } = await (await ApolloClient(req)).query({ - query: - gql` - ${ITEM_FIELDS} - { - item(id: ${params.id}) { - ...ItemFields - text - } - }` - }) - - if (!item || error) { - return { - notFound: true - } - } - - return { - props: { - item: item - } - } -} +import { gql, useQuery } from '@apollo/client' +import { useRouter } from 'next/router' export default function FullItem ({ item }) { - const commentsQuery = gql` + const router = useRouter() + const { id } = router.query + + const query = gql` + ${ITEM_FIELDS} ${COMMENTS} { - comments(parentId: ${item.id}) { - ...CommentsRecursive - } + item(id: ${id}) { + ...ItemFields + text + comments { + ...CommentsRecursive + } + } }` return ( + + + ) +} + +function LoadItem ({ query }) { + const { loading, error, data } = useQuery(query) + if (error) return
Failed to load!
+ + if (loading) { + return ( +
+ + + +
+ +
+
+ ) + } + + const { item } = data + + return ( + <> {item.parentId - ? + ? : ( <> {item.text && {item.text}} - + )}
- +
- + ) } diff --git a/styles/globals.scss b/styles/globals.scss index a751e4bf..98601fa2 100644 --- a/styles/globals.scss +++ b/styles/globals.scss @@ -82,12 +82,12 @@ $container-max-widths: ( } @keyframes flash { - from { filter: brightness(1); background-position: 0 0;} + from { filter: brightness(1);} 2% { filter: brightness(2.3); } 4% { filter: brightness(1.4); } 8% { filter: brightness(3); } 16% { filter: brightness(1); } - to { filter: brightness(1); background-position: 250px 0;} + to { filter: brightness(1);} } .clouds {