Skip to content

Support editing comments and replies on the frontend - #247

Open
ruibaby wants to merge 4 commits into
mainfrom
feat/edit-comment-content
Open

ruibaby wants to merge 4 commits into
mainfrom
feat/edit-comment-content

Conversation

@ruibaby

@ruibaby ruibaby commented Sep 14, 2026

Copy link
Copy Markdown
Member

Port the comment content editing capability from Halo Console (halo-dev/halo#10302) to the comment widget, so users with comment management permission can edit comment and reply bodies directly on the frontend.

  • Add an "Edit" entry to the per-comment/reply management dropdown, shown only to users with the system:comments:manage permission and hidden for deleted targets
  • Open an inline editor in place of the content, reusing the widget's rich text editor; the latest body and resource version are loaded when the editor opens
  • Save through the new PUT /apis/api.console.halo.run/v1alpha1/{comments|replies}/{name}/content endpoints with raw, content, and the loaded version, preserving moderation state and authorship
  • Match Console error handling: a 409 conflict (stale version) keeps the draft and asks the user to reopen the editor; load failures and already-deleted targets show inline messages
  • Disable image upload while editing, because the widget's upload tickets bind to comment creation and the content endpoint does not accept upload bindings; existing images remain editable
  • Fix the editor focus ring being clipped on three sides in editing state by disabling content-visibility: auto paint containment on the item content container while editing

Requires a Halo version that includes halo-dev/halo#10302. On older versions, saving fails with an inline error and the draft is kept; nothing else in the widget is affected.

Validation:

  • pnpm build, tsc --noEmit, biome check, and vitest run (122 tests) all pass
  • Manually verified in the example app against a local Halo instance: opening the editor, save button enablement, and light/dark appearance

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 14, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-20T08:54:45.920423Z d637f87 New commits
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

- Preserve newlines and consecutive spaces when editing plain-text
  comments created from the Console textarea editor
- Show a dedicated message when saving fails with 404 on Halo
  versions without the content endpoints
- Allow canceling while the latest content is loading and retrying
  after a load failure
- Focus the editor once it is ready and confirm before discarding
  unsaved changes
- Rename the generic close event to edit-close
- Cover the new content endpoints and plain-text conversion with tests

@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: e68dda894f

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

@@ -12,3 +12,31 @@ export function cleanHtml(content?: string) {
},
});
}

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 Escape tag-shaped text before loading the editor

When a plain-text Console comment contains literal code such as Use <T> here, this pattern classifies the entire value as HTML. Tiptap then parses <T> as an element rather than text, so the literal token disappears and saving any subsequent edit silently corrupts the original comment. Determine the source format without relying on a tag-shaped substring, or escape raw plain text before passing it to Tiptap.

Useful? React with 👍 / 👎.

Comment on lines +109 to +110
} catch {
this.loadFailed = true;

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 Treat a missing resource as deleted during loading

If another administrator fully deletes the comment after this stale list row was rendered but before the editor fetch completes, the resource endpoint returns 404 and this catch reports a retryable load failure. Retrying can never succeed, and the dedicated deleted state is only reached when a still-terminating resource is returned with deletionTimestamp; inspect a 404 here and show the deleted-target state instead.

Useful? React with 👍 / 👎.

- Join plain-text lines with hard breaks instead of paragraphs so line
  spacing matches the pre-wrap rendering of existing comments
- Keep existing HTML entities encoded once and expand tabs
- Treat angle-bracket text that cleaning would strip as plain text
- Record the editor-normalized content as the dirty-check baseline so
  undoing back to the original no longer prompts or enables save
- Cover concurrent deletion in the 404 save error message

@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: ab186fb9b4

ℹ️ 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 +128 to +130
for (let i = 0; i < 100 && !editor.editor && this.isConnected; i++) {
await new Promise((resolve) => setTimeout(resolve, 50));
}

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 Wait for editor initialization without a fixed timeout

On a slow connection or device where the editor's dynamic imports and draft initialization take more than five seconds, this polling loop exits before editor.editor exists. Nothing subsequently initializes baseline, so dirty remains false and the Save button cannot be enabled even after the user edits the content. Use an editor-ready signal or otherwise initialize the baseline whenever editor creation eventually completes.

Useful? React with 👍 / 👎.

return html`
<comment-editor
${ref(this.editorRef)}
.initialContent=${this.editorContent}

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 Preserve HTML nodes the editor cannot represent

When an existing comment contains supported display HTML outside the editor schema, passing it into this editor normalizes or drops that markup before any user action; for example, cleanHtml retains headings while comment-editor.ts explicitly configures heading: false. Saving an unrelated text change therefore silently converts or removes the original structure. Either add extensions for the HTML accepted by the renderer or prevent editing without preserving unsupported nodes.

Useful? React with 👍 / 👎.

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.

1 participant