Repository navigation
Releases: ZIye1208/dsh-settings-nav-manager
Release list
v1.4.4
1.4.4
评审 D-1 / D-2 的修复。这两条都属于「静默丢数据」:用户看不到任何异常,重启后排版就没了,而且消失的那次写盘是「成功」的,连失败提示都没有。
兼容性
- 已实测兼容 DSH Desktop
0.2.1-rc.3:逐项核对了本插件依赖的宿主契约——设置弹窗的sidebar.settings槽与其单例 store(openSection深链)、settings.action/settings.section子槽、[data-shortcut-modal="settings"]与navList/navCell/navLabel结构及.navCell定位 CSS(height:40px、padding:9px 16px 9px 12px,与本插件::after图标层的 7px/29px、上下 −9px 外扩完全对得上)、侧栏sidebar.panellist行与selectPanel → ctx.layout.selectPanel、sidebar.footer.action、main槽与retainMainPanels的可达性校验(报错文案未变)、ctx.remote.settings的describe/update/mutate与{writable,hasDocument,namespaces[{ns,revision,value,schema}]}视图。dsh-client-ui-renderer与 rc.2 完全一致。 - 兼容范围仍是
>=0.2.1-rc.2 <0.3.0,rc.2 不受影响。
修复
- D-2 读不到盘上的内容时不再写盘:旧实现
describe()一失败,内存态就被当成「空排版」,随后任意一次点眼睛/星标/拖拽都会把这份空态写回磁盘——一次网关抖动就变成一次静默清档。现在加了stateKnown门闩:只有describe()成功返回过才允许保存,读失败期间写操作直接短路,并在齿轮旁提示「未能读取已保存的排版,已暂停保存以免覆盖」。 - 失败自动退避重试:
describe()失败后按 400/800/1600ms 重试(共 3 次),期间保持只读;恢复后解除暂停并提示「已重新读取排版,保存已恢复」。 - D-1 写盘不再按「此刻存在的分区」裁剪:旧
serializeState(state, known)会把order/hidden/pinned/ 抽屉成员按本次 sync 时刻的已知分区过滤掉。但known只是「此刻的投影」——某插件被禁用、正在 HMR 重载、apply抛错时它就少一项,用户给那个分区设的顺序/隐藏/固定就会被永久删除。现在写盘只做类型清洗 + 上限(order 200、抽屉 50 组×100 项、hidden 200、pinned 5、id 120 字符),不再按 known 裁剪:盘上多留几个暂时不存在的 id 无害(渲染本来就会跳过),少一个 id 才是数据丢失。 - 单测里把 D-1 当正确行为锁死的三条旧断言(「只写已知 id」「known 为空返回 null」)改写为「不按 known 裁剪 + 上限生效」,并新增 2 条用例(读路径上限、抽屉名剔除双向控制符)。
测试
- 单测 42 → 44 条,仓库校验 16 条不变。
- e2e 34 → 36 条,新增两条针对 D-2 的归零用例:
- 「describe 一直失败:任何操作都不写盘」——连续失败的
describe+ 点眼睛 + 点星标,断言writes.length === 0、磁盘旧数据未被改动、提示可见; - 「describe 失败后重试成功:旧排版不丢,保存恢复」——首次失败、退避后成功,断言旧
hidden与抽屉成员仍在,且之后能正常写入。 - 两条均标
oldFails,在 1.4.3 的client.js上实测失败(36 条里 3 条失败),证明断言有效。
- 「describe 一直失败:任何操作都不写盘」——连续失败的
v1.4.3 —— 图标不再被第三方插件挤掉
说明:1.4.1 / 1.4.2 只打了标签,本次只发布 1.4.3 的 GitHub Release 与 npm 包。
1.4.2 只在「干净页面」里成立:真机上四行(OpenCode…、桌宠配置、插件市场、侧边卡片)的眼睛和星星仍然整排不见。原因是这些行被别的插件认领了。
修复
- 图标从
::before移到::after:dshmarket / dsh-pet / dsh-better-sidebar 这类插件用::before+flex:none;width:16px;height:16px给自己的分区画图标,正好和我们的两颗图标抢同一个伪元素。两套规则合并后,我们的left:0;right:0定位层被 16px 的规则压成小方块,两层遮罩直接被裁没——现象就是「这一行没有眼睛和星星」。现在我们把::before完整让出来,自己的两颗图标只占::after,并显式写width:auto;height:auto;flex:none防别家规则再次挤压。 - 四位归属于四个插件的行与插件一一对应(
opencode-go-i18n→dsh-opencode-go、pets→dsh-pet、market→dshmarket、side-cards→dsh-better-sidebar),所以此前只有「干净」的那些行是正常的。
测试
- e2e 33 → 34 条:新增「第三方插件占了
::before(dshmarket/dsh-pet 式)也不影响我们的两颗图标」——在行上注入对方的真实样式,断言我们的图标层仍是整行宽、两层遮罩位置不变(7px/29px)、且对方::before的 16px 分区图标还在。 - 归零证据:换回 1.4.2 的 client.js 跑同一套 e2e,34 条里 3 条失败(「第三方占用 ::before 后我们的图标层没了:none」等),换回 1.4.3 全绿 34/34。
- 单测 42 条、仓库校验 16 条不变(
::before→::after的断言同步改)。
1.4.0 —— 编辑模式里点星标直接固定到侧栏
编辑模式里顺手固定:设置导航每一行右端多一颗星标,和眼睛并排,点一下就把该分区钉到主界面插件栏,不用再进入口页找 ☆。顺带把齿轮旁那句被截断的说明改成三行完整版。
新增
- 导航行星标(☆/★):编辑模式下每行右端 0–26px 是星标区、26–50px 是眼睛区,两颗 18px 图标并排、中间留 6px。空心点一下变实心 = 已固定,再点取消。
- 两处 ☆ 同源:导航行星标与入口页的固定按钮共用
pinned与同一个setPinned(),任一处点,另一处立刻同步(已固定态、禁用态、上限 5 个、隐藏分区拒绝),并走同一条持久化。 - 说明文案改版:齿轮旁提示从单行改成三行(星标/眼睛 → 改名/分组 → 侧栏开关),不再被
ellipsis截断。
行为说明
- 星标只在编辑模式可见(规则都挂在
[data-snm-editing="1"]下),退出编辑即恢复干净的行;拖拽门槛 40 → 50px,两段命中区都不误触发拖拽。 - 已隐藏的分区星标压暗到 0.22,点了只给提示(「已隐藏的分区不能固定到侧栏,先显示它」),不改
pinned、不写盘。 - 行内右侧预留 52 → 56px,标签截断宽度 76 → 72px,长分区名仍在星标左侧。
测试
- 单测 39 → 41,e2e 27 → 29(真实 Chrome,A/B 对照 15 条标注全部有效),仓库校验 16 条全绿。
- 测试台的 locale 桩改为真解析词典,截图/文案不再显示原始 key。
安装:dsh plugin install dsh-settings-nav-manager 或从 npm / GitHub tarball 安装;完全退出并重开 DSH 后生效。完整对比见 CHANGELOG.md。
v1.3.0 — 分区固定到侧栏:点一行直达设置
把常用的几个设置分区钉到主界面侧栏,点一下就打开对应设置——不用再进入口页翻。 关掉设置后还停在你原来的页面,主面板不会被切走。
本次更新
| 功能 | 说明 |
|---|---|
| 📌 分区固定 | 入口页每行右侧的 ☆ 一点变 ★,该分区就钉到侧栏插件栏(排「设置导航」入口之后),最多 5 个,超限会提示、不静默丢弃 |
| ⚡ 一键直达 | 点固定行 = 打开设置并选中该分区。实现是在 document 捕获阶段拦下这一行的点击,宿主的 selectPanel 收不到事件,所以当前主面板不切走 |
| 🛟 兜底页 | 每个固定行同时注册同名 main 页。布局恢复 / 深链 / 键盘激活绕过拦截时,也不会抛 main panel "..." is not registered,而是给出「打开设置 / 返回」两个出口 |
| 🙈 隐藏即取消固定 | 已隐藏的分区不能钉(☆ 置灰);隐藏一个已钉的分区会自动取消固定 |
| 🌐 语言无关 | 固定行标题实时解析,切英文界面标签跟着变,不重建注册 |
| 💾 持久化 | pinned: string[] 与排版同一命名空间;未知分区写盘前过滤,隐藏分区归一化时自动取消固定 |
质量
- 单测 39 / 仓库校验 16 / e2e 27 全绿(新增 5 条固定相关场景,A/B 对照 15 条标注全部在旧版失败)
- 升到本版无需迁移:旧配置自动归一化,缺
pinned即空数组
安装
# 网页版(dsh web)
dsh plugin add dsh-settings-nav-manager
# 桌面版:装进 desktop profile 后重启应用已在 DSH 0.2.1-rc.2 的
web/desktopprofile 实测。纯 JS / ESM,无需构建。
v1.2.1 — 评审返工:深链可验证、入口开关三方一致、启动不闪
一次「代码评审打回」后的返工版本,修的是 1.2.0 里真实存在的健壮性问题。
修复
- 深链可验证:点入口页某行后不再「点了没反应」——失败会在页面里显示「未能打开该分区」+「重试」,并把内部原因打到控制台
- 入口开关三方一致:切换失败时按钮、磁盘、侧栏三处一起回滚并提示原因,不再出现「入口没了但磁盘还是 false」
- 启动不闪:
hideEntry: true时启动过程侧栏从不出现那一行(先读状态再注册,而不是先注册再摘) - 定时器托管:所有
setTimeout集中登记,卸载时统一清理,不留野定时器 - 清理自救出口:即使入口行被隐藏,也能从设置里把开关找回来
- 常量收敛:面板 id 命名空间化为
settings-nav-manager.nav,排序位抽成ENTRY_ORDER = 20
质量
- 单测 31 / 仓库校验 16 / e2e 22 全绿,其中 15 条为 A/B 对照(旧版必须失败)
安装
# 网页版(dsh web)
dsh plugin add dsh-settings-nav-manager
# 桌面版:装进 desktop profile 后重启应用已在 DSH 0.2.1-rc.2 的
web/desktopprofile 实测。纯 JS / ESM,无需构建。
v1.2.0 — 编辑模式可收起侧栏入口
在 1.1.0 的侧栏入口之上,加一个「不想要它就别显示」的开关。
新增
- 🙈 入口开关:编辑模式下齿轮旁多一个「侧栏入口 显示中 / 已隐藏」,点一下把侧栏那行收起来
- 页面保留在册:隐藏的只是侧栏入口行,
main页仍在注册表里,不会让宿主指向空面板 - 状态随排版持久化:重启仍是隐藏,且启动瞬间不会先闪一下
- 想找回:设置 → 齿轮进编辑模式 → 再点一下开关
说明:v1.1.0 与 v1.2.0 是同一提交发布(1.1.0 的功能先做完,1.2.0 在其上叠了开关),两个 tag 指向同一 commit,功能为叠加关系。
安装
# 网页版(dsh web)
dsh plugin add dsh-settings-nav-manager
# 桌面版:装进 desktop profile 后重启应用已在 DSH 0.2.1-rc.2 的
web/desktopprofile 实测。纯 JS / ESM,无需构建。
v1.1.0 — 侧栏「设置导航」入口:点一行直达设置分区
把设置页的分区清单搬到主界面侧栏,两下点到任意设置分区。
新增
- 🧭 侧栏入口:主界面插件栏新增一行「设置导航」(排在插件市场 / 自动化任务之后)
- 入口页:一页列出全部分区,跟随你整理的顺序与抽屉分组;已隐藏的分区折在底部,可展开查看
- 点行直达:点任意一行打开设置并选中该分区(深链走
sidebar.settings的openSection,失败自动退化为 DOM 点击) - 不切主面板:打开设置不会把你正在看的页面换掉
说明:该 tag 与 v1.2.0 指向同一提交(1.2.0 在同一提交里追加了入口开关),功能上 v1.2.0 ⊃ v1.1.0。
安装
# 网页版(dsh web)
dsh plugin add dsh-settings-nav-manager
# 桌面版:装进 desktop profile 后重启应用已在 DSH 0.2.1-rc.2 的
web/desktopprofile 实测。纯 JS / ESM,无需构建。
v1.0.3 —— 三个静默故障的修复
升级建议
所有 1.0.x 用户建议升级。 本版不新增功能,只修安全与正确性——三个问题都属于「界面上看不出异常、事后也查不出」的类型。
1. 可能覆写其他插件的配置(安全,最严重)
插件在找不到自己的设置命名空间时,会按「schema 里有 order/groups/hidden 三个字段」去猜一个命名空间来写。猜错的后果被同一条写入链上的 replace(整份替换)放大:对方命名空间里其余的字段会被直接删掉,没有备份,也不会提示。
现在猜必须猜得动:候选唯一、且值的形状也吻合,才允许认领;不满足就一个字都不写并提示「未能保存排版」。replace 整层写入已移除。
触发前提是「自己的命名空间不在
describe()里」,而这恰好是某一类安装/升级故障——也就是说,它在最需要保守的时刻最危险。
2. 被合法拒绝的写入会被「加权重试」(安全)
保存失败时,插件原先会依次换 update → replace → mutate 三条写入口重试。如果拒绝原因是校验失败 / 配额 / 只读 / 权限,换一条更宽的入口重试,等于用更大的权限去绕过宿主的校验。
现在只有「配置条目/命名空间不存在」这一类错误才换路重试,其余原样上报给用户看。
3. 快速拖拽时落点会丢(正确性)
这是 1.0.1 引入的回归。1.0.0 在抬手时同步提交落点,本来是对的;1.0.1 为了性能把预览改成按帧合并,顺手把「落点提交」也挪进了帧回调。
结果:如果最后一次移动和松手挤在同一帧(快速甩动、高刷屏、指针尾帧抖动),帧回调还没跑,拖拽状态已被清空——落点丢失,顺序弹回原位,而且还白写了一次盘。
现在抬手这一刻就同步结算落点,并用世代号作废已排队的帧回调。
升级后你会注意到的变化
- 拖拽更跟手:快速拖完松手,顺序会稳定落在你要的位置;
- 保存失败不再悄悄重试三次;提示里给的失败原因更准;
- 极端情况下(宿主把插件条目 id 改了、且无法确认对应命名空间)你会看到「未能保存排版」,而不是数据被写进别人的命名空间。
验证
| 项 | 结果 |
|---|---|
npm test |
35/35(原 31,新增 4 条:错误分类、认领条件、replace 守卫) |
npm run test:e2e |
18/18(原 13),含对 1.0.0 的 A/B 对照,15 条断言在旧版确实失败 |
同帧握手丢落点这条用例特意没有标进 A/B:它要拿 1.0.2 做基线才测得出来(1.0.0 本来是对的),标了反而会被判成无效断言。
升级方式
dsh plugin --profile <web|desktop> remove dsh-settings-nav-manager
dsh plugin --profile <web|desktop> add dsh-settings-nav-manager@1.0.3桌面版的
desktopprofile 由桌面应用独占管理:先启动一次应用让它初始化 profile,完全退出后再执行命令,然后重开应用。
装完必须完全退出并重开,页面才会加载新代码。
完整条目见 CHANGELOG。
v1.0.2
使用说明
打开 设置,点击标题栏中「打开配置文件」左侧的 ⚙ 齿轮进入编辑模式。齿轮高亮、旁边出现操作提示,就表示已经进入。
排序
- 按住任意条目整行上下拖动,实时预览插入位置,松手即保存。
- 也可以先聚焦到某一行,再按
Alt + ↑ / ↓逐格移动。
隐藏与恢复
- 点条目右侧的 👁 眼睛切换显隐;隐藏后条目置灰、眼睛变成划线眼,再点一次即恢复。
- 非编辑模式下,被隐藏的条目直接不显示;再进一次编辑模式就能找回。
- 允许把全部分区都隐藏。
抽屉(命名分组)
- 点底部「+ 新建抽屉」创建,创建后立刻可以输入名字(1–32 字,可重名)。
- 把条目拖到抽屉名上即入组;拖到抽屉外即出组;组内也可以继续排序。
- 点抽屉头任意位置折叠 / 展开(
▾/▸)。 - 双击抽屉名改名;点
×解散,成员回到未分组并保持原有顺序。 - 支持创建空抽屉。
恢复默认
编辑模式底部点「恢复默认」,清空所有抽屉、隐藏与排序,回到 DSH 的原始顺序。
退出
再点一次齿轮,或按 Esc。
(在抽屉改名的输入框里按 Esc 只会取消这次改名,不会退出编辑模式。)
键盘操作
| 操作 | 快捷键 |
|---|---|
| 条目 / 抽屉上下移动 | Alt + ↑ / Alt + ↓ |
| 切换显隐(聚焦到条目上) | h |
| 折叠 / 展开抽屉(聚焦到抽屉头上) | Enter 或 Space |
| 抽屉改名(聚焦到抽屉头上) | F2 |
| 退出编辑模式 | Esc |
数据保存在哪
排序、显隐与抽屉结构写入 DSH 设置文档的 settings-nav-manager 命名空间,重启与切换界面语言后都保留。如果写入失败,齿轮旁会出现提示并给出原因。
完整文档见 README。
