dsh-sidebar-organizer
给 DSH 侧栏做整理的插件:把上下两片"插件堆"折叠起来、条目太多时变成滑动窗口、任意条目可以变成可拖动的悬浮窗、还能自己调先后顺序。
写它是为了一个具体问题:侧栏同时装了费用计量、任务管理、归档、工作台、5 个导航项之后,纵向上挤成一条,主界面反而被压窄。
它做什么
| 区域 | 默认行为 | 展开后 | 固定 |
|---|---|---|---|
| 上方「导航面板」(插件 / 插件商店 / 自动化任务 / 上下文洞察 / 记忆系统) | 折叠,只留一行 ▾ 导航面板 5 |
全部显示;超过 7 条自动变成滑动窗口 | 点 ⚑ 固定,切换面板后不再自动收起 |
下方「快捷面板」(sidebar.footer.action 里注册的一切) |
折叠,只留一行 ▾ 快捷面板 4 |
向上展开;超过 5 条变成滑动窗口,滚动条停在底部 | 点 ⚑ 固定 |
| 下方条目 · 显示 | 折叠时整条保留(全量功能) | 在 ⚙ → 名单里勾「显示」 |
落盘保存 |
| 下方条目 · 摘要 | 折叠时只留你勾选的任意几行 | 勾「摘要」后逐行复选;与「显示」二选一,不支持悬浮 | 落盘保存 |
| 下方条目 · 悬浮 | 整块脱离侧栏变浮窗 | 勾「悬浮」;勾上会自动点亮「显示」 | 坐标会记住 |
| 条目的先后顺序 | 插件注册顺序 | 在名单里拖左侧抓手调整 | 落盘保存 |
登录 / 账户入口(sidebar.settings)永远不动:它在 footArea 的 settingsArea 里,是本插件唯一明确避开的一块——不折叠、不排序、不悬浮,任何时候都不参与排序。下方折叠条插在它上面。
复合条目(一个插件内部有多行)
计费插件那种「今日 / 余额 / 重置」堆在一起、或者一个卡片里既有标题又有金额的,DOM 上是一个根节点内部多个视觉行。本插件按根节点计量:
- 侧栏里算一条(折叠条的计数、名单里的一行都是一条);
- 不拆行:折叠、悬浮、拖动排序都按整条生效,内部结构原样保留;
- 名单里标
复合 · N 行; - 只有「摘要」是在行级别生效:勾上后出现一份行清单,每行一个复选,勾哪几行折叠后就留哪几行(顺序固定按原 UI 自上到下,默认只勾第一行;至少保留一行,所以只剩一行被勾时它不可取消)。
图形与图表(条形图 / 饼图 / 统计图)
行探测是按"垂直位置"分行的,而图形天生不适合这么切——饼图的扇区、条形图的柱子都在不同高度上,照行切就会把图表拦腰截断。所以图形一律当原子块:
- 认什么:
svg/canvas/img/video/iframe/progress/meter、role="img"、以及 class 命中chart|graph|spark|sparkline|pie|donut|gauge|progress|histogram|bar的节点; - 不下钻:图形节点内部的任何元素都不再参与分行(扇区、柱子、折线点都不算"行");
- 纯图形包装层也算一块:
<div class="chart-wrap"><svg>…</svg></div>这种"一路单子节点包到一个图形"的结构,整块算 1 行,摘要列表里显示为(图表)/(图形); - div 画的条形图:没有 svg 可认,就看结构——同一层里 ≥3 条、每条高度 ≤10px、宽度都明显窄于容器,判定为一组条形,合并成 1 行;
- 一行里有多个图形:并排的「文字 + 迷你趋势图」本来就垂直重叠,属于同一行,图的节点和文字一起保留/隐藏,不会被拆开;
- 多个图表各占一行:每个图表块各自成为一行,可以分别勾选保留哪些。
用法
- 上方那行折叠条:点一下展开/收起,
⚑固定,⚙打开设置。 - 下方那行同理,只是方向朝上。
- 设置里有:上下方名称(可自定义,留空回落默认)、顶部/底部滑动阈值、默认折叠开关、例外与悬浮名单、恢复默认。
- 悬浮窗拖动:按住 Alt 拖,或从顶部 3px 的抓取带拖。鼠标移入浮窗时下方会浮出一行无框的
Alt 拖动提示。 - 两个浮窗互相压住时,相交双方的顶边变成 4px 加粗告警边(错开就恢复)。
- 每行左侧是拖动抓手
⠿:按住上下拖调整该条在区域里的先后。已悬浮的条目不参与排序(抓手变灰),永远沉在所属区域最下方;取消悬浮后自动回到它在顺序里的位置。 - 复合条目标了
复合 · N 行,拖动时整块移动;勾「摘要」后才出现行清单,用来挑折叠后留哪几行(列表按真正的视觉行枚举,多层包装的卡片也能逐行列全)。 - 三态互斥且可逆:勾「摘要」时会把当前的「显示 / 悬浮」拍个快照,取消「摘要」就按快照还原——原来只是显示就还是显示,原来是浮窗就让它在原坐标回来,原来是隐藏态就仍然隐藏。
所有设置存在浏览器 localStorage 的 dsh-sidebar-organizer:v3,清掉即恢复默认。
卸载与清理
清理登记在 cordis 的 ctx.effect 上,宿主禁用插件或热更新时会真的执行:
- 断开
MutationObserver、resize监听、首绘轮询定时器; - 删掉插件自己创建的节点(折叠条、弹窗、
Alt 拖动提示)与注入的<style>; - 抹掉打在宿主节点上的全部标记(
data-dso-hide / ord / ordbox / bottombox / scroll / summary / vshow / collapsed、--dso-max-h、浮窗坐标变量),并按记录的引用摘掉挂在宿主容器上的中键监听。
第 3 步以前是缺的:那时只在 window.__dsoDispose 上挂了个函数,宿主卸载时没人调用,MutationObserver 还活着、会把折叠条一次次塞回侧栏。现在 apply(ctx) 里补了 ctx.effect,并且同一页面里重复 apply 会先完整拆掉上一轮(折叠条不会叠加成两份)。
实现与风险
它不接管任何插件的渲染,只做四件事:给侧栏已有的容器打 data-dso-* 标记、注入一段 CSS、在折叠条上挂点击事件、按需移动行。
定位用的是 nav[class*='panelList']、div[class*='footArea']、div[class*='footerActions']、div[class*='settingsArea']、[class*='dsh-wt_'] 这类属性选择器,匹配的是 CSS Module 类名里的语义部分,因此 DSH 升级重新生成哈希前缀也不会失效。
排序优先用 CSS order(不动 React 渲染的 DOM)。但 order 只在真正生效的 flex/grid 容器里对直接子节点起作用,所以运行时还会自检:容器是不是 flex/column、第 2 行拿到的 order 是不是真的变成 1;任一不成立就退回按目标顺序 insertBefore 的兜底。设置面板底部有一行自检结果,形如 下方 4 项 · flex/column · order 1 ✓ 或 … · DOM 兜底。
需要知道的两点:
- DSH 侧栏是 React 渲染的,本插件插在它旁边的折叠条是"外部节点"。React 重排时可能把它挤掉,插件靠
MutationObserver重新插回,极端情况下会看到一次闪动。 - 悬浮窗用的是
position: fixed。如果它的某层祖先带了transform/filter,fixed 会退化成相对定位,浮窗就贴不住视口。遇到这个情况关掉悬浮开关即可。
版本记录
- 0.2.3(首个公开发布版 · 2026-10-24):修复「设置弹窗在壁纸/玻璃主题下看不清字」——面板与悬浮窗原来只继承
--dsw-alias-bg-layer-2,而壁纸类插件会把这个 token 换成半透明玻璃色;不给它自己的backdrop-filter,就等于让壁纸从弹窗里透上来、文字发飘。现在底色改为「实色面板色(--we-panel-color)按 94% 混透明」并补上backdrop-filter: blur(16px) saturate(1.4);没有壁纸插件时自动退回原 token,观感不变。两个旋钮--dso-panel-solid/--dso-panel-blur可就地覆盖。
0.2.3 是首个对外发布版本;此前的 0.1.x / 0.2.0–0.2.2 都是本机迭代版,未对外发布,故不列入。
No comments yet. Be the first to write one.