# 竖屏 UI 修复:三个客户端插件 > 面向 Android 手机竖屏(约 386 CSS px 宽)的布局修复。全部以**客户端插件**实现: > 不修改引擎源码、不抢占 DOM 事件、不与其他 UI 插件冲突,引擎升级也不会覆盖。 ## 1. 问题:不是「挤」,是「宽度算成 0」 引擎 `@deepseek-ai/dsh-client-ui-layout` 用 CSS Grid 排三列,列宽由 `computeColumns()` 计算: ```js const s = sidebar === 0 ? collapsedWidth : clampWidth(sidebar, 264, 420); const available = viewport - s - 400; // 固定给中心对话区预留 400px const rightbar = rightbar === 0 || available < 300 ? 0 : Math.min(available, clampWidth(rightbar, 300, viewport * 0.7)); return { sidebar: s, center: Math.max(0, viewport - s - rightbar), rightbar }; ``` 手机竖屏下 `viewport` 只有约 386px。带入公式: | 场景 | 计算 | 结果 | |---|---|---| | 侧栏展开 + 对话区 | `386 - 280 = 106` | 对话区被压成 106px,文字逐字换行 | | 打开右侧面板 | `available = 386 - 56 - 400 = -70 < 300` | **右栏宽度直接为 0**(那一列根本没渲染) | 所以「查看更改 / 代码差异」在手机上不是显示不全,而是**面板所在的列宽度被算成了 0**。 设置面板则是另一处:`ui-settings-general` 的面板固定 `width: 800px; max-width: calc(100vw - 48px)`, 左导航固定 `width: 188px; flex: none` → 手机上内容区只剩约 150px,标签被压到 47px 逐字竖排。 ## 2. 为什么做成插件 DSH 的 WebUI 本身支持**客户端插件**(`dsh.client` 机制): - 包是标准 npm 包:`package.json` 声明 `dsh.client`(`platform: "web"` + 可选 `inject`), 并提供 `exports["./client"]`; - 引擎的 `dsh-client-modules` 会扫描宿主 Loader 的 entries,把浏览器端 bundle 注入页面; - bundle 以经典 script 加载,通过 `window.__ModuleLoader__.load({ id, factory })` 注册, `id` 必须等于包名。 这种方式的优点: - **零源码改动**:引擎升级不会覆盖我们的逻辑; - **天然隔离**:每个插件只给自己定位到的元素打属性、只在自己的 `