dsh-background-by-model 0.5.5 → 0.6.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 +29 -10
- package/README.zh.md +29 -10
- package/holiday/mid-autumn.webp +0 -0
- package/holiday/national-day.webp +0 -0
- package/lib/client.js +392 -46
- package/lib/client.js.map +1 -1
- package/lib/index.js +180 -4
- package/package.json +7 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,22 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
> The full release history lives here; the two most recent releases (v0.
|
|
3
|
+
> The full release history lives here; the two most recent releases (v0.6.0 / v0.5.5) are also listed in [README.md](./README.md#recent-optimizations).
|
|
4
|
+
|
|
5
|
+
## v0.6.0
|
|
6
|
+
|
|
7
|
+
- **Holiday backgrounds — one switch, not a settings block** — On 中秋节 and 国庆节 the wallpaper switches to that holiday's own image, with that holiday's own fixed theme color, and switches back the next morning. It ships ON, and the **only** UI it has is a single switch on the **Config** page. There is deliberately no card per holiday, no thumbnail and no image picker — the panels that briefly lived there made the feature read as something the user is expected to configure, which is exactly what it is not.
|
|
8
|
+
- **The switch is the off-ramp, and only an explicit `false` takes it down** — a config written before the feature existed, or one whose switch was never touched, keeps working.
|
|
9
|
+
- **A holiday with nothing to paint falls through instead of blanking the background** — the override needs all three of: the switch, a window that contains today, and actual bytes in that holiday's slot. The last one is the point — a switched-on holiday with no image leaves the model rules in charge.
|
|
10
|
+
- **中秋 is lunar, 国庆 is fixed, and both are read in Asia/Shanghai** — 中秋 is 农历八月十五 and moves across the Gregorian calendar (2024-09-17, 2025-10-06, 2026-09-25, 2027-09-15 …); National Day is the fixed October 1–7 window. The calendar comes from the browser's own ICU (no dependency at all). The zone is **pinned rather than taken from the machine**: the lunar day rolls over at Beijing midnight, so reading "today" off a UTC clock puts the festival on the wrong day for most of the planet — the day-boundary behaviour is pinned by a test at Beijing 23:59 / 00:01.
|
|
11
|
+
- **A leap eighth month cannot drag the festival a month late** — ICU marks a leap month by suffixing `bis`, so an exact `month === '8'` test is what keeps 中秋 on the **regular** eighth month. Checked against every leap-eighth-month year in 1900–2100 (1900, 1957, 1976, 1995, 2052, 2071, 2090): in 2052 the plugin fires on **2052-09-07**, never on the `8bis` fifteenth that falls in October that year.
|
|
12
|
+
- **中秋 wins the overlap with 国庆** — the two do collide (2025-10-06 was both). A single precise day is the better answer than one day inside a seven-day window.
|
|
13
|
+
- **The wallpapers ship inside the package, at one twelfth of the source art: 8.37 MB → 729 KB** — native resolution, WebP q80 (`中秋节` 1856 KB → 228 KB, `国庆节` 6716 KB → 500 KB). The tarball goes **401 KB → 1.12 MB**, and because the files are already-compressed images gzip cannot shrink them further — that is the entire cost of the feature, and the reason they are not shipped raw (raw would be a 21× heavier install, and every boot would then push a 6.7 MB base64 payload through the plugin's own RPC channel).
|
|
14
|
+
- **The wallpapers belong to the package, and nothing can replace them** — a holiday slot is read-only: the node half serves the bundled asset and never consults the data directory for it, and writing, deleting or URL-fetching into such a slot is refused. A file planted there is ignored by every read, which is what keeps the egg an egg instead of a setting.
|
|
15
|
+
- **An unused holiday costs nothing — and neither does an unused DAY** — with the override on by default and invisible, boot fetches only the holiday that can actually paint *today*; on any other day the 729 KB is never read at all. The rollover tick fetches the art if midnight lands *on* a holiday, since boot had no reason to. The node half looks the bundled file up lazily rather than loading it with the plugin.
|
|
16
|
+
- **The holiday theme colors are constants, not something read off the art** — 中秋 paints in `#384A77` and 国庆 in `#FFF6EB`: quoted as hex in the holiday definition, beside its slot and its wallpaper, converted to the rule shape's `[h, s, l]` by the shared schema, and forced on every read — so a hand-edited `color` in `theme-config.json` is replaced by the definition's on load. The extraction pass that decoded a full-size festival photo to re-derive a hue that was always going to be the same one is gone, and with it the "has this image been tried yet" bookkeeping; the palette is now a design decision that costs nothing at boot.
|
|
17
|
+
- **Theme exports carry rules only** — the holiday wallpapers are not in `dsh-background-by-model-theme.json`. They ship with the package, so exporting them would add ~970 KB of base64 to every file to move bytes that every install already has, into slots that refuse them anyway.
|
|
18
|
+
- **Two dependency-free checks now guard the parts that fail silently** — `pnpm check:holiday` (`scripts/holiday-check.ts`) pins the two windows, the Beijing day boundary, the leap-eighth-month behaviour, and the four gates `pickHoliday` applies before a holiday may take over; `pnpm check:ui` (`scripts/ui-strings-check.ts`) fails on a `t('…')` key missing from either dictionary, on a `dab-…` class with no rule in the stylesheet, and on a dictionary entry nothing references any more. A third, `pnpm check:node` (`scripts/node-half-check.mjs`), drives the BUILT node half through its real RPC handler with `DSH_HOME` pointed at a throwaway directory — so it covers the persistence layer without ever touching a real `~/.dsh`: the holiday block through the shared sanitizer, the packaged wallpapers served out of an empty slot, a holiday slot refusing writes, deletes and URL fetches while a file dropped into it is ignored, an ordinary rule slot still writing and deleting, and a hand-edited config unable to point a holiday at another rule's image. All three run on plain `node` (≥ 22.6 strips the types itself), so they need no dependency, no transformer and no browser, and `pnpm test` now runs them. The decision itself — `pickHoliday` — was extracted out of the plugin's apply closure into `src/holiday.ts` precisely so it could be tested at all.
|
|
19
|
+
- **`check:ui` immediately retired ten strings that had been dead since earlier releases** — `close`, `ruleMatchLabel`, `ruleFraming`, `ruleFramingLocked`, `colorHint`, `swatchTitle`, `hexCaption`, `extractColor`, `extractNoWp`, and the `holidayPreview` this release had just added.
|
|
4
20
|
|
|
5
21
|
## v0.5.5
|
|
6
22
|
|
package/CHANGELOG.zh.md
CHANGED
|
@@ -1,6 +1,22 @@
|
|
|
1
1
|
# 更新日志
|
|
2
2
|
|
|
3
|
-
> 这里保留完整的历史记录;最近两个版本(v0.
|
|
3
|
+
> 这里保留完整的历史记录;最近两个版本(v0.6.0 / v0.5.5)同时列在 [README.zh.md](./README.zh.md#近期优化) 里。
|
|
4
|
+
|
|
5
|
+
## v0.6.0
|
|
6
|
+
|
|
7
|
+
- **节日特殊背景 —— 只有一个开关,不是一整块设置** —— 中秋与国庆当天,壁纸自动换成那个节日自己的图片、并配上该节日固定的主题色,第二天早上自动换回。功能默认就是开的,而它在界面上**只有一行**:**「配置」页**上一个开关。刻意不做每个节日的卡片、缩略图和选图入口 —— 那些面板短暂存在过,但它们让这个功能看起来像是等着用户去配置的东西,而它恰恰不是。
|
|
8
|
+
- **这个开关是「下车口」,只有显式 `false` 才算关** —— 功能存在之前写下的配置、或者从没动过开关的配置,都照常工作。
|
|
9
|
+
- **没图可画的节日会回落到规则,而不是把背景刷空** —— 覆盖需要同时满足三件事:开关、今天在窗口内、槽位里确实有字节。最后一条是关键:开了开关却没有图的节日,仍然让模型规则说了算。
|
|
10
|
+
- **中秋按农历、国庆按公历,两者都按 Asia/Shanghai 判定** —— 中秋是农历八月十五,在公历上逐年移动(2024-09-17、2025-10-06、2026-09-25、2027-09-15……);国庆是固定的 10 月 1–7 日。农历换算直接用浏览器自带的 ICU,**零依赖**。时区是**钉死的,不取机器本地时区**:农历日期在北京时间午夜翻页,用 UTC 时钟读「今天」会让地球上大多数人过错日子 —— 北京 23:59 / 00:01 的跨日行为有测试钉住。
|
|
11
|
+
- **闰八月不会把中秋拖后一个月** —— ICU 用后缀 `bis` 标记闰月,所以判等必须写死 `month === '8'`,这样中秋才永远落在**正**八月。已对 1900–2100 年间所有闰八月年份做过校验(1900、1957、1976、1995、2052、2071、2090):2052 年插件在 **2052-09-07** 生效,而不是那年落在十月的 `8bis` 十五。
|
|
12
|
+
- **中秋与国庆重叠时中秋优先** —— 两者确实会撞(2025-10-06 就是同一天)。一个精确的单日,比七天窗口里的某一天更值得采信。
|
|
13
|
+
- **壁纸内置在包里,压到原图的十二分之一:8.37 MB → 729 KB** —— 原生分辨率、WebP q80(中秋节 1856 KB → 228 KB,国庆节 6716 KB → 500 KB)。npm 包从 **401 KB 涨到 1.12 MB**;图片本身已是压缩格式,gzip 再压不动,这就是这个功能的全部代价 —— 也正是不能直接塞原图的原因(原图会让安装包重 21 倍,而且每次启动都要把 6.7 MB 的 base64 从插件自己的 RPC 通道推一遍)。
|
|
14
|
+
- **壁纸属于包,任何入口都换不掉** —— 节日槽位是只读的:node 半边直接送出内置资源,从不为此查询数据目录,写入、删除和抓取这些槽位一律被拒。丢进去的文件不会被任何一次读取采用 —— 这正是让这个彩蛋保持为彩蛋、而不是一项设置的原因。
|
|
15
|
+
- **没启用的节日不花任何代价 —— 没在过节的那天也不花** —— 既然覆盖默认开着又不显示,启动时就只取**今天真能生效**的那一个节日,别的日子那 729 KB 一个字节都不读;如果午夜正好跨进某个节日,由跨日轮询去补取(启动时没理由取它)。node 半边同样是按需才去找内置文件,而不是跟着插件一起加载。
|
|
16
|
+
- **节日主题色是常量,不是从图里读出来的** —— 中秋用 `#384A77`,国庆用 `#FFF6EB`:以十六进制写在节日定义里(就在槽位和壁纸旁边),由共享 schema 转成规则形状的 `[h, s, l]`,并在每次读取时强制覆盖 —— 所以手改 `theme-config.json` 里的 `color`,加载时也会被定义值换掉。原来那个「解码一张全尺寸节日照片,只为重新算出一个永远相同的色相」的取色流程,以及配套的「这张图试过了吗」记账,全部删除;配色现在是一项不花启动代价的设计决定。
|
|
17
|
+
- **导出的主题文件只带规则** —— 节日壁纸不在 `dsh-background-by-model-theme.json` 里。它们随包发布,导出意味着给每个文件多加约 970 KB base64,只为了搬运每份安装本来就有、而槽位还拒绝接收的字节。
|
|
18
|
+
- **三道零依赖校验,守住那些「静默出错」的地方** —— `pnpm check:holiday`(`scripts/holiday-check.ts`)钉住两个节日窗口、北京时间的跨日边界、闰八月的行为,以及 `pickHoliday` 允许节日接管背景之前必须通过的四道闸门;`pnpm check:ui`(`scripts/ui-strings-check.ts`)会在某个 `t('…')` 键只存在于一本字典、某个 `dab-…` 类在样式表里没有规则、或某条字典条目已经没人引用时直接失败。第三道 `pnpm check:node`(`scripts/node-half-check.mjs`)把**构建产物**里的 node 半边通过它真实的 RPC 处理器跑一遍,`DSH_HOME` 指向临时目录 —— 因此它覆盖了持久化层却从不碰真实的 `~/.dsh`:节日配置块穿过共享 sanitizer、内置壁纸从空槽位送出、节日槽位拒绝写入 / 删除 / 抓取而丢进去的文件被忽略、普通规则槽位照常写入和删除,以及手改过的配置无法把节日指向别的规则的图片。三道都用裸 `node` 跑(≥ 22.6 自己剥类型),不需要依赖、不需要转译器、也不需要浏览器,`pnpm test` 现在会一并执行。判定本身 —— `pickHoliday` —— 正是为了能测才从插件的 apply 闭包里抽到 `src/holiday.ts` 的。
|
|
19
|
+
- **`check:ui` 当场清掉了从早期版本遗留至今的十个死键** —— `close`、`ruleMatchLabel`、`ruleFraming`、`ruleFramingLocked`、`colorHint`、`swatchTitle`、`hexCaption`、`extractColor`、`extractNoWp`,以及本次刚加进去的 `holidayPreview`。
|
|
4
20
|
|
|
5
21
|
## v0.5.5
|
|
6
22
|
|
package/README.md
CHANGED
|
@@ -83,6 +83,19 @@ One interface, one config — only the current model differs:
|
|
|
83
83
|
- **Bilingual** — Full Chinese / English UI with automatic locale detection.
|
|
84
84
|
- **Theme Watchdog** — Re-asserts the custom theme if the host resets it.
|
|
85
85
|
|
|
86
|
+
### Holiday backgrounds
|
|
87
|
+
|
|
88
|
+
A small one, not a settings block: **one switch on the Config page and nothing else**. It is on out of the box, and on the day the background changes by itself and changes back the next morning.
|
|
89
|
+
|
|
90
|
+
- **How it behaves** — On 中秋节 and 国庆节 the wallpaper switches to that holiday's own image, with that holiday's own fixed theme color (中秋 `#384A77`, 国庆 `#FFF6EB`). The next day, the model rules take over again.
|
|
91
|
+
- **Mid-Autumn Festival** — 农历八月十五, the day itself. It moves every year (2024-09-17, 2025-10-06, 2026-09-25, 2027-09-15 …), so it is resolved from the Chinese calendar at runtime, in **Asia/Shanghai** — the lunar day turns over at Beijing midnight, not yours.
|
|
92
|
+
- **National Day** — October 1–7.
|
|
93
|
+
- **Mid-Autumn wins the overlap** — the two do collide (2025-10-06 was both); the single precise day is the better answer.
|
|
94
|
+
- **A holiday with no image falls through** to the model rules rather than blanking the wallpaper.
|
|
95
|
+
- **Built-in wallpapers** — Both holidays ship with a compressed wallpaper (228 KB and 500 KB at native resolution, against 8.37 MB of source art). Only the holiday that can paint *today* is ever fetched, so a profile that is not on a holiday transfers none of it.
|
|
96
|
+
- **Neither the art nor the palette is swappable, by design** — an easter egg that asks to be configured is not an easter egg. A holiday slot is read-only: a file dropped into `modelbg-h-midautumn` / `modelbg-h-nationalday` is ignored by every read, and the plugin refuses to write, fetch into or delete those slots. The theme colors are constants in the holiday definition and are forced on every read, so a hand-edited `color` in `theme-config.json` cannot repaint a festival either. Theme exports therefore carry your rules only.
|
|
97
|
+
- **Turning it off** — the switch on the Config page, or `"holidays": { "enabled": false }` in the same file.
|
|
98
|
+
|
|
86
99
|
### Per-rule settings
|
|
87
100
|
|
|
88
101
|
- **Wallpaper** — Upload any image as this rule's wallpaper; each rule keeps its own file.
|
|
@@ -107,7 +120,7 @@ Settings → **Theme** now has three tabs:
|
|
|
107
120
|
| --- | --- | --- |
|
|
108
121
|
| **Interface** | Global, shared by every model | Opacity & blur for the main background, left panel, right panel, cards & panels, input & controls, settings panel, conversation text box and trajectory page |
|
|
109
122
|
| **Model Background** | Per rule | The ordered rule list, the live match readout, and each rule's wallpaper, theme color, layout mode, framing, opacity and blur |
|
|
110
|
-
| **Config** | — | Import / export the whole rule set (`dsh-background-by-model-theme.json`) |
|
|
123
|
+
| **Config** | — | Import / export the whole rule set (`dsh-background-by-model-theme.json`), plus the single [holiday background](#holiday-backgrounds) switch |
|
|
111
124
|
|
|
112
125
|
The old **Color** tab is gone — the theme color is now a property of each rule. The old **Background** tab became **Model Background**.
|
|
113
126
|
|
|
@@ -117,8 +130,9 @@ Data directory: `~/.dsh/.dsh-background-by-model-data/` (Windows: `C:\Users\<you
|
|
|
117
130
|
|
|
118
131
|
| File | Contents |
|
|
119
132
|
| --- | --- |
|
|
120
|
-
| `theme-config.json` | The rule list plus the global Interface settings |
|
|
133
|
+
| `theme-config.json` | The rule list plus the global Interface settings and the holiday overrides |
|
|
121
134
|
| `modelbg-<slot>` | The image of each rule, stored as raw bytes without a file extension |
|
|
135
|
+
| `modelbg-h-midautumn` / `modelbg-h-nationalday` | Not used: both holiday wallpapers ship inside the package and are served straight out of it |
|
|
122
136
|
|
|
123
137
|
## Installation
|
|
124
138
|
|
|
@@ -170,7 +184,11 @@ To mount a working copy into a profile instead, add it to the profile's `package
|
|
|
170
184
|
|
|
171
185
|
After changing anything under `src/`, run `pnpm run bundle` again — the mounted profile loads `lib/`, so edits do not take effect until the bundle is rebuilt.
|
|
172
186
|
|
|
173
|
-
`pnpm test` builds and
|
|
187
|
+
`pnpm test` builds, typechecks and runs three checks (`tsdown && tsc -p tsconfig.json && node scripts/holiday-check.ts && node scripts/ui-strings-check.ts && node scripts/node-half-check.mjs`). None of them needs a dependency, a transformer or a browser, and each can be run alone with `pnpm check:holiday` / `pnpm check:ui` / `pnpm check:node`:
|
|
188
|
+
|
|
189
|
+
- **`check:holiday`** — the two holiday windows against known dates, the Beijing day boundary (23:59 vs 00:01), leap eighth months across 1900–2100, and the four gates `pickHoliday` applies before a holiday is allowed to take over the background.
|
|
190
|
+
- **`check:ui`** — every `t('…')` key exists in both dictionaries, both dictionaries carry the same key set, every `dab-…` class has a rule in the stylesheet, and no dictionary entry has gone unreferenced.
|
|
191
|
+
- **`check:node`** — the built node half driven through its real RPC handler with `DSH_HOME` redirected to a throwaway directory: the holiday block through the shared sanitizer, the packaged wallpapers served from an empty slot (without being copied into the data directory), a holiday slot refusing writes, deletes and URL fetches while a file dropped into it is ignored, an ordinary rule slot still writing, listing and deleting, and a hand-edited config unable to redirect a holiday at another rule's image.
|
|
174
192
|
|
|
175
193
|
## FAQ
|
|
176
194
|
|
|
@@ -200,19 +218,20 @@ The other half of the same hole: while it owns a color the plugin **forces** `bo
|
|
|
200
218
|
|
|
201
219
|
## Recent Optimizations
|
|
202
220
|
|
|
203
|
-
> Only the two most recent releases are listed here; older ones (v0.5.
|
|
221
|
+
> Only the two most recent releases are listed here; older ones (v0.5.4 and earlier) live in [CHANGELOG.md](./CHANGELOG.md).
|
|
222
|
+
|
|
223
|
+
### v0.6.0
|
|
224
|
+
|
|
225
|
+
- **Holiday backgrounds** — Settings → Config gains exactly one thing: a switch. While it is on and today is inside a holiday's window, that holiday's wallpaper replaces the rule list's answer and paints with that holiday's own fixed theme color. On by default, and there is deliberately no card per holiday, no thumbnail and no image picker — the art ships in the package and its slots are read-only, so it cannot be replaced from anywhere.
|
|
226
|
+
- **中秋 is lunar, 国庆 is fixed, both read in Asia/Shanghai** — 中秋 (八月十五) moves every year, so it comes from the browser's own ICU Chinese calendar, no dependency. The zone is pinned rather than taken from the machine: the lunar day turns over at Beijing midnight. A leap eighth month is excluded by an exact `month === '8'` test — verified against every leap-eighth-month year from 1900 to 2100 (2052 fires on 2052-09-07, not on that year's `8bis` fifteenth in October). Where the two overlap (2025-10-06), 中秋 wins.
|
|
227
|
+
- **The built-in wallpapers are compressed 12×: 8.37 MB → 729 KB** — native resolution WebP q80; the tarball goes 401 KB → 1.12 MB, and gzip cannot shrink already-compressed images further. That is the whole cost of the feature.
|
|
228
|
+
- **An unused holiday costs nothing — and neither does an unused day** — boot fetches only the holiday that can paint *today*, and the node half looks the asset up lazily rather than loading it with the plugin.
|
|
204
229
|
|
|
205
230
|
### v0.5.5
|
|
206
231
|
|
|
207
232
|
- **The color preview field prints its own hex** — it sat at the bottom of the H/S/L (R/G/B) column behind the same 1px border and carried no text, so on a light color (reported: `#BADEE8`, L 82%) it read as one more — blank — text input with nothing to type into it. It now prints `#RRGGBB` in monospace centered on the color, inked by **Rec.709 luma** (the wallpaper extractor's own brightness measure) so the value never disappears into its fill, and the hover `scale(1.02)` it never backed up is gone. The duplicate hex caption above the HSL/RGB toggle went with it.
|
|
208
233
|
- **The clear-color button says what it does** — **System theme** (a state) is now **Follow system theme** (the action), with the host's own sun glyph. It is the mirror of the 0.5.3 rename that turned the no-color button into **Custom color**.
|
|
209
234
|
|
|
210
|
-
### v0.5.4
|
|
211
|
-
|
|
212
|
-
- **A brand-filled control takes its label from the host's on-brand ink, not from `brand-text`** — Following the system theme painted the active layout chip, the **+ Add rule** button and the settings brand tile from the host's own `--dsw-alias-brand-primary`, which is a **contrast ink rather than a hue**: near-black (`#0f1115`) in the host's light scheme, near-white (`#f9fafb`) in its dark one. Their labels read `--dsw-alias-brand-text`, which the host defines as that very same color in both schemes and never uses in its own CSS. On a dark system that made them filled boxes with invisible labels — white primary button, white active chip, white icon tile (measured at exactly `#f9fafb`) — and they were only ever readable while the plugin owned the palette and generated its own brand pair. All four now read `--dsw-alias-label-primary-inverted`, the host's own ink for a brand/contrast fill: `#fff` on the light scheme's black fill, `#353638` on the dark scheme's white one.
|
|
213
|
-
- **The toggle's on-state knob was the same bug one size smaller** — a hard-coded `#fff` on a `--dsw-alias-brand-primary` track, i.e. a white knob on the white track the dark scheme paints there.
|
|
214
|
-
- **The plugin's own dark palette had the mirror of it** — that branch deliberately keeps its brand fill at 50%+ lightness, while `--dsw-alias-label-primary-foreground` — the token the **host's** own primary buttons label themselves with over `--dsw-alias-button-primary-fill` — was hard-coded white. It now flips with the fill (one shared verdict with `brand-text`), and the light branch re-emits `label-primary-inverted` so the plugin's palette owns the pair instead of inheriting it from whichever scheme the host happens to be in.
|
|
215
|
-
|
|
216
235
|
## Star History
|
|
217
236
|
|
|
218
237
|
[](https://www.star-history.com/?repos=HarmlessFunny%2Fdsh-background-by-model&type=timeline&legend=bottom-right)
|
package/README.zh.md
CHANGED
|
@@ -83,6 +83,19 @@
|
|
|
83
83
|
- **中英双语** — 完整的中英文界面,自动跟随语言设置。
|
|
84
84
|
- **主题守护** — 宿主重置主题后自动重新激活自定义主题。
|
|
85
85
|
|
|
86
|
+
### 节日特殊背景
|
|
87
|
+
|
|
88
|
+
小小一个,不是一整块设置:**「配置」页上一个开关,别的什么都没有**。它默认就是开的;到了日子背景自己换,第二天早上自己换回。
|
|
89
|
+
|
|
90
|
+
- **行为** — 中秋与国庆当天,壁纸换成那个节日自己的图片,并配上该节日固定的主题色(中秋 `#384A77`、国庆 `#FFF6EB`);第二天交还给模型规则。
|
|
91
|
+
- **中秋节** — 农历八月十五当天。它在公历上逐年移动(2024-09-17、2025-10-06、2026-09-25、2027-09-15……),所以是运行时按农历换算的,时区钉在 **Asia/Shanghai** —— 农历日期在北京时间午夜翻页,不是你那边的午夜。
|
|
92
|
+
- **国庆节** — 公历 10 月 1–7 日。
|
|
93
|
+
- **两者重叠时中秋优先** — 它们确实会撞(2025-10-06 就是同一天),一个精确的单日比七天窗口里的某一天更值得采信。
|
|
94
|
+
- **没有图的节日会回落到模型规则**,而不是把背景刷空。
|
|
95
|
+
- **内置壁纸** — 两个节日都自带一张压缩过的壁纸(原生分辨率下 228 KB 与 500 KB,原图共 8.37 MB)。只会去取**今天真能生效**的那一张,所以不在节日的配置一点都不会传。
|
|
96
|
+
- **图片和配色都不可替换,这是刻意的** — 一个要求用户去配置的彩蛋就不是彩蛋了。节日槽位是只读的:往 `modelbg-h-midautumn` / `modelbg-h-nationalday` 里放文件不会被任何一次读取采用,插件也拒绝写入、抓取和删除这两个槽位。主题色是节日定义里的常量、每次读取都强制覆盖,所以手改 `theme-config.json` 里的 `color` 也换不掉节日配色。导出的主题文件只包含你自己的规则。
|
|
97
|
+
- **不想要它** — 关掉「配置」页那个开关,或者在同一个文件里写 `"holidays": { "enabled": false }`。
|
|
98
|
+
|
|
86
99
|
### 每条规则自带的外观
|
|
87
100
|
|
|
88
101
|
- **背景图片** — 上传任意图片作为该规则的壁纸,每条规则一张独立图片文件。
|
|
@@ -107,7 +120,7 @@
|
|
|
107
120
|
| --- | --- | --- |
|
|
108
121
|
| **界面** | 全局,所有模型共用 | 主背景、左侧栏、右侧栏、卡片面板、输入框与控件、设置面板、对话文本框、轨迹页的透明度与模糊度 |
|
|
109
122
|
| **模型背景** | 每条规则 | 有序规则列表、顶部实时状态,以及每条规则的壁纸、主题色、布局模式、取景、透明度与模糊度 |
|
|
110
|
-
| **配置** | — | 导入 / 导出整套规则(`dsh-background-by-model-theme.json
|
|
123
|
+
| **配置** | — | 导入 / 导出整套规则(`dsh-background-by-model-theme.json`),外加[节日特殊背景](#节日特殊背景)那一个开关 |
|
|
111
124
|
|
|
112
125
|
原先的 **「色彩」** 选项卡已删除——主题色改为每条规则自己的属性;原 **「背景」** 选项卡已改造成 **「模型背景」**。
|
|
113
126
|
|
|
@@ -117,8 +130,9 @@
|
|
|
117
130
|
|
|
118
131
|
| 文件 | 内容 |
|
|
119
132
|
| --- | --- |
|
|
120
|
-
| `theme-config.json` | 规则列表 + 全局「界面」设置 |
|
|
133
|
+
| `theme-config.json` | 规则列表 + 全局「界面」设置 + 节日覆盖配置 |
|
|
121
134
|
| `modelbg-<slot>` | 每条规则的图片,保存为原始字节,无扩展名 |
|
|
135
|
+
| `modelbg-h-midautumn` / `modelbg-h-nationalday` | 不使用:两张节日壁纸都随包发布,直接从包内送出 |
|
|
122
136
|
|
|
123
137
|
## 安装
|
|
124
138
|
|
|
@@ -170,7 +184,11 @@ pnpm run typecheck
|
|
|
170
184
|
|
|
171
185
|
改完 `src/` 必须重新执行 `pnpm run bundle` 才会生效——挂载的 profile 加载的是 `lib/`。
|
|
172
186
|
|
|
173
|
-
`pnpm test`
|
|
187
|
+
`pnpm test` 会构建、类型检查并跑三道校验(`tsdown && tsc -p tsconfig.json && node scripts/holiday-check.ts && node scripts/ui-strings-check.ts && node scripts/node-half-check.mjs`)。三道都不需要依赖、不需要转译器、也不需要浏览器,也可以单独跑:`pnpm check:holiday` / `pnpm check:ui` / `pnpm check:node`。
|
|
188
|
+
|
|
189
|
+
- **`check:holiday`** — 两个节日窗口对照已知日期、北京时间的跨日边界(23:59 与 00:01)、1900–2100 年间的闰八月,以及 `pickHoliday` 允许节日接管背景之前必须通过的四道闸门。
|
|
190
|
+
- **`check:ui`** — 每个 `t('…')` 键在中英两本字典里都存在、两本字典键集完全一致、每个 `dab-…` 类在样式表里都有规则,且没有字典条目变成没人引用的死键。
|
|
191
|
+
- **`check:node`** — 把构建好的 node 半边通过它真实的 RPC 处理器跑一遍,`DSH_HOME` 指向临时目录:节日配置块穿过共享的 sanitizer、内置壁纸从空槽位被送出(且不会因此写进数据目录)、节日槽位拒绝写入 / 删除 / 抓取而丢进去的文件被忽略、普通规则槽位照常写入和删除,以及手改过的配置无法把节日指向别的规则的图片。
|
|
174
192
|
|
|
175
193
|
## 常见问题
|
|
176
194
|
|
|
@@ -200,19 +218,20 @@ pnpm run typecheck
|
|
|
200
218
|
|
|
201
219
|
## 近期优化
|
|
202
220
|
|
|
203
|
-
> 这里只列最近两个版本;更早的版本(v0.5.
|
|
221
|
+
> 这里只列最近两个版本;更早的版本(v0.5.4 及以前)见 [CHANGELOG.zh.md](./CHANGELOG.zh.md)。
|
|
222
|
+
|
|
223
|
+
### v0.6.0
|
|
224
|
+
|
|
225
|
+
- **节日特殊背景** — 设置 →「配置」页只多了一样东西:一个开关。开关打开且今天落在某个节日的窗口内时,该节日的壁纸会顶掉规则列表的结果,主题色用该节日固定的配色。默认开启;刻意不做每个节日的卡片、缩略图和选图入口,图片也无处可换 —— 两张壁纸随包发布,槽位只读。
|
|
226
|
+
- **中秋按农历、国庆按公历,都按 Asia/Shanghai 判定** — 中秋(八月十五)逐年移动,直接用浏览器自带的 ICU 农历换算,零依赖。时区是钉死的而非取机器本地:农历日期在北京时间午夜翻页。闰八月由 `month === '8'` 的精确判等排除 —— 已对 1900–2100 年间所有闰八月年份做过校验(2052 年在 2052-09-07 生效,而不是那年落在十月的 `8bis` 十五)。两者重叠时(2025-10-06)中秋优先。
|
|
227
|
+
- **内置壁纸压到原图的十二分之一:8.37 MB → 729 KB** — 原生分辨率 WebP q80;npm 包从 401 KB 涨到 1.12 MB,而图片本身已是压缩格式、gzip 再压不动。这就是这个功能的全部代价。
|
|
228
|
+
- **没启用的节日不花任何代价 —— 没在过节的那天也不花** — 启动时只取今天真能生效的那一个;node 半边按需查找内置文件,而不是跟着插件一起加载。
|
|
204
229
|
|
|
205
230
|
### v0.5.5
|
|
206
231
|
|
|
207
232
|
- **颜色预览块把色值打在自己身上** — 它位于 H/S/L(R/G/B)那一列的底部,边框同样是 1px,却一个字都没有,于是颜色一浅(报告里是 `#BADEE8`,L 82%)就读成第四个空白输入框,而它没有任何可输入的内容。现在把 `#RRGGBB` 用等宽字体居中打在颜色上,字色按 **Rec.709 亮度**(壁纸取色用的同一个公式)选取,值不会消失在自己的底色里;那个它从未兑现的 `scale(1.02)` hover 也去掉了。HSL/RGB 切换器上方重复的那行色值一并删除。
|
|
208
233
|
- **清空颜色的按钮改成说它做什么** — **「系统主题」**(一个状态)现在是**「跟随系统主题」**(那个动作),并带上宿主自己的太阳字形。它与 0.5.3 把无颜色按钮改成**「自定义颜色」**的那次是同一种修正的两侧。
|
|
209
234
|
|
|
210
|
-
### v0.5.4
|
|
211
|
-
|
|
212
|
-
- **填充上的文字改读宿主的「色块墨色」,不再用 `brand-text`** — 跟随系统主题时,布局模式的选中胶囊、「+ 新增规则」按钮和设置页的品牌方块,底色取自宿主自己的 `--dsw-alias-brand-primary`,而它**不是品牌色、是对比墨色**:宿主浅色档近黑(`#0f1115`),深色档近白(`#f9fafb`)。它们的文字读的是 `--dsw-alias-brand-text`,而宿主在两档里都把它定义成与底色**完全相同**的值、自己的 CSS 从不使用。于是在深色系统上就成了有底色却没有文字的方块 —— 白底主按钮、白底选中胶囊、白底图标块(实测正好 `#f9fafb`),只有插件自己持有一套调色板时才看得见。四处现在统一读 `--dsw-alias-label-primary-inverted`,也就是宿主自己画在品牌/对比色块上的墨色:浅色档 `#fff`,深色档 `#353638`。
|
|
213
|
-
- **开关打开态的圆点是同一个毛病的小号版本** — 硬编码 `#fff` 画在 `--dsw-alias-brand-primary` 轨道上,而深色档那条轨道本身就是白的。
|
|
214
|
-
- **插件自建的深色调色板是同一问题的镜像** — 那一档的品牌填充故意保持 50% 以上亮度,而**宿主自己的主按钮**用来写标签的 `--dsw-alias-label-primary-foreground`(画在 `--dsw-alias-button-primary-fill` 上)被写死成白色。现在它随填充亮度翻转(与 `brand-text` 共用一条判定),浅色分支也补上了 `label-primary-inverted`,让插件的调色板自己成对,而不是继承宿主当前恰好所处的档位。
|
|
215
|
-
|
|
216
235
|
## Star History
|
|
217
236
|
|
|
218
237
|
[](https://www.star-history.com/?repos=HarmlessFunny%2Fdsh-background-by-model&type=timeline&legend=bottom-right)
|
|
Binary file
|
|
Binary file
|