Skip to content

feat(comments): replace the legacy options menu with the post options sheet - #3405

Merged
feruzm merged 2 commits into
developmentfrom
feature/comment-options-parity
Aug 1, 2026
Merged

feat(comments): replace the legacy options menu with the post options sheet#3405
feruzm merged 2 commits into
developmentfrom
feature/comment-options-parity

Conversation

@feruzm

@feruzm feruzm commented Aug 1, 2026

Copy link
Copy Markdown
Member

Closes #3394

Five comment surfaces never used PostOptionsModal. They fell back to the menu in commentsView.tsx, which offered four items: copy link, copy text, open thread, cancel.

  • src/screens/botComments/screen/botComments.tsx
  • src/components/commentsDisplay/view/commentsDisplayView.tsx
  • src/components/commentsModal/container/commentsModal.tsx
  • src/components/profile/children/wavesTabContent.tsx
  • src/components/profile/children/commentsTabContent.tsx

On those screens a comment had no delete, edit, report, pin, translate, bookmark or moderation action. The fallback now mounts PostOptionsModal, so they get what the post detail screen already had. Surfaces that pass handleOnOptionsPress (waves) keep routing to their own sheet, unchanged.

The two actions that would have been silently dropped

PostOptionsModal had no equivalent for two of the legacy menu's items, so a straight swap would have quietly removed them. Both are added instead:

  • copy-text copies a plain-text summary via postBodySummary, so links and images do not come through as raw markdown, matching the old behaviour exactly. Offered wherever the content has a body.
  • open-thread is delegated through a new optional onOpenThread prop and only offered where a handler is given, since only comment surfaces can open a thread. It defers with await delay(700) like the other cases that leave the sheet.

Labels go in post_dropdown lowercase, matching the block: the sheet uppercases at render.

Things worth knowing, not changed here

  • The sheet offers reblog and cross-post on comments. That is pre-existing: post detail comments already route through PostOptionsModal, so those have been shown on comments all along. This change makes them visible on five more surfaces. Gating them on depth === 0 would be a behaviour change to the post detail screen too, so it belongs in its own issue rather than riding along here.
  • commentsModal is documented as draft. Its own source note says actions "do not respond as expected since most of action rely on modals and action sheets which causes a conflict". That conflict is unchanged: the legacy OptionsModal was also an ActionSheet, so this swaps one nested sheet for another. Not fixed, not made worse.

Cleanup

_handleOnPressCommentMenu and the handleOnPressCommentMenu prop are removed, along with four imports in commentsContainer that only it used.

Testing

  • yarn test:ci: 730 passed, 1 skipped, 49 suites.
  • yarn lint: 0 errors.
  • Grepped for dangling references to the removed prop: none.

Device checks, ideally on a profile comments tab and the waves tab:

  • Confirm the sheet opens with the full action set rather than four items.
  • Confirm copy link and copy text both work, and that copy text is plain, not markdown.
  • Confirm open thread navigates, and that it is absent on the post detail screen where no handler is passed.
  • Confirm delete only appears on your own comment, and that it works.
  • As a community moderator, confirm mute/unmute now appears on comments on these surfaces.
  • Confirm the waves tab still uses its own sheet and is unchanged.

Summary by CodeRabbit

  • New Features
    • Added options to copy post text and open a discussion thread from comment views.
    • Added localized labels for the new post actions.
  • Changes
    • Comment actions now use the post options modal, while existing deletion and navigation behavior remains available.

… sheet

Five comment surfaces never used PostOptionsModal. They fell back to the
menu in commentsView, which offered four items: copy link, copy text,
open thread, cancel. On botComments, commentsDisplay, commentsModal and
the profile waves and comments tabs, a comment had no delete, edit,
report, pin, translate, bookmark or moderation action at all.

The fallback now mounts PostOptionsModal, so every comment surface gets
the same actions the post detail screen already had. Surfaces that pass
handleOnOptionsPress (waves) keep routing to their own sheet.

Two actions the legacy menu had were missing from the sheet, so they are
added rather than dropped:

- copy-text copies a plain-text summary, so links and images do not come
  through as markdown syntax, matching what the old menu did. Offered
  wherever the content has a body.
- open-thread is delegated through a new optional onOpenThread prop and
  is offered only where a handler is given, since only comment surfaces
  can open a thread. It defers like the other cases that leave the sheet.

The dead legacy handler and its now-unused imports are removed from
commentsContainer.
@greptile-apps

greptile-apps Bot commented Aug 1, 2026

Copy link
Copy Markdown

Greptile Summary

