- 新 src/client/EditorHost.tsx:'editor' tab 组件。matchFileViewer → 按 fetchStrategy 分发(纯逻辑在 editor-load.ts)→ 渲染 viewer.component; binary 无匹配时渲染共享 BinaryDownload。标题栏保留在 host - 新 src/client/TextEditor.tsx:code/markdown 的 viewer 组件(CodeMirror + 保存/脏点/截断横幅 + md 预览/编辑切换),内容由 host 经 fsRead 传入, 自身不再 fetch;按 viewerId === 'markdown' 分支(不再解析扩展名) - 新 src/client/editor-load.ts:planFirstMatch / planFsReadOutcome / decodeHead 纯函数,策略分发可单测 - 新 src/client/binary-download.tsx:共享下载兜底组件(viewer 注册与 host fallback 同一 UI) - host src/index.ts:fs.read 二进制响应增加 head 字段(base64,前 4KB, 唯一 host 触碰,设计文档 detect 机制所需);客户端 FsBinaryResult 同步 - builtins:注册 8 个 viewer(新增 markdown exts md/markdown、code catch-all -100);binary-download 增加 NUL detect + 复用 BinaryDownload - 删除 src/client/EditorView.tsx(职责一分为二);陈旧注释同步 - 新增 tests/editor-load.spec.ts(12 用例)
24 lines
903 B
TypeScript
24 lines
903 B
TypeScript
/**
|
|
* The "no preview — download instead" pane: shown by the editor host when no
|
|
* viewer can render a file (binary without a registered renderer, or the
|
|
* `binary-download` strategy) and registered as the `binary-download` viewer
|
|
* component so the declarative route and the host fallback share one UI.
|
|
*/
|
|
import type { ReactNode } from 'react'
|
|
import type { SessionScope } from './api.ts'
|
|
import { downloadUrl } from './api.ts'
|
|
import { t } from './locales.ts'
|
|
import css from './sidebar.module.css'
|
|
|
|
export function BinaryDownload(props: { scope: SessionScope; path: string }): ReactNode {
|
|
const { scope, path } = props
|
|
return (
|
|
<div className={css.editorBinary}>
|
|
<span className={css.editorBinaryNotice}>{t('binaryNoPreview')}</span>
|
|
<a className={css.editorDownloadLink} href={downloadUrl(scope, path)} download>
|
|
{t('downloadToView')}
|
|
</a>
|
|
</div>
|
|
)
|
|
}
|