@nonamelego/dsh-catppuccin 0.5.1 → 0.5.2
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.en.md +50 -15
- package/README.md +34 -18
- package/lib/client.js +57 -23
- package/lib/client.js.map +1 -1
- package/lib/index.js +1 -1
- package/package.json +7 -2
- package/assets/.gitkeep +0 -0
- package/assets/previews/combine.py +0 -39
- package/assets/previews/combined.png +0 -0
- package/assets/previews/frappe.png +0 -0
- package/assets/previews/glass-combined.png +0 -0
- package/assets/previews/glass-latte.png +0 -0
- package/assets/previews/glass-mocha.png +0 -0
- package/assets/previews/latte.png +0 -0
- package/assets/previews/macchiato.png +0 -0
- package/assets/previews/mocha.png +0 -0
package/README.en.md
CHANGED
|
@@ -30,9 +30,9 @@
|
|
|
30
30
|
- [💝 Credits](#-credits)
|
|
31
31
|
|
|
32
32
|
<p align="center">
|
|
33
|
-
<img src="assets/previews/combined.png" width="100%" alt="DeepSeek Harness under the four Catppuccin flavours"/>
|
|
33
|
+
<img src="https://raw.githubusercontent.com/NoNameLeGo/dsh-catppuccin-theme/main/assets/previews/combined.png" width="100%" alt="DeepSeek Harness under the four Catppuccin flavours"/>
|
|
34
34
|
<br/><br/>
|
|
35
|
-
<img src="assets/previews/glass-combined.png" width="100%" alt="Glass skin · Latte & Mocha"/>
|
|
35
|
+
<img src="https://raw.githubusercontent.com/NoNameLeGo/dsh-catppuccin-theme/main/assets/previews/glass-combined.png" width="100%" alt="Glass skin · Latte & Mocha"/>
|
|
36
36
|
</p>
|
|
37
37
|
|
|
38
38
|
## Introduction
|
|
@@ -58,7 +58,9 @@ Catppuccin theme automatically.
|
|
|
58
58
|
- 🧩 Registered into the official theme system, on a par with the built-in light / dark / system themes
|
|
59
59
|
- 🎯 Full-UI colour coverage — not just one or two accent colours
|
|
60
60
|
- ⚙️ One-click switch in Settings, persisted and restored across restarts
|
|
61
|
-
-
|
|
61
|
+
- 🔧 **Custom token overrides**: override individual colour tokens with `--dsw-* var: value` pairs (e.g. turn comments blue); persisted alongside the selected flavour
|
|
62
|
+
- 🖍️ **Code-block highlight style**: default / italic-comments shiki themes
|
|
63
|
+
- 🌐 Seven UI languages (Chinese / English / Japanese / Korean / Spanish / French / German, follows the system language)
|
|
62
64
|
- 🪟 **Glass skin**: frosted glass for the top bar / sidebar / composer / stats line /
|
|
63
65
|
trajectory view / chat bubbles / new-session button, one-click toggle in Settings;
|
|
64
66
|
mica & compatibility modes, adjustable blur, frost and backdrop brightness
|
|
@@ -68,7 +70,8 @@ Catppuccin theme automatically.
|
|
|
68
70
|
content softens as it scrolls under the panes
|
|
69
71
|
- 🎨 Glass colours follow the current Catppuccin theme
|
|
70
72
|
- 🔄 **Update check**: one-click "Check for updates" in Settings compares the latest npm
|
|
71
|
-
version and gives you a copyable upgrade command
|
|
73
|
+
version and gives you a copyable upgrade command; **auto-check is on by default** (once at
|
|
74
|
+
startup, then every 6 hours) and the release channel switches between stable and beta
|
|
72
75
|
- 💻 **dsh-TUI terminal themes**: one command installs into dsh-TUI; the four themes sync to
|
|
73
76
|
`~/.dsh-tui/themes/` automatically (see [Installation · dsh-TUI](#dsh-tui-terminal-themes))
|
|
74
77
|
|
|
@@ -78,19 +81,19 @@ Actual screenshots from a local GUI (the header image is a diagonal blend of the
|
|
|
78
81
|
|
|
79
82
|
<details>
|
|
80
83
|
<summary>🌻 Latte (light)</summary>
|
|
81
|
-
<img src="assets/previews/latte.png"/>
|
|
84
|
+
<img src="https://raw.githubusercontent.com/NoNameLeGo/dsh-catppuccin-theme/main/assets/previews/latte.png"/>
|
|
82
85
|
</details>
|
|
83
86
|
<details>
|
|
84
87
|
<summary>🪴 Frappé (dark)</summary>
|
|
85
|
-
<img src="assets/previews/frappe.png"/>
|
|
88
|
+
<img src="https://raw.githubusercontent.com/NoNameLeGo/dsh-catppuccin-theme/main/assets/previews/frappe.png"/>
|
|
86
89
|
</details>
|
|
87
90
|
<details>
|
|
88
91
|
<summary>🌺 Macchiato (dark)</summary>
|
|
89
|
-
<img src="assets/previews/macchiato.png"/>
|
|
92
|
+
<img src="https://raw.githubusercontent.com/NoNameLeGo/dsh-catppuccin-theme/main/assets/previews/macchiato.png"/>
|
|
90
93
|
</details>
|
|
91
94
|
<details>
|
|
92
95
|
<summary>🌿 Mocha (dark)</summary>
|
|
93
|
-
<img src="assets/previews/mocha.png"/>
|
|
96
|
+
<img src="https://raw.githubusercontent.com/NoNameLeGo/dsh-catppuccin-theme/main/assets/previews/mocha.png"/>
|
|
94
97
|
</details>
|
|
95
98
|
|
|
96
99
|
### Glass skin (Mica mode)
|
|
@@ -101,11 +104,11 @@ past the page edges; the background is the theme's solid base colour:
|
|
|
101
104
|
|
|
102
105
|
<details>
|
|
103
106
|
<summary>🌻 Latte (light glass)</summary>
|
|
104
|
-
<img src="assets/previews/glass-latte.png"/>
|
|
107
|
+
<img src="https://raw.githubusercontent.com/NoNameLeGo/dsh-catppuccin-theme/main/assets/previews/glass-latte.png"/>
|
|
105
108
|
</details>
|
|
106
109
|
<details>
|
|
107
110
|
<summary>🌿 Mocha (dark glass)</summary>
|
|
108
|
-
<img src="assets/previews/glass-mocha.png"/>
|
|
111
|
+
<img src="https://raw.githubusercontent.com/NoNameLeGo/dsh-catppuccin-theme/main/assets/previews/glass-mocha.png"/>
|
|
109
112
|
</details>
|
|
110
113
|
|
|
111
114
|
## Installation
|
|
@@ -146,8 +149,13 @@ The same package covers the TUI. Install it into the dsh-tui profile:
|
|
|
146
149
|
dsh plugin --profile dsh-tui add @nonamelego/dsh-catppuccin
|
|
147
150
|
```
|
|
148
151
|
|
|
149
|
-
Installing from the repository works the same way
|
|
150
|
-
|
|
152
|
+
Installing from the repository works the same way:
|
|
153
|
+
|
|
154
|
+
```sh
|
|
155
|
+
dsh plugin --profile dsh-tui add https://github.com/NoNameLeGo/dsh-catppuccin-theme
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
The package ships a tiny theme-sync plugin row
|
|
151
159
|
(`dsh-catppuccin-tui-themes`, no service dependencies): on every dsh-TUI start it syncs the
|
|
152
160
|
four theme JSONs to `~/.dsh-tui/themes/`, so upgrades pick up the new palettes. After
|
|
153
161
|
installing, launch `dsh --profile dsh-tui` and pick the theme with `/theme` —
|
|
@@ -178,6 +186,15 @@ installing, launch `dsh --profile dsh-tui` and pick the theme with `/theme` —
|
|
|
178
186
|
4. Choosing **Follow system** reverts to the official theme — it restores the preference
|
|
179
187
|
you had before enabling Catppuccin (light / dark / follow system) instead of forcing a reset.
|
|
180
188
|
|
|
189
|
+
### Other options in the Catppuccin row
|
|
190
|
+
|
|
191
|
+
- **Code highlight style**: default / **italic comments** — affects only the shiki colours used
|
|
192
|
+
in code blocks and diffs.
|
|
193
|
+
- **Custom overrides** (collapsible; the button shows the entry count): override individual tokens
|
|
194
|
+
with `--dsw-* var: value` pairs, e.g. `--dsw-static-blue-500` → `#89b4fa`. The **key** commits on
|
|
195
|
+
blur and must start with `--` (otherwise the entry is dropped); the **value** applies as you type,
|
|
196
|
+
and an **empty value deletes the entry**; ✕ removes the row. Overrides persist with the flavour.
|
|
197
|
+
|
|
181
198
|
### Glass skin
|
|
182
199
|
|
|
183
200
|
Right below the **Catppuccin theme** row in **Settings → General** you'll find the **Glass** row:
|
|
@@ -201,6 +218,8 @@ In **Settings → General**, right below the **Glass** row:
|
|
|
201
218
|
- Clicking **Check for updates** compares the latest npm version with the installed one:
|
|
202
219
|
up to date → shows the current version; newer → shows the new version plus a copyable
|
|
203
220
|
upgrade command (the profile name is detected automatically, falling back to `web`).
|
|
221
|
+
- **Auto-check**: on by default — once after startup, then every 6 hours (switch it off on this row);
|
|
222
|
+
the **Channel** picks **Stable** (follows `latest` only) or **Beta** (prereleases too).
|
|
204
223
|
- Locally linked / source installs (`link:` / `file:` / git) don't show an npm upgrade
|
|
205
224
|
command — you'll be told to `git pull` or rebuild instead.
|
|
206
225
|
- Channel policy: stable builds follow the `latest` tag; prereleases follow both `latest`
|
|
@@ -233,9 +252,10 @@ What this plugin does:
|
|
|
233
252
|
|
|
234
253
|
```sh
|
|
235
254
|
pnpm install
|
|
236
|
-
pnpm typecheck
|
|
237
|
-
pnpm
|
|
238
|
-
pnpm
|
|
255
|
+
pnpm typecheck # tsc --noEmit: type check for src
|
|
256
|
+
pnpm typecheck:tests # tsc --noEmit: type check for the specs (vitest transpiles, it never type checks)
|
|
257
|
+
pnpm test # vitest palette-coverage tests
|
|
258
|
+
pnpm build # tsdown build -> lib/index.js (host) + lib/client.js (browser)
|
|
239
259
|
```
|
|
240
260
|
|
|
241
261
|
Palettes are produced by a generator script — after editing
|
|
@@ -253,6 +273,17 @@ pnpm changelog:gen # print the draft since the last tag
|
|
|
253
273
|
pnpm changelog:gen -- --write # write it into the [Unreleased] section
|
|
254
274
|
```
|
|
255
275
|
|
|
276
|
+
TypeDoc docs for the public API (`./client`, `./tui-themes` subpath exports) are generated
|
|
277
|
+
locally on demand into `docs/api/` (that directory is **not** committed — it's in
|
|
278
|
+
`.gitignore`; wire up CI Pages publishing later if an online copy is ever wanted):
|
|
279
|
+
|
|
280
|
+
```sh
|
|
281
|
+
pnpm docs:api
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for the contribution guide and
|
|
285
|
+
[docs/state-migrations.md](docs/state-migrations.md) for the state versioning contract.
|
|
286
|
+
|
|
256
287
|
### Local link debugging
|
|
257
288
|
|
|
258
289
|
Clone the repo, link it into a profile and add it to the bundles (use your own paths):
|
|
@@ -301,4 +332,8 @@ Then add `@nonamelego/dsh-catppuccin` to the profile's `package.json`
|
|
|
301
332
|
|
|
302
333
|
<p align="center">
|
|
303
334
|
Copyright © 2021-present <a href="https://github.com/catppuccin/catppuccin" target="_blank">Catppuccin Org</a>
|
|
335
|
+
</p>
|
|
336
|
+
|
|
337
|
+
<p align="center">
|
|
338
|
+
<a href="https://github.com/catppuccin/catppuccin/blob/main/LICENSE"><img src="https://img.shields.io/static/v1.svg?style=for-the-badge&label=License&message=MIT&logoColor=d9e0ee&colorA=363a4f&colorB=b7bdf8"/></a>
|
|
304
339
|
</p>
|
package/README.md
CHANGED
|
@@ -28,9 +28,9 @@
|
|
|
28
28
|
- [💝 致谢](#致谢)
|
|
29
29
|
|
|
30
30
|
<p align="center">
|
|
31
|
-
<img src="assets/previews/combined.png" width="100%" alt="Catppuccin 四主题下的 DeepSeek Harness"/>
|
|
31
|
+
<img src="https://raw.githubusercontent.com/NoNameLeGo/dsh-catppuccin-theme/main/assets/previews/combined.png" width="100%" alt="Catppuccin 四主题下的 DeepSeek Harness"/>
|
|
32
32
|
<br/><br/>
|
|
33
|
-
<img src="assets/previews/glass-combined.png" width="100%" alt="玻璃质感 · Latte & Mocha"/>
|
|
33
|
+
<img src="https://raw.githubusercontent.com/NoNameLeGo/dsh-catppuccin-theme/main/assets/previews/glass-combined.png" width="100%" alt="玻璃质感 · Latte & Mocha"/>
|
|
34
34
|
</p>
|
|
35
35
|
|
|
36
36
|
## 简介
|
|
@@ -55,6 +55,8 @@ Catppuccin 主题。
|
|
|
55
55
|
- 🧩 接入官方主题系统,与内置浅色 / 深色 / 跟随系统主题平级
|
|
56
56
|
- 🎯 全界面配色覆盖,不只是一两个强调色
|
|
57
57
|
- ⚙️ 设置页一行切换,选择自动保存、重启自动恢复
|
|
58
|
+
- 🔧 **自定义 token 覆盖**:按「`--dsw-* 变量: 值`」逐条覆盖单个配色 token(例如把注释色换成蓝色),与所选风味一起持久保存
|
|
59
|
+
- 🖍️ **代码块高亮风格**:默认 / 注释斜体(italic-comments)两套 shiki 风格可选
|
|
58
60
|
- 🌐 中 / 英 / 日 / 韩 / 西 / 法 / 德七语文案(跟随系统语言)
|
|
59
61
|
- 🪟 **玻璃质感**:顶栏 / 侧边栏 / 输入框 / 统计行 / 轨迹视图 / 聊天气泡 /
|
|
60
62
|
新会话按钮磨砂玻璃效果,设置里一键开关;云母 / 兼容双模式,模糊度、磨砂度、
|
|
@@ -62,7 +64,7 @@ Catppuccin 主题。
|
|
|
62
64
|
- 🌫️ **玻璃拟态细节**:页面上下边缘渐变模糊、折叠侧边栏悬浮玻璃、
|
|
63
65
|
纯色背景跟随主题底色——内容滚入视口边缘时柔化穿过,层次更立体
|
|
64
66
|
- 🎨 玻璃配色自动跟随当前 Catppuccin 主题
|
|
65
|
-
- 🔄 **检查 Catppuccin 插件更新**:设置页一键检测本插件(dsh-catppuccin)在 npm
|
|
67
|
+
- 🔄 **检查 Catppuccin 插件更新**:设置页一键检测本插件(dsh-catppuccin)在 npm 上的最新版本,发现新版直接给出可复制的升级命令;**默认开启自动检查**(启动后一次 + 每 6 小时),更新渠道可选稳定版 / Beta
|
|
66
68
|
- 💻 **dsh-TUI 终端主题**:一条安装命令装进 dsh-TUI,四套主题自动同步到 `~/.dsh-tui/themes/`,见[安装 · dsh-TUI](#dsh-tui-终端版主题)
|
|
67
69
|
|
|
68
70
|
## 预览
|
|
@@ -71,19 +73,19 @@ Catppuccin 主题。
|
|
|
71
73
|
|
|
72
74
|
<details>
|
|
73
75
|
<summary>🌻 Latte(浅色)</summary>
|
|
74
|
-
<img src="assets/previews/latte.png"/>
|
|
76
|
+
<img src="https://raw.githubusercontent.com/NoNameLeGo/dsh-catppuccin-theme/main/assets/previews/latte.png"/>
|
|
75
77
|
</details>
|
|
76
78
|
<details>
|
|
77
79
|
<summary>🪴 Frappé(深色)</summary>
|
|
78
|
-
<img src="assets/previews/frappe.png"/>
|
|
80
|
+
<img src="https://raw.githubusercontent.com/NoNameLeGo/dsh-catppuccin-theme/main/assets/previews/frappe.png"/>
|
|
79
81
|
</details>
|
|
80
82
|
<details>
|
|
81
83
|
<summary>🌺 Macchiato(深色)</summary>
|
|
82
|
-
<img src="assets/previews/macchiato.png"/>
|
|
84
|
+
<img src="https://raw.githubusercontent.com/NoNameLeGo/dsh-catppuccin-theme/main/assets/previews/macchiato.png"/>
|
|
83
85
|
</details>
|
|
84
86
|
<details>
|
|
85
87
|
<summary>🌿 Mocha(深色)</summary>
|
|
86
|
-
<img src="assets/previews/mocha.png"/>
|
|
88
|
+
<img src="https://raw.githubusercontent.com/NoNameLeGo/dsh-catppuccin-theme/main/assets/previews/mocha.png"/>
|
|
87
89
|
</details>
|
|
88
90
|
|
|
89
91
|
### 玻璃质感(Mica 云母模式)
|
|
@@ -92,16 +94,13 @@ Catppuccin 主题。
|
|
|
92
94
|
聊天气泡、输入框与统计行都是玻璃卡片,消息滚过页面边缘时被柔化,
|
|
93
95
|
背景为主题底色的纯色(截图来自本地 GUI):
|
|
94
96
|
|
|
95
|
-
<p align="center">
|
|
96
|
-
</p>
|
|
97
|
-
|
|
98
97
|
<details>
|
|
99
98
|
<summary>🌻 Latte(浅色玻璃)</summary>
|
|
100
|
-
<img src="assets/previews/glass-latte.png"/>
|
|
99
|
+
<img src="https://raw.githubusercontent.com/NoNameLeGo/dsh-catppuccin-theme/main/assets/previews/glass-latte.png"/>
|
|
101
100
|
</details>
|
|
102
101
|
<details>
|
|
103
102
|
<summary>🌿 Mocha(深色玻璃)</summary>
|
|
104
|
-
<img src="assets/previews/glass-mocha.png"/>
|
|
103
|
+
<img src="https://raw.githubusercontent.com/NoNameLeGo/dsh-catppuccin-theme/main/assets/previews/glass-mocha.png"/>
|
|
105
104
|
</details>
|
|
106
105
|
|
|
107
106
|
## 安装
|
|
@@ -143,7 +142,7 @@ dsh plugin --profile web add https://github.com/NoNameLeGo/dsh-catppuccin-theme
|
|
|
143
142
|
dsh plugin --profile dsh-tui add @nonamelego/dsh-catppuccin
|
|
144
143
|
```
|
|
145
144
|
|
|
146
|
-
|
|
145
|
+
从仓库安装同理(也可用 git 形式,效果一致):
|
|
147
146
|
|
|
148
147
|
```sh
|
|
149
148
|
dsh plugin --profile dsh-tui add https://github.com/NoNameLeGo/dsh-catppuccin-theme
|
|
@@ -171,6 +170,13 @@ dsh plugin --profile dsh-tui add https://github.com/NoNameLeGo/dsh-catppuccin-th
|
|
|
171
170
|
4. 选择 **跟随系统** 则回退到官方主题——会还原你启用 Catppuccin 之前
|
|
172
171
|
的官方偏好(浅色 / 深色 / 跟随系统),而不是强制重置。
|
|
173
172
|
|
|
173
|
+
### Catppuccin 行里的其它选项
|
|
174
|
+
|
|
175
|
+
- **代码高亮风格**:默认 / **注释斜体**(italic-comments)——只影响代码块与 diff 的 shiki 高亮配色。
|
|
176
|
+
- **自定义覆盖**(折叠区,按钮上显示已有条数):按「`--dsw-* 变量: 值`」逐条覆盖单个 token,
|
|
177
|
+
例如 `--dsw-static-blue-500` → `#89b4fa`。**键名**失焦生效(必须以 `--` 开头,否则该条会被丢弃);
|
|
178
|
+
**值**输入即生效、**清空值即删除该条**;✕ 删除整行。覆盖持久保存,与所选风味一起生效。
|
|
179
|
+
|
|
174
180
|
### 玻璃质感
|
|
175
181
|
|
|
176
182
|
在 **设置 → 常规** 的 **Catppuccin 主题** 正下方找到 **玻璃质感** 行:
|
|
@@ -196,6 +202,8 @@ dsh plugin --profile dsh-tui add https://github.com/NoNameLeGo/dsh-catppuccin-th
|
|
|
196
202
|
- 点击 **检查更新** 即对比 npm 上的最新版与当前版本:已是最新 → 显示当前
|
|
197
203
|
版本号;发现新版 → 显示新版本号并给出可复制的升级命令(命令中的 profile
|
|
198
204
|
名自动探测,无需手动替换;探测失败才回退为 `web`)。
|
|
205
|
+
- **自动检查**:默认开启——启动后检查一次、之后每 6 小时一次(该行可关闭);
|
|
206
|
+
**渠道**可选 **稳定版**(只跟 `latest`)或 **Beta 版**(连预发布一起跟)。
|
|
199
207
|
- 本插件为本地链接 / 源码安装(`link:` / `file:` / git)时不显示 npm 升级
|
|
200
208
|
命令,会提示改用 `git pull` 或重新构建。
|
|
201
209
|
- 通道策略:正式版只跟随 `latest` 标签;预发布版同时跟随 `beta`(升级命令
|
|
@@ -224,9 +232,10 @@ dsh plugin --profile dsh-tui add https://github.com/NoNameLeGo/dsh-catppuccin-th
|
|
|
224
232
|
|
|
225
233
|
```sh
|
|
226
234
|
pnpm install
|
|
227
|
-
pnpm typecheck
|
|
228
|
-
pnpm
|
|
229
|
-
pnpm
|
|
235
|
+
pnpm typecheck # tsc --noEmit:src 的类型检查
|
|
236
|
+
pnpm typecheck:tests # tsc --noEmit:tests 的类型检查(vitest 跑 esbuild,不做类型检查)
|
|
237
|
+
pnpm test # vitest 跑配色表 / 契约 / e2e 覆盖测试
|
|
238
|
+
pnpm build # tsdown 构建 -> lib/index.js(服务端)+ lib/client.js(浏览器)
|
|
230
239
|
```
|
|
231
240
|
|
|
232
241
|
配色表由生成器脚本产出——修改 `scripts/generate-palettes.mjs` 后重跑
|
|
@@ -237,8 +246,15 @@ pnpm build # tsdown 构建 -> lib/index.js(服务端)+ lib/client.js
|
|
|
237
246
|
node scripts/generate-palettes.mjs [--pin <upstream-sha>]
|
|
238
247
|
```
|
|
239
248
|
|
|
240
|
-
|
|
241
|
-
|
|
249
|
+
CHANGELOG 草稿由 conventional 提交生成(提交正文里的 `EN:` 行会被渲染成英文摘要):
|
|
250
|
+
|
|
251
|
+
```sh
|
|
252
|
+
pnpm changelog:gen # 打印上一 tag 之后的草稿
|
|
253
|
+
pnpm changelog:gen -- --write # 直接写入 [Unreleased] 节
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
对外 API(`./client`、`./tui-themes` 子路径导出)的 typedoc 文档**按需本地生成**到
|
|
257
|
+
`docs/api/`(该目录不入库、已进 `.gitignore`;哪天真需要在线版本再接 CI 发布):
|
|
242
258
|
|
|
243
259
|
```sh
|
|
244
260
|
pnpm docs:api
|
package/lib/client.js
CHANGED
|
@@ -134,8 +134,9 @@ window.__ModuleLoader__.load({
|
|
|
134
134
|
const style = (0, react.useSyncExternalStore)(subscribePrefs, shikiStyle);
|
|
135
135
|
const [overridesOpen, setOverridesOpen] = (0, react.useState)(false);
|
|
136
136
|
const [draftRows, setDraftRows] = (0, react.useState)([]);
|
|
137
|
+
const isTokenKey = (key) => key.trim().startsWith("--");
|
|
137
138
|
const commitDraft = (index, key, value) => {
|
|
138
|
-
if (key
|
|
139
|
+
if (isTokenKey(key) && value.trim() !== "") {
|
|
139
140
|
setOverrides({
|
|
140
141
|
...overrideMap,
|
|
141
142
|
[key.trim()]: value
|
|
@@ -146,11 +147,15 @@ window.__ModuleLoader__.load({
|
|
|
146
147
|
value
|
|
147
148
|
} : row));
|
|
148
149
|
};
|
|
150
|
+
/** Rename (or, with an empty/invalid key, delete) a persisted override. The
|
|
151
|
+
* key input is uncontrolled and commits on blur: writing on every keystroke
|
|
152
|
+
* repersisted the entry under each intermediate key, and an intermediate
|
|
153
|
+
* key that is not a `--` token made the row delete itself mid-typing. */
|
|
149
154
|
const commitPersistedKey = (oldKey, newKey) => {
|
|
150
155
|
if (newKey === oldKey) return;
|
|
151
156
|
const next = { ...overrideMap };
|
|
152
157
|
delete next[oldKey];
|
|
153
|
-
if (newKey
|
|
158
|
+
if (isTokenKey(newKey)) next[newKey.trim()] = overrideMap[oldKey];
|
|
154
159
|
setOverrides(next);
|
|
155
160
|
};
|
|
156
161
|
const commitPersistedValue = (key, value) => {
|
|
@@ -334,8 +339,8 @@ window.__ModuleLoader__.load({
|
|
|
334
339
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
335
340
|
type: "text",
|
|
336
341
|
"aria-label": t("row.overridesKey"),
|
|
337
|
-
|
|
338
|
-
|
|
342
|
+
defaultValue: key,
|
|
343
|
+
onBlur: (e) => {
|
|
339
344
|
commitPersistedKey(key, e.target.value);
|
|
340
345
|
},
|
|
341
346
|
placeholder: "--dsw-static-blue-500",
|
|
@@ -1198,7 +1203,7 @@ window.__ModuleLoader__.load({
|
|
|
1198
1203
|
"--dsw-static-amber-400": "color-mix(in srgb, #ef9f76 70%, #303446)",
|
|
1199
1204
|
"--dsw-static-amber-500": "#ef9f76",
|
|
1200
1205
|
"--dsw-static-amber-600": "#ef9f76",
|
|
1201
|
-
"--dsw-static-amber-900": "color-mix(in srgb, #ef9f76
|
|
1206
|
+
"--dsw-static-amber-900": "color-mix(in srgb, #ef9f76 18%, #232634)",
|
|
1202
1207
|
"--dsw-static-blue-100": "color-mix(in srgb, #8caaee 24%, #303446)",
|
|
1203
1208
|
"--dsw-static-blue-300": "color-mix(in srgb, #8caaee 50%, #303446)",
|
|
1204
1209
|
"--dsw-static-blue-400": "color-mix(in srgb, #8caaee 66%, #303446)",
|
|
@@ -1225,7 +1230,7 @@ window.__ModuleLoader__.load({
|
|
|
1225
1230
|
"--dsw-static-green-100": "color-mix(in srgb, #a6d189 18%, #303446)",
|
|
1226
1231
|
"--dsw-static-green-400": "color-mix(in srgb, #a6d189 80%, #303446)",
|
|
1227
1232
|
"--dsw-static-green-500": "#a6d189",
|
|
1228
|
-
"--dsw-static-green-900": "color-mix(in srgb, #a6d189
|
|
1233
|
+
"--dsw-static-green-900": "color-mix(in srgb, #a6d189 18%, #232634)",
|
|
1229
1234
|
"--dsw-static-neutral-00": "#c6d0f5",
|
|
1230
1235
|
"--dsw-static-neutral-1000": "#232634",
|
|
1231
1236
|
"--dsw-static-neutral-100": "#a5adce",
|
|
@@ -1368,7 +1373,7 @@ window.__ModuleLoader__.load({
|
|
|
1368
1373
|
"--dsw-static-amber-400": "color-mix(in srgb, #f5a97f 70%, #24273a)",
|
|
1369
1374
|
"--dsw-static-amber-500": "#f5a97f",
|
|
1370
1375
|
"--dsw-static-amber-600": "#f5a97f",
|
|
1371
|
-
"--dsw-static-amber-900": "color-mix(in srgb, #f5a97f
|
|
1376
|
+
"--dsw-static-amber-900": "color-mix(in srgb, #f5a97f 18%, #181926)",
|
|
1372
1377
|
"--dsw-static-blue-100": "color-mix(in srgb, #8aadf4 24%, #24273a)",
|
|
1373
1378
|
"--dsw-static-blue-300": "color-mix(in srgb, #8aadf4 50%, #24273a)",
|
|
1374
1379
|
"--dsw-static-blue-400": "color-mix(in srgb, #8aadf4 66%, #24273a)",
|
|
@@ -1395,7 +1400,7 @@ window.__ModuleLoader__.load({
|
|
|
1395
1400
|
"--dsw-static-green-100": "color-mix(in srgb, #a6da95 18%, #24273a)",
|
|
1396
1401
|
"--dsw-static-green-400": "color-mix(in srgb, #a6da95 80%, #24273a)",
|
|
1397
1402
|
"--dsw-static-green-500": "#a6da95",
|
|
1398
|
-
"--dsw-static-green-900": "color-mix(in srgb, #a6da95
|
|
1403
|
+
"--dsw-static-green-900": "color-mix(in srgb, #a6da95 18%, #181926)",
|
|
1399
1404
|
"--dsw-static-neutral-00": "#cad3f5",
|
|
1400
1405
|
"--dsw-static-neutral-1000": "#181926",
|
|
1401
1406
|
"--dsw-static-neutral-100": "#a5adcb",
|
|
@@ -1538,7 +1543,7 @@ window.__ModuleLoader__.load({
|
|
|
1538
1543
|
"--dsw-static-amber-400": "color-mix(in srgb, #fab387 70%, #1e1e2e)",
|
|
1539
1544
|
"--dsw-static-amber-500": "#fab387",
|
|
1540
1545
|
"--dsw-static-amber-600": "#fab387",
|
|
1541
|
-
"--dsw-static-amber-900": "color-mix(in srgb, #fab387
|
|
1546
|
+
"--dsw-static-amber-900": "color-mix(in srgb, #fab387 18%, #11111b)",
|
|
1542
1547
|
"--dsw-static-blue-100": "color-mix(in srgb, #89b4fa 24%, #1e1e2e)",
|
|
1543
1548
|
"--dsw-static-blue-300": "color-mix(in srgb, #89b4fa 50%, #1e1e2e)",
|
|
1544
1549
|
"--dsw-static-blue-400": "color-mix(in srgb, #89b4fa 66%, #1e1e2e)",
|
|
@@ -1565,7 +1570,7 @@ window.__ModuleLoader__.load({
|
|
|
1565
1570
|
"--dsw-static-green-100": "color-mix(in srgb, #a6e3a1 18%, #1e1e2e)",
|
|
1566
1571
|
"--dsw-static-green-400": "color-mix(in srgb, #a6e3a1 80%, #1e1e2e)",
|
|
1567
1572
|
"--dsw-static-green-500": "#a6e3a1",
|
|
1568
|
-
"--dsw-static-green-900": "color-mix(in srgb, #a6e3a1
|
|
1573
|
+
"--dsw-static-green-900": "color-mix(in srgb, #a6e3a1 18%, #11111b)",
|
|
1569
1574
|
"--dsw-static-neutral-00": "#cdd6f4",
|
|
1570
1575
|
"--dsw-static-neutral-1000": "#11111b",
|
|
1571
1576
|
"--dsw-static-neutral-100": "#a6adc8",
|
|
@@ -1847,7 +1852,7 @@ window.__ModuleLoader__.load({
|
|
|
1847
1852
|
},
|
|
1848
1853
|
{
|
|
1849
1854
|
attribute: "data-dsh-glass-settings",
|
|
1850
|
-
selector: "[
|
|
1855
|
+
selector: ":has(> [role=\"dialog\"][aria-modal=\"true\"])"
|
|
1851
1856
|
}
|
|
1852
1857
|
];
|
|
1853
1858
|
function stamp(seam) {
|
|
@@ -1879,6 +1884,7 @@ window.__ModuleLoader__.load({
|
|
|
1879
1884
|
stampAll();
|
|
1880
1885
|
let frame;
|
|
1881
1886
|
let dirty = false;
|
|
1887
|
+
let disposed = false;
|
|
1882
1888
|
const stampFrame = () => {
|
|
1883
1889
|
frame = void 0;
|
|
1884
1890
|
if (!dirty) return;
|
|
@@ -1886,6 +1892,7 @@ window.__ModuleLoader__.load({
|
|
|
1886
1892
|
stampAll();
|
|
1887
1893
|
};
|
|
1888
1894
|
const schedule = () => {
|
|
1895
|
+
if (disposed) return;
|
|
1889
1896
|
dirty = true;
|
|
1890
1897
|
if (frame !== void 0) return;
|
|
1891
1898
|
frame = requestAnimationFrame(stampFrame);
|
|
@@ -1896,6 +1903,7 @@ window.__ModuleLoader__.load({
|
|
|
1896
1903
|
subtree: true
|
|
1897
1904
|
});
|
|
1898
1905
|
return () => {
|
|
1906
|
+
disposed = true;
|
|
1899
1907
|
observer.disconnect();
|
|
1900
1908
|
if (frame !== void 0) cancelAnimationFrame(frame);
|
|
1901
1909
|
frame = void 0;
|
|
@@ -2415,6 +2423,7 @@ window.__ModuleLoader__.load({
|
|
|
2415
2423
|
max,
|
|
2416
2424
|
step,
|
|
2417
2425
|
value,
|
|
2426
|
+
"aria-valuetext": `${value}${unit}`,
|
|
2418
2427
|
onChange: (e) => {
|
|
2419
2428
|
onChange(clamp(Number(e.target.value)));
|
|
2420
2429
|
}
|
|
@@ -2792,13 +2801,23 @@ window.__ModuleLoader__.load({
|
|
|
2792
2801
|
const [dismissedConflicts, setDismissedConflicts] = (0, react.useState)(0);
|
|
2793
2802
|
const [retryRemaining, setRetryRemaining] = (0, react.useState)(null);
|
|
2794
2803
|
const retryTimer = (0, react.useRef)(void 0);
|
|
2804
|
+
const tickerTimer = (0, react.useRef)(void 0);
|
|
2805
|
+
const retriesUsed = (0, react.useRef)(0);
|
|
2795
2806
|
const mounted = (0, react.useRef)(true);
|
|
2796
|
-
|
|
2807
|
+
/** Drop a pending auto-retry (its timeout and its countdown ticker). */
|
|
2808
|
+
const cancelRetry = () => {
|
|
2797
2809
|
if (retryTimer.current !== void 0) {
|
|
2798
2810
|
window.clearTimeout(retryTimer.current);
|
|
2799
2811
|
retryTimer.current = void 0;
|
|
2800
|
-
setRetryRemaining(null);
|
|
2801
2812
|
}
|
|
2813
|
+
if (tickerTimer.current !== void 0) {
|
|
2814
|
+
window.clearInterval(tickerTimer.current);
|
|
2815
|
+
tickerTimer.current = void 0;
|
|
2816
|
+
}
|
|
2817
|
+
setRetryRemaining(null);
|
|
2818
|
+
};
|
|
2819
|
+
const runCheck = async (withChannel = channelValue) => {
|
|
2820
|
+
cancelRetry();
|
|
2802
2821
|
setPhase("checking");
|
|
2803
2822
|
setCopied(false);
|
|
2804
2823
|
let next;
|
|
@@ -2813,27 +2832,36 @@ window.__ModuleLoader__.load({
|
|
|
2813
2832
|
}
|
|
2814
2833
|
setPayload(next);
|
|
2815
2834
|
setPhase("done");
|
|
2816
|
-
if (!next.ok) {
|
|
2835
|
+
if (!next.ok && retriesUsed.current === 0) {
|
|
2836
|
+
retriesUsed.current = 1;
|
|
2817
2837
|
const target = Date.now() + UPDATE_RETRY_AFTER_MS;
|
|
2818
2838
|
setRetryRemaining(UPDATE_RETRY_AFTER_MS / 1e3);
|
|
2819
2839
|
const ticker = window.setInterval(() => {
|
|
2820
2840
|
const remaining = Math.max(0, Math.ceil((target - Date.now()) / 1e3));
|
|
2821
2841
|
setRetryRemaining(remaining);
|
|
2822
|
-
if (remaining <= 0)
|
|
2842
|
+
if (remaining <= 0) {
|
|
2843
|
+
window.clearInterval(ticker);
|
|
2844
|
+
tickerTimer.current = void 0;
|
|
2845
|
+
}
|
|
2823
2846
|
}, 1e3);
|
|
2847
|
+
tickerTimer.current = ticker;
|
|
2824
2848
|
retryTimer.current = window.setTimeout(() => {
|
|
2825
|
-
window.clearInterval(ticker);
|
|
2826
|
-
retryTimer.current = void 0;
|
|
2827
|
-
setRetryRemaining(null);
|
|
2828
2849
|
if (mounted.current) runCheck();
|
|
2850
|
+
else cancelRetry();
|
|
2829
2851
|
}, UPDATE_RETRY_AFTER_MS);
|
|
2830
2852
|
}
|
|
2831
2853
|
};
|
|
2854
|
+
/** A user-initiated check: re-arms the one auto-retry budget (item V). */
|
|
2855
|
+
const runManualCheck = () => {
|
|
2856
|
+
retriesUsed.current = 0;
|
|
2857
|
+
runCheck();
|
|
2858
|
+
};
|
|
2832
2859
|
(0, react.useEffect)(() => {
|
|
2833
2860
|
mounted.current = true;
|
|
2834
2861
|
return () => {
|
|
2835
2862
|
mounted.current = false;
|
|
2836
2863
|
if (retryTimer.current !== void 0) window.clearTimeout(retryTimer.current);
|
|
2864
|
+
if (tickerTimer.current !== void 0) window.clearInterval(tickerTimer.current);
|
|
2837
2865
|
};
|
|
2838
2866
|
}, []);
|
|
2839
2867
|
const autoResult = lastAutoResult();
|
|
@@ -3035,7 +3063,7 @@ window.__ModuleLoader__.load({
|
|
|
3035
3063
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
3036
3064
|
type: "button",
|
|
3037
3065
|
disabled: phase === "checking",
|
|
3038
|
-
onClick:
|
|
3066
|
+
onClick: runManualCheck,
|
|
3039
3067
|
style: {
|
|
3040
3068
|
...buttonStyle,
|
|
3041
3069
|
cursor: phase === "checking" ? "default" : "pointer",
|
|
@@ -3178,7 +3206,7 @@ window.__ModuleLoader__.load({
|
|
|
3178
3206
|
}),
|
|
3179
3207
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
3180
3208
|
type: "button",
|
|
3181
|
-
onClick:
|
|
3209
|
+
onClick: runManualCheck,
|
|
3182
3210
|
style: {
|
|
3183
3211
|
...buttonStyle,
|
|
3184
3212
|
cursor: "pointer"
|
|
@@ -3432,13 +3460,19 @@ window.__ModuleLoader__.load({
|
|
|
3432
3460
|
localStorage.setItem(UPDATE_CHANNEL_KEY, value);
|
|
3433
3461
|
} catch {}
|
|
3434
3462
|
}
|
|
3435
|
-
/** Read the persisted token overrides (unparseable/absent → empty map).
|
|
3463
|
+
/** Read the persisted token overrides (unparseable/absent → empty map).
|
|
3464
|
+
*
|
|
3465
|
+
* Sanitized on read (`sanitizeOverrides`, the same guard the settings document
|
|
3466
|
+
* goes through) so localStorage and the durable section always have the SAME
|
|
3467
|
+
* shape. Without it a key that is not a `--` token (e.g. `dsw-static-blue-500`
|
|
3468
|
+
* typed without the dashes) lives in localStorage only: the hydration compares
|
|
3469
|
+
* the two shapes, sees a difference, and "the document wins" overwrites the
|
|
3470
|
+
* entry — the user's row vanished a debounce-beat after it was typed. */
|
|
3436
3471
|
function readOverrides() {
|
|
3437
3472
|
try {
|
|
3438
3473
|
const raw = localStorage.getItem(OVERRIDES_KEY);
|
|
3439
3474
|
if (raw === null) return {};
|
|
3440
|
-
|
|
3441
|
-
return typeof parsed === "object" && parsed !== null ? parsed : {};
|
|
3475
|
+
return sanitizeOverrides(JSON.parse(raw));
|
|
3442
3476
|
} catch {
|
|
3443
3477
|
return {};
|
|
3444
3478
|
}
|