Skip to content

Fixed hidden comments collapsing threaded replies#28123

Merged
jonatansberg merged 5 commits into
mainfrom
ber-3677-hidden-comments-collapse-thread
May 27, 2026
Merged

Fixed hidden comments collapsing threaded replies#28123
jonatansberg merged 5 commits into
mainfrom
ber-3677-hidden-comments-collapse-thread

Conversation

@jonatansberg
Copy link
Copy Markdown
Member

@jonatansberg jonatansberg commented May 26, 2026

Summary

  • Stack follow-up fixes on top of Fixed threaded comments handling of hidden/deleted replies #28024 for hidden/deleted threaded comment tombstones
  • Scope non-page reply tombstone CTEs to the loaded comment to avoid broad table materialization
  • Preserve admin-visible hidden replies during local delete handling
  • Prune structural leaf tombstones from comments-ui state when they no longer have loaded descendants
  • Bump @tryghost/comments-ui to 1.5.4

Context

This is stacked on #28024, which introduces the server-side threaded comment tombstone selection. These commits address the follow-up review findings around query scope, local comments-ui state after deleting replies in deep threads, and the package version bump needed for the public comments-ui change.

ref https://linear.app/ghost/issue/BER-3677/hidden-comments-collapse-thread-nesting-incorrectly

Testing

  • pnpm --dir ghost/core test:single test/unit/server/models/comment.test.js
  • pnpm --filter @tryghost/comments-ui test:unit -- actions.test.js thread-graph.test.ts comment.test.jsx

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 26, 2026

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 82f8a43a-3fb4-4037-8fbd-402a4d0c9c90

📥 Commits

Reviewing files that changed from the base of the PR and between f4f1c7c and 9d9e215.

⛔ Files ignored due to path filters (1)
  • ghost/core/test/e2e-api/members-comments/__snapshots__/comments.test.js.snap is excluded by !**/*.snap
📒 Files selected for processing (9)
  • apps/comments-ui/package.json
  • apps/comments-ui/src/actions.ts
  • apps/comments-ui/src/app-context.ts
  • apps/comments-ui/test/unit/actions.test.js
  • apps/comments-ui/test/unit/utils/thread-graph.test.ts
  • ghost/core/core/server/models/comment.js
  • ghost/core/test/e2e-api/admin/comments.test.js
  • ghost/core/test/e2e-api/members-comments/comments.test.js
  • ghost/core/test/unit/server/models/comment.test.js

Walkthrough

This PR implements tombstone preservation for deleted and hidden comments that have visible descendants. The feature uses a recursive CTE query to identify displayable comment IDs while preserving thread structure through redacted (HTML-cleared) intermediate comments. The frontend deletion logic conditionally keeps deleted replies as tombstones when they have descendants, prunes orphaned tombstones, and updates reply counts accordingly. The backend query model computes displayable IDs, filters replies using parent scope, and includes documentation clarifying that reply counts reflect visible content only. Comprehensive E2E tests verify tombstone inclusion/exclusion across admin and member API endpoints, including pagination and ordering semantics.

Suggested reviewers

  • rob-ghost
  • 9larsons
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ber-3677-hidden-comments-collapse-thread

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ast-grep (0.42.3)
ghost/core/test/e2e-api/admin/comments.test.js
ghost/core/test/e2e-api/members-comments/comments.test.js

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@nx-cloud
Copy link
Copy Markdown

nx-cloud Bot commented May 26, 2026

🤖 Nx Cloud AI Fix

Ensure the fix-ci command is configured to always run in your CI pipeline to get automatic fixes in future runs. For more information, please see https://nx.dev/ci/features/self-healing-ci


View your CI Pipeline Execution ↗ for commit ef3c2a5

Command Status Duration Result
nx run ghost:test:ci:integration ✅ Succeeded 2m 6s View ↗
nx run ghost:test:ci:e2e ✅ Succeeded 7m 47s View ↗
nx run ghost:test:ci:legacy ✅ Succeeded 3m 8s View ↗
nx build @tryghost/announcement-bar ✅ Succeeded <1s View ↗
nx build @tryghost/activitypub ✅ Succeeded 2s View ↗
nx build @tryghost/signup-form ✅ Succeeded <1s View ↗
nx build @tryghost/sodo-search ✅ Succeeded <1s View ↗
nx build @tryghost/portal ✅ Succeeded <1s View ↗
Additional runs (8) ✅ Succeeded ... View ↗

☁️ Nx Cloud last updated this comment at 2026-05-26 09:24:27 UTC

@jonatansberg jonatansberg force-pushed the ber-3677-hidden-comments-collapse-thread branch 2 times, most recently from edb99d3 to c3b432d Compare May 27, 2026 07:15
kevinansfield and others added 5 commits May 27, 2026 09:30
ref https://linear.app/ghost/issue/BER-3677/hidden-comments-collapse-thread-nesting-incorrectly

Comment APIs need to return hidden/deleted tombstones when they preserve the path to visible descendants. This uses a post-scoped path-based recursive SQL query for displayable comment IDs, keeps reply counts tied to visible comments, preserves local deleted reply tombstones while descendants are loaded, and bumps Comments UI for release.
ref https://linear.app/ghost/issue/BER-3677/hidden-comments-collapse-thread-nesting-incorrectly

Single-comment reads and mutation responses should not build displayable reply paths across the full comments table when the loaded comment already gives us the reply parent scope.
ref https://linear.app/ghost/issue/BER-3677/hidden-comments-collapse-thread-nesting-incorrectly

Hidden comments are visible and actionable for admins, so local delete handling should only treat them as structural tombstones for member-facing state.
ref https://linear.app/ghost/issue/BER-3677/hidden-comments-collapse-thread-nesting-incorrectly

Local delete handling should not retain structural placeholder replies once they have no loaded descendants, because they render no content but still affect reply state.
ref https://linear.app/ghost/issue/BER-3677/hidden-comments-collapse-thread-nesting-incorrectly

The stacked comments-ui changes need their own package version bump so CI and release checks see the public app change.
@jonatansberg jonatansberg force-pushed the ber-3677-hidden-comments-collapse-thread branch from 8c7c316 to 9d9e215 Compare May 27, 2026 07:31
@jonatansberg jonatansberg marked this pull request as ready for review May 27, 2026 08:12
@jonatansberg jonatansberg merged commit c0aa1ce into main May 27, 2026
47 of 48 checks passed
@jonatansberg jonatansberg deleted the ber-3677-hidden-comments-collapse-thread branch May 27, 2026 08:14
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9d9e215a6a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

// pagination displays the correct number of replies still to load
if (hasDeletedReply && topLevelComment.count?.replies) {
topLevelComment.count.replies = topLevelComment.count.replies - 1;
if (hasDeletedReply && replyToDelete && !['hidden', 'deleted'].includes(replyToDelete.status)) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Decrement counts when deleting hidden admin replies

When state.isAdmin is true, hidden replies are still admin-visible and the backend counts them because count.replies/count.direct_replies only exclude deleted for admin requests. This guard skips count updates for hidden replies, so deleting a hidden reply in the admin UI leaves the parent’s reply counts overstated until a refetch, which can make the remaining-replies pagination/counts incorrect.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Admins can only hide comments so this edge won't be hit

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants