Stabilize image drops in issue composer

This commit is contained in:
Dotta committed 2026-04-24 07:43:41 -05:00
1 parent b25ecb5c23
commit cddb379145
4 files changed
+37 -2

No files matched your search

+3 -1
View File
@@ -928,7 +928,9 @@ describe("IssueChatThread", () => {
});
expect(onAttachImage).toHaveBeenCalledWith(file);
expect(container.querySelector('[data-testid="issue-chat-composer-attachments"]')).not.toBeNull();
const attachmentList = container.querySelector('[data-testid="issue-chat-composer-attachments"]');
expect(attachmentList).not.toBeNull();
expect(attachmentList?.className).toContain("mb-3");
expect(container.textContent).toContain("report.pdf");
expect(container.textContent).toContain("Attached to issue");
+1 -1
View File
@@ -2362,7 +2362,7 @@ const IssueChatComposer = forwardRef<IssueChatComposerHandle, IssueChatComposerP
{composerAttachments.length > 0 ? (
<div
data-testid="issue-chat-composer-attachments"
className="mt-2 space-y-1.5 rounded-md border border-dashed border-border/80 bg-muted/20 p-2"
className="mb-3 mt-2 space-y-1.5 rounded-md border border-dashed border-border/80 bg-muted/20 p-2"
>
{composerAttachments.map((attachment) => {
const sizeLabel = formatAttachmentSize(attachment.size);
+26
View File
@@ -347,6 +347,32 @@ describe("MarkdownEditor", () => {
root.unmount();
});
});
it("does not show the raw fallback while image-only markdown is settling", async () => {
mdxEditorMockState.emitMountSilentEmptyState = true;
const root = createRoot(container);
await act(async () => {
root.render(
<MarkdownEditor
value="![Screenshot](/api/attachments/image/content)"
onChange={() => {}}
placeholder="Markdown body"
/>,
);
});
await flush();
await flush();
expect(container.querySelector("textarea")).toBeNull();
expect(container.textContent).not.toContain("Rich editor unavailable for this markdown");
await act(async () => {
root.unmount();
});
});
it("anchors the mention menu inside the visual viewport when mobile offsets are present", () => {
expect(
computeMentionMenuPosition(
+7
View File
@@ -126,6 +126,10 @@ function hasMeaningfulEditorContent(node: Node | null): boolean {
return Array.from(element.childNodes).some((child) => hasMeaningfulEditorContent(child));
}
function hasMarkdownImage(value: string): boolean {
return /!\[[\s\S]*?\]\([^)]+\)/.test(value);
}
function isRichEditorDomEmpty(
editable: HTMLElement,
expectedValue: string,
@@ -133,9 +137,11 @@ function isRichEditorDomEmpty(
): boolean {
const expectedText = expectedValue.trim();
if (!expectedText) return false;
const expectedHasImage = hasMarkdownImage(expectedText);
const visibleText = (editable.textContent ?? "").trim();
if (visibleText.length === 0) {
if (expectedHasImage) return false;
return !Array.from(editable.childNodes).some((child) => hasMeaningfulEditorContent(child));
}
@@ -145,6 +151,7 @@ function isRichEditorDomEmpty(
&& visibleText === normalizedPlaceholder
&& expectedText !== normalizedPlaceholder
) {
if (expectedHasImage) return false;
return true;
}