支持在软件内预览图片

This commit is contained in:
xintaofei
2026-03-24 16:31:33 +08:00
parent 6067d5f9c4
commit b7df63c5f8
13 changed files with 399 additions and 11 deletions

View File

@@ -18,6 +18,7 @@ import {
gitIsTracked,
gitShowDiff,
gitShowFile,
readFileBase64,
readFileForEdit,
readFilePreview,
saveFileContent,
@@ -127,6 +128,33 @@ function isDirtyFileTab(tab: FileWorkspaceTab): boolean {
return tab.kind === "file" && Boolean(tab.isDirty)
}
const IMAGE_EXTENSIONS = new Set([
"png",
"jpg",
"jpeg",
"gif",
"svg",
"webp",
"bmp",
"ico",
])
const IMAGE_MIME: Record<string, string> = {
png: "image/png",
jpg: "image/jpeg",
jpeg: "image/jpeg",
gif: "image/gif",
svg: "image/svg+xml",
webp: "image/webp",
bmp: "image/bmp",
ico: "image/x-icon",
}
function isImageFile(path: string): boolean {
const ext = path.split(".").pop()?.toLowerCase() ?? ""
return IMAGE_EXTENSIONS.has(ext)
}
function loadingTab(
id: string,
kind: FileWorkspaceTabKind,
@@ -350,6 +378,7 @@ export function WorkspaceProvider({ children }: WorkspaceProviderProps) {
setPendingFileReveal(null)
}
const tabId = `file:${path}`
const image = isImageFile(path)
upsertLoadingTab(
loadingTab(
tabId,
@@ -357,10 +386,43 @@ export function WorkspaceProvider({ children }: WorkspaceProviderProps) {
fileName(path),
path,
path,
languageFromPath(path)
image ? "image" : languageFromPath(path)
)
)
if (image) {
try {
const absPath = `${folderPath}/${path}`
const ext = path.split(".").pop()?.toLowerCase() ?? ""
const mime = IMAGE_MIME[ext] ?? "image/png"
const b64 = await withTimeout(
readFileBase64(absPath),
15_000,
t("previewRequestTimedOut")
)
setFileTabs((prev) =>
prev.map((tab) =>
tab.id === tabId
? {
...tab,
content: `data:${mime};base64,${b64}`,
readonly: true,
loading: false,
saveState: "idle",
saveError: null,
}
: tab
)
)
} catch (error) {
rejectTab(
tabId,
error instanceof Error ? error.message : String(error)
)
}
return
}
try {
const [result, gitBaseContent] = await withTimeout(
Promise.all([