dsh-any-background 0.3.10 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -12
- package/README.zh.md +13 -12
- package/lib/client.js +313 -92
- package/lib/client.js.map +1 -1
- package/lib/index.js +325 -73
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -82,9 +82,9 @@ controls (`z-index:-1`) and carries its own ink (`--dsh-any-caption-ink`), so th
|
|
|
82
82
|
应用 / 编辑 menubar stay readable even when a low sidebar opacity makes the strip light — and 「标题条带文字」 says who wins when the strip's brightness and the theme's direction disagree (自动 derives it from the strip, 跟随主题 leaves the host's own label ink alone, 始终白色 / 始终黑色 pins it; see issue #30). The anchor is expressed in CSS (the row is the `conversation.session.header` slot's direct parent) instead of guessing a hashed class or tagging a host element at runtime; before `0.1.7-alpha.1` the host mounts that slot bare with no such element, so there the rule matches nothing and the part is simply inert. On the Windows desktop shell the same slider pair also drives the window caption band — except for the segment that sits above the left sidebar, which belongs to that sidebar's own pair (see **Left sidebar + the caption band above it**) — and the native minimize/maximize/close block is handed `transparent` so Windows paints no background of its own, leaving the band itself showing through. A blank session marks the row `headerBlank` (a placeholder left with only its padding) and the plugin skips claiming it.
|
|
83
83
|
- **Sidebar "Theme" page (dual mode)** — The same five pages (Color / Interface / Font / Background / Profiles) register into two surfaces: without dsh-better-sidebar, a "Theme" card is contributed to the **official right Sidebar's guide page** through its public extension points (`sidebarRightTabs` + the `sidebar.right.pane.tab` keyed seat); with dsh-better-sidebar installed, the page registers in that plugin's sidebar instead and the official guide card withdraws itself, so the two never duplicate. Settings panel, official sidebar and better-sidebar all share one page implementation and one state store — a change in any of them shows up everywhere. The shell adapts to the panel width, and a narrow panel tightens padding and falls back to a single column. On a host without the right Sidebar the registration silently never happens.
|
|
84
84
|
- **Conversation View Cards** — The message list is wrapped in a translucent card automatically, and the trajectory page gets whole-page opacity & blur controls, letting the wallpaper shine through the content.
|
|
85
|
-
- **Theme Export / Import** — One-click export to a self-contained `dsh-any-theme.json` (config + wallpaper, video embedded as a data URL) and import to restore it anywhere.
|
|
86
|
-
- **Appearance Presets & Profiles** — Six one-click presets (Default / Frosted glass / Minimal / Midnight / Cyber / Warm daylight) plus named profiles: save the current look and re-apply it anytime
|
|
87
|
-
- **Wallpaper Rotation** — Add images to a rotation pool (thumbnail picker included) and let the wallpaper change by shuffle or order on every refresh, daily, or weekly. Advancing copies the chosen image into the active wallpaper slot, so export/import and color extraction keep working unchanged.
|
|
85
|
+
- **Theme Export / Import** — One-click export to a self-contained `dsh-any-theme.json` (config + wallpaper, video embedded as a data URL, and — from v0.4.0 — the whole rotation pool's image bytes) and import to restore it anywhere.
|
|
86
|
+
- **Appearance Presets & Profiles** — Six one-click presets (Default / Frosted glass / Minimal / Midnight / Cyber / Warm daylight) plus named profiles: save the current look and re-apply it anytime; profiles can be renamed and duplicated, and a two-step confirm guards deletion.
|
|
87
|
+
- **Wallpaper Rotation** — Add images to a rotation pool (thumbnail picker included) and let the wallpaper change by shuffle or order on every refresh, hourly, daily, or weekly — the cadence advances while the page stays open, not only on reload. Advancing copies the chosen image into the active wallpaper slot, so export/import and color extraction keep working unchanged.
|
|
88
88
|
- **Day/Night Auto Switch** — Assign a day profile and a night profile; the plugin switches automatically at fixed clock times or by following the OS dark mode.
|
|
89
89
|
- **Custom Font** — Upload a ttf / otf / woff / woff2 file (up to 100 MB) and apply it to the whole interface through `@font-face`; toggle it off or remove it at any time. Fonts stream as raw bytes and persist in the plugin data dir; code blocks keep their monospace stack.
|
|
90
90
|
- **Per-part Text Outline** — The same surface groups as the interface page (now eleven, including the header popovers and the header bar), each with its own `-webkit-text-stroke`: width 0–4 px (0 = off) and a color of auto-contrast / gray / black / white / accent / custom. Code blocks, inline `code`, icons and the host's `background-clip: text` shimmer chrome (the "深度求索中" turn-status line and the turn-process rows) are exempted automatically, so multi-color syntax never smears and gradient text is never flattened into a stroke-coloured blob.
|
|
@@ -95,18 +95,19 @@ controls (`z-index:-1`) and carries its own ink (`--dsh-any-caption-ink`), so th
|
|
|
95
95
|
|
|
96
96
|
## Changelog (latest two releases)
|
|
97
97
|
|
|
98
|
-
### v0.
|
|
98
|
+
### v0.4.1 (fix: the "Every refresh" rotation cadence flipped the wallpaper every 30 seconds)
|
|
99
99
|
|
|
100
|
-
-
|
|
100
|
+
- **What happened.** v0.4.0 taught the 30-second schedule tick to advance a due rotation so an `Hourly` cadence works while the page stays open. But the due-math says "always due" for the `Every refresh` cadence — that is how a page load earns a fresh pick (the server advances it inside the `read` RPC). Wired into the tick, it meant: rotation enabled + `Every refresh` selected → the wallpaper switched itself every 30 seconds, and again on every OS dark/light flip or enabling the day/night schedule (both also drive the tick).
|
|
101
|
+
- **The fix.** Whether a cadence participates in live ticking is now a shared-math question: `rotationAdvancesLive()` in `src/shared/rotation.ts` (inlined into both bundles, like the rest of the cadence math) says only the time-based cadences — hourly / daily / weekly — do. `Every refresh` keeps its exact original semantics: one fresh pick per page load, plus the manual next button. Boot-time fallback and the enable-toggle behavior are unchanged.
|
|
101
102
|
|
|
102
|
-
### v0.
|
|
103
|
+
### v0.4.0 (persistence-integrity batch + rotation / export / profile features)
|
|
103
104
|
|
|
104
|
-
- **
|
|
105
|
-
- **
|
|
106
|
-
- **
|
|
107
|
-
- **
|
|
108
|
-
- **
|
|
109
|
-
- **
|
|
105
|
+
- **Theme exports now carry the whole rotation pool (v3).** The old export carried the config and the active wallpaper only: the pool's metadata (file names + thumbnails) travelled with the config while the image bytes stayed on the source machine, so after an import on another machine every activation failed with `file missing`. A v3 export embeds each pool image's bytes (fetched from the new `/dsh-any-background/rotation/file` route, whose name goes through the same anti-traversal fence the config sanitizer uses) as `pool`; the import runs a new `rotationRestore` RPC that rebuilds the pool wholesale — bytes land under their exported file names, unreferenced files are dropped, and the cursor clamps into the new range. Dead entries in v2 files clear on import instead of failing on every activation.
|
|
106
|
+
- **Rotation gains an hourly cadence — and advances while the page stays open.** Advancing used to happen only inside the `read` RPC on page load, so a long-lived window never changed wallpaper; the 30-second schedule tick now re-checks it too (pure math gate — a no-op when nothing is due). The due/pick math moved into a shared module inlined into both bundles at build time (`src/shared/rotation.ts`), so the two halves can never disagree on a day/week boundary again.
|
|
107
|
+
- **Profiles can be renamed and duplicated.** Each row gains an inline rename (Enter commits) and a one-click duplicate (fresh id, `(2)` name suffix, same 20-entry oldest-eviction limit).
|
|
108
|
+
- **Persistence correctness fixes — each matching a failure mode this repo has already hit.** `readConfig`'s failure path handed back a shallow copy whose nested arrays rotation add/remove mutated in place, leaving ghost pool items in the module-level defaults forever (now `structuredClone`); a failed config write left the mtime-keyed cache describing changes the disk never got (cache dropped before writing); the font slot's stray-file adoption mislabelled MIME by file name, serving woff2 bytes as ttf (now sniffed from real magic bytes and persisted); raw wallpaper uploads skipped byte validation (now the same magic-number fence as the URL download and the font upload); rotation file names could collide within one millisecond (random suffix added); manual activation did not persist the cursor, so a reload jumped back to the old image (server-side read-modify-write, the same semantics as the auto-advance).
|
|
109
|
+
- **Structure & performance.** The browser half's four body-level MutationObservers merged into a single bus (`src/client/dom-watch.ts`, auto-disconnecting on the last unsubscribe); the parts pass moved from rAF to microtask coalescing — the v0.3.9 lesson (a queued frame never runs while the window is not painting), so a view or takeover card mounted in the background is styled immediately; `applyWp`'s fan-out deduplicated (the produced / header-popover passes ran twice per apply); a failed config write retries once (a transient Windows EBUSY from an antivirus scan) and then warns explicitly instead of being swallowed; `read` probes its three slots concurrently; a first run writes the config once, not twice; startup sweeps crash-leftover tmp files, excess `.corrupt-*` archives (keeping the newest 3) and orphaned pool files (10-minute grace); rotation advance/activate uses `copyFile`, so multi-MB wallpapers no longer pass through the heap whole.
|
|
110
|
+
- **i18n cleanup.** Four dead keys removed and embedded Chinese quotes in the English copy replaced; zh/en at 197/197 key parity.
|
|
110
111
|
|
|
111
112
|
## Installation
|
|
112
113
|
|
package/README.zh.md
CHANGED
|
@@ -80,9 +80,9 @@
|
|
|
80
80
|
- **标题栏(会话标题行)** — 会话顶部那条标题 / 操作 / 视图页签行终于有了自己的一对滑块。宿主自身不给它任何底色(中心列的底色直接透上来),所以壁纸一起来,标题与页签就直接压在图上、和周围被蒙住的表面割裂。现在它按「区块淡色」作画,配方与对话文本框那张卡一致:材质取插件主背景面的颜色、按本部件自己的透明度上色,读起来是压在列上的一条带,而不是叠上去的第二层颜色;模糊落在行前的一块 `::before` 垫层上(配合 `isolation:isolate`——它是层叠上下文,但**不是** backdrop root;0.3.8 之前霜直接压在行身上,而行一旦带上 `backdrop-filter` 就成了 backdrop root,恰恰把挂在行里的那些浮层的磨砂压成一片平色);而这道霜仍然把行变成层叠上下文,所以行同时带上补偿性的 `z-index:10`——行内挂出的浮层(直到 `0.2.1-alpha.1` 的后台任务列表、每个 release 上都可能就地的日程任务菜单与「会话日志」`…` 菜单)本来用 `z-index:100`,否则会被关在行里、压到对话之下。10 高于它会重叠到的列内部件(输入位 9、回到底部 8),又远低于所有页面级表面(100 / 1000 / 1100),因此打开菜单时这一条的颜色和模糊都不会变;`z-index` 无需 `position`——该行本是 flex 子项,`z-index` 天然生效,而垫层要用的 `position:relative` 只在模糊非 0、且宿主把这一行留在 static 时才以内联方式写入。详见 v0.3.7 / v0.3.9。Windows 上它驱动的条带与侧栏分段(见上一条);模态打开时条带会跟着宿主蒙版自行变暗(宿主蒙版故意停在标题区下方);生成出来的那一段只负责绘制——`pointer-events:none` 且不声明 app-region——因此不会吞掉本该给原生标题栏菜单的点击(issue #29)。它还画在控件之下(`z-index:-1`),并自带墨色(`--dsh-any-caption-ink`):即使侧栏透明度很低、条带发浅,开合按钮与「应用 / 编辑」菜单也清楚可读;而当条带的明暗与主题方向冲突时,由「标题条带文字」裁定谁获胜——「自动」沿用条带推导,「跟随主题」完全不写覆盖(回到宿主的标签墨色,即 0.3.7 及之前),「始终白色 / 始终黑色」直接钉死(issue #30)。这一行是**运行时认领**的:插件从 `conversation.session.header*` 槽位锚点向上找到最近的那个 `<header>` 再打上自己的类(与卡片、帧同款做法),不猜哈希类名、也不依赖宿主把槽位摆在哪个层级;`0.1.7-alpha.1` 之前宿主把槽位裸挂在会话根上、没有这一行元素,那种宿主上插件什么都不会认领,部件自然无效果。桌面壳(Windows)上这一对滑块同时驱动窗口标题条带——**但左侧栏正上方的那一段除外**,那一段归「侧栏」这对滑块管(见下条);原生最小化/最大化/关闭那块改由取色探针报 `transparent`,让 Windows 不画自己的背景,露出的正是条带本身。空会话时宿主把该行标为 `headerBlank`(一条只留 padding 的占位),插件跳过认领。
|
|
81
81
|
- **侧边栏「主题」页面(双模式)** — 同一套五页(色彩 / 界面 / 字体 / 背景 / 配置)注册到两处:未安装 dsh-better-sidebar 时,通过官方右侧栏的公开扩展点(`sidebarRightTabs` + `sidebar.right.pane.tab`)在**官方侧边栏**的引导页挂一张「主题」卡片,点开即五页;安装了 dsh-better-sidebar 时,改为在它的侧边栏注册同名页面,官方引导页上的卡片自动撤下,避免重复。两处(加设置面板共三处)共用同一套页面代码与同一份状态,改一处处处同步;外壳按面板宽度自适应,窄面板收紧内边距并回到单列。宿主没有右侧栏扩展点时静默不注册,不影响任何其它功能。
|
|
82
82
|
- **对话视图卡片** — 消息列表自动包裹为半透明卡片,轨迹页可整页调节透明度与模糊,让壁纸从内容后方透出来。
|
|
83
|
-
- **主题导出 / 导入** — 一键导出为自包含的 `dsh-any-theme.json`(配置 + 壁纸,视频以 data URL
|
|
84
|
-
- **外观预设与配置档案** — 六套一键预设(默认 / 毛玻璃 / 极简白 / 暗夜紫 / 赛博 /
|
|
85
|
-
- **壁纸轮换** — 把多张图片加入轮换池(缩略图选择器),按随机或顺序、每次刷新 / 每天 /
|
|
83
|
+
- **主题导出 / 导入** — 一键导出为自包含的 `dsh-any-theme.json`(配置 + 壁纸,视频以 data URL 内嵌,v0.4.0 起连同整个轮换池的图片字节),可随时导入还原。
|
|
84
|
+
- **外观预设与配置档案** — 六套一键预设(默认 / 毛玻璃 / 极简白 / 暗夜紫 / 赛博 / 暖阳),外加自定义命名档案:随时保存当前观感、随时套回,支持重命名与复制,删除有二次确认保护。
|
|
85
|
+
- **壁纸轮换** — 把多张图片加入轮换池(缩略图选择器),按随机或顺序、每次刷新 / 每小时 / 每天 / 每周的频率自动更换,页面开着也会按时推进(不再只在刷新时更换);切换时服务端把所选图片复制进当前壁纸槽,导出/导入与取色管线完全不用改。
|
|
86
86
|
- **昼夜自动切换** — 指定日间与夜间两套配置,按固定时段或跟随系统深色模式自动切换。
|
|
87
87
|
- **自定义字体** — 上传一个 ttf / otf / woff / woff2 字体文件(上限 100 MB),通过 `@font-face` 应用到整个界面的文字;可随时停用或移除。字体按原始字节流式上传并持久化到插件数据目录,代码块仍保持等宽字体。
|
|
88
88
|
- **分组文字描边** — 沿用界面页的分组(现为十一组,含顶栏选项与标题栏),为每个分组单独加 `-webkit-text-stroke` 描边:粗细 0–4 px(0 = 关闭),颜色支持自动反色 / 灰 / 黑 / 白 / 主题色 / 自定义。代码块、`inline code`、图标,以及宿主那类 `background-clip: text` 的流光文字(「深度求索中」状态行与轮次过程行)自动豁免——多色语法不会糊成一团,渐变文字也不会被描边压成一坨纯色。
|
|
@@ -93,18 +93,19 @@
|
|
|
93
93
|
|
|
94
94
|
## 更新日志(只保留最近两个版本)
|
|
95
95
|
|
|
96
|
-
### v0.
|
|
96
|
+
### v0.4.1(修复:「每次刷新」档位壁纸每 30 秒自动切换)
|
|
97
97
|
|
|
98
|
-
-
|
|
98
|
+
- **发生了什么。** v0.4.0 让 30 秒一次的定时检查顺带推进到期的轮换,好让「每小时」档在页面长驻时也能换图。但到期数学对「每次刷新」档位是**恒为到期**——这正是页面加载能拿到新图的原因(服务端在 `read` RPC 里推进它)。把它接进定时器后就成了:轮换开启 + 选了「每次刷新」→ 壁纸每 30 秒自己换一张;系统明暗翻转、开启昼夜定时时也会跟着再切一次(这两处同样驱动该定时器)。
|
|
99
|
+
- **怎么修的。** 「哪些档位参与活推进」现在是共享数学的一部分:`src/shared/rotation.ts` 新增 `rotationAdvancesLive()`(与其余到期数学一样构建时内联进两个 bundle),只有时间档位——每小时 / 每天 / 每周——参与活推进。「每次刷新」回到它原本的语义:每次页面加载换一张,外加手动「换一张」按钮。boot 回退与开启开关时的立即换图行为不变。
|
|
99
100
|
|
|
100
|
-
### v0.
|
|
101
|
+
### v0.4.0(持久化正确性批次 + 轮换 / 导出 / 档案功能)
|
|
101
102
|
|
|
102
|
-
-
|
|
103
|
-
-
|
|
104
|
-
-
|
|
105
|
-
-
|
|
106
|
-
-
|
|
107
|
-
-
|
|
103
|
+
- **主题导出现在带上整个轮换池(v3)。** 旧导出只带配置与主壁纸:轮换池的元数据(文件名 + 缩略图)随配置走了,图片字节却留在原机器上,换机导入后每次切换都报 `file missing`。v3 导出把池内每张图的字节(从新路由 `/dsh-any-background/rotation/file` 取回,名称走与配置清洗相同的防穿越围栏)内嵌为 `pool`;导入走新的 `rotationRestore` RPC 整体重建——字节按导出时的原文件名落盘、清掉未被引用的旧文件、游标夹取进新范围。v2 旧文件里的死条目会在导入时清空,而不是留着每次激活都失败。
|
|
104
|
+
- **轮换新增「每小时」档,且页面开着也会推进。** 到期推进原来只发生在页面加载时的 `read` RPC 里,长驻窗口永远不换图;现在 30 秒一次的定时检查也会过一遍轮换(纯数学门控,没到期就是空操作)。日 / 周 / 随机的到期与选图数学同时抽成双端共享的 `src/shared/rotation.ts`(构建时内联进两个 bundle),两端不会再在日 / 周边界上各自为政。
|
|
105
|
+
- **配置档案支持重命名与复制。** 每条档案新增行内重命名(Enter 提交)与一键复制(新 id、`(2)` 名字后缀,沿用 20 条上限的最旧淘汰)。
|
|
106
|
+
- **持久化正确性修复——每条都对应一个已发生过的故障模式。** 首启或读盘瞬时失败时 `readConfig` 返回的浅拷贝会被轮换增删原地污染,模块级默认配置从此带上幽灵池项(改 `structuredClone`);配置写失败后按 mtime 的内存缓存与磁盘分叉(改为写前丢缓存);字体槽收养杂散文件时按文件名错标 MIME,woff2 字节被当 ttf 服务(改为嗅探真实魔数并回写配置);壁纸裸字节上传不验内容(补上与 URL 下载、字体上传相同的魔数围栏);轮换池文件名毫秒碰撞(加随机后缀);手动激活轮换后游标不落盘、刷新回跳旧图(服务端按「合并进最新配置」回写,与自动推进同一套语义)。
|
|
107
|
+
- **结构与性能。** 浏览器半侧四个 body 级 MutationObserver 合并为单一总线(`src/client/dom-watch.ts`,最后一个退订自动断开);parts 观察的合批从 rAF 挪到微任务——对齐 v0.3.9 的教训(不绘制的窗口里排队的帧根本不跑),后台挂载的视图与 takeover 卡现在立即补上样式;`applyWp` 扇出去重(产出物 / 顶栏浮层等 pass 从每次两遍降为一遍);配置写失败先重试一次(Windows 上杀软扫描文件造成的瞬时 EBUSY)再明确告警,不再静默吞掉;`read` 的三个槽位并行探测;首启只写一次配置;启动时清扫崩溃残留的 tmp 文件、超额的 `.corrupt-*` 归档(保留最近 3 份)与轮换池孤儿文件(10 分钟宽限期);轮换推进 / 激活改用 `copyFile`,多 MB 壁纸不再整块过内存。
|
|
108
|
+
- **i18n 清理。** 删除四个无引用死键,英文文案里内嵌的中文引号改为英文写法;中英 197/197 键位对齐。
|
|
108
109
|
|
|
109
110
|
## 安装
|
|
110
111
|
|