fix: route images before binary detection

This commit is contained in:
HuanLinOTO
2026-08-10 16:54:13 +08:00
parent a6befc8b6b
commit eb5059574e
3 changed files with 27 additions and 5 deletions
+7 -5
View File
@@ -23,9 +23,9 @@ import { DocxView, XlsxView } from './office-view.tsx'
import { isPdfExt } from './pdf-types.ts'
import { PdfView } from './PdfView.tsx'
import { PptxView } from './PptxView.tsx'
import { isImageExt } from './image-types.ts'
import css from './sidebar.module.css'
const IMAGE_EXT = ['.png', '.jpg', '.jpeg', '.gif', '.webp', '.svg', '.bmp', '.ico', '.avif']
const MD_EXT = ['.md', '.markdown']
type EditorLoad =
@@ -67,6 +67,12 @@ export function EditorView(props: { scope: SessionScope; path: string; title: st
// own renderers below. Detect by extension and skip fsRead entirely —
// the renderer fetches bytes through the media route itself.
const ext = extOfPath(path)
// Images are binary by nature; short-circuit before fsRead's NUL probe or
// every PNG/JPEG would be classified as an unsupported binary file.
if (isImageExt(ext)) {
setLoad({ status: 'ready', kind: 'image', content: '', truncated: false })
return
}
if (isPdfExt(ext)) {
setLoad({ status: 'ready', kind: 'pdf', content: '', truncated: false })
return
@@ -86,10 +92,6 @@ export function EditorView(props: { scope: SessionScope; path: string; title: st
setLoad({ status: 'binary' })
return
}
if (IMAGE_EXT.includes(ext)) {
setLoad({ status: 'ready', kind: 'image', content: '', truncated: false })
return
}
setLoad({
status: 'ready',
kind: MD_EXT.includes(ext) ? 'md' : 'text',
+8
View File
@@ -0,0 +1,8 @@
/** Image extension dispatch, separate from React for unit testing. */
export const IMAGE_EXTENSIONS = [
'.png', '.jpg', '.jpeg', '.gif', '.webp', '.svg', '.bmp', '.ico', '.avif',
] as readonly string[]
export function isImageExt(ext: string): boolean {
return IMAGE_EXTENSIONS.includes(ext)
}
+12
View File
@@ -11,6 +11,7 @@ import { SIDEBAR_PREFS_DEFAULTS } from '../src/prefs-shared.ts'
import { extOf, languageKeyForExt } from '../src/client/lang.ts'
import { officeKindForExt } from '../src/client/office-types.ts'
import { isPdfExt } from '../src/client/pdf-types.ts'
import { isImageExt } from '../src/client/image-types.ts'
import { relativeTo } from '../src/client/paths.ts'
import { producedForClosing, resolveSidebarPath, selectProducedFiles } from '../src/client/produced-files.ts'
import { defaultShell, ensureSpawnHelper } from '../src/pty-manager.ts'
@@ -486,6 +487,17 @@ describe('pdf preview kind', () => {
})
})
describe('image preview kind', () => {
it('routes supported image extensions before binary probing', () => {
expect(isImageExt('.png')).toBe(true)
expect(isImageExt('.jpg')).toBe(true)
expect(isImageExt('.svg')).toBe(true)
expect(isImageExt('.avif')).toBe(true)
expect(isImageExt('.pdf')).toBe(false)
expect(isImageExt('')).toBe(false)
})
})
describe('side card preferences', () => {
/** A fake settings wire face whose settingsGet resolves to one raw value. */
const wire = (value: unknown): SidebarSettingsClient => ({