Skip to content

Commit b56158a

Browse files
azizmejri1claude
andcommitted
Address PR review comments
- Fix data-loss bug: sendStyleModification now preserves imageSrc and imageUpload in pending changes - Extract duplicated image src extraction logic into extractStaticSrc helper - Add image load error feedback: preview iframe now shows toast when image fails to load Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent b71188d commit b56158a

File tree

4 files changed

+45
-28
lines changed

4 files changed

+45
-28
lines changed

src/components/preview_panel/PreviewIframe.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -548,6 +548,11 @@ export const PreviewIframe = ({ loading }: { loading: boolean }) => {
548548
return;
549549
}
550550

551+
if (event.data?.type === "dyad-image-load-error") {
552+
showError("Image failed to load. Please check the URL and try again.");
553+
return;
554+
}
555+
551556
if (event.data?.type === "dyad-component-coordinates-updated") {
552557
if (event.data.coordinates) {
553558
setCurrentComponentCoordinates(event.data.coordinates);

src/components/preview_panel/VisualEditingToolbar.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,8 @@ export function VisualEditingToolbar({
173173
lineNumber: selectedComponent.lineNumber,
174174
styles: newStyles,
175175
textContent: existing?.textContent || "",
176+
imageSrc: existing?.imageSrc,
177+
imageUpload: existing?.imageUpload,
176178
});
177179
return updated;
178180
});

src/pro/main/utils/visual_editing_utils.ts

Lines changed: 23 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,27 @@ interface ComponentAnalysis {
1616
imageSrc?: string;
1717
}
1818

19+
/**
20+
* Extracts the static src value from a JSX opening element's attributes.
21+
* Handles both StringLiteral and JSXExpressionContainer wrapping a StringLiteral.
22+
*/
23+
function extractStaticSrc(openingElement: any): string | undefined {
24+
const srcAttr = openingElement.attributes.find(
25+
(attr: any) => attr.type === "JSXAttribute" && attr.name?.name === "src",
26+
);
27+
if (!srcAttr?.value) return undefined;
28+
if (srcAttr.value.type === "StringLiteral") {
29+
return srcAttr.value.value;
30+
}
31+
if (
32+
srcAttr.value.type === "JSXExpressionContainer" &&
33+
srcAttr.value.expression.type === "StringLiteral"
34+
) {
35+
return srcAttr.value.expression.value;
36+
}
37+
return undefined;
38+
}
39+
1940
/**
2041
* Pure function that transforms JSX/TSX content by applying style and text changes
2142
* @param content - The source code content to transform
@@ -418,19 +439,7 @@ export function analyzeComponent(
418439
// Check if the element itself is an <img>
419440
if (tagName.type === "JSXIdentifier" && tagName.name === "img") {
420441
hasImage = true;
421-
const srcAttr = foundElement.openingElement.attributes.find(
422-
(attr: any) => attr.type === "JSXAttribute" && attr.name?.name === "src",
423-
);
424-
if (srcAttr?.value) {
425-
if (srcAttr.value.type === "StringLiteral") {
426-
imageSrc = srcAttr.value.value;
427-
} else if (
428-
srcAttr.value.type === "JSXExpressionContainer" &&
429-
srcAttr.value.expression.type === "StringLiteral"
430-
) {
431-
imageSrc = srcAttr.value.expression.value;
432-
}
433-
}
442+
imageSrc = extractStaticSrc(foundElement.openingElement);
434443
}
435444

436445
// Recursively check descendants for <img> elements
@@ -444,20 +453,7 @@ export function analyzeComponent(
444453
node.openingElement.name.name === "img"
445454
) {
446455
hasImage = true;
447-
const srcAttr = node.openingElement.attributes.find(
448-
(attr: any) =>
449-
attr.type === "JSXAttribute" && attr.name?.name === "src",
450-
);
451-
if (srcAttr?.value) {
452-
if (srcAttr.value.type === "StringLiteral") {
453-
imageSrc = srcAttr.value.value;
454-
} else if (
455-
srcAttr.value.type === "JSXExpressionContainer" &&
456-
srcAttr.value.expression.type === "StringLiteral"
457-
) {
458-
imageSrc = srcAttr.value.expression.value;
459-
}
460-
}
456+
imageSrc = extractStaticSrc(node.openingElement);
461457
return;
462458
}
463459

worker/dyad-visual-editor-client.js

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,21 @@
275275
};
276276

277277
imgEl.addEventListener("load", sendCoordinates, { once: true });
278-
imgEl.addEventListener("error", sendCoordinates, { once: true });
278+
imgEl.addEventListener(
279+
"error",
280+
() => {
281+
sendCoordinates();
282+
window.parent.postMessage(
283+
{
284+
type: "dyad-image-load-error",
285+
elementId,
286+
src,
287+
},
288+
"*",
289+
);
290+
},
291+
{ once: true },
292+
);
279293
imgEl.src = src;
280294
}
281295
}

0 commit comments

Comments
 (0)