The PR replaces the legacy comment menu with the shared post-options sheet while preserving copy-text, open-thread, and in-place deletion behavior.

  • Adds comment-specific copy-text and open-thread actions to PostOptionsModal.
  • Routes deletion through the comments container so embedded comment lists update without navigating away.
  • Removes the legacy menu handler and adds English labels for the new actions.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains; the previously reported deletion navigation issue is fixed by delegating deletion to the comments container and returning before the modal fallback can navigate back.

Important Files Changed

Filename Overview
src/components/comments/container/commentsContainer.tsx Removes the legacy menu callback while retaining the internal comment deletion and thread-opening behavior.
src/components/comments/view/commentsView.tsx Replaces the legacy options modal with PostOptionsModal and correctly adapts deletion to the container callback.
src/components/postOptionsModal/container/postOptionsModal.tsx Adds gated copy-text and open-thread actions while preserving delegated deletion behavior.
src/constants/options/post.ts Registers the two new actions in the shared post-options ordering.
src/config/locales/en-US.json Adds valid English labels for copy-text and open-thread.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A[User opens comment options] --> B{Custom options handler?}
  B -->|Yes| C[Open surface-specific sheet]
  B -->|No| D[Open PostOptionsModal]
  D --> E{Selected action}
  E -->|Copy text| F[Create plain-text summary and copy]
  E -->|Open thread| G[Delegate to onOpenThread]
  E -->|Delete| H[Delegate to CommentsContainer]
  H --> I[Delete comment and update list in place]
Loading

Reviews (2): Last reviewed commit: "fix(comments): delegate delete, and scop..." | Re-trigger Greptile

Comment thread src/components/comments/view/commentsView.tsx

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

Copy link
Copy Markdown

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: e4d22ea3ba

ℹ️ 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".

Comment on lines +177 to +180
<PostOptionsModal
ref={postOptionsModalRef}
isVisibleTranslateModal={true}
onOpenThread={_openReplyThread}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Route comment deletion through the list handler

When a user selects Delete for an owned, deletable comment on any newly converted list surface, this modal receives no onDelete, so PostOptionsModal falls through to its default deletion path, which calls navigation.goBack() instead of the existing handleDeleteComment. This unexpectedly closes the profile/bot-comments screen and leaves the deleted item in the list state; on the profile Waves tab it also bypasses wavesQuery.deleteWave and therefore its infinite-query cache update. Pass a deletion callback that delegates to the existing comment/wave handler rather than using the modal default.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Confirmed and fixed in a371e95. Both of you flagged this independently and it was the real defect in the PR.

Traced it: _deletePost only delegates when onDelete is present (postOptionsModal.tsx:451); otherwise it runs its own mutation and calls navigation.goBack() at :478. On a profile tab or bot-comments screen that pops the screen the list is embedded in. It also skips the container's in-place list removal, and on waves it bypasses the PostTypes.WAVE branch of _handleDeleteComment that routes through handleCommentDelete.

The list already had the right handler; the sheet just was not given it. commentsView now passes onDelete forwarding to handleDeleteComment with the same five arguments the inline delete button uses (commentView.tsx:317-323), so permlink, parent and root all arrive as they did before:

const _handleDeleteFromMenu = (item) =>
  handleDeleteComment(
    item.permlink, item.parent_permlink, item.parent_author,
    item.root_author, item.root_permlink,
  );

Worth noting this is exactly the failure mode the existing comment on _deletePost warns about for waves. The comment was there; I did not apply it when adding a new consumer.

@coderabbitai

coderabbitai Bot commented Aug 1, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@feruzm, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 22 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: bc66831c-cf8a-4094-b1a2-70b4a76e1030

📥 Commits

Reviewing files that changed from the base of the PR and between e4d22ea and a371e95.

📒 Files selected for processing (2)
  • src/components/comments/view/commentsView.tsx
  • src/components/postOptionsModal/container/postOptionsModal.tsx
📝 Walkthrough

Walkthrough

CommentsView now uses PostOptionsModal for comment actions when no external handler is provided. PostOptionsModal adds conditional copy-text and open-thread actions with localization and platform-specific text summarization.

Changes

Comment options

Layer / File(s) Summary
Post options action support
src/components/postOptionsModal/..., src/constants/options/post.ts, src/config/locales/en-US.json
PostOptionsModal supports conditional copy-text and open-thread actions. It copies plain-text post summaries and invokes onOpenThread after the sheet closes.
Comment surface modal wiring
src/components/comments/container/commentsContainer.tsx, src/components/comments/view/commentsView.tsx
CommentsView replaces the legacy options menu with PostOptionsModal. CommentsContainer removes the legacy menu handler and related props. Existing external options routing remains available.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related PRs

Poem

