dsh-background-by-model 0.9.2 → 0.10.0
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/CHANGELOG.md +17 -1
- package/CHANGELOG.zh.md +17 -1
- package/README.md +22 -19
- package/README.zh.md +23 -20
- package/lib/client.js +405 -131
- package/lib/index.js +271 -92
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,22 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
> The full release history lives here; the **Recent optimizations** section of [README.md](./README.md#recent-optimizations) lists only the two most recent releases (v0.
|
|
3
|
+
> The full release history lives here; the **Recent optimizations** section of [README.md](./README.md#recent-optimizations) lists only the two most recent releases (v0.10.0 / v0.9.2).
|
|
4
|
+
|
|
5
|
+
## v0.10.0
|
|
6
|
+
|
|
7
|
+
- **The config is written atomically, with a `.bak` of the last good file** — every save writes a temp file and renames it over the live one, rotating the current **parseable** file into `theme-config.json.bak` first. It used to be one in-place `writeFile`: a crash, a pulled cable or a full disk could leave half a JSON document, which `readConfig` answered with the factory defaults — and the next slider drag then persisted those defaults over the ruin. The original rules were gone for good.
|
|
8
|
+
- **A file that will not parse is restored from the backup, not treated as a fresh install** — when the live file is missing or corrupt and the `.bak` parses, that copy is read, written back to the live path, and reported once in the host log. Only when neither parses does the factory default answer.
|
|
9
|
+
- **The cleanup card still refuses on a corrupt config with no backup** — with a parseable backup it prunes against the backup's rules, because that is exactly the config the user is about to get back; with neither, the button stays disabled, because nothing on disk can be told apart from an orphan.
|
|
10
|
+
- **`resetStore` removes the `.bak` too** — leaving it behind would have the next read restore it, silently undoing the replacement the recommended profile exists to perform.
|
|
11
|
+
- **Opacity, brightness and blur moved from each RULE to each IMAGE** — the same layer the layout mode, the framing and the theme colour already live on: a daylight photo and a night shot in one rotation should not share one exposure. A schema-9 config's three rule-level values are lifted onto every one of its images on read, so upgrading changes nothing on screen.
|
|
12
|
+
- **`SCHEMA_VERSION` is 10** — the fields moved, and a schema-9 sanitizer rebuilds every image entry from the keys it knows: it would drop all three AND keep reading the rule-level values that no longer exist, so a dimmed wallpaper would come back at 100% in silence.
|
|
13
|
+
- **A blurred wallpaper no longer paints a dark rim around the viewport** — `blur()` treats everything outside the layer as transparent, so the edge came out half opaque and the page behind it showed through as a border that thickened with the slider. Each layer's box is now grown 2σ past the viewport (clipped by the container) with its placement moved back by the same amount, so the framing does not move.
|
|
14
|
+
- **A switch between two different opacity, brightness or blur values now animates** — each wallpaper layer keeps the filter of the picture it is painting, and the wallpaper's own opacity rides the switch instead of snapping to the incoming value on its first frame. Both used to be read live from the active image, so the outgoing picture was already wearing the incoming one's exposure before the fade ran: the transition was there, it just had nothing left to animate.
|
|
15
|
+
- **A repaint in the middle of a fade no longer cuts it short** — the steady opacity is mirrored in the render layer rather than read back from the store, so a theme re-registration or a panel re-render re-writes the value the fade is heading for.
|
|
16
|
+
- **Dragging a wallpaper's opacity, brightness or blur no longer repaints everything on every frame** — a drag frame writes only the property that field owns on the wallpaper layer, and the full `setRule` (skin, palette, wallpaper) runs once when the gesture ends. It used to be one full repaint per frame, which a large image made visibly slow.
|
|
17
|
+
- **`setWpOpacity` / `setWpFilter` have callers again** — the two zero-lag writers had none since the merged slider landed, while a comment and `check:image-mode` still asserted "two sites". `check:image-mode` now pins that the panel reaches them, and that a preview only touches the rule that is on screen.
|
|
18
|
+
- **The slider's preview and its commit are separate now** — `onInput` previews each frame and the commit rides the native `change` event, once. React's `onChange` for a range input is wired to that same `input` event, so committing from it was committing per frame.
|
|
19
|
+
- **Checks** — `check:node` gains a section on the atomic write and the backup (a corrupt file must not overwrite the good copy, no temp file survives, a reset takes the backup with it, a corrupt file heals from the copy) and pins the per-image lift, its clamps, the absent key and the holiday entry; `check:image-mode` pins that the render layer reads the image being PAINTED, that the panel writes the image being EDITED, that `defaultImage` is the only creation path, that the blurred edge is sampled off screen (the 2σ growth, written on the drag frame too), and that a layer carries its own picture's three effects rather than a live read.
|
|
4
20
|
|
|
5
21
|
## v0.9.2
|
|
6
22
|
|
package/CHANGELOG.zh.md
CHANGED
|
@@ -1,6 +1,22 @@
|
|
|
1
1
|
# 更新日志
|
|
2
2
|
|
|
3
|
-
> 这里保留完整的历史记录;[README.zh.md](./README.zh.md#近期优化) 的「近期优化」一节只列最近两个版本(v0.
|
|
3
|
+
> 这里保留完整的历史记录;[README.zh.md](./README.zh.md#近期优化) 的「近期优化」一节只列最近两个版本(v0.10.0 / v0.9.2)。
|
|
4
|
+
|
|
5
|
+
## v0.10.0
|
|
6
|
+
|
|
7
|
+
- **配置改成原子写,并留一份 `.bak`** —— 每次保存先写临时文件、再改名覆盖,覆盖前把当前这份**能解析**的文件旋转成 `theme-config.json.bak`。此前是原地 `writeFile`:崩溃、断电或磁盘写满都可能留下半截 JSON,而 `readConfig` 遇到读不出来的文件会退回出厂默认,下一次拖动滑块就把这份默认写回去,原规则表彻底没了。
|
|
8
|
+
- **读不出来时从备份恢复,而不是当新装** —— 主文件缺失或损坏、而 `.bak` 能解析时,读它、把它写回主文件,并在宿主日志里说一句;两份都读不出时才是出厂默认。
|
|
9
|
+
- **清理卡在「没有备份的坏配置」上仍然拒绝删图** —— 有能解析的备份时,清理按备份里的规则走(那正是用户即将拿回的配置);一份都没有时按钮照旧是灰的,因为盘上没有任何东西能和孤儿区分开。
|
|
10
|
+
- **`resetStore` 连 `.bak` 一起删** —— 留着它,下一次读取会把它恢复回来,悄悄抵消掉「推荐配置」那次真正的替换。
|
|
11
|
+
- **透明度、亮度与模糊从「每条规则」下沉到「每张图」** —— 与布局模式、取景、主题色落在同一层:一组轮换里的一张白天照片和一张夜景,本来就不该共用一套曝光。schema-9 的规则级三个值在读取时一次性抬到它的每一张图上,所以升级不改变屏幕上任何东西。
|
|
12
|
+
- **`SCHEMA_VERSION` 升到 10** —— 字段搬了位置,而 schema-9 的 sanitizer 会按它知道的键重建每个图片条目:它既会丢掉这三个字段,也会继续读已经不存在的规则级值,于是一张被调暗的壁纸会静默回到 100%。
|
|
13
|
+
- **模糊的壁纸不再在视口四周画一圈黑边** —— `blur()` 把图层之外一律当作透明,于是边缘只有一半不透明,背后的页面透出来就是一道随模糊值变粗的暗边。现在每个图层的盒子向视口外各扩 2σ(由容器裁掉),取景位置同时补回同样的距离,画面不动。
|
|
14
|
+
- **透明度、亮度或模糊不同的两张图之间切换,现在真的会有动画** —— 每个壁纸图层记住的是**它正在画的那张图**的滤镜,壁纸自身的透明度则跟着过渡一起走,而不是在开始那一帧直接切成新值。此前两者都实时读当前图,等于 fade 还没跑,出去的图就已经换上新图的曝光了 —— 动画一直在,只是没有东西可动。
|
|
15
|
+
- **过渡中途重绘不会再把它掐断** —— 稳定后的透明度记在渲染层自己手里,而不是从 store 回读,所以主题重注册或面板重渲染时写回的是这次过渡要去的值,不是它离开的那个值。
|
|
16
|
+
- **拖动壁纸的透明度、亮度与模糊不再每帧整块重绘** —— 拖动只写壁纸层自己的那个属性,松手才走一次完整的 `setRule`(皮肤、调色板、壁纸一起)。此前拖动一帧就是一次全量重绘,图一大就明显卡。
|
|
17
|
+
- **滑块的预览与提交分开了** —— `onInput` 每帧只预览,提交改由原生 `change` 事件触发、一次落地;range 输入的 React `onChange` 本来就绑在同一个 `input` 事件上,所以按它提交等于按帧提交。
|
|
18
|
+
- **`setWpOpacity` / `setWpFilter` 又有人调用了** —— 这两个零延迟写入函数在合并滑块那一版之后一直没有调用者,而注释和 `check:image-mode` 仍按「两个站点」断言。`check:image-mode` 现在钉住面板真的接上了它们,以及预览只作用于正在生效的那条规则。
|
|
19
|
+
- **门禁** —— `check:node` 新增原子写与备份一节(坏文件不得覆盖好备份、临时文件不残留、清空连备份一起走、坏文件从备份恢复),并把「每张图三个效果」的抬升、上下限、缺省键与节日条目一起钉住;`check:image-mode` 钉住渲染层读的是**正在画的那张图**、面板写的是**正在编辑的那张图**、`defaultImage` 是所有创建点的唯一入口、模糊边缘取样到屏幕之外(2σ 扩幅,拖动那一帧也写),以及每个图层携带的是自己那张图的三个效果而不是实时读取。
|
|
4
20
|
|
|
5
21
|
## v0.9.2
|
|
6
22
|
|
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@ English | [中文](README.zh.md)
|
|
|
9
9
|
|
|
10
10
|
> Forked from [`Tkingxiao/dsh-any-background`](https://github.com/Tkingxiao/dsh-any-background) and renamed to `dsh-background-by-model`.
|
|
11
11
|
|
|
12
|
-
A **DeepSeek Harness** appearance plugin built around an **ordered list of model rules**: each rule carries its own images,
|
|
12
|
+
A **DeepSeek Harness** appearance plugin built around an **ordered list of model rules**: each rule carries its own images, and each image its own layout mode, framing, theme color, opacity, brightness and blur. Switch the model and the background switches with it, through the global [switch effect](#switch-effect-global) you choose on the Config page.
|
|
13
13
|
|
|
14
14
|
> **v0.3.0 was a breaking release** — video wallpapers, generated backgrounds and the single global theme color were removed. See the [v0.3.0 entry in CHANGELOG.md](./CHANGELOG.md#v030).
|
|
15
15
|
|
|
@@ -61,7 +61,7 @@ One interface, one config — only the current model differs:
|
|
|
61
61
|
<p align="center">
|
|
62
62
|
<img src="https://cdn.jsdelivr.net/gh/HarmlessFunny/assets@v0.1.0/dsh-background-by-model/rule-editor.webp" alt="One rule's editor" width="660">
|
|
63
63
|
<br/>
|
|
64
|
-
<em>One rule on the Model Background tab · the
|
|
64
|
+
<em>One rule on the Model Background tab · the layout mode, the framing, the theme color and the opacity/brightness/blur all belong to the image being edited</em>
|
|
65
65
|
</p>
|
|
66
66
|
|
|
67
67
|
<p align="center">
|
|
@@ -74,7 +74,7 @@ One interface, one config — only the current model differs:
|
|
|
74
74
|
|
|
75
75
|
An ordered list of rules, matched first-hit against the current model's name, with rule 1 as the fallback.
|
|
76
76
|
|
|
77
|
-
- **Rules** — add, remove, reorder and name them; each carries its own match string,
|
|
77
|
+
- **Rules** — add, remove, reorder and name them; each carries its own match string, and a set of images with their own look.
|
|
78
78
|
- **Images per rule** — a filmstrip filled by file picker, drag & drop or a list of URLs; reorder it, promote one to first, or replace one in place (which keeps its position in the rotation). A rule may also hold none, and an empty rule still matches while it has a theme color of its own, so emptying one is a visible state rather than a trap.
|
|
79
79
|
- **Live match readout** — the Model Background tab shows which model was read and which rule it resolved to.
|
|
80
80
|
- **Import / export** — the whole rule set as `dsh-background-by-model-theme.json` with every image inlined; files written by earlier releases still import.
|
|
@@ -116,7 +116,7 @@ One switch on the Config page and nothing else: on 中秋节 and 国庆节 the w
|
|
|
116
116
|
- **Theme color** — HSL wheel, numeric input, **Extract from this image** and an eyedropper. It belongs to the **image**, and an image with none follows the system theme rather than inheriting its rule's.
|
|
117
117
|
- **Layout mode** — fit / fill / stretch / tile / center, stored per image; disabled on a rule that holds no picture, rather than hidden.
|
|
118
118
|
- **Framing** — drag to pan and scroll to zoom, editable in fit mode only, stored per image and stable across window resizes.
|
|
119
|
-
- **Image opacity** `0–100%`, **image brightness** `0–200%` (`100%` is the picture as saved) and **image blur** `0–60 px`, all three per
|
|
119
|
+
- **Image opacity** `0–100%`, **image brightness** `0–200%` (`100%` is the picture as saved) and **image blur** `0–60 px`, all three **saved per image** and edited through **one slider with a menu beside it** that picks the effect — so a daylight photo and a night shot in one rotation keep their own exposures. They treat the image (wallpaper) layer only; the Interface tab's opacity treats interface surfaces. A rule with no image has all three disabled rather than hidden.
|
|
120
120
|
|
|
121
121
|
### Global settings (Interface tab)
|
|
122
122
|
|
|
@@ -141,6 +141,7 @@ The last card on the Config tab. Images are stored at **full fidelity**, so an i
|
|
|
141
141
|
- **Only unreferenced files** — every byte a current rule uses is untouched, and the config itself is never written. The card re-reads after the sweep instead of subtracting, so a file that failed to delete still counts.
|
|
142
142
|
- **Failures are named** — one undeletable file does not protect the other six, and it is not reported as success either: the toast lists which ones.
|
|
143
143
|
- **No confirmation step** — what it deletes is by definition referenced by no rule, and is not a choice made from a working set, so a "confirm?" here only teaches people to click through. The safety is in the **gate**: when the config cannot be read the button is disabled (next bullet), rather than seven files being listed and then asked about.
|
|
144
|
+
- **A corrupt live file is answered by the backup** — when the live config will not parse but the `.bak` does, the sweep runs against the **backup's** rules, because that is the config you are about to get back; only when neither parses does it read as unknown and disable the button.
|
|
144
145
|
- **It also clears a stray `modelbg-h-*`** — that slot belongs to no config (festival art lives in `holiday-cache/`, and the slot is read-only), so this is the only path that can ever remove such a file.
|
|
145
146
|
- **An older host reads as "unknown", not "0 B"** — the two nothings must not look the same.
|
|
146
147
|
|
|
@@ -162,7 +163,8 @@ Data directory: `~/.dsh/.dsh-background-by-model-data/` (Windows: `C:\Users\<you
|
|
|
162
163
|
|
|
163
164
|
| File | Contents |
|
|
164
165
|
| --- | --- |
|
|
165
|
-
| `theme-config.json` | The rule list (each rule with its image list and rotation) plus the global Interface settings, the global switch effect and the holiday overrides |
|
|
166
|
+
| `theme-config.json` | The rule list (each rule with its image list, and each image with its own look and rotation settings) plus the global Interface settings, the global switch effect and the holiday overrides |
|
|
167
|
+
| `theme-config.json.bak` | The previous config, as of the last **successful** save. Every save writes a temp file and renames it over the live one, rotating the current good file into `.bak` first; a live file that will not parse is restored from here instead of falling back to the factory defaults. With neither readable, the cleanup card refuses to delete images |
|
|
166
168
|
| `modelbg-<slot>` | One image, stored as raw bytes without a file extension — one file per image, so a rule with three images owns three slots |
|
|
167
169
|
| `holiday-cache/<tag>/<asset>` | Festival art downloaded from the CDN, one file per holiday (`mid-autumn.webp`, `national-day.webp`) inside a directory named after the assets release this build pins (`v0.1.0`). The tag is part of the path so that a build pinning a new tag starts from an empty directory instead of being answered with the previous generation's bytes; the file inside is named after the **asset**, deliberately outside the slot namespace, which is what keeps a holiday slot read-only. Superseded generations are pruned once the new art is on disk. Delete a file here and it is simply re-downloaded the next time that holiday is in force |
|
|
168
170
|
|
|
@@ -224,14 +226,14 @@ After changing anything under `src/`, run `pnpm run bundle` again — the mounte
|
|
|
224
226
|
- **`check:transition`** — `resolveFadeMs` / `transitionPlan`: the shipped default still producing byte-for-byte the transition string earlier releases wrote, every route to a hard cut being one, reduced motion vetoing rather than shortening, and every effect ending visible and unscaled.
|
|
225
227
|
- **`check:repaint`** — `shouldRepaint`, including the edit that **creates** the winner, plus a failure if any write path stops asking, or if a rotation step stops re-emitting the interface palette.
|
|
226
228
|
- **`check:code-plate`** — the code block's plate: its tokens declared on both `:root` and `body`, the light branch emitting the banner, and each surface reading its own plugin variable.
|
|
227
|
-
- **`check:image-mode`** — the layout mode
|
|
229
|
+
- **`check:image-mode`** — the lift onto the image for the layout mode and the three paint effects, and which image a control edits against which the render layer reads.
|
|
228
230
|
- **`check:rules`** — the two decisions behind the tab strip, which live in `src/client/rules-view.ts`, plus the page structure the layout rests on.
|
|
229
231
|
- **`check:preset`** — the recommended profile's retry policy and what a failed attempt holds for the next one, with both halves shown using them.
|
|
230
232
|
- **`check:ui`** — both dictionaries carrying the same keys, every `dab-…` class styled, no dead entry, and every `var(--dsw-…)` published by the installed theme.
|
|
231
233
|
- **`check:watchdogs`** — one heartbeat, entries firing on their own due time, paused while the tab is hidden, no timer left by dispose, and no module outside the entry starting its own interval.
|
|
232
234
|
- **`check:scheme`** — the `data-ds-dark-theme` hand-off: the plugin only rewrites the value it wrote, hands the flag back when it drops its tokens, and repaints when the scheme moves.
|
|
233
235
|
- **`check:store`** — the two decisions behind the storage cleanup, `referencedSlots` and `orphanSlots`: a picture in use is never an orphan, a stray holiday-slot file always is, and the browser half sends RULE slots rather than the whole config.
|
|
234
|
-
- **`check:node`** — the built node half through its real RPC handler with `DSH_HOME` redirected and `fetch` stubbed: the holiday block, the festival art's caching and pruning, mirror fallback, the per-image color
|
|
236
|
+
- **`check:node`** — the built node half through its real RPC handler with `DSH_HOME` redirected and `fetch` stubbed: the holiday block, the festival art's caching and pruning, mirror fallback, the per-image color AND effect lifts, the global switch effect, the atomic config write with its backup and its recovery, the store's usage report and cleanup, and the recommended profile end to end.
|
|
235
237
|
|
|
236
238
|
## FAQ
|
|
237
239
|
|
|
@@ -242,7 +244,10 @@ Rule 1 probably has an empty match string, which makes it a pure fallback holdin
|
|
|
242
244
|
Matching is first-hit, not best-hit: put the more specific rule higher in the list, or reorder.
|
|
243
245
|
|
|
244
246
|
**Where are my wallpapers?**
|
|
245
|
-
In `~/.dsh/.dsh-background-by-model-data/`, one `modelbg-<slot>` file per image plus `theme-config.json`.
|
|
247
|
+
In `~/.dsh/.dsh-background-by-model-data/`, one `modelbg-<slot>` file per image plus `theme-config.json` and its `.bak` backup.
|
|
248
|
+
|
|
249
|
+
**What is `theme-config.json.bak`, and can I delete it?**
|
|
250
|
+
The previous config as of the last **successful** save. Every save writes a temp file and renames it over the live one, keeping the then-current parseable file as the backup — so if the live file ever stops parsing (a crash, a pulled cable, a hand edit gone wrong), the plugin restores from it instead of falling back to the factory defaults. You can delete it; the cost is having nothing to restore the next time the live file really is broken.
|
|
246
251
|
|
|
247
252
|
**I turned the rotation on and the background never changed.**
|
|
248
253
|
Three things can hold it: the rule needs two or more images, the tab has to be visible, and only the rule the current model resolved to rotates.
|
|
@@ -284,22 +289,20 @@ The effect is **Instant**, or the duration is `0` — an effect and a duration a
|
|
|
284
289
|
|
|
285
290
|
> Only the two most recent releases are listed here; older ones live in [CHANGELOG.md](./CHANGELOG.md).
|
|
286
291
|
|
|
292
|
+
### v0.10.0
|
|
293
|
+
|
|
294
|
+
- **The config is written atomically, with a `.bak` of the last good file** — a save writes a temp file and renames it over the live one, keeping the previous parseable file as the backup; a corrupt live file is restored from it instead of falling back to the factory defaults and then being overwritten by your next drag.
|
|
295
|
+
- **Opacity, brightness and blur are saved per image** — the same layer as the layout mode, framing and theme color; a schema-9 config's rule-level values are lifted onto every image on read, so nothing changes on screen.
|
|
296
|
+
- **`SCHEMA_VERSION` is 10** — the fields moved, and an older host would drop them in silence, so the browser half has to know.
|
|
297
|
+
- **A blurred wallpaper no longer paints a dark rim around the viewport** — the layer's box is grown 2σ past the screen edge and clipped, with the framing moved back by the same amount, so the blur samples off screen instead of fading into the page behind it.
|
|
298
|
+
- **A switch between two different opacity, brightness or blur values animates now** — each layer keeps its own picture's filter, and the wallpaper's opacity rides the transition instead of snapping.
|
|
299
|
+
- **Dragging one of the three sliders no longer repaints everything per frame** — a drag frame writes only that field's property, and one full repaint lands when the gesture ends.
|
|
300
|
+
|
|
287
301
|
### v0.9.2
|
|
288
302
|
|
|
289
303
|
- **The Config tab gains an "Image storage" card** — it reports how much is cleanable and how many files that is, then offers the button; only unreferenced files go, the config and the festival art stay, and any file that resists is named.
|
|
290
304
|
- **`check:store`, so there are thirteen checks now** — both READMEs had been claiming ten, having missed `check:watchdogs` and `check:scheme` since v0.8.1; they are listed again alongside the new one.
|
|
291
305
|
|
|
292
|
-
### v0.9.1
|
|
293
|
-
|
|
294
|
-
- **The three wallpaper sliders are now one slider plus a picker** — the options read Image opacity / Image brightness / Image blur, the picker matches the buttons, and the hint below is gone.
|
|
295
|
-
|
|
296
|
-
### v0.9.0
|
|
297
|
-
|
|
298
|
-
- **The RPC channel is the plugin's own prefix route on `webServer`**, so envelope, body cap and the auth fence stay here and `requestRejection` is asked per request.
|
|
299
|
-
- **One scheduler for every recurring check** — model poll, theme watchdog, holiday rollover and the delayed restores share a clock, pause while the tab is hidden, and stop with one dispose.
|
|
300
|
-
- **The browser entry point is wiring again** — skin, watchdogs, rotation, boot, model state, extraction and theme files are their own modules.
|
|
301
|
-
- **Exporting a theme no longer cancels its own download**, and comments say why the code is what it is rather than what it used to be.
|
|
302
|
-
|
|
303
306
|
## Star History
|
|
304
307
|
[](https://www.star-history.com/?repos=HarmlessFunny%2Fdsh-background-by-model&type=timeline&legend=bottom-right)
|
|
305
308
|
|
package/README.zh.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
> 派生自 [`Tkingxiao/dsh-any-background`](https://github.com/Tkingxiao/dsh-any-background),并重命名为 `dsh-background-by-model`。
|
|
11
11
|
|
|
12
|
-
一个 **DeepSeek Harness**
|
|
12
|
+
一个 **DeepSeek Harness** 外观插件,核心是一份**有序的模型规则列表**:每条规则自带壁纸(可多张),**每张图各有自己的布局模式、取景、主题色,以及透明度、亮度与模糊度**。切换模型即切换背景,切换过程走你在「配置」页选定的全局[切换效果](#切换效果全局)。
|
|
13
13
|
|
|
14
14
|
> **v0.3.0 是破坏性更新** —— 视频背景、生成式背景与全局主题色均已被移除。详见 [CHANGELOG.zh.md 的 v0.3.0 条目](./CHANGELOG.zh.md#v030)。
|
|
15
15
|
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
<p align="center">
|
|
62
62
|
<img src="https://cdn.jsdelivr.net/gh/HarmlessFunny/assets@v0.1.0/dsh-background-by-model/rule-editor.webp" alt="单条规则的编辑器" width="660">
|
|
63
63
|
<br/>
|
|
64
|
-
<em>「模型背景」页的单条规则 ·
|
|
64
|
+
<em>「模型背景」页的单条规则 · 布局模式、取景、主题色与透明度/亮度/模糊,全都属于它正在编辑的那张图</em>
|
|
65
65
|
</p>
|
|
66
66
|
|
|
67
67
|
<p align="center">
|
|
@@ -74,7 +74,7 @@
|
|
|
74
74
|
|
|
75
75
|
一份有序的规则列表,按当前模型名先命中者胜,第 1 条兼任兜底。
|
|
76
76
|
|
|
77
|
-
- **规则** ——
|
|
77
|
+
- **规则** —— 增删、排序、命名;每条自带一个匹配串,以及一组图片与它们各自的外观。
|
|
78
78
|
- **每条规则多张图** —— 胶片条可用文件选择、拖放或一行一个网址填入;可排序、设为第一张、或原地替换(替换会保住它在轮换里的位置)。规则也可以一张图都没有,而只要它还有自己的主题色,空规则依旧参与匹配,所以「清空」是一个看得见的状态,而不是一个陷阱。
|
|
79
79
|
- **实时匹配状态** —— 「模型背景」页会显示读到的是哪个模型、落在哪条规则上。
|
|
80
80
|
- **导入 / 导出** —— 整套规则导出为 `dsh-background-by-model-theme.json`,图片全部内联;旧版本写出的文件仍可导入。
|
|
@@ -110,13 +110,13 @@
|
|
|
110
110
|
- **画是下载的,不随包发布** —— 每个节日一张压缩后的壁纸,钉在项目 [assets 仓库](https://github.com/HarmlessFunny/assets)的一个发行 tag 上,当天第一次读取时缓存到 `holiday-cache/<tag>/`。下载由日历把关,所以平常的日子一个字节都不取,此后的每一次启动都直接读盘。
|
|
111
111
|
- **画和它的配色都不可以换** —— 节日槽位只读,颜色与满幅的「填充」都取自定义,主题导出也只带你的规则。
|
|
112
112
|
|
|
113
|
-
###
|
|
113
|
+
### 每条规则与每张图各自的设置
|
|
114
114
|
|
|
115
115
|
- **壁纸** —— 每条规则一张或多张图;不轮换时规则画的是第一张。
|
|
116
116
|
- **主题色** —— HSL 色轮、数值输入、**从本图提取**与吸管。它属于**图片**,没有自己颜色的图跟随系统主题,而不是继承规则色。
|
|
117
117
|
- **布局模式** —— 适应 / 填充 / 拉伸 / 平铺 / 居中,逐图保存;规则没有图片时这排是禁用而不是隐藏。
|
|
118
118
|
- **取景** —— 拖动平移、滚轮缩放,只在适应模式下可编辑,逐图保存,窗口缩放后保持一致。
|
|
119
|
-
- **图片透明度** `0–100%`、**图片亮度** `0–200%`(`100%` 即原图)与**图片模糊** `0–60 px
|
|
119
|
+
- **图片透明度** `0–100%`、**图片亮度** `0–200%`(`100%` 即原图)与**图片模糊** `0–60 px`,三者都**逐图保存**,并通过**同一条滑块 + 旁边的下拉框**切换调节项 —— 一张亮图和一张夜景图因此在同一组轮换里各有各的曝光。它们只作用于图片层;「界面」页的透明度作用于界面各区域。没有任何图片的规则这三项是禁用而不是隐藏。
|
|
120
120
|
|
|
121
121
|
### 全局设置(「界面」页)
|
|
122
122
|
|
|
@@ -141,6 +141,7 @@
|
|
|
141
141
|
- **只删没人引用的** —— 当前规则用到的图一个字节都不动,配置本身也不写。清理完会重新读一次,而不是用减法算,所以删除失败的文件仍然算在里面。
|
|
142
142
|
- **失败会点名** —— 一个文件删不掉不会让其余六个留下来,但也不会被说成「已清理」:提示里会列出是哪几个。
|
|
143
143
|
- **不问确认** —— 要删的东西按定义没有任何规则引用,而且不是从一个能用的集合里挑出来的,所以「确认」在这里只教人不看就点。安全性放在**前置判断**上:配置读不出来时按钮是灰的(见下一条),而不是先把七个文件列出来再问一遍。
|
|
144
|
+
- **坏掉的主文件由备份作答** —— 主配置读不出来、而 `.bak` 能解析时,清理按**备份里的规则**走:那正是你马上会拿回的配置。两份都读不出来才是「读不到」,按钮这时候才是灰的。
|
|
144
145
|
- **顺手清掉误入槽位的节日文件** —— `modelbg-h-*` 不属于任何配置(节日画在 `holiday-cache/` 里,那个槽位只读),所以它是唯一一个只有这条路径能清掉的残留。
|
|
145
146
|
- **宿主是旧版时显示「读不到」而不是「0 B」** —— 两种「没有」必须长得不一样。
|
|
146
147
|
|
|
@@ -162,7 +163,8 @@
|
|
|
162
163
|
|
|
163
164
|
| 文件 | 内容 |
|
|
164
165
|
| --- | --- |
|
|
165
|
-
| `theme-config.json` |
|
|
166
|
+
| `theme-config.json` | 规则列表(每条规则含图片列表,每张图含自己的外观与轮换设置)+ 全局「界面」设置 + 全局切换效果 + 节日覆盖配置 |
|
|
167
|
+
| `theme-config.json.bak` | 上一份**写成功时**的配置。每次保存都是「先写临时文件、再改名覆盖」,并在覆盖前把当前这份合格的文件留成 `.bak`;主文件读不出来时就从这里恢复,而不是退回出厂默认。读不出且没有备份时,清理卡会拒绝删图 |
|
|
166
168
|
| `modelbg-<slot>` | 一张图片,保存为原始字节、无扩展名 —— 一张图一个文件,所以一条有三张图的规则占三个槽位 |
|
|
167
169
|
| `holiday-cache/<tag>/<asset>` | 从 CDN 下载的节日画,一个节日一个文件(`mid-autumn.webp`、`national-day.webp`),装在一个以**插件所钉的 assets 发行版**命名的目录里(`v0.1.0`)。tag 进了路径,所以钉了新 tag 的构建从一个空目录开始,而不是被告知上一代的字节就是答案;目录里的文件名仍然是**素材名**,刻意放在槽位命名空间之外,这正是节日槽位只读的原因。被取代的旧代会在新图落盘之后被清掉。删掉这里的文件也没关系,下次那个节日生效时会重新下载 |
|
|
168
170
|
|
|
@@ -224,14 +226,14 @@ pnpm test # 构建 lib/、类型检查、跑十三道检查
|
|
|
224
226
|
- **`check:transition`** —— `resolveFadeMs` / `transitionPlan`:出厂默认仍然产出与旧版本逐字节相同的过渡串、每一条硬切路径都确实是硬切、「减少动态效果」是否决而非缩短,以及每种效果结束时都完全可见且没有残留缩放。
|
|
225
227
|
- **`check:repaint`** —— `shouldRepaint`,包括那条**制造**赢家的编辑,以及任何一条写入路径不再询问、或轮换步骤不再重发界面调色板时报错。
|
|
226
228
|
- **`check:code-plate`** —— 代码块底板:token 在 `:root` 与 `body` 上都有声明、浅色分支发出 banner、两块表面各读自己的插件变量。
|
|
227
|
-
- **`check:image-mode`** ——
|
|
229
|
+
- **`check:image-mode`** —— 布局模式与三个壁纸效果放到图片上的那次抬升,以及某个控件编辑的是哪张图、渲染层读的又是哪张图。
|
|
228
230
|
- **`check:rules`** —— 选项卡背后那两个住在 `src/client/rules-view.ts` 的判定,以及布局所依赖的页面结构。
|
|
229
231
|
- **`check:preset`** —— 推荐配置的重试策略与失败那一次给下一次留下什么,并验证两侧真的在用它们。
|
|
230
232
|
- **`check:ui`** —— 两本字典键集一致、每个 `dab-…` 类都有样式、没有死键,以及每个 `var(--dsw-…)` 都是已安装主题发布过的 token。
|
|
231
233
|
- **`check:watchdogs`** —— 一条心跳、按各自到期时间触发、隐藏即暂停、dispose 不留定时器,且入口之外没有模块自己起 interval。
|
|
232
234
|
- **`check:scheme`** —— `data-ds-dark-theme` 的交接:插件只改自己写的那个值、清掉 token 时一起交还标记、方案变了会重绘。
|
|
233
235
|
- **`check:store`** —— 存储清理的两个判定:`referencedSlots` 与 `orphanSlots`。钉住「正在用的图不会被当成孤儿」与「节日槽位的文件必须可清」,外加浏览器半边传的是**规则槽位**而不是整份配置。
|
|
234
|
-
- **`check:node`** —— 把构建好的 node 半边通过真实的 RPC 处理器跑一遍(`DSH_HOME` 指向临时目录、`fetch`
|
|
236
|
+
- **`check:node`** —— 把构建好的 node 半边通过真实的 RPC 处理器跑一遍(`DSH_HOME` 指向临时目录、`fetch` 换成桩):节日配置块、节日画的缓存与清理、镜像回落、逐图颜色与逐图效果的抬升、全局切换效果、配置的原子写与备份/恢复、图片存储的用量报告与清理,以及推荐配置的整条链路。
|
|
235
237
|
|
|
236
238
|
## 常见问题
|
|
237
239
|
|
|
@@ -242,7 +244,10 @@ pnpm test # 构建 lib/、类型检查、跑十三道检查
|
|
|
242
244
|
匹配是先命中者胜,而不是最精确者胜:把更具体的规则往上拖,或调整顺序。
|
|
243
245
|
|
|
244
246
|
**图片存在哪?**
|
|
245
|
-
在 `~/.dsh/.dsh-background-by-model-data/`:每张图一个 `modelbg-<slot>` 文件,外加 `theme-config.json
|
|
247
|
+
在 `~/.dsh/.dsh-background-by-model-data/`:每张图一个 `modelbg-<slot>` 文件,外加 `theme-config.json` 与它的 `.bak` 备份。
|
|
248
|
+
|
|
249
|
+
**`theme-config.json.bak` 是什么?可以删吗?**
|
|
250
|
+
是上一份**成功保存**的配置。每次保存都先写临时文件再改名覆盖,覆盖前把当时那份能解析的文件留成备份,所以主文件哪天读不出来(断电、崩溃、手滑编辑),插件会从备份恢复而不是退回出厂默认。可以删,代价是下次真的坏掉时就没有可恢复的那一份。
|
|
246
251
|
|
|
247
252
|
**我开了轮换,背景却一直没变。**
|
|
248
253
|
有三件事会拦住它:规则至少要有两张图;标签页必须可见;只有当前模型解析出的那条规则在轮换。
|
|
@@ -284,22 +289,20 @@ pnpm test # 构建 lib/、类型检查、跑十三道检查
|
|
|
284
289
|
|
|
285
290
|
> 这里只列最近两个版本;更早的版本见 [CHANGELOG.zh.md](./CHANGELOG.zh.md)。
|
|
286
291
|
|
|
292
|
+
### v0.10.0
|
|
293
|
+
|
|
294
|
+
- **配置改成原子写,并留一份 `.bak`** —— 保存先写临时文件再改名覆盖,覆盖前把当前能解析的那份留成备份;主文件坏了就从备份恢复,而不是退回出厂默认、再被你下一次拖动覆盖掉。
|
|
295
|
+
- **透明度、亮度与模糊改成逐图保存** —— 与布局模式、取景、主题色同一层;schema-9 的规则级三个值读取时抬到每张图上,升级不改屏幕。
|
|
296
|
+
- **`SCHEMA_VERSION` 升到 10** —— 字段搬了位置,旧宿主会静默丢掉它们,所以必须让浏览器半边知道。
|
|
297
|
+
- **模糊的壁纸不再在视口四周画一圈黑边** —— 图层盒子向屏幕外各扩 2σ 再裁掉,取景位置补回同样的距离,模糊因此取样到屏幕之外,边缘不再透出背后页面的颜色。
|
|
298
|
+
- **透明度、亮度或模糊不同的两张图之间切换现在有动画了** —— 每个图层记住自己那张图的滤镜,壁纸透明度也跟着过渡走,不再直接切。
|
|
299
|
+
- **拖动这三个滑块不再每帧整块重绘** —— 拖动只写那个字段自己的属性,松手才走一次完整重绘。
|
|
300
|
+
|
|
287
301
|
### v0.9.2
|
|
288
302
|
|
|
289
303
|
- **「配置」页多了一张「图片存储」卡片** —— 先报出可清理多少、涉及几个文件,再给你一个清理按钮;只删没有规则引用的文件,配置与节日画都不动,删不掉的文件会点名。
|
|
290
304
|
- **`check:store`,于是现在十三道校验** —— 两份 README 此前一直写着「十道」,`check:watchdogs` 与 `check:scheme` 从 v0.8.1 起就没列进去,这次一并补上。
|
|
291
305
|
|
|
292
|
-
### v0.9.1
|
|
293
|
-
|
|
294
|
-
- **三条壁纸滑块合并成一条,旁边用下拉框切换** —— 选项改叫图片透明度 / 图片亮度 / 图片模糊,下拉框与按钮同色,滑块下的说明文字删掉。
|
|
295
|
-
|
|
296
|
-
### v0.9.0
|
|
297
|
-
|
|
298
|
-
- **RPC 通道是插件自己在 `webServer` 上的 prefix 路由** —— envelope、请求上限与鉴权围墙留在插件这侧,每个请求都询问 `requestRejection`。
|
|
299
|
-
- **所有周期性检查合并成一个调度器** —— 模型轮询、主题看守、节日换日与延迟恢复共用一条时钟,标签页隐藏时暂停,一个 dispose 全停。
|
|
300
|
-
- **浏览器半边入口只剩接线** —— 皮肤、看守、轮换、启动、模型状态、取色与主题文件各自成模块。
|
|
301
|
-
- **导出主题不再取消自己的下载**,注释也只讲代码为什么是现在这样、不讲它曾经是什么样。
|
|
302
|
-
|
|
303
306
|
## Star History
|
|
304
307
|
|
|
305
308
|
[](https://www.star-history.com/?repos=HarmlessFunny%2Fdsh-background-by-model&type=timeline&legend=bottom-right)
|