From efdcbef733dda51617154c82b46ec52bd4b52378 Mon Sep 17 00:00:00 2001 From: k00b Date: Thu, 30 Jan 2025 19:19:49 -0600 Subject: [PATCH] fixes related to comment paging --- components/comment.js | 25 ++++++++-- components/reply.js | 17 ------- lib/item.js | 4 +- .../migration.sql | 49 +++++++++++++++++++ 4 files changed, 72 insertions(+), 23 deletions(-) create mode 100644 prisma/migrations/20250131010955_fix_anon_comments_depth/migration.sql diff --git a/components/comment.js b/components/comment.js index 5076a42f..86654dcb 100644 --- a/components/comment.js +++ b/components/comment.js @@ -2,7 +2,7 @@ import itemStyles from './item.module.css' import styles from './comment.module.css' import Text, { SearchText } from './text' import Link from 'next/link' -import Reply, { ReplyOnAnotherPage } from './reply' +import Reply from './reply' import { useEffect, useMemo, useRef, useState } from 'react' import UpVote from './upvote' import Eye from '@/svgs/eye-fill.svg' @@ -27,6 +27,7 @@ import Pin from '@/svgs/pushpin-fill.svg' import LinkToContext from './link-to-context' import Boost from './boost-button' import { gql, useApolloClient } from '@apollo/client' +import classNames from 'classnames' function Parent ({ item, rootText }) { const root = useRoot() @@ -142,7 +143,7 @@ export default function Comment ({ } }, [item.id]) - const bottomedOut = depth === COMMENT_DEPTH_LIMIT + const bottomedOut = depth === COMMENT_DEPTH_LIMIT || (item.comments?.comments.length === 0 && item.nDirectComments > 0) // Don't show OP badge when anon user comments on anon user posts const op = root.user.name === item.user.name && Number(item.user.id) !== USER_ID.anon ? 'OP' @@ -244,7 +245,7 @@ export default function Comment ({ {collapse !== 'yep' && ( bottomedOut - ?
+ ?
: (
{item.outlawed && !me?.privates?.wildWestMode @@ -261,7 +262,7 @@ export default function Comment ({ {item.comments.comments.map((item) => ( ))} - {item.comments.comments.length < item.nDirectComments && } + {item.comments.comments.length < item.nDirectComments && } ) : null} @@ -286,6 +287,22 @@ export function ViewAllReplies ({ id, nshown, nhas }) { ) } +function ReplyOnAnotherPage ({ item }) { + const root = useRoot() + const rootId = commentSubTreeRootId(item, root) + + let text = 'reply on another page' + if (item.ncomments > 0) { + text = `view all ${item.ncomments} replies` + } + + return ( + + {text} + + ) +} + export function CommentSkeleton ({ skeletonChildren }) { return (
diff --git a/components/reply.js b/components/reply.js index e901298c..0928ccdf 100644 --- a/components/reply.js +++ b/components/reply.js @@ -3,7 +3,6 @@ import styles from './reply.module.css' import { COMMENTS } from '@/fragments/comments' import { useMe } from './me' import { forwardRef, useCallback, useEffect, useState, useRef, useMemo } from 'react' -import Link from 'next/link' import { FeeButtonProvider, postCommentBaseLineItems, postCommentUseRemoteLineItems } from './fee-button' import { commentsViewedAfterComment } from '@/lib/new-comments' import { commentSchema } from '@/lib/validate' @@ -11,26 +10,10 @@ import { ItemButtonBar } from './post' import { useShowModal } from './modal' import { Button } from 'react-bootstrap' import { useRoot } from './root' -import { commentSubTreeRootId } from '@/lib/item' import { CREATE_COMMENT } from '@/fragments/paidAction' import useItemSubmit from './use-item-submit' import gql from 'graphql-tag' -export function ReplyOnAnotherPage ({ item }) { - const rootId = commentSubTreeRootId(item) - - let text = 'reply on another page' - if (item.ncomments > 0) { - text = 'view replies' - } - - return ( - - {text} - - ) -} - export default forwardRef(function Reply ({ item, replyOpen, diff --git a/lib/item.js b/lib/item.js index cecdb1a1..7bde10af 100644 --- a/lib/item.js +++ b/lib/item.js @@ -105,8 +105,8 @@ export const deleteReminders = async ({ id, userId, models }) => { }) } -export const commentSubTreeRootId = (item) => { - if (item.root?.ncomments > FULL_COMMENTS_THRESHOLD) { +export const commentSubTreeRootId = (item, root) => { + if (item.root?.ncomments > FULL_COMMENTS_THRESHOLD || root?.ncomments > FULL_COMMENTS_THRESHOLD) { return item.id } diff --git a/prisma/migrations/20250131010955_fix_anon_comments_depth/migration.sql b/prisma/migrations/20250131010955_fix_anon_comments_depth/migration.sql new file mode 100644 index 00000000..5d252bfd --- /dev/null +++ b/prisma/migrations/20250131010955_fix_anon_comments_depth/migration.sql @@ -0,0 +1,49 @@ +-- add limit and offset +CREATE OR REPLACE FUNCTION item_comments_limited( + _item_id int, _limit int, _offset int, _grandchild_limit int, + _level int, _where text, _order_by text) + RETURNS jsonb + LANGUAGE plpgsql VOLATILE PARALLEL SAFE AS +$$ +DECLARE + result jsonb; +BEGIN + IF _level < 1 THEN + RETURN '[]'::jsonb; + END IF; + + EXECUTE 'CREATE TEMP TABLE IF NOT EXISTS t_item ON COMMIT DROP AS ' + || 'WITH RECURSIVE base AS ( ' + || ' (SELECT "Item".*, 1 as level, ROW_NUMBER() OVER () as rn ' + || ' FROM "Item" ' + || ' WHERE "Item"."parentId" = $1 ' + || _order_by || ' ' + || ' LIMIT $2 ' + || ' OFFSET $3) ' + || ' UNION ALL ' + || ' (SELECT "Item".*, b.level + 1, ROW_NUMBER() OVER (PARTITION BY "Item"."parentId" ' || _order_by || ') ' + || ' FROM "Item" ' + || ' JOIN base b ON "Item"."parentId" = b.id ' + || ' WHERE b.level < $5 AND (b.level = 1 OR b.rn <= $4)) ' + || ') ' + || 'SELECT "Item".*, "Item".created_at at time zone ''UTC'' AS "createdAt", "Item".updated_at at time zone ''UTC'' AS "updatedAt", ' + || ' "Item"."invoicePaidAt" at time zone ''UTC'' AS "invoicePaidAtUTC", ' + || ' to_jsonb(users.*) as user ' + || 'FROM base "Item" ' + || 'JOIN users ON users.id = "Item"."userId" ' + || 'WHERE ("Item".level = 1 OR "Item".rn <= $4 - "Item".level + 2) ' || _where + USING _item_id, _limit, _offset, _grandchild_limit, _level, _where, _order_by; + + + EXECUTE '' + || 'SELECT COALESCE(jsonb_agg(sub), ''[]''::jsonb) AS comments ' + || 'FROM ( ' + || ' SELECT "Item".*, item_comments_limited("Item".id, $2, $3, $4, $5 - 1, $6, $7) AS comments ' + || ' FROM t_item "Item" ' + || ' WHERE "Item"."parentId" = $1 ' + || _order_by + || ' ) sub' + INTO result USING _item_id, _limit, _offset, _grandchild_limit, _level, _where, _order_by; + RETURN result; +END +$$; \ No newline at end of file