A rabbit taps the options tray,
Copying words in a tidy way.
Threads now open when called to start,
Old menus hop away from the chart.
“Squeak!” says the bunny, “clean and bright!”

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes replacing the legacy comment options menu with the post options sheet.
Linked Issues check ✅ Passed The changes implement options parity by routing secondary comment surfaces through PostOptionsModal and preserving copy-text and open-thread actions for issue [#3394].
Out of Scope Changes check ✅ Passed The changes are limited to replacing the legacy comment menu, preserving its actions, and adding the required modal options and localization.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ 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 feature/comment-options-parity

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/components/comments/view/commentsView.tsx`:
- Around line 52-53: Update the upvotePopoverRef declaration to call useRef with
an initial null value, and apply the available popover handle type if one is
defined nearby; leave postOptionsModalRef unchanged.
- Around line 177-180: Update the delete eligibility logic used by
PostOptionsModal, specifically _canDeletePost, to safely handle a missing
currentAccount before accessing its name. Preserve deletion behavior for
authenticated accounts while returning an ineligible result for anonymous access
or when no current account exists, including when _openCommentMenu() opens the
modal.

In `@src/components/postOptionsModal/container/postOptionsModal.tsx`:
- Around line 852-860: Update the copy-text case in the post options handler to
await and store the boolean result from writeToClipboard(_body), then schedule
the alert.copied toast only when that result is true. Base the check on the
generated summary rather than _canCopyText’s raw Markdown validation, preserving
the existing clipboard and timer behavior for successful copies.
- Around line 248-252: Update the copy-text eligibility logic in the post
options modal, specifically _canCopyText, to require both comment context via
isComment and content?.markdownBody. Ensure normal posts cannot receive the
copy-text action while preserving copying for comments with a body.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 207114a6-44d8-46fd-8a04-338be0ec63f2

📥 Commits

Reviewing files that changed from the base of the PR and between efb4f31 and e4d22ea.

📒 Files selected for processing (5)
  • src/components/comments/container/commentsContainer.tsx
  • src/components/comments/view/commentsView.tsx
  • src/components/postOptionsModal/container/postOptionsModal.tsx
  • src/config/locales/en-US.json
  • src/constants/options/post.ts
💤 Files with no reviewable changes (1)
  • src/components/comments/container/commentsContainer.tsx

Comment thread src/components/comments/view/commentsView.tsx
Comment thread src/components/comments/view/commentsView.tsx
Comment thread src/components/postOptionsModal/container/postOptionsModal.tsx Outdated
Comment thread src/components/postOptionsModal/container/postOptionsModal.tsx
Three review findings.

Delete was falling through to the sheet's own path on every converted
surface, which calls navigation.goBack() and would pop the profile or
bot-comments screen the list is embedded in. It also skipped the
container's in-place list removal and, on waves, the wave-specific delete
that updates the infinite-query cache. The sheet now receives an onDelete
that forwards to the list's existing handler with the same arguments the
inline delete button uses.

copy-text and open-thread were documented as comment-only but gated only
on a body and a handler, so copy-text would have appeared on the post
detail sheet too. Both are now scoped to content with a parent, so post
detail is unchanged.

The copy-text success toast fired on attempt rather than result.
writeToClipboard returns false for empty text, and the plain-text summary
can be empty where a comment body is only an image or markup, so that
path could report a copy that never happened.
@feruzm
feruzm merged commit d89f1d7 into development Aug 1, 2026
15 checks passed
@feruzm
feruzm deleted the feature/comment-options-parity branch August 1, 2026 07:59
feruzm added a commit that referenced this pull request Aug 1, 2026
…mation

Two review findings, both regressions in the previous commit.

postScreen renders comments and waves as primary content, so gating
navigation.goBack() on parent_author left a comment's own detail screen
showing content that had just been deleted. Content shape cannot
distinguish 'comment in a list' from 'comment as the screen' - only the
caller knows - so the fallback pops unconditionally again and consumers
that own a list must pass onDelete. #3407 tracks inverting this into an
explicit opt-in, which is the version that fails safe.

The delete delegation also asked twice: PostOptionsModal confirms before
invoking onDelete, and _handleDeleteComment then confirmed again, so one
action needed two confirmations and could be cancelled at the second
after being confirmed at the first.

Splits that handler in two. _deleteCommentConfirmed mutates without
prompting and is what the sheet delegates to; _handleDeleteComment
prompts and then calls it, for the inline delete button which has no
confirmation of its own.

commentsContainer has no confirmation step, so the equivalent path added
in #3405 was never affected.
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.

feat(comments): replace the legacy options menu on secondary comment surfaces

1 participant