Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAdds quote support to the note composer: PostControls opens the composer with a quoted post id; NoteComposeContext stores/clears Changes
Sequence DiagramsequenceDiagram
actor User
participant PostControls as "PostControls"
participant NoteComposeContext as "NoteComposeContext"
participant NoteComposeModal as "NoteComposeModal"
participant NoteComposer as "NoteComposer"
participant Relay as "Relay (GraphQL)"
User->>PostControls: Click "Quote" on a post
PostControls->>NoteComposeContext: open(quotedPostId)
NoteComposeContext->>NoteComposeContext: store quotedPostId, set isOpen
NoteComposeContext->>NoteComposeModal: open modal (with quotedPostId)
NoteComposeModal->>NoteComposer: render with quotedPostId & onQuoteRemoved
NoteComposer->>Relay: fetch quoted-post preview (NoteComposerQuotedPostQuery)
Relay-->>NoteComposer: return preview data
NoteComposer->>User: render quoted preview + editor
User->>NoteComposer: Click "Remove quote"
NoteComposer->>NoteComposeContext: clearQuote()
NoteComposeContext-->>NoteComposer: quotedPostId cleared
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request introduces the functionality to quote existing posts within the application. It enables users to initiate a new note composition with a reference to another post, displaying a preview of the quoted content directly within the composer. This enhancement streamlines the process of responding to or referencing other posts, improving user interaction and content linking. Highlights
🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console. Changelog
Activity
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request wires up the quote post functionality in the new web-next stack. The changes correctly update the context, modal, and composer to handle quoting a post. The implementation looks good, but I've found a critical security vulnerability (XSS), a potential runtime error, and some areas for improving robustness in data fetching that should be addressed.
| <div | ||
| class="text-sm text-muted-foreground mt-1 line-clamp-3 prose prose-sm dark:prose-invert max-w-none" | ||
| innerHTML={html()} | ||
| /> |
There was a problem hiding this comment.
Using innerHTML with content that can come from external federated sources (contentHtml) is a significant security risk, as it can lead to Cross-Site Scripting (XSS) attacks. Malicious HTML or script tags in the content could be executed in the user's browser.
To mitigate this, you must sanitize the HTML content before rendering it. A popular library for this is DOMPurify.
There was a problem hiding this comment.
This is consistent with the rest of the codebase — all HTML content is sanitized server-side via sanitizeHtml() using the xss library (FilterXSS with an allowlist) before it's stored or served through GraphQL.
The preprocessContentHtml() function calls sanitizeHtml() as its first step for all content.
References:
Lines 296 to 298 in 1463561
Lines 423 to 432 in 1463561
Lines 9 to 282 in 1463561
| setQuotedPost({ | ||
| typename: node.__typename, | ||
| contentHtml: node.content, | ||
| name: "name" in node ? (node.name ?? undefined) : undefined, | ||
| actorName: node.actor?.name ?? undefined, | ||
| actorHandle: node.actor.handle, | ||
| actorAvatarUrl: node.actor.avatarUrl, | ||
| }); |
There was a problem hiding this comment.
There's an inconsistency in how node.actor properties are accessed. node.actor?.name uses optional chaining, suggesting actor could be null, but node.actor.handle and node.actor.avatarUrl are accessed directly. If node.actor is ever null, this will cause a runtime crash.
Please add a guard to handle cases where actor might be missing, or use optional chaining consistently if the downstream components can handle undefined values (which they currently can't, as actorHandle and actorAvatarUrl are required in QuotedPostPreview).
if (!node.actor) {
setQuotedPost(null);
showToast({
title: t`Error`,
description: t`Could not load quoted post author.`,
variant: "error",
});
return;
}
setQuotedPost({
typename: node.__typename,
contentHtml: node.content,
name: "name" in node ? (node.name ?? undefined) : undefined,
actorName: node.actor.name ?? undefined,
actorHandle: node.actor.handle,
actorAvatarUrl: node.actor.avatarUrl,
});
| ).subscribe({ | ||
| next(data) { | ||
| const node = data.node; | ||
| if (!node) return; | ||
| if (node.__typename === "Note" || node.__typename === "Article") { | ||
| setQuotedPost({ | ||
| typename: node.__typename, | ||
| contentHtml: node.content, | ||
| name: "name" in node ? (node.name ?? undefined) : undefined, | ||
| actorName: node.actor?.name ?? undefined, | ||
| actorHandle: node.actor.handle, | ||
| actorAvatarUrl: node.actor.avatarUrl, | ||
| }); | ||
| } | ||
| }, | ||
| error() { | ||
| setQuotedPost(null); | ||
| }, | ||
| }); |
There was a problem hiding this comment.
The subscription logic for fetchQuery can be improved for better robustness and user experience:
- In the
nexthandler, ifdata.nodeisnull(e.g., post not found), thequotedPoststate is not cleared. This can lead to showing stale data from a previous quote. The state should be cleared. - In the
errorhandler, the fetch failure is handled silently. It would be better to show a toast notification to inform the user that loading the quoted post failed.
).subscribe({
next(data) {
const node = data.node;
if (!node) {
setQuotedPost(null);
return;
}
if (node.__typename === "Note" || node.__typename === "Article") {
setQuotedPost({
typename: node.__typename,
contentHtml: node.content,
name: "name" in node ? (node.name ?? undefined) : undefined,
actorName: node.actor?.name ?? undefined,
actorHandle: node.actor.handle,
actorAvatarUrl: node.actor.avatarUrl,
});
}
},
error(err) {
console.error("Failed to fetch quoted post:", err);
showToast({
title: t`Error`,
description: t`Failed to load quoted post.`,
variant: "error",
});
setQuotedPost(null);
},
});
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
web-next/src/components/NoteComposer.tsx (1)
44-44: Rename the query constant to avoid redeclaration with the imported type.The static analyzer correctly identifies that
NoteComposerQuotedPostQueryis declared both as an imported type (line 22) and as a const (line 44). While this works because one is a type-only import, it can cause confusion and some tooling issues.♻️ Suggested rename
-const NoteComposerQuotedPostQuery = graphql` +const noteComposerQuotedPostQuery = graphql` query NoteComposerQuotedPostQuery($id: ID!) {Then update the usage at line 116:
environment(), - NoteComposerQuotedPostQuery, + noteComposerQuotedPostQuery, { id },🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@web-next/src/components/NoteComposer.tsx` at line 44, Rename the const query to a different identifier to avoid shadowing the imported type NoteComposerQuotedPostQuery (e.g. NoteComposerQuotedPostQueryDoc or NoteComposerQuotedPost_Query) and update all usages where the query const is passed (the place that currently references NoteComposerQuotedPostQuery as the query variable inside the NoteComposer component) to the new const name; ensure imports of the type NoteComposerQuotedPostQuery remain unchanged and that only the const query identifier is renamed.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@web-next/src/components/NoteComposer.tsx`:
- Around line 127-130: The code is dereferencing node.actor (actorHandle and
actorAvatarUrl) without null checks; update the assignment in NoteComposer.tsx
to safely access actor fields—either add an early guard that returns/omits
creating the object when node.actor is null, or use optional chaining/fallbacks
(e.g., actorHandle: node.actor?.handle ?? undefined, actorAvatarUrl:
node.actor?.avatarUrl ?? undefined) so actorName, actorHandle, and
actorAvatarUrl cannot throw when node.actor is missing.
---
Nitpick comments:
In `@web-next/src/components/NoteComposer.tsx`:
- Line 44: Rename the const query to a different identifier to avoid shadowing
the imported type NoteComposerQuotedPostQuery (e.g.
NoteComposerQuotedPostQueryDoc or NoteComposerQuotedPost_Query) and update all
usages where the query const is passed (the place that currently references
NoteComposerQuotedPostQuery as the query variable inside the NoteComposer
component) to the new const name; ensure imports of the type
NoteComposerQuotedPostQuery remain unchanged and that only the const query
identifier is renamed.
ℹ️ Review info
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
web-next/src/components/AppSidebar.tsxweb-next/src/components/NoteComposeModal.tsxweb-next/src/components/NoteComposer.tsxweb-next/src/components/PostControls.tsxweb-next/src/contexts/NoteComposeContext.tsx
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (1)
web-next/src/components/NoteComposer.tsx (1)
1-4: Reorder imports so external modules come before internal modules.
~/lib/langdet.tsis currently above package imports. Please keep package imports first, then internal imports.💡 Suggested import reorder
-import { detectLanguage } from "~/lib/langdet.ts"; import { fetchQuery, graphql } from "relay-runtime"; import { createEffect, createSignal, onCleanup, Show } from "solid-js"; import { createMutation, useRelayEnvironment } from "solid-relay"; +import { detectLanguage } from "~/lib/langdet.ts";As per coding guidelines,
**/*.{ts,tsx,js,jsx}: Imports: External imports first, internal imports second (alphabetically within groups).🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@web-next/src/components/NoteComposer.tsx` around lines 1 - 4, The import order in NoteComposer.tsx is incorrect: move external package imports (fetchQuery, graphql from "relay-runtime"; createEffect, createSignal, onCleanup, Show from "solid-js"; createMutation, useRelayEnvironment from "solid-relay") above the internal import (detectLanguage from "~/lib/langdet.ts"), and alphabetize imports within each group per the project style; update the top-of-file import block so all third‑party modules appear first and the local "~/lib/langdet.ts" import comes after.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@web-next/src/components/NoteComposer.tsx`:
- Around line 257-264: In NoteComposer's remove-quote button (the button with
onClick={() => props.onQuoteRemoved?.()} that renders <IconX class="size-4" />),
add an accessible name by adding an aria-label (for example aria-label="Remove
quoted text" or similar) to the button element; keep the existing title if
desired but ensure aria-label is present so screen readers receive a reliable
name for the icon-only control.
- Around line 109-122: The NoteComposer currently risks submitting a stale
quotedPostId when the fetch for props.quotedPostId returns null/unsupported;
update the fetchQuery subscription in NoteComposer (where
NoteComposerQuotedPostQuery is used) to call setQuotedPost(null) whenever
data.node is missing or node.__typename is not "Note"/"Article" so the preview
is cleared; also ensure the submit handler (instead of reading
props.quotedPostId at submission) reads the current quotedPost state and omits
the quote from the payload or prevents submission if quotedPost is null so no
invisible/stale quote association can be sent.
- Line 22: The imported types NoteComposerQuotedPostQuery and
NoteComposerMutation conflict with template literal constants currently named
the same; rename the graphql template literal constants to camelCase
(noteComposerQuotedPostQuery and noteComposerMutation) and update all usages
where those constants are referenced (e.g., in the createFragment/commit
mutation calls that currently reference NoteComposerQuotedPostQuery and
NoteComposerMutation) so the imported types remain distinct from the runtime
constants.
---
Nitpick comments:
In `@web-next/src/components/NoteComposer.tsx`:
- Around line 1-4: The import order in NoteComposer.tsx is incorrect: move
external package imports (fetchQuery, graphql from "relay-runtime";
createEffect, createSignal, onCleanup, Show from "solid-js"; createMutation,
useRelayEnvironment from "solid-relay") above the internal import
(detectLanguage from "~/lib/langdet.ts"), and alphabetize imports within each
group per the project style; update the top-of-file import block so all
third‑party modules appear first and the local "~/lib/langdet.ts" import comes
after.
e7c8e27 to
dc3921b
Compare
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
web-next/src/components/NoteComposer.tsx (1)
188-196:⚠️ Potential issue | 🟡 MinorConsider preventing submission of unverified quote associations.
If the quoted post fetch fails or returns unsupported data,
quotedPost()will be null whileprops.quotedPostIdmay still be set. This could create a quote association that the user cannot verify in the UI.🛡️ Suggested defensive fix
input: { content: noteContent, language: language()?.baseName ?? i18n.locale, visibility: visibility(), - quotedPostId: props.quotedPostId ?? null, + quotedPostId: quotedPost() ? (props.quotedPostId ?? null) : null, },🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@web-next/src/components/NoteComposer.tsx` around lines 188 - 196, The createNote submission currently uses props.quotedPostId even when quotedPost() may be null (fetch failed or unsupported), risking creation of an unverifiable quote; update the submission logic in NoteComposer so that the variables.input.quotedPostId is only set when quotedPost() is non-null and valid (e.g., quotedPost() !== null/undefined and has expected fields); otherwise pass null. Locate the createNote call in NoteComposer and guard the quotedPostId with a conditional that prefers quotedPost() presence over props.quotedPostId to ensure the backend only receives verified quote associations.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Outside diff comments:
In `@web-next/src/components/NoteComposer.tsx`:
- Around line 188-196: The createNote submission currently uses
props.quotedPostId even when quotedPost() may be null (fetch failed or
unsupported), risking creation of an unverifiable quote; update the submission
logic in NoteComposer so that the variables.input.quotedPostId is only set when
quotedPost() is non-null and valid (e.g., quotedPost() !== null/undefined and
has expected fields); otherwise pass null. Locate the createNote call in
NoteComposer and guard the quotedPostId with a conditional that prefers
quotedPost() presence over props.quotedPostId to ensure the backend only
receives verified quote associations.
ℹ️ Review info
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (10)
web-next/src/components/AppSidebar.tsxweb-next/src/components/NoteComposeModal.tsxweb-next/src/components/NoteComposer.tsxweb-next/src/components/PostControls.tsxweb-next/src/contexts/NoteComposeContext.tsxweb-next/src/locales/en-US/messages.poweb-next/src/locales/ja-JP/messages.poweb-next/src/locales/ko-KR/messages.poweb-next/src/locales/zh-CN/messages.poweb-next/src/locales/zh-TW/messages.po
🚧 Files skipped from review as they are similar to previous changes (7)
- web-next/src/components/PostControls.tsx
- web-next/src/components/AppSidebar.tsx
- web-next/src/locales/ja-JP/messages.po
- web-next/src/locales/en-US/messages.po
- web-next/src/locales/zh-CN/messages.po
- web-next/src/locales/ko-KR/messages.po
- web-next/src/contexts/NoteComposeContext.tsx
dc3921b to
392c37c
Compare
There was a problem hiding this comment.
🧹 Nitpick comments (1)
web-next/src/components/NoteComposer.tsx (1)
44-60: Consider fetching a lightweight preview field instead of fullcontentfor quotes.The composer preview only needs a snippet, but the query pulls full HTML content. For long articles/notes this inflates payload and render cost in a hot UI path.
Also applies to: 134-139, 252-257
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@web-next/src/components/NoteComposer.tsx` around lines 44 - 60, The query NoteComposerQuotedPostQuery (and the other NoteComposer quote fetches) currently requests full HTML `content`; change those selections to a lightweight preview field instead (e.g., `contentPreview`, `excerpt`, `summary`, or use a truncation arg if your schema supports something like `content(truncate: 200)`) so the composer only pulls a short snippet and actor info; update the NoteComposerQuotedPostQuery selection set and the other two quote query locations to use that preview field and adjust any consuming JSX/props to render the snippet instead of full `content`.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@web-next/src/components/NoteComposer.tsx`:
- Around line 44-60: The query NoteComposerQuotedPostQuery (and the other
NoteComposer quote fetches) currently requests full HTML `content`; change those
selections to a lightweight preview field instead (e.g., `contentPreview`,
`excerpt`, `summary`, or use a truncation arg if your schema supports something
like `content(truncate: 200)`) so the composer only pulls a short snippet and
actor info; update the NoteComposerQuotedPostQuery selection set and the other
two quote query locations to use that preview field and adjust any consuming
JSX/props to render the snippet instead of full `content`.
ℹ️ Review info
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (10)
web-next/src/components/AppSidebar.tsxweb-next/src/components/NoteComposeModal.tsxweb-next/src/components/NoteComposer.tsxweb-next/src/components/PostControls.tsxweb-next/src/contexts/NoteComposeContext.tsxweb-next/src/locales/en-US/messages.poweb-next/src/locales/ja-JP/messages.poweb-next/src/locales/ko-KR/messages.poweb-next/src/locales/zh-CN/messages.poweb-next/src/locales/zh-TW/messages.po
✅ Files skipped from review due to trivial changes (1)
- web-next/src/locales/ja-JP/messages.po
🚧 Files skipped from review as they are similar to previous changes (2)
- web-next/src/locales/ko-KR/messages.po
- web-next/src/locales/en-US/messages.po
Add quotedPostId support to the NoteCompose context, fetch and display a quoted post preview in NoteComposer, and connect the quote button in PostControls to open the composer with the quoted post ID.
Re-extract message catalogs after adding aria-label to the remove quote button, and restore the "Remove quote" translations for all locales.
392c37c to
507c934
Compare
dahlia
left a comment
There was a problem hiding this comment.
Overall the implementation is clean and the major issues raised in prior review discussions (actor null guard, submit button timing, aria-label) have been well addressed. A few things to follow up on below.
| <SidebarMenuItem class="list-none"> | ||
| <SidebarMenuButton | ||
| onClick={openNoteCompose} | ||
| onClick={() => openNoteCompose()} |
There was a problem hiding this comment.
This looks like a style change but it is actually a necessary bug fix. Since open's signature changed to (quotedPostId?: string) => void, the original onClick={openNoteCompose} would have passed the MouseEvent object as quotedPostId, causing incorrect behavior. Worth calling out explicitly in the commit message.
| node(id: $id) { | ||
| ... on Note { | ||
| __typename | ||
| content |
There was a problem hiding this comment.
The content field here is rendered via innerHTML. Could you confirm that this GraphQL field returns server-sanitized HTML rather than the Markdown source? It is easy to conflate with the content field on the CreateNotePayload in NoteComposerMutation (same file), which likely returns the Markdown source.
| <div class="flex items-start gap-3 rounded-md border border-input bg-muted/50 p-3"> | ||
| <Avatar class="size-8 flex-shrink-0"> | ||
| <AvatarImage src={qp().actorAvatarUrl} /> | ||
| </Avatar> |
There was a problem hiding this comment.
No <AvatarFallback> is provided. If the avatar URL fails to load (common with federated accounts), the space will be blank. Consider adding a fallback with initials or a default icon.
| }, | ||
| }); | ||
| onCleanup(() => subscription.unsubscribe()); | ||
| }); |
There was a problem hiding this comment.
The legacy web/ Composer.tsx supports paste-to-quote: when the user pastes a URL into the text area, it fetches the post at that URL and offers to attach it as a quote (only for public/unlisted posts). See the implementation here.
This is a core part of the quoting UX and a notable feature parity gap. Could this be included in this PR?
The rough flow from web/:
- On paste, check if the clipboard text is a valid URL
- Fetch
/api/posts?iri=...to resolve the post - Only offer to quote if visibility is
publicorunlisted - Ask for confirmation, then set
quotedPostId
There was a problem hiding this comment.
Pull request overview
This PR wires up “quote” composition in the web-next/ Solid + Relay app by passing a quoted post ID through the compose modal flow, showing a quoted-post preview in the composer, and sending the quote association to the createNote mutation.
Changes:
- Extend
NoteComposeContextto trackquotedPostId, open the composer with an optional quoted post ID, and allow clearing the quote. - Hook the Quote button in
PostControlsto open the compose modal pre-populated with the quoted post. - Add a quoted-post preview UI + “Remove quote” i18n strings, and pass
quotedPostIdinto the note creation mutation.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| web-next/src/contexts/NoteComposeContext.tsx | Adds quotedPostId signal + APIs to open/clear quote state. |
| web-next/src/components/PostControls.tsx | Wires Quote button to open composer with the selected post ID. |
| web-next/src/components/NoteComposeModal.tsx | Shows “Quote” title when quoting and passes quote props to composer. |
| web-next/src/components/NoteComposer.tsx | Fetches and renders quoted-post preview; includes remove-quote action; passes quotedPostId into mutation input. |
| web-next/src/components/AppSidebar.tsx | Updates compose button click handler to call open explicitly (avoid accidental event arg). |
| web-next/src/locales/en-US/messages.po | Adds/updates translation entries including “Remove quote” and updated source refs. |
| web-next/src/locales/ja-JP/messages.po | Adds/updates translation entries including “Remove quote” and updated source refs. |
| web-next/src/locales/ko-KR/messages.po | Adds/updates translation entries including “Remove quote” and updated source refs. |
| web-next/src/locales/zh-CN/messages.po | Adds/updates translation entries including “Remove quote” and updated source refs. |
| web-next/src/locales/zh-TW/messages.po | Adds/updates translation entries including “Remove quote” and updated source refs. |
| isOpen: () => boolean; | ||
| open: () => void; | ||
| quotedPostId: () => string | null; | ||
| open: (quotedPostId?: string) => void; | ||
| close: () => void; | ||
| clearQuote: () => void; |
There was a problem hiding this comment.
open now accepts an optional quotedPostId, which makes it easy to accidentally pass an event object when using it as a UI handler (e.g., onSelect={openNoteCompose} / onClick={openNoteCompose}). This can result in quotedPostId being set to a non-ID value at runtime and break quote fetching / modal state. Consider separating the APIs (e.g., keep open() parameterless and add openWithQuote(id: string)), or otherwise ensure all callers wrap it to avoid passing events.
| {/* Quoted post preview */} | ||
| <Show when={quotedPost()}> | ||
| {(qp) => ( |
There was a problem hiding this comment.
The quote preview is only rendered when quotedPost() is non-null. If quotedPostId is set but the fetch fails (or the node isn't accessible), the user won't see the preview or the "Remove quote" button, leaving no in-UI way to clear the quote.
| <Button type="submit" disabled={isCreating()}> | ||
| <Button | ||
| type="submit" | ||
| disabled={isCreating() || (!!props.quotedPostId && !quotedPost())} |
There was a problem hiding this comment.
The submit button is disabled whenever quotedPostId is set but quotedPost() is still null. Combined with the preview being hidden in that state, this can permanently block composing if the quoted-post preview fails to load. Suggest tracking a separate loading/error state and always allowing either (a) clearing the quote, or (b) submitting with quotedPostId even if preview fetch fails.
| disabled={isCreating() || (!!props.quotedPostId && !quotedPost())} | |
| disabled={isCreating()} |
| import { detectLanguage } from "~/lib/langdet.ts"; | ||
| import { graphql } from "relay-runtime"; | ||
| import { createEffect, createSignal, Show } from "solid-js"; | ||
| import { createMutation } from "solid-relay"; | ||
| import { fetchQuery, graphql } from "relay-runtime"; | ||
| import { createEffect, createSignal, onCleanup, Show } from "solid-js"; | ||
| import { createMutation, useRelayEnvironment } from "solid-relay"; |
There was a problem hiding this comment.
Import ordering here doesn't follow the repo convention of grouping external imports before internal imports (per AGENTS.md). Please reorder the imports so relay-runtime / solid-js / solid-relay come before ~/... imports.
Summary
PostControlsto open the note composer modal with the quoted post's IDquotedPostIdsignal toNoteComposeContextso the compose flow tracks which post is being quotedNoteComposer, with a dismiss button to remove the quotequotedPostIdthrough to thecreateNotemutation inputScreenshot
Test plan
Summary by CodeRabbit
New Features
Behavior
Localization