dsh-mobile-flow
已验证dsh-mobile-flow · v0.8.0 · MIT · Web 界面
Mobile fixes for the DeepSeek Harness Web UI: on narrow (≤720px) screens the input bar and AI confirmation cards scroll with the page instead of pinning to the viewport floor, edges slim down, and touch devices (any width, a tablet included) no longer aut
安装
dsh plugin add dsh-mobile-flow 用 dsh --profile default --dump-config 确认 layer 已生效 —— 参见安装指南。
源码
标签
说明文档
dsh-mobile-flow
English | 简体中文
DeepSeek Harness(dsh)Web UI 的移动端插件,两件事:
- in-flow composer:窄屏(≤720px)时输入框与 AI 确认选择框随页面滚动,而不是钉死在屏幕底部——上滑阅读时消息区拿回全屏空间。
- 原生输入框接管:窄屏或触屏设备(大屏平板同样在内)时输入区换成原生
<textarea>,绕开 Lexical contenteditable 在 Android/鸿蒙输入法(尤其是语音输入)下吞字/清空已输入文字的问题。
纯客户端实现(CSS overlay + 一个 slot 组件),不修改产品源码;卸载插件即完全还原官方行为。
解决的问题
1. 输入框吸在屏幕底部
官方 Web UI 用 position: sticky; bottom: 0 把 composer 座位钉在视口底。这个座位承载的不只是输入框,还有 AI 会话中途弹出的交互卡片——ask_user_question 选项卡、approval 权限确认框、plan review。手机上它们全部粘在屏幕底部,往回翻阅回复时永久遮挡一块视口。
2. 手机输入法输入后文字被清空
官方 composer 的文本面是 Lexical contenteditable(packages/client/ui-conversation 里 createEditor + registerPlainText)。Android 输入法(语音输入尤其明显)走 Chrome 的 InputConnection → beforeinput("insertCompositionText") 重组流程,框架编辑器会用自身 state 回写 DOM 来应答这些事件——正在拼写的文字、乃至重组时已提交的文字就被抹掉。原生 <textarea> 由平台自己编辑,不参与这场 DOM 与 state 的拉锯,所以同一个输入法在普通 textarea 评论框里一切正常(例如博客评论区的输入框)。
实际效果
≤720px 视口(与官方问题卡片的断点一致)下,前四条是布局修复;后几条按「窄屏或触屏设备」生效——输入法问题跟屏幕大小无关,鸿蒙平板在 1280px 上照样吞字(2026-10-05 用户反馈:MatePad + 豆包语音输入):
- composer 座位回归文档流 —— 输入框和确认卡片位于消息流末尾。上滑时随内容滚出视口,消息全屏可读。
- 短会话仍然贴底 —— 消息不足一屏时消息区自动拉伸,输入框保持贴视口底,视觉与官方行为完全一致;长会话则享受全屏阅读。
- 浮动控件重新锚定 —— 回到底部按钮、轮次导航不再为吸底座位预留高度,回到贴近视口底的位置。
- 纤细边距 —— 消息区、会话头部、输入卡、确认卡片与屏幕边缘之间的内容层 padding(每边 16–32px)收窄为左右 4px、顶部 8px 的纤细边距,收复大部分被浪费的宽度,又不像完全贴边那样局促。页面外壳本身不产生空白,间隙完全来自这些 padding。
- 切会话不自动聚焦 —— 官方在每次挂载/切换会话时把焦点还给输入框(桌面便利设计),手机上会弹出输入法占掉半屏,平板上也一样挡事。窄屏与触屏设备上拦截这类程序化聚焦;你主动点输入框时照常聚焦。
- workspace 行操作按钮常显 —— 分组行与会话行尾部的按钮(⋯ 菜单含重命名/删除、+ 在该 workspace 新建会话)官方仅在悬停时显示;触屏没有悬停,窄屏与触屏设备下侧边栏列表渲染时常显这两个按钮。
- 原生输入框接管 —— 窄屏或触屏设备默认接管(鼠标操作的桌面端不动),输入区绘制成原生 textarea,外观、内边距、字号行高与官方完全一致(几何按官方输入区实时测量对齐)。回车仍是官方发送手势(含
/菜单仲裁、busy-Enter 策略),粘贴图片转发给官方附件入口,锁定态跟随官方可编辑性开关。 - 发送按钮跟「输入框里有什么」走 —— 只要输入框里有字,右下角发送按钮就是可点的亮色(不再是灰的),点一下即发送(运行中的回合则是排队/引导);打字期间这个状态由纯 CSS 驱动,零 DOM 写入,不破坏「打字期零 DOM 变动」这条硬约束。
- 开关不分屏幕大小 —— 工具行的「输入法✓/✗」在任何视口都显示(不只在手机上),所以「大屏平板要不要用原生输入框」永远有一键可切的地方;它同时也兼容「本插件没识别出这是触屏设备」的情况。
鼠标操作的桌面端完全不受影响(触屏设备即使屏幕很宽也会接管——这正是本次改动要的结果)。
工作原理
插件带浏览器半(exports["./client"],经 dsh.client.platform: "web" 声明),由 client-modules 扫描器发现并从 boot manifest 装载到每个页面。
- 布局部分:注入一个
<style>标签(@media (max-width: 720px)覆盖),卸载时移除标签——完全可逆。所有选择器都瞄准产品的稳定data-*属性(data-composer-seat、data-conversation-scroll、data-phase、data-slot),绝不依赖 CSS Modules 哈希类名。sticky→static 切换用:not(:has([data-conversation-composer-overlay]))排除了自带 composer overlay 的视图(如 trajectory)。不支持:has()的引擎上规则安全退回官方 sticky 行为。 - 输入框部分:注册进官方的
conversation.input.overlayslot(composer 卡片内的会话级插槽),拿到官方标准 props(useInput/inputActions)。textarea 的每次输入都通过官方输入机(conversation.input.for(ctx)的setDraft)写回,读侧订阅同一个 store 的实时快照——因此发按钮、占位符、/触发管线、附件、草稿持久化全部照常工作,且不会出现「回显旧值把刚输入的字冲掉」的竞态。官方 Lexical 编辑器保留布局盒(隐藏、不删除),卡片高度继续由草稿内容驱动。 - 范围:仅在输入机处于
plain阶段接管。一旦进入 claim(从/菜单选中命令、adjudicating、submitting),立即把输入面交还官方编辑器——命令 token/chip/装饰是纯文本镜像无法复现的状态。
环境要求
- DeepSeek Harness Web profile(
dsh web),任意较新的 0.1.x 版本 - 选择器与 slot 契约已在 0.1.2-rc.1、0.1.5-rc.1 与 0.2.0-rc.2 上验证(0.2.0 复核于 2026-10-04,用下方真机探针 + 装机客户端包静态审查);它们瞄准产品 slot 契约,同一版本线内稳定,产品大改版后可能需要小幅更新
安装
npm
dsh plugin --profile web add dsh-mobile-flow
GitHub
dsh plugin --profile web add github:imroc/dsh-mobile-flow
重启 dsh web,然后刷新浏览器页面。
开关(可选)
原生输入框接管默认在窄屏(≤720px)或触屏设备上启用——跟屏幕多大无关。需要覆盖时(例如在桌面浏览器上验证):
// 浏览器控制台,同源页面均生效,持久化
localStorage.setItem("dsh-mobile-flow:input", "off"); // 永远用官方输入框
localStorage.setItem("dsh-mobile-flow:input", "on"); // 永远接管(任何视口,含桌面)
localStorage.setItem("dsh-mobile-flow:input", "force"); // 与 "on" 等价(URL 参数 =1 写的也是它)
localStorage.removeItem("dsh-mobile-flow:input"); // 恢复默认:窄屏或触屏设备自动接管
页面上更省事的办法:点工具行的「输入法✓/✗」——它显示的是当前这台设备实际有没有在接管(不是存了什么偏好),点一下即在「永远接管」与「永远不接管」之间切换。
一次性覆盖也可用 URL 参数:?dsh-mobile-input=1(强制)/=0(关闭)。
诊断开关同理(持久化,点工具行「诊断」按钮即可,无需手打 URL):
localStorage.setItem("dsh-mobile-flow:diagnostics", "bench"); // 真机测试台
localStorage.setItem("dsh-mobile-flow:diagnostics", "debug"); // 事件面板
localStorage.removeItem("dsh-mobile-flow:diagnostics"); // 关闭
增高策略(默认 commit:只在提交点增高):
localStorage.setItem("dsh-mobile-flow:growth", "live"); // 逐键增高(v0.5.2 行为,A/B 用)
localStorage.setItem("dsh-mobile-flow:growth", "none"); // 永远固定高度
localStorage.removeItem("dsh-mobile-flow:growth"); // 恢复默认
验证
手机上(或桌面 DevTools 缩到 ≤720px 窄窗)打开一个会话;平板上(任何宽度)同样适用:
- 往上滑几屏——输入框和确认卡片应随消息滚出屏幕。
- 输入区应是原生 textarea(页面里存在
[data-mobile-input])。用输入法打字/语音输入,文字不应被自动清除。 - 发送:点发按钮或按回车(回车等同官方发送手势)。
- 发送按钮状态:输入框里有字时按钮就是亮色可点的(灰→亮由字段内容驱动);点一下即发送,一次点击一条消息。
- 工具行日常只有一个小按钮「输入法✓」(逃生通道);在它上面长按 600ms 才会叫出「诊断」(再长按收起)。
- 0.2.0 上全新浏览器 profile 首次打开会弹产品的「预览版说明」提示框,先点「继续」再验证——它会夺走焦点并盖在输入框上,不点掉的话下面什么都打不进去。
- 关键回归点(v0.6.0):打字期间不要有任何布局跳动——字段高度在聚焦期间不变,失焦后才按内容长高。
- 拉宽窗口:用鼠标的桌面才恢复官方行为;平板/手机即使屏幕很宽也应保持接管(工具行有「输入法✓」)。
更新纪律(本插件的约定)
- 必须支持热更新:改完刷新页面即可,不要让用户自己清缓存——客户端产物带
immutable缓存,但 rev 是按产物文件 mtime/size 重算的(client-modules 的 HMR 监视,2026-10-06 实测:改完不重启 dsh-web,新开页面即拿到新码);只有监视被关掉时才需要重启 dsh-web。 - 必须预留逃生通道:凡是接管官方 UI 行为的功能,都要能在页面上一条操作回退(见下文「输入法✓/✗」按钮),改坏了不影响正常使用。
兼容性加固(v0.5.1 / v0.5.2 / v0.6.0,HarmonyOS / ArkWeb 实测反馈)
首版在**鸿蒙 7 自带浏览器(ArkWeb)**上暴露两个问题,已针对性加固:
- 点击输入区弹不出输入法(只有少数位置能点中)——根因是绘制/命中层级:官方输入行所在的
.grow是position: relative且 DOM 顺序在我们的 overlay seat 之后,同级堆叠下它盖在我们上面。实测(Chromium 探针document.elementFromPoint)输入框 5 个采样点里 3 个命中的是官方容器而不是 textarea。 修复:seat 加z-index: 5+ 不透明背景;官方输入行额外pointer-events: none;并在卡片捕获阶段接管pointerdown(点在输入框范围内就聚焦 textarea),几何漂移也不会再点不中。 - 只能输入一个字符 / 输入法中断——两条防御:
- 失焦前字段自持文本:DSH 侧的非空草稿不再回写进正在聚焦的 textarea(IME 组合期间的回写会重置输入会话),只有「发送成功清空」这种外部清空才写回;
- 官方编辑器移出焦点/输入法候选:接管期间给它加
inert+aria-hidden;若引擎不支持inert,则用focusin守卫把被抢走的焦点抢回 textarea;几何写入改为幂等(无变化不写样式),避免无谓重排干扰 IME;textarea 显式user-select: text/touch-action: manipulation(WebKit 系有继承user-select:none导致"键盘弹出但输不进去"的历史 bug)。
v0.5.2(鸿蒙反馈第二轮):开启原生输入框后"每输入一个字符输入法就自动收起"。原因是每次按键都镜像草稿 → 触发 composer 卡片重渲染 + Lexical 改写隐藏编辑器 DOM → ArkWeb 在编辑面churn 时收起键盘。改为:
- 打字期间零 DOM 变动:字段自持文本,不再逐键回写机器;只在提交点同步——回车、失焦、点击输入框以外的任意位置(工具行/发送)、页面隐藏、组件卸载,以及输入
/@触发字符时立即同步(菜单需要); - 字段自己长高:textarea 自动增高(上限沿用官方 14 行 token,下限读官方 min-height:停靠 36px / 新会话 hero 52px),并给官方输入行盒子加等高的
min-height兜底(绝对定位的 seat 无法撑高卡片),发送清空后自动缩回; - 发送按钮桥接:机器草稿为空时官方发送按钮是禁用的,点击输入框以外区域时先提交草稿,若这次提交把按钮"点亮"了,就把这记点击补发给它(一次点击即可发送);
- 官方编辑器除
inert+aria-hidden外,再强制contenteditable="false"(把 IME 的可编辑候选集只留 textarea); - 打字聚焦期间不改 seat 的 left/top、不动隐藏滚动容器(避免编辑面下的布局位移触发收键盘),几何像素取整避免亚像素抖动反复写样式。
v0.6.0(鸿蒙反馈第三轮,当前):把镜像挪出打字路径仍然不够——逐键的几何写入才是收键盘的触发点:autosize 每按一次键就把字段 style.height 置 0px、读 scrollHeight、再写回(聚焦中的可编辑面在每个按键上塌陷一次),seat 还会随卡片盒子重新对齐。现在这是一条硬约束:字段有焦点时插件零 DOM 写入。
- 打字期间尺寸固定:高度锁在产品自身的下限(停靠 36px / 新会话 hero 52px),超出内容在字段内滚动;
- 只有提交点才动 DOM:失焦、回车、页面隐藏、组件卸载、阶段切换时才做测量 / 重对齐 / chrome 同步(placeholder、只读态);几何测量改为非破坏式(不再有
height: 0px探针);失焦后按内容长高并同步官方输入行的min-height,发送清空后缩回(发送清空由用户显式动作触发,是唯一在聚焦状态下写入的场景); - 未提交的文字不会被空草稿冲掉:打字期间机器草稿本来就是旧的,空发布不再被当成"用户清空了输入框";
- 诊断面板不再自我扰动:日志先进内存缓冲,只在失焦 / 手动刷新 / 键盘开合时渲染——旧面板每事件写一次 DOM,本身就是收键盘的嫌疑;
- 键盘开合进入日志:记录 window / visualViewport 高度变化(ArkWeb 用它上报软键盘),"键盘在某次按键后收起"于是变成有时间戳的事实。
v0.6.1(鸿蒙反馈第四轮,斜杠场景):真机实测只剩一种情况还会收键盘——以 / 开头的草稿(手动触发技能的常见写法);普通文字已完全正常。原因是插件里唯一的逐键例外:TRIGGER.test(整个字段值) 判断的是「文本里有 /」,于是只要草稿含斜杠,之后每敲一个字符都立刻回写机器草稿 → composer 卡片重渲染 + 命令菜单刷新 + 隐藏编辑器改写 DOM,每键一次 churn,正是 ArkWeb 收键盘的触发条件。改为:
- 只同步「触发字符本身」:按
/或@(以及删掉它们)的那一次立即回写(菜单需要),之后的字符只留在字段里,等提交点(失焦/回车/点输入框以外/页面隐藏/卸载)才一次性写入; - 输入法组合期间一律不同步(用组合开始时的触发符计数判断),避免在组合中churn;
- 诊断面板新增「触发符:仅触发 / 逐键 / 关」开关,可在真机上直接 A/B:切「逐键」即可复现旧行为(同时也验证了"逐键回写 = 收键盘"这条因果);
- 工具行新增「复制日志」按钮(只要开着诊断就显示),不用点开面板就能复制日志;
- 日志新增
CHURN while focused行:聚焦期间应用侧(菜单/Lexical)自己发生的 DOM 变更也会被登记,用于区分"我们的写入"和"应用自己的重渲染"。
已知取舍:斜杠菜单会照常弹出,但列表可能不会随输入实时过滤(过滤读的是机器草稿,而草稿在提交点前是旧的)。要实时过滤就切「触发符:逐键」,代价是那台机器上每字符收键盘。
v0.7.0(鸿蒙反馈第五轮,斜杠那一下;✅ 鸿蒙 7 ArkWeb 真机确认有效:刷新后普通打字、/ 技能命令、连续输入均正常):真机实测只剩 / 触发那一刻的单次收键盘(之后继续输入正常)。真机日志 + 官方输入框对照实验(官方输入框打 / 不收键盘)把机制收窄到一点:回写草稿会让应用异步重写隐藏的官方编辑器 DOM(EDITOR childList +1,在我们手势之外发生),ArkWeb 对这种"输入法之外的可编辑面变化"会收键盘;而官方路径里那次变化就是用户自己的编辑(同一个手势内),所以没事。
处理:触发字符的回写改成「放手 → 落盘 → 拿回来」,整段发生在同一个按键手势内——先 blur()(输入法先下去),再用 react-dom 的 flushSync 让这次回写引起的重渲染同步完成(编辑器改写 + 菜单挂载都发生在没有焦点的时候),最后 focus() 把输入法拉回来(仍在手势内,引擎允许)。
- 面板新开关 「触发:重聚焦(默认)/ 仅触发(v0.6.1 行为)/ 逐键 / 关」,可一键比较;若「重聚焦」在你的机器上无效,切「仅触发」就是上一版行为(菜单能用、斜杠那一下要再点一次)。
- 顺带修掉一个斜杠流程的隐藏缺陷:从菜单里选中命令现在能真正落进输入框了(此前"字段有焦点就不接受外部写入"的守卫会把它挡掉,现已收敛为"只挡未提交文字")。
v0.7.1:工具行清爽化——日常只留 「输入法✓/✗」 一个按钮(逃生通道),长按 600ms 才把 「诊断」 按钮叫出来(再长按收起);诊断开着时「诊断」「复制日志」两个按钮自动出现,方便你取日志或关掉。
v0.7.3(手机反馈:勾选「输入法」后输入文本,右下角发送按钮是灰的,像没法发):根因是按钮读的是机器草稿,而接管期间机器草稿故意是旧的——打字时插件只在提交点才回写草稿(ArkWeb 收键盘的教训),于是官方发送按钮一直以为输入框是空的,保持禁用(40% 透明度的灰)。旧代码虽然写了「提交后补发点击」的桥接,但它依赖引擎在指针落下之后再复查一次这个刚被"点亮"的按钮,不同引擎结果不一样,且运行中的回合还会把 Stop 方块画在这颗按钮上(点下去可能变成打断)。
改法两条:
- 外观:机器草稿是旧的,但字段自己知道有没有字,而
:placeholder-shown是纯 CSS 里唯一能读字段值的探针。于是接管卡片在「字段有字 + 机器草稿仍为空」时把发送按钮画成启用态(opacity 1、手型光标、按下有反馈)——零 DOM 写入,硬约束不破;机器草稿已经同步(如已提交)时不动它,保持官方原样。 - 手势:卡片捕获阶段的
pointerdown判断「点的是不是提交按钮(trailing 行里最后一颗 primary,可中断子会话额外的 Stop 圆钮在它前面)」且「还有未提交的文字」,是则拿走这次手势:先落草稿,再走官方自己的发送手势(与回车同一条路:斜杠仲裁、busy 策略、排队/引导),一次点击一条消息,不再看引擎脸色。运行中的回合里,字段有字时按钮换成发送箭头(隐藏官方的 Stop 方块,用官方同一份箭头 path 画 mask),点它就是发送——脸和手势一致。
v0.7.2(手机反馈:新建会话后点输入框没反应):新会话刚建出来、workspace 还没解析出来时,官方卡片其实是「选择工作区」的选择器触发器(aria-haspopup="menu"、contenteditable="false"、没有绑编辑器),根本不是输入框。旧版接管照样压上去,还把这份「不可编辑」锁存成原生 textarea 的 readOnly —— 于是:点输入框不弹键盘、不出现光标,同时把官方那记「打开选择器」的点击吞掉,用户既不能打字也打不开选择器;而且 workspace 解析好之后它不会自愈(只有换会话重新挂载才恢复),正好对上「第一次新建会话没反应、切走再新建就好」的现象(2026-09-19)。
处理:
- 接管前先问产品一句「你现在真是输入框吗」——只看产品自己写、插件从不碰的两个属性:
aria-haspopup="menu"(workspace 选择器触发器)与aria-disabled="true"(被 blocked / removed / 离线父会话锁住)。不是输入框就完全不接管:不标记卡片、不渲染 seat、不吞点击,官方那记点击照常打开选择器。 - 这份判断跟着产品实时更新(
MutationObserver盯着这两个属性),workspace 一解析好、产品把 composer 变成真输入框,接管立刻接上——不再有「锁存」。 - 兜底自愈:插件只会把官方编辑器写成
contenteditable="false",所以只要观测到"true"就一定是产品自己恢复可编辑 —— 此时同步把字段的readOnly解开(历史上被锁存的字段不再永久失灵)。
逃生开关:输入框工具行新增小按钮 「输入法✓ / 输入法✗」(仅窄屏显示)——一键在原生输入框与官方输入框之间切换并记住选择;任何设备上都不会被卡死。
诊断(工具行「诊断」按钮,或 URL ?dsh-mobile-input=bench / ,debug):
- ⚠️ 带 token 的 URL 会被 shell 重写掉 query(插件 apply 之前 query 已被清空),所以手机上请用工具行的「诊断」按钮——它把请求写进 localStorage,刷新即生效;不带 token 的浏览器地址栏访问也可直接用 URL 参数。
- 面板只占屏幕顶部(变体默认收起,点「展开变体 A-E」打开),下方真实输入框可直接打字——先测真实输入框;要定位再展开变体,每格各输 3-4 个字:
- A 裸 textarea(普通流,零 JS 写入)——基线;
- B 零高容器内的 textarea(复刻 seat 结构,零 JS 写入)——测结构;
- C 同 B + 每次按键都写高度——复刻 v0.5.2 的逐键 autosize(对照组);
- D 同 B + 只记录、不写任何 DOM——v0.6 的行为;
- E iframe 隔离文档里的裸 textarea——测页面级因素。
- 判读:日志里哪一格后面跟着
KEYBOARD ...px,哪一格就是元凶(A/B/D 正常、C 收键盘 → 逐键写样式;连 A 都收 → 与插件无关)。 - 另有「生产:提交点增高 / 逐键增高 / 固定高度」三个切换,可在真机上直接 A/B 生产字段的增高策略(默认提交点增高)。
- 事件面板(debug,与 bench 同时开启时只留 bench 的日志面板)记录 composer 的 tap 坐标/命中目标、focus 变化、input/composition、几何写入;两种面板都能一键复制日志。日志在打字期间不刷新(面板自己写 DOM 会污染取证),失焦、手动点「刷新」或键盘开合时才更新。
真机自测记录:见 knowledge 条目 与 test/probe-live.mjs(CDP 驱动真实页面,断言"打字期间页面零 DOM 变更")。
已知限制
- 原生接管期间,输入区内联的 chip/装饰(如
@引用装饰)不显示;进入命令 claim 阶段会自动切回官方编辑器。 - 移动端「粘贴图片」通过转发给官方附件入口实现,浏览器若不允许构造粘贴事件则退化为用回形针按钮选择文件。
- 输入法自身的候选词栏/联想行为由系统输入法决定,插件无法控制。
- 回合运行中 + 输入框里有未提交文字时,那颗按钮是「发送」(排队/引导),不再提供「停止」——想打断这个回合就先清空输入框(清空后按钮立刻变回 Stop)。这与官方「草稿非空时主按钮是发送」的取向一致。
开发与自测
npm install --no-save jsdom react@18 react-dom@18
node test/takeover.test.mjs # jsdom:渲染 + 打字路径(含"打字期零 DOM 写入"断言)
node test/facts-probe.mjs <token> # 真实页面:DOM/CSS 结构与引擎能力
node test/probe-live.mjs <token> # 真实页面:接管契约 + 诊断开关(CDP,390x844 移动视口)
node test/probe-send.mjs <token> # 真实页面:发送按钮的亮色状态 + 一次点击发送 + 运行中回合
token 取自 journalctl --user -u dsh-web | grep -o 'token=[A-Za-z0-9_-]*' | tail -1(每次重启换新;单次有效,探针只用一次)。
测试会加载真实的 lib/client.js,用 React 把 slot 组件渲染进一个 composer 卡片形状的 DOM,断言渲染路径、
草稿镜像(打字 / 输入法组合 / 机器侧写入)、回车手势、以及"claim 阶段把输入面交还官方编辑器"的开关。
存在的理由:slot 组件渲染出错时页面看不出异常,只有控制台报错。
回退
- Bundle 安装:
dsh plugin --profile web remove dsh-mobile-flow - 手动:移除依赖与
dsh.profile.bundles条目,重启dsh web - 临时:
localStorage.setItem("dsh-mobile-flow:input", "off")后刷新页面(只关原生输入框,布局修复保留)
不修改产品源码;升级不会覆盖。
许可证
MIT