Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ import { Button } from "@superset/ui/button";
import { toast } from "@superset/ui/sonner";
import { useWorkspaceClient, workspaceTrpc } from "@superset/workspace-client";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { LuFileCode } from "react-icons/lu";
import { LuFileCode, LuLoader } from "react-icons/lu";
import { useWorkspaceEvent } from "renderer/hooks/host-service/useWorkspaceEvent";
import {
createPaneScrollStateKey,
getPaneScrollState,
Expand All @@ -31,6 +32,7 @@ import { DiffFileHeaderName } from "renderer/screens/main/components/DiffFileHea
import { DiffViewToolbar } from "renderer/screens/main/components/DiffViewToolbar";
import { MarkdownSearch } from "renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/FileViewerPane/components/MarkdownSearch";
import { toAbsoluteWorkspacePath } from "shared/absolute-paths";
import { getImageMimeType } from "shared/file-types";
import type { DiffPaneData, PaneViewerData } from "../../../../types";
import {
type ChangesetFile,
Expand Down Expand Up @@ -119,9 +121,30 @@ export function DiffPane({
const workspaceQuery = workspaceTrpc.workspace.get.useQuery({
id: workspaceId,
});
const worktreePath = workspaceQuery.data?.worktreePath;
const writeFile = workspaceTrpc.filesystem.writeFile.useMutation();
const utils = workspaceTrpc.useUtils();
const { trpcClient } = useWorkspaceClient();
// Image previews read the working tree, so a replaced image has to refetch
// when git reports it changed. Scope to the reported paths when we have
// them so an unrelated edit doesn't refetch every preview on screen.
useWorkspaceEvent(
"git:changed",
workspaceId,
({ paths }) => {
if (!worktreePath || !paths) {
void utils.filesystem.readFile.invalidate({ workspaceId });
return;
}
for (const path of paths) {
void utils.filesystem.readFile.invalidate({
workspaceId,
absolutePath: toAbsoluteWorkspacePath(worktreePath, path),
});
}
},
!!worktreePath,
);
const [editingSet, setEditingSet] = useState<ReadonlySet<string>>(new Set());
const [dirtyItemIds, setDirtyItemIds] = useState<ReadonlySet<string>>(
new Set(),
Expand Down Expand Up @@ -672,7 +695,14 @@ export function DiffPane({
if (item.type !== "file") return null;
const file = fileByItemId.get(item.id);
if (!file) return null;
return <BinaryDiffPlaceholder file={file} onOpenFile={onOpenFile} />;
return (
<BinaryDiffPlaceholder
file={file}
workspaceId={workspaceId}
worktreePath={worktreePath}
onOpenFile={onOpenFile}
/>
);
}
if (m.kind === "deferred-placeholder") {
if (item.type !== "file") return null;
Expand Down Expand Up @@ -746,6 +776,7 @@ export function DiffPane({
commentNav.isNavFocused,
commentNav.navFocusTick,
t,
worktreePath,
],
);

Expand Down Expand Up @@ -817,20 +848,79 @@ export function DiffPane({
);
}

const IMAGE_PREVIEW_MAX_BYTES = 10 * 1024 * 1024;

function BinaryDiffPlaceholder({
file,
workspaceId,
worktreePath,
onOpenFile,
}: {
file: ChangesetFile;
workspaceId: string;
worktreePath?: string;
onOpenFile: (path: string, openInNewTab?: boolean) => void;
}) {
const canOpen = file.status !== "deleted";
// The preview reads the working tree, which is only the "new" side of a
// working-tree diff. A commit's image may since have changed or gone.
const mimeType =
file.source.kind === "commit" ? null : getImageMimeType(file.path);
const canPreview = canOpen && !!worktreePath && mimeType !== null;
const imageQuery = workspaceTrpc.filesystem.readFile.useQuery(
{
workspaceId,
absolutePath: toAbsoluteWorkspacePath(worktreePath ?? "", file.path),
maxBytes: IMAGE_PREVIEW_MAX_BYTES,
},
{
enabled: canPreview,
retry: false,
staleTime: 30_000,
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Resolved
},
);
const image =
canPreview && !imageQuery.isError && imageQuery.data?.kind === "bytes"
? imageQuery.data
: null;
const isLoading = canPreview && imageQuery.isLoading;

if (image && !image.exceededLimit) {
return (
<div className="flex flex-col items-center justify-center gap-3 bg-muted/30 p-4">
<div className="max-w-full bg-[conic-gradient(color-mix(in_srgb,var(--color-foreground)_10%,transparent)_25%,transparent_0_50%,color-mix(in_srgb,var(--color-foreground)_10%,transparent)_0_75%,transparent_0)] bg-[length:16px_16px]">
<img

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2: When a supported image file contains corrupt or non-renderable bytes, the <img> emits an error but this component never switches back to the binary fallback. Add an image-error state and render the existing fallback when the image load fails.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/DiffPane/DiffPane.tsx, line 892:

<comment>When a supported image file contains corrupt or non-renderable bytes, the `<img>` emits an error but this component never switches back to the binary fallback. Add an image-error state and render the existing fallback when the image load fails.</comment>

<file context>
@@ -817,20 +848,79 @@ export function DiffPane({
+		return (
+			<div className="flex flex-col items-center justify-center gap-3 bg-muted/30 p-4">
+				<div className="max-w-full bg-[conic-gradient(color-mix(in_srgb,var(--color-foreground)_10%,transparent)_25%,transparent_0_50%,color-mix(in_srgb,var(--color-foreground)_10%,transparent)_0_75%,transparent_0)] bg-[length:16px_16px]">
+					<img
+						src={`data:${mimeType};base64,${image.content}`}
+						alt={file.path}
</file context>

src={`data:${mimeType};base64,${image.content}`}
alt={file.path}
className="block max-h-96 max-w-full object-contain"
/>
</div>
<Button
variant="outline"
size="sm"
onClick={() => onOpenFile(file.path)}
>
<Trans>Open file</Trans>
</Button>
</div>
);
}

return (
<div className="flex flex-col items-center justify-center gap-3 bg-muted/30 py-8 text-muted-foreground">
<LuFileCode className="size-8" />
{isLoading ? (
<LuLoader className="size-6 animate-spin" />
) : (
<LuFileCode className="size-8" />
)}
<p className="cursor-text select-text text-sm">
<Trans>Binary file hidden</Trans>
{isLoading ? (
<Trans>Loading image…</Trans>
) : image?.exceededLimit ? (
<Trans>File is too large to preview</Trans>
) : (
<Trans>Binary file hidden</Trans>
)}
</p>
{canOpen ? (
<Button
Expand Down
3 changes: 3 additions & 0 deletions packages/i18n/locales/cs/messages.po
Original file line number Diff line number Diff line change
Expand Up @@ -7545,6 +7545,9 @@ msgstr "Načítám fonty..."
msgid "Loading groups…"
msgstr "Načítám skupiny…"

msgid "Loading image…"
msgstr "Načítám obrázek…"

msgid "Loading issue…"
msgstr "Načítám issue…"

Expand Down
2 changes: 1 addition & 1 deletion packages/i18n/locales/cs/messages.ts

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions packages/i18n/locales/de/messages.po
Original file line number Diff line number Diff line change
Expand Up @@ -7545,6 +7545,9 @@ msgstr "Schriften werden geladen..."
msgid "Loading groups…"
msgstr "Gruppen werden geladen…"

msgid "Loading image…"
msgstr "Bild wird geladen…"

msgid "Loading issue…"
msgstr "Issue wird geladen…"

Expand Down
2 changes: 1 addition & 1 deletion packages/i18n/locales/de/messages.ts

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions packages/i18n/locales/en/messages.po
Original file line number Diff line number Diff line change
Expand Up @@ -7545,6 +7545,9 @@ msgstr "Loading fonts..."
msgid "Loading groups…"
msgstr "Loading groups…"

msgid "Loading image…"
msgstr "Loading image…"

msgid "Loading issue…"
msgstr "Loading issue…"

Expand Down
2 changes: 1 addition & 1 deletion packages/i18n/locales/en/messages.ts

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions packages/i18n/locales/es/messages.po
Original file line number Diff line number Diff line change
Expand Up @@ -7545,6 +7545,9 @@ msgstr "Cargando fuentes..."
msgid "Loading groups…"
msgstr "Cargando grupos…"

msgid "Loading image…"
msgstr "Cargando imagen…"

msgid "Loading issue…"
msgstr "Cargando issue…"

Expand Down
2 changes: 1 addition & 1 deletion packages/i18n/locales/es/messages.ts

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions packages/i18n/locales/fr/messages.po
Original file line number Diff line number Diff line change
Expand Up @@ -7545,6 +7545,9 @@ msgstr "Chargement des polices..."
msgid "Loading groups…"
msgstr "Chargement des groupes…"

msgid "Loading image…"
msgstr "Chargement de l’image…"

msgid "Loading issue…"
msgstr "Chargement de l'issue…"

Expand Down
2 changes: 1 addition & 1 deletion packages/i18n/locales/fr/messages.ts

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions packages/i18n/locales/id/messages.po
Original file line number Diff line number Diff line change
Expand Up @@ -7545,6 +7545,9 @@ msgstr "Memuat font..."
msgid "Loading groups…"
msgstr "Memuat grup…"

msgid "Loading image…"
msgstr "Memuat gambar…"

msgid "Loading issue…"
msgstr "Memuat issue…"

Expand Down
2 changes: 1 addition & 1 deletion packages/i18n/locales/id/messages.ts

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions packages/i18n/locales/it/messages.po
Original file line number Diff line number Diff line change
Expand Up @@ -7545,6 +7545,9 @@ msgstr "Caricamento dei font..."
msgid "Loading groups…"
msgstr "Caricamento dei gruppi…"

msgid "Loading image…"
msgstr "Caricamento dell'immagine…"

msgid "Loading issue…"
msgstr "Caricamento della issue…"

Expand Down
2 changes: 1 addition & 1 deletion packages/i18n/locales/it/messages.ts

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions packages/i18n/locales/ja/messages.po
Original file line number Diff line number Diff line change
Expand Up @@ -7545,6 +7545,9 @@ msgstr "フォントを読み込み中..."
msgid "Loading groups…"
msgstr "グループを読み込み中…"

msgid "Loading image…"
msgstr "画像を読み込み中…"

msgid "Loading issue…"
msgstr "Issueを読み込み中…"

Expand Down
2 changes: 1 addition & 1 deletion packages/i18n/locales/ja/messages.ts

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions packages/i18n/locales/ko/messages.po
Original file line number Diff line number Diff line change
Expand Up @@ -7545,6 +7545,9 @@ msgstr "글꼴 불러오는 중..."
msgid "Loading groups…"
msgstr "그룹 불러오는 중…"

msgid "Loading image…"
msgstr "이미지 불러오는 중…"

msgid "Loading issue…"
msgstr "이슈 불러오는 중…"

Expand Down
2 changes: 1 addition & 1 deletion packages/i18n/locales/ko/messages.ts

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions packages/i18n/locales/nl/messages.po
Original file line number Diff line number Diff line change
Expand Up @@ -7545,6 +7545,9 @@ msgstr "Lettertypen laden..."
msgid "Loading groups…"
msgstr "Groepen laden…"

msgid "Loading image…"
msgstr "Afbeelding laden…"

msgid "Loading issue…"
msgstr "Issue laden…"

Expand Down
2 changes: 1 addition & 1 deletion packages/i18n/locales/nl/messages.ts

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions packages/i18n/locales/pl/messages.po
Original file line number Diff line number Diff line change
Expand Up @@ -7545,6 +7545,9 @@ msgstr "Wczytywanie czcionek..."
msgid "Loading groups…"
msgstr "Wczytywanie grup…"

msgid "Loading image…"
msgstr "Wczytywanie obrazu…"

msgid "Loading issue…"
msgstr "Wczytywanie zgłoszenia…"

Expand Down
2 changes: 1 addition & 1 deletion packages/i18n/locales/pl/messages.ts

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions packages/i18n/locales/pt-BR/messages.po
Original file line number Diff line number Diff line change
Expand Up @@ -7545,6 +7545,9 @@ msgstr "Carregando as fontes..."
msgid "Loading groups…"
msgstr "Carregando grupos…"

msgid "Loading image…"
msgstr "Carregando imagem…"

msgid "Loading issue…"
msgstr "Carregando a issue…"

Expand Down
2 changes: 1 addition & 1 deletion packages/i18n/locales/pt-BR/messages.ts

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions packages/i18n/locales/ru/messages.po
Original file line number Diff line number Diff line change
Expand Up @@ -7545,6 +7545,9 @@ msgstr "Загрузка шрифтов..."
msgid "Loading groups…"
msgstr "Загрузка групп…"

msgid "Loading image…"
msgstr "Загрузка изображения…"

msgid "Loading issue…"
msgstr "Загрузка задачи…"

Expand Down
2 changes: 1 addition & 1 deletion packages/i18n/locales/ru/messages.ts

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions packages/i18n/locales/tr/messages.po
Original file line number Diff line number Diff line change
Expand Up @@ -7545,6 +7545,9 @@ msgstr "Yazı tipleri yükleniyor..."
msgid "Loading groups…"
msgstr "Gruplar yükleniyor…"

msgid "Loading image…"
msgstr "Görsel yükleniyor…"

msgid "Loading issue…"
msgstr "Issue yükleniyor…"

Expand Down
2 changes: 1 addition & 1 deletion packages/i18n/locales/tr/messages.ts

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions packages/i18n/locales/vi/messages.po
Original file line number Diff line number Diff line change
Expand Up @@ -7545,6 +7545,9 @@ msgstr "Đang tải font..."
msgid "Loading groups…"
msgstr "Đang tải nhóm…"

msgid "Loading image…"
msgstr "Đang tải hình ảnh…"

msgid "Loading issue…"
msgstr "Đang tải issue…"

Expand Down
2 changes: 1 addition & 1 deletion packages/i18n/locales/vi/messages.ts

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions packages/i18n/locales/zh-CN/messages.po
Original file line number Diff line number Diff line change
Expand Up @@ -7545,6 +7545,9 @@ msgstr "正在加载字体..."
msgid "Loading groups…"
msgstr "正在加载分组…"

msgid "Loading image…"
msgstr "正在加载图片…"

msgid "Loading issue…"
msgstr "正在加载议题…"

Expand Down
2 changes: 1 addition & 1 deletion packages/i18n/locales/zh-CN/messages.ts

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions packages/i18n/locales/zh-TW/messages.po
Original file line number Diff line number Diff line change
Expand Up @@ -7545,6 +7545,9 @@ msgstr "正在載入字型..."
msgid "Loading groups…"
msgstr "正在載入群組…"

msgid "Loading image…"
msgstr "正在載入圖片…"

msgid "Loading issue…"
msgstr "正在載入議題…"

Expand Down
2 changes: 1 addition & 1 deletion packages/i18n/locales/zh-TW/messages.ts

Large diffs are not rendered by default.