dsh-any-background 0.1.4 → 0.1.6

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 CHANGED
@@ -45,23 +45,23 @@ dsh-any-background/
45
45
 
46
46
  ## Implementation
47
47
 
48
- The plugin is a Cordis plugin split into two halves:
49
-
50
- - **Node half** (`src/index.ts`) — owns file-backed persistence. It manages the `.dsh-any-background-data/` store under the DSH data home (`~/.dsh/`) and exposes a small RPC surface over the shared `/api` channel.
51
- - **Browser half** (`src/client/index.tsx`) — all UI logic lives here. The browser cannot touch the filesystem, so it reads/writes the store through the node half's RPC endpoints.
52
-
53
- ### Persistence
54
-
55
- Since the plugin surfaces in the browser, persisted data is stored on disk by the **node half**:
56
-
57
- ```
58
- ~/.dsh/.dsh-any-background-data/
59
- ├── theme-config.json # color, main/settings/wallpaper opacity, blur, bg edit state
60
- └── wallpaper.jpg # the chosen background image (deleted when removed)
61
- ```
62
-
63
- - On startup the client calls `read`, which returns the config and (if present) the wallpaper as a data URL.
64
- - Every setting change is written back synchronously to `theme-config.json`; changing the wallpaper writes `wallpaper.jpg`, removing it deletes the file.
48
+ The plugin is a Cordis plugin split into two halves:
49
+
50
+ - **Node half** (`src/index.ts`) — owns file-backed persistence. It manages the `.dsh-any-background-data/` store under the DSH data home (`~/.dsh/`) and exposes a small RPC surface over the shared `/api` channel.
51
+ - **Browser half** (`src/client/index.tsx`) — all UI logic lives here. The browser cannot touch the filesystem, so it reads/writes the store through the node half's RPC endpoints.
52
+
53
+ ### Persistence
54
+
55
+ Since the plugin surfaces in the browser, persisted data is stored on disk by the **node half**:
56
+
57
+ ```
58
+ ~/.dsh/.dsh-any-background-data/
59
+ ├── theme-config.json # color, main/settings/wallpaper opacity, blur, bg edit state
60
+ └── wallpaper.jpg # the chosen background image (deleted when removed)
61
+ ```
62
+
63
+ - On startup the client calls `read`, which returns the config and (if present) the wallpaper as a data URL.
64
+ - Every setting change is written back synchronously to `theme-config.json`; changing the wallpaper writes `wallpaper.jpg`, removing it deletes the file.
65
65
  - The store is created automatically if missing; a missing or malformed config falls back to defaults (with a warning), and all writes are error-guarded to avoid data loss.
66
66
 
67
67
  ### Architecture
@@ -187,7 +187,9 @@ Install the plugin directly from GitHub into your Web profile:
187
187
  ```sh
188
188
  dsh plugin --profile web add github:Tkingxiao/dsh-any-background
189
189
  ```
190
-
190
+ ```sh
191
+ dsh plugin --profile web add dsh-any-background
192
+ ```
191
193
  Then launch the Web UI:
192
194
 
193
195
  ```sh
@@ -203,6 +205,9 @@ If you don't have `dsh` installed globally, use `npx`:
203
205
  ```sh
204
206
  npx @deepseek-ai/dsh plugin --profile web add github:Tkingxiao/dsh-any-background
205
207
  ```
208
+ ```sh
209
+ npx @deepseek-ai/dsh plugin --profile web add dsh-any-background
210
+ ```
206
211
 
207
212
  Then launch:
208
213
 
@@ -228,10 +233,11 @@ pnpm run bundle
228
233
 
229
234
  # 4. Install the plugin into the web profile from the local checkout
230
235
  # (`dsh plugin add` wraps `pnpm add <dir>`, so point it at this directory)
231
- dsh plugin --profile web add .
236
+ cd .
237
+ pnpm dsh plugin --profile web add “dsh-any-background”
232
238
 
233
239
  # 5. Launch
234
- dsh web
240
+ pnpm dsh web
235
241
  ```
236
242
 
237
243
  ## Compatibility
@@ -255,11 +261,11 @@ The plugin works on both the **Web UI** and the **desktop client**:
255
261
 
256
262
  ## Star History
257
263
 
258
- <a href="https://www.star-history.com/?repos=Tkingxiao%2Fdsh-any-background&type=date&legend=bottom-right">
264
+ <a href="https://www.star-history.com/?repos=Tkingxiao%2Fdsh-any-background&type=timeline&legend=bottom-right">
259
265
  <picture>
260
- <source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/chart?repos=Tkingxiao/dsh-any-background&type=date&theme=dark&legend=bottom-right&sealed_token=7GSnWLC53Di99WoOA-OGKn_GLJ-kQ6jgcdGRLS7wUzlwkbtJxLtH9kT3D7gCvxb0HoMF8aZklqQT4ijJ7hcFA2zO43Sfh-ccbqGBtvLundJKPELZ1a2xNA" />
261
- <source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/chart?repos=Tkingxiao/dsh-any-background&type=date&legend=bottom-right&sealed_token=7GSnWLC53Di99WoOA-OGKn_GLJ-kQ6jgcdGRLS7wUzlwkbtJxLtH9kT3D7gCvxb0HoMF8aZklqQT4ijJ7hcFA2zO43Sfh-ccbqGBtvLundJKPELZ1a2xNA" />
262
- <img alt="Star History Chart" src="https://api.star-history.com/chart?repos=Tkingxiao/dsh-any-background&type=date&legend=bottom-right&sealed_token=7GSnWLC53Di99WoOA-OGKn_GLJ-kQ6jgcdGRLS7wUzlwkbtJxLtH9kT3D7gCvxb0HoMF8aZklqQT4ijJ7hcFA2zO43Sfh-ccbqGBtvLundJKPELZ1a2xNA" />
266
+ <source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/chart?repos=Tkingxiao/dsh-any-background&type=timeline&theme=dark&legend=bottom-right&sealed_token=eWfGjN-Qq27TMTaT_VVvuRZMI72MUHAVfaHws-WOwQE7ld9defq7Bn7Xsgmlg-7iFSCeNoOIhgxFfZM3jazeXnLzldBkMCN3jm4CMxvn6Em0EBEZWWK5pA" />
267
+ <source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/chart?repos=Tkingxiao/dsh-any-background&type=timeline&legend=bottom-right&sealed_token=eWfGjN-Qq27TMTaT_VVvuRZMI72MUHAVfaHws-WOwQE7ld9defq7Bn7Xsgmlg-7iFSCeNoOIhgxFfZM3jazeXnLzldBkMCN3jm4CMxvn6Em0EBEZWWK5pA" />
268
+ <img alt="Star History Chart" src="https://api.star-history.com/chart?repos=Tkingxiao/dsh-any-background&type=timeline&legend=bottom-right&sealed_token=eWfGjN-Qq27TMTaT_VVvuRZMI72MUHAVfaHws-WOwQE7ld9defq7Bn7Xsgmlg-7iFSCeNoOIhgxFfZM3jazeXnLzldBkMCN3jm4CMxvn6Em0EBEZWWK5pA" />
263
269
  </picture>
264
270
  </a>
265
271
 
package/README.zh.md CHANGED
@@ -164,7 +164,7 @@ dsh-any-background/
164
164
 
165
165
  <p align="center">
166
166
  <img src="example_img/image-8.png" alt="壁纸透明度100%" width="400">
167
- <img src="example_img/image-9.png" alt="壁纸透明度500%" width="400">
167
+ <img src="example_img/image-9.png" alt="壁纸透明度50%" width="400">
168
168
  <br/>
169
169
  <em>壁纸透明度 0% · 壁纸透明度 100%</em>
170
170
  </p>
@@ -187,7 +187,9 @@ dsh-any-background/
187
187
  ```sh
188
188
  dsh plugin --profile web add github:Tkingxiao/dsh-any-background
189
189
  ```
190
-
190
+ ```sh
191
+ dsh plugin --profile web add dsh-any-background
192
+ ```
191
193
  然后启动 Web UI:
192
194
 
193
195
  ```sh
@@ -203,6 +205,9 @@ dsh web
203
205
  ```sh
204
206
  npx @deepseek-ai/dsh plugin --profile web add github:Tkingxiao/dsh-any-background
205
207
  ```
208
+ ```sh
209
+ npx @deepseek-ai/dsh plugin --profile web add dsh-any-background
210
+ ```
206
211
 
207
212
  然后启动:
208
213
 
@@ -227,10 +232,11 @@ pnpm run bundle
227
232
 
228
233
  # 4. 从本地安装到 web profile
229
234
  # (`dsh plugin add` 是 `pnpm add <dir>` 的封装,传入本目录即可)
230
- dsh plugin --profile web add .
235
+ cd .
236
+ pnpm dsh plugin --profile web add "dsh-any-background"
231
237
 
232
238
  # 5. 启动
233
- dsh web
239
+ pnpm dsh web
234
240
  ```
235
241
 
236
242
  ## 兼容性
@@ -254,11 +260,11 @@ dsh web
254
260
 
255
261
  ## Star History
256
262
 
257
- <a href="https://www.star-history.com/?repos=Tkingxiao%2Fdsh-any-background&type=date&legend=bottom-right">
263
+ <a href="https://www.star-history.com/?repos=Tkingxiao%2Fdsh-any-background&type=timeline&legend=bottom-right">
258
264
  <picture>
259
- <source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/chart?repos=Tkingxiao/dsh-any-background&type=date&theme=dark&legend=bottom-right&sealed_token=7GSnWLC53Di99WoOA-OGKn_GLJ-kQ6jgcdGRLS7wUzlwkbtJxLtH9kT3D7gCvxb0HoMF8aZklqQT4ijJ7hcFA2zO43Sfh-ccbqGBtvLundJKPELZ1a2xNA" />
260
- <source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/chart?repos=Tkingxiao/dsh-any-background&type=date&legend=bottom-right&sealed_token=7GSnWLC53Di99WoOA-OGKn_GLJ-kQ6jgcdGRLS7wUzlwkbtJxLtH9kT3D7gCvxb0HoMF8aZklqQT4ijJ7hcFA2zO43Sfh-ccbqGBtvLundJKPELZ1a2xNA" />
261
- <img alt="Star History Chart" src="https://api.star-history.com/chart?repos=Tkingxiao/dsh-any-background&type=date&legend=bottom-right&sealed_token=7GSnWLC53Di99WoOA-OGKn_GLJ-kQ6jgcdGRLS7wUzlwkbtJxLtH9kT3D7gCvxb0HoMF8aZklqQT4ijJ7hcFA2zO43Sfh-ccbqGBtvLundJKPELZ1a2xNA" />
265
+ <source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/chart?repos=Tkingxiao/dsh-any-background&type=timeline&theme=dark&legend=bottom-right&sealed_token=eWfGjN-Qq27TMTaT_VVvuRZMI72MUHAVfaHws-WOwQE7ld9defq7Bn7Xsgmlg-7iFSCeNoOIhgxFfZM3jazeXnLzldBkMCN3jm4CMxvn6Em0EBEZWWK5pA" />
266
+ <source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/chart?repos=Tkingxiao/dsh-any-background&type=timeline&legend=bottom-right&sealed_token=eWfGjN-Qq27TMTaT_VVvuRZMI72MUHAVfaHws-WOwQE7ld9defq7Bn7Xsgmlg-7iFSCeNoOIhgxFfZM3jazeXnLzldBkMCN3jm4CMxvn6Em0EBEZWWK5pA" />
267
+ <img alt="Star History Chart" src="https://api.star-history.com/chart?repos=Tkingxiao/dsh-any-background&type=timeline&legend=bottom-right&sealed_token=eWfGjN-Qq27TMTaT_VVvuRZMI72MUHAVfaHws-WOwQE7ld9defq7Bn7Xsgmlg-7iFSCeNoOIhgxFfZM3jazeXnLzldBkMCN3jm4CMxvn6Em0EBEZWWK5pA" />
262
268
  </picture>
263
269
  </a>
264
270
 
package/lib/client.js CHANGED
@@ -86,7 +86,7 @@ window.__ModuleLoader__.load({
86
86
  };
87
87
  let wpUrl = null;
88
88
  let rpcCallFn = null;
89
- const RPC_CHANNEL = "/api";
89
+ const RPC_CHANNEL = "/dsh-any-background";
90
90
  const RPC_NS = "dshAnyBackground";
91
91
  const rpcEndpoint = (method) => `${RPC_NS}/${method}`;
92
92
  async function rpcCall(method, payload) {
@@ -205,6 +205,9 @@ window.__ModuleLoader__.load({
205
205
  "--dsw-alias-label-primary": hsl(0, 0, 1),
206
206
  "--dsw-alias-label-secondary": hsl(0, 0, 1),
207
207
  "--dsw-alias-label-tertiary": hsl(0, 0, 1),
208
+ "--dsw-alias-label-caption": hsl(0, 0, 1),
209
+ "--dsw-alias-label-dimmed": hsl(0, 0, 1),
210
+ "--dsw-alias-label-quaternary": hsl(0, 0, 1),
208
211
  "--dsw-alias-brand-primary": hsl(h(0), s(.1), Math.max(l(.2), .5)),
209
212
  "--dsw-alias-brand-text": l(.2) > .6 ? "#000" : "#fff",
210
213
  "--dsw-alias-button-primary-hover": hsl(h(0), s(.1), Math.max(l(.28), .58)),
@@ -240,6 +243,9 @@ window.__ModuleLoader__.load({
240
243
  "--dsw-alias-label-primary": hsl(0, 0, 0),
241
244
  "--dsw-alias-label-secondary": hsl(0, 0, 0),
242
245
  "--dsw-alias-label-tertiary": hsl(0, 0, 0),
246
+ "--dsw-alias-label-caption": hsl(0, 0, 0),
247
+ "--dsw-alias-label-dimmed": hsl(0, 0, 0),
248
+ "--dsw-alias-label-quaternary": hsl(0, 0, 0),
243
249
  "--dsw-alias-brand-primary": hsl(h(0), s(.05), Math.min(l(-.18), .45)),
244
250
  "--dsw-alias-brand-text": "#fff",
245
251
  "--dsw-alias-button-primary-hover": hsl(h(0), s(.05), Math.min(l(-.12), .5)),
package/lib/client.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","names":["useRef","useState","useCallback","defineStore"],"sources":["../src/client/index.tsx"],"sourcesContent":["/**\r\n * dsh-any-background — browser half.\r\n *\r\n * Appearance plugin with:\r\n * 1. PS-style color wheel (hue ring + saturation/lightness square) for\r\n * real-time theme color selection with dynamic token generation.\r\n * 2. Background image editor modal with drag-to-pan and scroll-to-zoom\r\n * inside a viewport-proportional preview rectangle.\r\n * 3. Opacity / blur sliders with zero-lag direct DOM manipulation: the\r\n * homepage background opacity (主界面透明度) and the settings panel opacity\r\n * (设置界面透明度) are separate sliders.\r\n *\r\n * The color wheel is one canvas: a hue ring and an inscribed SL square.\r\n * Mouse interaction on either region regenerates the full theme token set\r\n * and applies it instantly via ctx.theme.setTheme().\r\n *\r\n * The bg editor modal shows a rectangle matching the viewport aspect ratio.\r\n * The image can be dragged and zoomed (mouse wheel) inside it. What you see\r\n * in the rectangle is exactly how the background appears on the page.\r\n */\r\nimport { createElement as h } from 'react'\r\nimport { useRef, useState, useEffect, useCallback } from 'react'\r\nimport { defineStore } from '@deepseek-ai/dsh-client-runtime/client'\r\n\r\nexport const name = 'dsh-any-background'\r\nexport const inject = ['slots', 'locale', 'theme', 'connection']\r\n\r\n// ── Interfaces ─────────────────────────────────────────────────────────────────\r\n\r\ninterface ThemeSnapshot {\r\n preference: string; revision: number\r\n active: { colorScheme: string; tokens: Record<string, string> }\r\n themes: Array<{ id: string; colorScheme: string; tokens: Record<string, string> }>\r\n}\r\ninterface ThemeService {\r\n getTheme(): ThemeSnapshot; setTheme(id: string): void\r\n register(def: { id: string; colorScheme: string; tokens: Record<string, string> }): () => void\r\n overrideTokens(source: string, overrides: Record<string, Record<string, string>>): () => void\r\n}\r\ninterface LocaleService {\r\n register(ns: string, dicts: { zh: Record<string, string>; en: Record<string, string> }): unknown\r\n bind(ns: string): (key: string) => string\r\n subscribe(cb: () => void): () => void; getSnapshot(): { active: string }\r\n}\r\ninterface SlotsService {\r\n inject(slot: string, register: () => unknown): void\r\n register(meta: Record<string, unknown>, component: () => unknown): unknown\r\n}\r\ninterface ConnectionService {\r\n rpc: { call(channel: string, endpoint: string, payload: unknown): Promise<unknown> }\r\n}\r\ninterface Ctx {\r\n effect(cb: () => unknown, label?: string): void\r\n on(event: string, cb: (...a: any[]) => void): () => void\r\n locale: LocaleService; slots: SlotsService; theme: ThemeService; connection: ConnectionService\r\n}\r\n\r\n// ── Constants ──────────────────────────────────────────────────────────────────\r\n\r\nconst NS = 'settings.anyBg'\r\nconst DEF_OP = 0.85; const DEF_BL = 0; const DEF_SOP = 1\r\nconst CUSTOM_ID = 'custom-color'\r\n\r\n// ── i18n ───────────────────────────────────────────────────────────────────────\r\n\r\nconst zh: Record<string, string> = {\r\n nav: '主题', subtitle: '自定义界面外观',\r\n colorTitle: '主题色', colorHint: '在色轮上选择色相,在方形中调整饱和度和明度',\r\n uiTitle: '界面',\r\n uiOpacity: '主界面透明度', uiOpacityHint: '拖动滑块调整主页界面背景的透明度',\r\n uiSop: '设置界面透明度', uiSopHint: '拖动滑块调整设置页界面背景的透明度',\r\n bgTitle: '背景图片', bgChoose: '选择图片', bgRemove: '移除图片',\r\n bgEdit: '编辑位置', wpOpacity: '壁纸透明度', bgBlur: '壁纸模糊',\r\n bgHint: '拖动滑块实时调整。点击背景图可打开编辑器调整位置和大小',\r\n editorTitle: '背景编辑器', editorHint: '拖动移动图片,滚轮缩放大小',\r\n editorCommit: '确认', editorCancel: '取消', editorReset: '重置',\r\n}\r\nconst en: Record<string, string> = {\r\n nav: 'Theme', subtitle: 'Customize appearance',\r\n colorTitle: 'Theme color', colorHint: 'Pick hue on the ring, adjust saturation & lightness in the square',\r\n uiTitle: 'Interface',\r\n uiOpacity: 'Main interface opacity', uiOpacityHint: 'Drag to adjust homepage interface background opacity',\r\n uiSop: 'Settings interface opacity', uiSopHint: 'Drag to adjust the settings page background opacity',\r\n bgTitle: 'Wallpaper', bgChoose: 'Choose image', bgRemove: 'Remove image',\r\n bgEdit: 'Edit position', wpOpacity: 'Wallpaper opacity', bgBlur: 'Wallpaper blur',\r\n bgHint: 'Drag sliders for real-time adjustment. Click the image to open the editor',\r\n editorTitle: 'Background editor', editorHint: 'Drag to move, scroll to zoom',\r\n editorCommit: 'Confirm', editorCancel: 'Cancel', editorReset: 'Reset',\r\n}\r\n\r\n// ── Persistence (file-backed via node half) ───────────────────────────────────\r\n// The node half owns `.dsh-any-background-data/` on the DSH data home. This\r\n// module keeps an in-memory ThemeConfig mirror + the wallpaper data URL, and\r\n// pushes changes to the node half over the shared `/api` RPC channel. Reads\r\n// fall back to defaults when the connection is unavailable or the file is\r\n// missing/malformed, so the UI never crashes on a broken store.\r\n\r\ninterface BgState { zoom: number; x: number; y: number; iw: number; ih: number }\r\ninterface ThemeConfig {\r\n color: [number, number, number] | null\r\n opacity: number\r\n settingsOpacity: number\r\n wallpaperOpacity: number\r\n blur: number\r\n bgState: BgState\r\n}\r\ninterface RpcResultLike { ok: boolean; value?: any; error?: any }\r\n\r\nconst DEFAULT_CONFIG: ThemeConfig = {\r\n color: null,\r\n opacity: 0.85,\r\n settingsOpacity: 1,\r\n wallpaperOpacity: 1,\r\n blur: 0,\r\n bgState: { zoom: 1, x: 0, y: 0, iw: 0, ih: 0 },\r\n}\r\n\r\nlet cfg: ThemeConfig = { ...DEFAULT_CONFIG, bgState: { ...DEFAULT_CONFIG.bgState } }\r\nlet wpUrl: string | null = null\r\nlet rpcCallFn: ((endpoint: string, payload: unknown) => Promise<RpcResultLike | undefined>) | null = null\r\n\r\nconst RPC_CHANNEL = '/api'\r\nconst RPC_NS = 'dshAnyBackground'\r\nconst rpcEndpoint = (method: string): string => `${RPC_NS}/${method}`\r\n\r\nasync function rpcCall(method: string, payload: unknown): Promise<any> {\r\n if (!rpcCallFn) return undefined\r\n try {\r\n const res = await rpcCallFn(rpcEndpoint(method), payload)\r\n if (res && res.ok === true) return res.value\r\n console.warn(`dsh-any-background: rpc \"${method}\" failed`, res?.error)\r\n return undefined\r\n } catch (e) {\r\n console.warn(`dsh-any-background: rpc \"${method}\" threw`, e)\r\n return undefined\r\n }\r\n}\r\n\r\n/** Move a possibly-absent partial config into the shape the UI reads. */\r\nfunction adoptConfig(raw: any): void {\r\n const c = (raw ?? {}) as Partial<ThemeConfig>\r\n const color = Array.isArray(c.color) && c.color.length === 3\r\n ? [c.color[0], c.color[1], c.color[2]] as [number, number, number]\r\n : null\r\n const bg = (c.bgState ?? {}) as Partial<BgState>\r\n cfg = {\r\n color,\r\n opacity: typeof c.opacity === 'number' ? c.opacity : DEFAULT_CONFIG.opacity,\r\n settingsOpacity: typeof c.settingsOpacity === 'number' ? c.settingsOpacity : DEFAULT_CONFIG.settingsOpacity,\r\n wallpaperOpacity: typeof c.wallpaperOpacity === 'number' ? c.wallpaperOpacity : DEFAULT_CONFIG.wallpaperOpacity,\r\n blur: typeof c.blur === 'number' ? c.blur : DEFAULT_CONFIG.blur,\r\n bgState: {\r\n zoom: typeof bg.zoom === 'number' ? bg.zoom : 1,\r\n x: typeof bg.x === 'number' ? bg.x : 0,\r\n y: typeof bg.y === 'number' ? bg.y : 0,\r\n iw: typeof bg.iw === 'number' && bg.iw > 0 ? bg.iw : 0,\r\n ih: typeof bg.ih === 'number' && bg.ih > 0 ? bg.ih : 0,\r\n },\r\n }\r\n}\r\n\r\n/** Persist the current in-memory config to the node half (fire-and-forget). */\r\nfunction saveConfig(): void {\r\n void rpcCall('writeConfig', { config: cfg })\r\n}\r\n\r\n/** Load the persisted theme (config + wallpaper) from the node half. */\r\nasync function loadPersisted(): Promise<void> {\r\n const data = await rpcCall('read', {})\r\n if (data) {\r\n if (data.config) adoptConfig(data.config)\r\n if (typeof data.wallpaper === 'string') wpUrl = data.wallpaper\r\n else if (data.wallpaper === null) wpUrl = null\r\n }\r\n}\r\n\r\nfunction rHasColor(): boolean { return cfg.color !== null }\r\nfunction rColor(): [number, number, number] { return cfg.color ?? [220, 0.55, 0.25] }\r\nfunction rWp(): string | null { return wpUrl }\r\nfunction rOp(): number { return typeof cfg.opacity === 'number' ? Math.min(1, Math.max(0, cfg.opacity)) : DEF_OP }\r\nfunction rWop(): number { return typeof cfg.wallpaperOpacity === 'number' ? Math.min(1, Math.max(0, cfg.wallpaperOpacity)) : 1 }\r\nfunction rBl(): number { return typeof cfg.blur === 'number' ? Math.min(60, Math.max(0, cfg.blur)) : DEF_BL }\r\nfunction rSop(): number { return typeof cfg.settingsOpacity === 'number' ? Math.min(1, Math.max(0, cfg.settingsOpacity)) : DEF_SOP }\r\nfunction rBgState(): BgState { return cfg.bgState }\r\n\r\n// ── HSV ↔ HSL ────────────────────────────────────────────────────────────────\r\n// The wheel works in HSV end to end: props and pickSL are HSV, the canvas\r\n// renders the HSV S-V plane directly. Storage and genTokens expect HSL, so\r\n// setColor converts HSV → HSL at the boundary; sectionInject converts stored\r\n// HSL → HSV for the initial wheel props. Conversions never stack.\r\n\r\nfunction hsvToHsl(h: number, s: number, v: number): [number, number, number] {\r\n const l = v * (1 - s / 2)\r\n const sl = l === 0 || l === 1 ? 0 : (v - l) / Math.min(l, 1 - l)\r\n return [h, sl, l]\r\n}\r\n\r\nfunction hslToHsv(h: number, s: number, l: number): [number, number, number] {\r\n const v = l + s * Math.min(l, 1 - l)\r\n const sv = v === 0 ? 0 : 2 * (1 - l / v)\r\n return [h, sv, v]\r\n}\r\n\r\n// ── Token generation from HSL ──────────────────────────────────────────────────\r\n\r\nfunction genTokens(hue: number, sat: number, lit: number): { colorScheme: 'light' | 'dark'; tokens: Record<string, string> } {\r\n const dark = lit < 0.55\r\n const h = (d: number) => ((hue + d) % 360 + 360) % 360\r\n const s = (d: number) => Math.max(0, Math.min(1, sat + d))\r\n const l = (d: number) => Math.max(0, Math.min(1, lit + d))\r\n const hsl = (hh: number, ss: number, ll: number) => `hsl(${Math.round(hh)},${Math.round(ss * 100)}%,${Math.round(ll * 100)}%)`\r\n const rgba = (hh: number, ss: number, ll: number, a: number) => {\r\n const c = `hsl(${Math.round(hh)},${Math.round(ss * 100)}%,${Math.round(ll * 100)}%)`\r\n void c; return `hsla(${Math.round(hh)},${Math.round(ss * 100)}%,${Math.round(ll * 100)}%,${a})`\r\n }\r\n\r\n if (dark) {\r\n return {\r\n colorScheme: 'dark',\r\n tokens: {\r\n '--dsw-alias-bg-base': hsl(h(0), s(0), l(-0.04)),\r\n '--dsw-alias-bg-layer-1': hsl(h(0), s(0), l(0.02)),\r\n '--dsw-alias-bg-layer-2': hsl(h(0), s(0), l(0.07)),\r\n '--dsw-alias-bg-layer-3': hsl(h(0), s(-0.05), l(0.12)),\r\n '--dsw-alias-bg-overlay': hsl(h(0), s(-0.05), l(0.12)),\r\n '--dsw-alias-border-l1': rgba(h(0), s(-0.1), l(0.18), 0.12),\r\n '--dsw-alias-border-l2': rgba(h(0), s(-0.1), l(0.22), 0.22),\r\n '--dsw-alias-label-primary': hsl(0, 0, 1),\r\n '--dsw-alias-label-secondary': hsl(0, 0, 1),\r\n '--dsw-alias-label-tertiary': hsl(0, 0, 1),\r\n '--dsw-alias-brand-primary': hsl(h(0), s(0.1), Math.max(l(0.2), 0.5)),\r\n '--dsw-alias-brand-text': l(0.2) > 0.6 ? '#000' : '#fff',\r\n '--dsw-alias-button-primary-hover': hsl(h(0), s(0.1), Math.max(l(0.28), 0.58)),\r\n '--dsw-alias-button-primary-dimmed': hsl(h(0), s(0), l(0.07)),\r\n '--dsw-alias-button-elevated-fill': hsl(h(0), s(0), l(0.04)),\r\n '--dsw-alias-interactive-bg-hover': rgba(h(0), s(0), Math.max(l(0.15), 0.4), 0.12),\r\n '--dsw-alias-interactive-bg-active': rgba(h(0), s(0), Math.max(l(0.15), 0.4), 0.2),\r\n '--dsw-alias-markdown-code-block': hsl(h(0), s(0), l(-0.06)),\r\n '--dsw-alias-markdown-inline-code': hsl(h(0), s(0), l(0.04)),\r\n '--dsw-alias-state-error-primary': '#ff5c72',\r\n '--dsw-alias-state-success-primary': '#3ddc84',\r\n '--dsw-alias-state-warn-primary': '#ffb347',\r\n '--dsw-specific-sidebar-fill': hsl(h(0), s(0), l(-0.06)),\r\n '--dsw-specific-sidebar-nav-item-active': hsl(h(0), s(0), l(0.04)),\r\n '--dsw-specific-sidebar-nav-item-hover': hsl(h(0), s(0), l(0)),\r\n '--dsw-specific-input-major': hsl(h(0), s(0), l(0.02)),\r\n '--dsw-alias-scrollbar-bg-l1': hsl(h(0), s(-0.05), l(0.12)),\r\n '--dsw-alias-scrollbar-bg-l2': hsl(h(0), s(-0.05), l(0.16)),\r\n '--dsw-alias-scrollbar-hover-l1': hsl(h(0), s(-0.05), l(0.22)),\r\n '--dsw-alias-scrollbar-hover-l2': hsl(h(0), s(-0.05), l(0.22)),\r\n },\r\n }\r\n }\r\n return {\r\n colorScheme: 'light',\r\n tokens: {\r\n // Backgrounds track the picked color at its lightness — theme-colored,\r\n // with only mild desaturation so the surfaces stay readable.\r\n '--dsw-alias-bg-base': hsl(h(0), s(-0.08), l(0.03)),\r\n '--dsw-alias-bg-layer-1': hsl(h(0), s(-0.12), l(0.07)),\r\n '--dsw-alias-bg-layer-2': hsl(h(0), s(-0.1), l(-0.03)),\r\n '--dsw-alias-bg-layer-3': hsl(h(0), s(-0.08), l(-0.09)),\r\n '--dsw-alias-bg-overlay': hsl(h(0), s(-0.12), l(0.08)),\r\n '--dsw-alias-border-l1': rgba(h(0), s(-0.15), l(-0.35), 0.18),\r\n '--dsw-alias-border-l2': rgba(h(0), s(-0.15), l(-0.35), 0.3),\r\n // Text is pure black on light surfaces, pure white on dark.\r\n '--dsw-alias-label-primary': hsl(0, 0, 0),\r\n '--dsw-alias-label-secondary': hsl(0, 0, 0),\r\n '--dsw-alias-label-tertiary': hsl(0, 0, 0),\r\n '--dsw-alias-brand-primary': hsl(h(0), s(0.05), Math.min(l(-0.18), 0.45)),\r\n '--dsw-alias-brand-text': '#fff',\r\n '--dsw-alias-button-primary-hover': hsl(h(0), s(0.05), Math.min(l(-0.12), 0.5)),\r\n '--dsw-alias-button-primary-dimmed': hsl(h(0), s(-0.1), l(-0.03)),\r\n '--dsw-alias-button-elevated-fill': hsl(h(0), s(-0.1), l(0.1)),\r\n '--dsw-alias-interactive-bg-hover': rgba(h(0), s(0), l(-0.3), 0.08),\r\n '--dsw-alias-interactive-bg-active': rgba(h(0), s(0), l(-0.3), 0.14),\r\n '--dsw-alias-markdown-code-block': hsl(h(0), s(-0.1), l(-0.03)),\r\n '--dsw-alias-markdown-inline-code': hsl(h(0), s(-0.08), l(0.04)),\r\n '--dsw-specific-sidebar-fill': hsl(h(0), s(-0.1), l(-0.03)),\r\n '--dsw-specific-sidebar-nav-item-active': hsl(h(0), s(-0.08), l(0.05)),\r\n '--dsw-specific-sidebar-nav-item-hover': hsl(h(0), s(-0.12), l(0)),\r\n '--dsw-specific-input-major': hsl(h(0), s(-0.12), l(0.1)),\r\n '--dsw-alias-scrollbar-bg-l1': hsl(h(0), s(-0.1), l(-0.08)),\r\n '--dsw-alias-scrollbar-bg-l2': hsl(h(0), s(-0.08), l(-0.12)),\r\n '--dsw-alias-scrollbar-hover-l1': hsl(h(0), s(-0.08), l(-0.16)),\r\n '--dsw-alias-scrollbar-hover-l2': hsl(h(0), s(-0.08), l(-0.16)),\r\n },\r\n }\r\n}\r\n\r\n// ── Wallpaper layer (direct DOM) ───────────────────────────────────────────────\r\n\r\nlet wpEl: HTMLDivElement | null = null\r\nlet ctxRef: Ctx = null as any\r\n\r\nfunction toRgba(c: string, a: number): string {\r\n const hx = /^#([0-9a-f]{3}|[0-9a-f]{6})$/i.exec(c.trim())\r\n if (hx) { let d = hx[1]!; if (d.length === 3) d = d.split('').map(x => x + x).join(''); const n = parseInt(d, 16); return `rgba(${(n >> 16) & 255},${(n >> 8) & 255},${n & 255},${a})` }\r\n const rgb = /^rgba?\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)(?:\\s*,\\s*([\\d.]+))?\\s*\\)$/i.exec(c.trim())\r\n if (rgb) return `rgba(${rgb[1]},${rgb[2]},${rgb[3]},${a})`\r\n const hsl = /^hsla?\\(\\s*([\\d.]+)\\s*,\\s*([\\d.]+)%\\s*,\\s*([\\d.]+)%/i.exec(c.trim())\r\n if (hsl) return `hsla(${hsl[1]},${hsl[2]}%,${hsl[3]}%,${a})`\r\n return c.trim()\r\n}\r\n\r\nlet appliedTokenNames: string[] = []\r\n\r\n/** Remove every inline token this plugin wrote (teardown symmetry). */\r\nfunction clearCustomTokens(): void {\r\n for (const name of appliedTokenNames) document.body.style.removeProperty(name)\r\n appliedTokenNames = []\r\n}\r\n\r\n/**\r\n * Write the saved color's full token set as inline variables on body — the\r\n * same write surface the theme presenter owns, but derived DIRECTLY from the\r\n * saved pick, so the theme color never depends on the theme service's active\r\n * state or the presenter's timing. The bg-base and sidebar tokens are\r\n * re-emitted at the requested alpha; every other token (layers, labels,\r\n * borders, brand) is written verbatim. No reads: nothing can observe a stale\r\n * or reset theme value and leave the homepage on the system color.\r\n */\r\nfunction applyCustomTokens(op: number): void {\r\n const [h, s, l] = rColor()\r\n const { tokens } = genTokens(h, s, l)\r\n const sideOp = Math.min(1, op + 0.08)\r\n clearCustomTokens()\r\n // Drive the base-palette switch ourselves so tokens the plugin does not\r\n // override (the input surface, masks, static tokens) follow the picked\r\n // color's dark/light scheme even while the theme service preference is\r\n // being adopted/reset.\r\n if (l < 0.55) document.body.setAttribute('data-ds-dark-theme', '')\r\n else document.body.removeAttribute('data-ds-dark-theme')\r\n for (const [name, value] of Object.entries(tokens)) {\r\n let v = value\r\n if (name === '--dsw-alias-bg-base') v = toRgba(value, op)\r\n else if (name === '--dsw-specific-sidebar-fill') v = toRgba(value, sideOp)\r\n document.body.style.setProperty(name, v)\r\n appliedTokenNames.push(name)\r\n }\r\n}\r\n\r\n// ── Settings panel opacity ─────────────────────────────────────────────────────\r\n// The settings modal is the only aria-modal dialog that identifies itself with\r\n// aria-labelledby (ui-primitives' Modal and the image lightbox use aria-label),\r\n// so this selector scopes the translucency to the settings panel alone. The\r\n// panel surface is --dsw-alias-bg-layer-2, resolved here from body's computed\r\n// style (the theme presenter writes custom-theme tokens inline on body; the\r\n// base palettes declare the alias in the stylesheets) and re-emitted with an\r\n// alpha through a plugin-owned variable, so the panel keeps its current color\r\n// while fading toward whatever sits behind the modal.\r\n\r\nconst SETTINGS_PANEL_SEL = '[role=\"dialog\"][aria-modal=\"true\"][aria-labelledby]'\r\nconst SETTINGS_STYLE_RULE = `${SETTINGS_PANEL_SEL}{background:var(--dsh-any-bg-settings-surface,var(--dsw-alias-bg-layer-2))}`\r\n\r\nfunction applySettingsOverrides(op: number): void {\r\n if (op >= 1) {\r\n document.documentElement.style.removeProperty('--dsh-any-bg-settings-surface')\r\n return\r\n }\r\n // Derive the panel surface from the saved color's layer-2 token (not a\r\n // computed-style read), so the settings panel matches the homepage tint\r\n // without depending on the presenter or theme state.\r\n const [h, s, l] = rColor()\r\n const layer2 = genTokens(h, s, l).tokens['--dsw-alias-bg-layer-2']\r\n if (layer2 !== undefined) {\r\n document.documentElement.style.setProperty('--dsh-any-bg-settings-surface', toRgba(layer2, op))\r\n }\r\n}\r\n\r\nfunction applyWp(ctx: Ctx): void {\r\n const url = rWp()\r\n // Wallpaper element (only when image exists)\r\n if (!url) { wpEl?.remove(); wpEl = null } else {\r\n if (!wpEl || !document.body.contains(wpEl)) {\r\n wpEl = document.createElement('div')\r\n wpEl.style.cssText = 'position:fixed;inset:0;z-index:-1;pointer-events:none;background-repeat:no-repeat;'\r\n document.body.prepend(wpEl)\r\n }\r\n const bg = rBgState()\r\n wpEl.style.backgroundImage = `url(\"${url}\")`\r\n if (bg.iw > 0) {\r\n // Saved placement: contain-fit at zoom with the image CENTER pinned to\r\n // the committed fractional viewport point (x, y are center fractions,\r\n // 0.5 = viewport center — the editor commits the same anchor), so the\r\n // framed region survives viewport changes: window moves between screens,\r\n // aspect-ratio changes, and panel splitters re-derive a consistent view.\r\n const fit = Math.min(window.innerWidth / bg.iw, window.innerHeight / bg.ih)\r\n const w = bg.iw * fit * bg.zoom\r\n const h = bg.ih * fit * bg.zoom\r\n wpEl.style.backgroundSize = `${w}px ${h}px`\r\n wpEl.style.backgroundPosition = `${bg.x * window.innerWidth - w / 2}px ${bg.y * window.innerHeight - h / 2}px`\r\n } else {\r\n // Fresh image: match the editor's initial centered contain view.\r\n wpEl.style.backgroundSize = 'contain'\r\n wpEl.style.backgroundPosition = 'center'\r\n }\r\n const blur = rBl()\r\n wpEl.style.filter = blur > 0 ? `blur(${blur}px)` : 'none'\r\n wpEl.style.opacity = String(rWop())\r\n }\r\n // Theme color + opacity: write the full token set inline (self-contained),\r\n // then the settings panel surface.\r\n const op = rOp()\r\n applyCustomTokens(op)\r\n applySettingsOverrides(rSop())\r\n}\r\nfunction teardownWp(): void {\r\n wpEl?.remove(); wpEl = null\r\n clearCustomTokens()\r\n document.documentElement.style.removeProperty('--dsh-any-bg-settings-surface')\r\n}\r\n\r\n// ── Color Wheel (combined hue ring + SL square on single canvas) ───────────────\r\n\r\nconst WHEEL_SIZE = 220\r\nconst CX = WHEEL_SIZE / 2\r\nconst RING_OUTER = 106\r\nconst RING_INNER = 82\r\n// Square inscribed in the ring's inner circle: half-side = RING_INNER / √2,\r\n// so the four corners sit exactly on the inner edge of the hue ring.\r\nconst SQ_HALF = Math.round(RING_INNER / Math.SQRT2)\r\n\r\nfunction drawWheel(cvs: HTMLCanvasElement, hue: number, sat: number, lit: number): void {\r\n // Wheel coordinates are HSV (the S-V plane); props arrive in HSV from the\r\n // section. The HSL conversion happens at the setColor boundary.\r\n const c = cvs.getContext('2d')!\r\n c.clearRect(0, 0, WHEEL_SIZE, WHEEL_SIZE)\r\n // Hue ring\r\n for (let a = 0; a < 360; a++) {\r\n const r1 = (a - 90) * Math.PI / 180\r\n const r2 = (a + 1.5 - 90) * Math.PI / 180\r\n c.beginPath(); c.arc(CX, CX, RING_OUTER, r1, r2); c.arc(CX, CX, RING_INNER, r2, r1, true); c.closePath()\r\n c.fillStyle = `hsl(${a},100%,50%)`; c.fill()\r\n }\r\n // SL square inside ring (HSV S-V plane)\r\n const gx = CX - SQ_HALF, gy = CX - SQ_HALF, sz = SQ_HALF * 2\r\n c.fillStyle = '#fff'; c.fillRect(gx, gy, sz, sz)\r\n const gh = c.createLinearGradient(gx, 0, gx + sz, 0)\r\n gh.addColorStop(0, 'rgba(255,255,255,1)'); gh.addColorStop(1, `hsl(${hue},100%,50%)`)\r\n c.fillStyle = gh; c.fillRect(gx, gy, sz, sz)\r\n const gv = c.createLinearGradient(0, gy, 0, gy + sz)\r\n gv.addColorStop(0, 'rgba(0,0,0,0)'); gv.addColorStop(1, 'rgba(0,0,0,1)')\r\n c.fillStyle = gv; c.fillRect(gx, gy, sz, sz)\r\n // Hue marker on ring\r\n const hRad = (hue - 90) * Math.PI / 180\r\n const hR = (RING_OUTER + RING_INNER) / 2\r\n const hmx = CX + Math.cos(hRad) * hR, hmy = CX + Math.sin(hRad) * hR\r\n c.beginPath(); c.arc(hmx, hmy, 8, 0, Math.PI * 2)\r\n c.fillStyle = 'rgba(0,0,0,0.25)'; c.fill()\r\n c.beginPath(); c.arc(hmx, hmy, 6.5, 0, Math.PI * 2)\r\n c.strokeStyle = '#fff'; c.lineWidth = 2; c.stroke()\r\n // SL marker (HSV coordinates)\r\n const smx = gx + sat * sz, smy = gy + (1 - lit) * sz\r\n c.beginPath(); c.arc(smx, smy, 7, 0, Math.PI * 2)\r\n c.fillStyle = 'rgba(0,0,0,0.25)'; c.fill()\r\n c.beginPath(); c.arc(smx, smy, 5.5, 0, Math.PI * 2)\r\n c.strokeStyle = '#fff'; c.lineWidth = 2; c.stroke()\r\n c.beginPath(); c.arc(smx, smy, 3.5, 0, Math.PI * 2)\r\n c.strokeStyle = '#000'; c.lineWidth = 1; c.stroke()\r\n}\r\n\r\nfunction hitTest(x: number, y: number): 'ring' | 'square' | null {\r\n if (Math.abs(x - CX) <= SQ_HALF && Math.abs(y - CX) <= SQ_HALF) return 'square'\r\n const dx = x - CX, dy = y - CX\r\n const dist = Math.sqrt(dx * dx + dy * dy)\r\n if (dist >= RING_INNER - 4 && dist <= RING_OUTER + 4) return 'ring'\r\n return null\r\n}\r\n\r\nfunction pickHue(x: number, y: number): number {\r\n let angle = Math.atan2(y - CX, x - CX) * 180 / Math.PI + 90\r\n if (angle < 0) angle += 360\r\n return angle\r\n}\r\n\r\nfunction pickSL(x: number, y: number): [number, number] {\r\n const gx = CX - SQ_HALF, gy = CX - SQ_HALF, sz = SQ_HALF * 2\r\n return [\r\n Math.max(0, Math.min(1, (x - gx) / sz)),\r\n Math.max(0.02, Math.min(0.98, 1 - (y - gy) / sz)),\r\n ]\r\n}\r\n\r\nfunction ColorWheel({ hue, sat, lit, onChange }: {\r\n hue: number; sat: number; lit: number\r\n onChange: (h: number, s: number, l: number) => void\r\n}) {\r\n const cvsRef = useRef<HTMLCanvasElement>(null)\r\n // Internal HSV state: the slots host caches injected section props once, so\r\n // the canvas must redraw from interaction state instead of from props.\r\n const [col, setCol] = useState({ hue, sat, lit })\r\n const colRef = useRef(col)\r\n colRef.current = col\r\n\r\n // Adopt external changes (e.g. section remount after theme restore).\r\n useEffect(() => {\r\n setCol(c => (c.hue === hue && c.sat === sat && c.lit === lit ? c : { hue, sat, lit }))\r\n }, [hue, sat, lit])\r\n\r\n useEffect(() => { if (cvsRef.current) drawWheel(cvsRef.current, col.hue, col.sat, col.lit) }, [col])\r\n\r\n const apply = useCallback((nh: number, ns: number, nl: number) => {\r\n setCol({ hue: nh, sat: ns, lit: nl })\r\n onChange(nh, ns, nl)\r\n }, [onChange])\r\n\r\n const onDown = useCallback((e: React.MouseEvent<HTMLCanvasElement>) => {\r\n const r = cvsRef.current!.getBoundingClientRect()\r\n const x = e.clientX - r.left, y = e.clientY - r.top\r\n const region = hitTest(x, y)\r\n if (!region) return\r\n if (region === 'ring') {\r\n apply(pickHue(x, y), colRef.current.sat, colRef.current.lit)\r\n } else {\r\n const [s, l] = pickSL(x, y)\r\n apply(colRef.current.hue, s, l)\r\n }\r\n const onMove = (ev: MouseEvent) => {\r\n const rr = cvsRef.current!.getBoundingClientRect()\r\n const mx = ev.clientX - rr.left, my = ev.clientY - rr.top\r\n if (region === 'ring') {\r\n const d = Math.sqrt((mx - CX) ** 2 + (my - CX) ** 2)\r\n if (d >= RING_INNER - 10 && d <= RING_OUTER + 10) apply(pickHue(mx, my), colRef.current.sat, colRef.current.lit)\r\n } else {\r\n const [s, l] = pickSL(mx, my)\r\n apply(colRef.current.hue, s, l)\r\n }\r\n }\r\n const onUp = () => { document.removeEventListener('mousemove', onMove); document.removeEventListener('mouseup', onUp) }\r\n document.addEventListener('mousemove', onMove); document.addEventListener('mouseup', onUp)\r\n }, [apply])\r\n\r\n return <canvas ref={cvsRef} width={WHEEL_SIZE} height={WHEEL_SIZE} style={ST.wheelCanvas} onMouseDown={onDown} />\r\n}\r\n\r\n// ── Image compression ──────────────────────────────────────────────────────────\r\n\r\nfunction compress(img: HTMLImageElement, side: number, q: number): string {\r\n const s = Math.min(1, side / Math.max(img.width, img.height))\r\n const c = document.createElement('canvas')\r\n c.width = Math.max(1, Math.round(img.width * s)); c.height = Math.max(1, Math.round(img.height * s))\r\n c.getContext('2d')!.drawImage(img, 0, 0, c.width, c.height)\r\n return c.toDataURL('image/jpeg', q)\r\n}\r\nfunction readImg(file: File, cb: (url: string | null) => void): void {\r\n const r = new FileReader()\r\n r.onerror = () => cb(null)\r\n r.onload = () => {\r\n const img = new Image()\r\n img.onerror = () => cb(null)\r\n img.onload = () => {\r\n try { let u = compress(img, 1600, 0.75); if (u.length > 2e6) u = compress(img, 1000, 0.6); if (u.length > 2e6) u = compress(img, 800, 0.5); cb(u) } catch { cb(null) }\r\n }\r\n img.src = r.result as string\r\n }\r\n r.readAsDataURL(file)\r\n}\r\n\r\n// ── Styles ─────────────────────────────────────────────────────────────────────\r\n\r\nconst ST = {\r\n root: { display: 'flex', flexDirection: 'column' as const, gap: '20px', padding: '4px 0', maxWidth: '640px' },\r\n h2: { color: 'var(--dsw-alias-label-primary)', fontSize: '18px', fontWeight: 600, margin: 0 },\r\n sub: { color: 'var(--dsw-alias-label-tertiary)', fontSize: '13px' },\r\n hr: { height: '1px', background: 'var(--dsw-alias-border-l2)', border: 'none', margin: '4px 0' },\r\n label: { color: 'var(--dsw-alias-label-primary)', fontSize: '16px', fontWeight: 600, marginBottom: '8px' },\r\n hint: { color: 'var(--dsw-alias-label-tertiary)', fontSize: '12px', lineHeight: '18px', marginTop: '4px' },\r\n colorHint: { color: 'var(--dsw-alias-label-tertiary)', fontSize: '12px', lineHeight: '18px', marginTop: '7px', textAlign: 'center' as const },\r\n wheelCanvas: { cursor: 'crosshair', borderRadius: '50%' },\r\n center: { display: 'flex', justifyContent: 'center' },\r\n btnGroup: { display: 'flex', justifyContent: 'center', marginTop: '10px' },\r\n row: { display: 'flex', alignItems: 'center', gap: '10px', flexWrap: 'wrap' as const },\r\n sliderBlock: { display: 'flex', flexDirection: 'column' as const, gap: '4px' },\r\n sliderRow: { display: 'flex', alignItems: 'center', gap: '10px' },\r\n sliderLabel: { color: 'var(--dsw-alias-label-secondary)', fontSize: '13px' },\r\n smallHint: { color: 'var(--dsw-alias-label-tertiary)', fontSize: '11px', lineHeight: '16px' },\r\n slider: { flex: 1, accentColor: 'var(--dsw-alias-brand-primary)', minWidth: '160px' },\r\n sliderVal: { color: 'var(--dsw-alias-label-secondary)', fontSize: '12px', whiteSpace: 'nowrap' as const, width: '44px', textAlign: 'right' as const },\r\n btn: { height: '32px', padding: '0 14px', borderRadius: '8px', border: '1px solid var(--dsw-alias-border-l2)', background: 'var(--dsw-alias-button-elevated-fill)', color: 'var(--dsw-alias-label-primary)', cursor: 'pointer', fontSize: '13px', font: 'inherit', boxSizing: 'border-box' as const },\r\n btnDanger: { color: 'var(--dsw-alias-state-error-primary)' },\r\n btnPrimary: { background: 'var(--dsw-alias-brand-primary)', color: 'var(--dsw-alias-brand-text)', border: 'none' },\r\n preview: { width: '368px', height: '225px', objectFit: 'cover' as const, borderRadius: '6px', border: '1px solid var(--dsw-alias-border-l2)', cursor: 'pointer' },\r\n sliders: { display: 'flex', flexDirection: 'column' as const, gap: '12px', marginTop: '8px' },\r\n // Modal\r\n overlay: { position: 'fixed' as const, inset: 0, zIndex: 9999, background: 'rgba(0,0,0,0.7)', display: 'flex', flexDirection: 'column' as const, alignItems: 'center', justifyContent: 'center', gap: '12px' },\r\n modalTitle: { color: '#fff', fontSize: '16px', fontWeight: 500 },\r\n modalHint: { color: 'rgba(255,255,255,0.6)', fontSize: '12px' },\r\n previewRect: { position: 'relative' as const, overflow: 'hidden', border: '2px solid rgba(255,255,255,0.3)', borderRadius: '8px', background: '#000', cursor: 'grab' },\r\n previewImg: { position: 'absolute' as const, transformOrigin: '0 0', pointerEvents: 'none' as const },\r\n modalBtns: { display: 'flex', gap: '10px' },\r\n}\r\n\r\n// ── Background Editor Modal ────────────────────────────────────────────────────\r\n\r\nfunction BgEditor({ url, t, onClose, onCommit }: {\r\n url: string; t: (key: string) => string; onClose: () => void\r\n onCommit: (zoom: number, x: number, y: number, iw: number, ih: number) => void\r\n}) {\r\n const pw = Math.min(window.innerWidth * 0.75, 860)\r\n const ph = Math.round(pw * window.innerHeight / window.innerWidth)\r\n const saved = rBgState()\r\n const [zoom, setZoom] = useState(saved.iw > 0 ? saved.zoom : 1)\r\n const [pos, setPos] = useState(saved.iw > 0 ? { x: saved.x * pw, y: saved.y * ph } : { x: 0, y: 0 })\r\n const [imgSize, setImgSize] = useState({ w: 0, h: 0 })\r\n const containerRef = useRef<HTMLDivElement>(null)\r\n const imgRef = useRef<HTMLImageElement>(null)\r\n const dragRef = useRef({ active: false, sx: 0, sy: 0, spx: 0, spy: 0 })\r\n\r\n useEffect(() => {\r\n const img = new Image()\r\n img.onload = () => {\r\n const scale = Math.min(pw / img.width, ph / img.height)\r\n const w = img.width * scale, h = img.height * scale\r\n setImgSize({ w, h })\r\n const s = rBgState()\r\n if (s.iw > 0 && s.iw === img.width && s.ih === img.height) {\r\n setZoom(s.zoom)\r\n // Saved x, y are CENTER fractions of the preview: the image center\r\n // lands at (x·pw, y·ph), so the top-left comes from subtracting half\r\n // the displayed (zoom-scaled) image size.\r\n setPos({ x: s.x * pw - w * s.zoom / 2, y: s.y * ph - h * s.zoom / 2 })\r\n } else {\r\n setZoom(1)\r\n setPos({ x: (pw - w) / 2, y: (ph - h) / 2 })\r\n }\r\n }\r\n img.src = url\r\n }, [url, pw, ph])\r\n\r\n const onDown = useCallback((e: React.MouseEvent) => {\r\n e.preventDefault()\r\n dragRef.current = { active: true, sx: e.clientX, sy: e.clientY, spx: pos.x, spy: pos.y }\r\n const onMove = (ev: MouseEvent) => {\r\n if (!dragRef.current.active) return\r\n setPos({ x: dragRef.current.spx + ev.clientX - dragRef.current.sx, y: dragRef.current.spy + ev.clientY - dragRef.current.sy })\r\n }\r\n const onUp = () => { dragRef.current.active = false; document.removeEventListener('mousemove', onMove); document.removeEventListener('mouseup', onUp) }\r\n document.addEventListener('mousemove', onMove); document.addEventListener('mouseup', onUp)\r\n }, [pos])\r\n\r\n const onWheelCb = useCallback((e: WheelEvent) => {\r\n e.preventDefault()\r\n const rect = containerRef.current!.getBoundingClientRect()\r\n const mx = e.clientX - rect.left, my = e.clientY - rect.top\r\n const factor = e.deltaY > 0 ? 0.92 : 1.08\r\n const nz = Math.max(0.1, Math.min(10, zoom * factor))\r\n const nx = mx - (mx - pos.x) * (nz / zoom)\r\n const ny = my - (my - pos.y) * (nz / zoom)\r\n setZoom(nz); setPos({ x: nx, y: ny })\r\n }, [zoom, pos])\r\n\r\n useEffect(() => {\r\n const el = containerRef.current\r\n if (!el) return\r\n el.addEventListener('wheel', onWheelCb, { passive: false })\r\n return () => el.removeEventListener('wheel', onWheelCb)\r\n }, [onWheelCb])\r\n\r\n const resetView = useCallback(() => {\r\n if (imgSize.w === 0) return\r\n setZoom(1); setPos({ x: (pw - imgSize.w) / 2, y: (ph - imgSize.h) / 2 })\r\n }, [pw, ph, imgSize])\r\n\r\n return (\r\n <div style={ST.overlay} onClick={e => { if (e.target === e.currentTarget) onClose() }}>\r\n <div style={ST.modalTitle}>{t('editorTitle')}</div>\r\n <div ref={containerRef} style={{ ...ST.previewRect, width: pw, height: ph }} onMouseDown={onDown}>\r\n <img ref={imgRef} src={url} alt=\"\" draggable={false} style={{\r\n ...ST.previewImg, width: imgSize.w, height: imgSize.h,\r\n transform: `translate(${pos.x}px,${pos.y}px) scale(${zoom})`,\r\n }} />\r\n </div>\r\n <div style={ST.modalHint}>{t('editorHint')}</div>\r\n <div style={ST.modalBtns}>\r\n <button style={ST.btn} onClick={resetView}>{t('editorReset')}</button>\r\n <button style={ST.btn} onClick={onClose}>{t('editorCancel')}</button>\r\n <button style={{ ...ST.btn, ...ST.btnPrimary }} onClick={() => onCommit(zoom, (pos.x + imgSize.w * zoom / 2) / pw, (pos.y + imgSize.h * zoom / 2) / ph, imgRef.current?.naturalWidth ?? 0, imgRef.current?.naturalHeight ?? 0)}>{t('editorCommit')}</button>\r\n </div>\r\n </div>\r\n )\r\n}\r\n\r\n// ── Uncontrolled slider ────────────────────────────────────────────────────────\r\n\r\nfunction LiveSlider({ min, max, step, def, fmt, onInput, onChange }: {\r\n min: number; max: number; step: number; def: number\r\n fmt: (v: number) => string; onInput: (v: number) => void; onChange: (v: number) => void\r\n}) {\r\n const valRef = useRef<HTMLSpanElement>(null)\r\n return (\r\n <div style={ST.sliderRow}>\r\n <input type=\"range\" min={min} max={max} step={step} defaultValue={def} style={ST.slider}\r\n onInput={e => { const v = Number((e.target as HTMLInputElement).value); onInput(v); if (valRef.current) valRef.current.textContent = fmt(v) }}\r\n onChange={e => onChange(Number((e.target as HTMLInputElement).value))} />\r\n <span ref={valRef} style={ST.sliderVal}>{fmt(def)}</span>\r\n </div>\r\n )\r\n}\r\n\r\n// ── Theme Section ──────────────────────────────────────────────────────────────\r\n\r\nfunction ThemeSection(props: any) {\r\n const { t, hue, sat, lit, setColor, url, setWp, setOp, setWop, setBl, setSop, useStore } = props\r\n const storeUrl = useStore((s: any) => s.url)\r\n const fileRef = useRef<HTMLInputElement>(null)\r\n const [editorOpen, setEditorOpen] = useState(false)\r\n\r\n return (\r\n <div style={ST.root}>\r\n <div><h2 style={ST.h2}>{t('nav')}</h2><div style={ST.sub}>{t('subtitle')}</div></div>\r\n\r\n {/* Theme color */}\r\n <div>\r\n <div style={ST.label}>{t('colorTitle')}</div>\r\n <div style={ST.center}><ColorWheel hue={hue} sat={sat} lit={lit} onChange={setColor} /></div>\r\n <div style={ST.colorHint}>{t('colorHint')}</div>\r\n </div>\r\n\r\n <hr style={ST.hr} />\r\n\r\n {/* Interface: homepage + settings opacity, each its own slider */}\r\n <div>\r\n <div style={ST.label}>{t('uiTitle')}</div>\r\n <div style={ST.sliders}>\r\n <div style={ST.sliderBlock}>\r\n <div style={ST.sliderLabel}>{t('uiOpacity')}</div>\r\n <div style={ST.smallHint}>{t('uiOpacityHint')}</div>\r\n <LiveSlider min={0} max={100} step={1} def={Math.round(rOp() * 100)}\r\n fmt={v => `${v}%`}\r\n onInput={v => { const op = v / 100; cfg.opacity = op; applyCustomTokens(op); saveConfig() }}\r\n onChange={v => setOp(v / 100)} />\r\n </div>\r\n <div style={ST.sliderBlock}>\r\n <div style={ST.sliderLabel}>{t('uiSop')}</div>\r\n <div style={ST.smallHint}>{t('uiSopHint')}</div>\r\n <LiveSlider min={0} max={100} step={1} def={Math.round(rSop() * 100)}\r\n fmt={v => `${v}%`}\r\n onInput={v => { const op = v / 100; cfg.settingsOpacity = op; applySettingsOverrides(op); saveConfig() }}\r\n onChange={v => setSop(v / 100)} />\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <hr style={ST.hr} />\r\n\r\n {/* Background image */}\r\n <div>\r\n <div style={ST.label}>{t('bgTitle')}</div>\r\n <div style={ST.center}>{storeUrl ? <img src={storeUrl} alt=\"\" style={ST.preview} onClick={() => setEditorOpen(true)} /> : null}</div>\r\n <div style={ST.btnGroup}>\r\n <div style={ST.row}>\r\n <button type=\"button\" style={ST.btn} onClick={() => fileRef.current?.click()}>{t('bgChoose')}</button>\r\n {storeUrl ? <button type=\"button\" style={ST.btn} onClick={() => setEditorOpen(true)}>{t('bgEdit')}</button> : null}\r\n {storeUrl ? <button type=\"button\" style={{ ...ST.btn, ...ST.btnDanger }} onClick={() => setWp(null)}>{t('bgRemove')}</button> : null}\r\n <input ref={fileRef} type=\"file\" accept=\"image/*\" style={{ display: 'none' }} onChange={e => {\r\n const f = e.target.files?.[0]; if (!f) return\r\n readImg(f, d => { if (d) setWp(d); e.target.value = '' })\r\n }} />\r\n </div>\r\n </div>\r\n <div style={ST.sliders}>\r\n <div style={ST.sliderBlock}>\r\n <div style={ST.sliderLabel}>{t('wpOpacity')}</div>\r\n <LiveSlider min={0} max={100} step={1} def={Math.round(rWop() * 100)}\r\n fmt={v => `${v}%`}\r\n onInput={v => { const op = v / 100; cfg.wallpaperOpacity = op; if (wpEl) wpEl.style.opacity = String(op); saveConfig() }}\r\n onChange={v => setWop(v / 100)} />\r\n </div>\r\n <div style={ST.sliderBlock}>\r\n <div style={ST.sliderLabel}>{t('bgBlur')}</div>\r\n <LiveSlider min={0} max={60} step={1} def={rBl()}\r\n fmt={v => `${v}px`}\r\n onInput={v => { cfg.blur = v; if (wpEl) wpEl.style.filter = v > 0 ? `blur(${v}px)` : 'none'; saveConfig() }}\r\n onChange={v => setBl(v)} />\r\n </div>\r\n </div>\r\n <div style={ST.hint}>{t('bgHint')}</div>\r\n </div>\r\n\r\n {/* Background editor modal */}\r\n {editorOpen && storeUrl ? (\r\n <BgEditor url={storeUrl} t={t} onClose={() => setEditorOpen(false)}\r\n onCommit={(z, x, y, iw, ih) => { cfg.bgState = { zoom: z, x, y, iw, ih }; applyWp(ctxRef); saveConfig(); setEditorOpen(false) }} />\r\n ) : null}\r\n </div>\r\n )\r\n}\r\n\r\n// ── Plugin entry ───────────────────────────────────────────────────────────────\r\n\r\nexport function apply(ctx: Ctx): void {\r\n ctxRef = ctx\r\n // Bind the shared `/api` RPC caller so the persistence module can reach the\r\n // node half's file-backed store.\r\n rpcCallFn = (endpoint: string, payload: unknown) =>\r\n ctx.connection.rpc.call(RPC_CHANNEL, endpoint, payload).then((res: any) => res as RpcResultLike | undefined)\r\n\r\n // 1. Restore custom color and register as a skin. The saved color's\r\n // lightness decides the scheme — a dark pick gets white text, a light pick\r\n // black text — so both the theme color and the dark/light text follow the\r\n // picked color.\r\n const [initH, initS, initL] = rColor()\r\n let customDispose: (() => void) | null = null\r\n // registerCustom takes HSL (the storage/wheel space and genTokens space).\r\n const registerCustom = (h: number, s: number, l: number) => {\r\n customDispose?.()\r\n try {\r\n const { colorScheme, tokens } = genTokens(h, s, l)\r\n customDispose = ctx.theme.register({ id: CUSTOM_ID, colorScheme, tokens })\r\n } catch {\r\n // A live registration from an earlier apply pass (HMR swap that could\r\n // not run this fiber's disposer) cannot be torn down here; keep it and\r\n // activate it below. Without this the duplicate-id throw would abort\r\n // apply and skip the wallpaper/opacity restore.\r\n customDispose = null\r\n }\r\n ctx.theme.setTheme(CUSTOM_ID)\r\n }\r\n // Restore saved color on boot.\r\n if (rHasColor()) registerCustom(initH, initS, initL)\r\n ctx.effect(() => () => { customDispose?.() }, 'dsh-any-background: skin dispose')\r\n\r\n // 2. Gradient CSS (for custom dark themes).\r\n let styleEl: HTMLStyleElement | undefined\r\n if (typeof document !== 'undefined') {\r\n styleEl = document.createElement('style')\r\n styleEl.dataset.plugin = 'dsh-any-background'\r\n styleEl.textContent = `body[data-ds-dark-theme=\"${CUSTOM_ID}\"]::before{content:'';position:fixed;inset:0;z-index:-1;pointer-events:none;background:radial-gradient(ellipse 80% 60% at 50% 0%,rgba(255,255,255,0.03) 0%,transparent 60%)}${SETTINGS_STYLE_RULE}`\r\n document.head.appendChild(styleEl)\r\n }\r\n ctx.effect(() => () => { styleEl?.parentNode?.removeChild(styleEl) }, 'dsh-any-background: gradient')\r\n\r\n // 3. State store.\r\n let rev = 0\r\n const store = defineStore({\r\n init: () => ({ url: null as string | null, rev: -1 }),\r\n actions: { syncBg: (d: any, url: string | null, r: number) => { if (r <= d.rev) return; d.url = url; d.rev = r } },\r\n })\r\n let bound: any\r\n const syncBg = () => { rev++; bound?.syncBg(rWp(), rev) }\r\n\r\n // 4. Wallpaper.\r\n applyWp(ctx); syncBg()\r\n // Load the file-backed theme from the node half and re-apply once it lands\r\n // (the node store may be absent or unreachable at this instant; defaults are\r\n // already applied above, and the deferred restore below re-asserts too).\r\n void loadPersisted().then(() => { applyWp(ctx); syncBg() })\r\n ctx.effect(() => () => { teardownWp() }, 'dsh-any-background: wp cleanup')\r\n ctx.effect(() => ctx.on('theme/change', () => {\r\n // The theme service persists only built-in preferences; the custom theme's\r\n // preference lives in memory, so a host-scope adoption can silently reset\r\n // it. While a color is saved, re-assert the custom theme so it stays\r\n // active. Guard on registry presence — registerCustom disposes the old\r\n // skin before re-registering, and during that transient the registry lacks\r\n // CUSTOM_ID, so asserting there would throw.\r\n if (rHasColor()) {\r\n const snapshot = ctx.theme.getTheme()\r\n if (snapshot.preference !== CUSTOM_ID && snapshot.themes.some(t => t.id === CUSTOM_ID)) {\r\n ctx.theme.setTheme(CUSTOM_ID)\r\n }\r\n }\r\n applyWp(ctx)\r\n }), 'dsh-any-background: theme change')\r\n // The wallpaper's inline size/position are absolute pixels computed for the\r\n // viewport at apply time, so a stale viewport leaves them misplaced.\r\n // Watch the viewport itself: a fixed inset:0 sentinel's box always equals\r\n // the viewport, so a ResizeObserver on it fires for ANY viewport change\r\n // (window resize, moving between monitors, panel splitters, zoom) where\r\n // window.resize can be missed; a resolution media query catches DPI-only\r\n // moves between differently scaled screens. All re-applies are coalesced to\r\n // one per animation frame. Re-running applyWp recomputes the contain-fit\r\n // scale and the fractional offsets for the new viewport (the editor's model).\r\n let frame = 0\r\n const applySoon = (): void => {\r\n if (frame !== 0) return\r\n frame = requestAnimationFrame(() => { frame = 0; applyWp(ctx) })\r\n }\r\n const sentinel = document.createElement('div')\r\n sentinel.style.cssText = 'position:fixed;inset:0;pointer-events:none;visibility:hidden'\r\n document.body.append(sentinel)\r\n const viewportObserver = new ResizeObserver(applySoon)\r\n viewportObserver.observe(sentinel)\r\n const dprQuery = window.matchMedia(`(resolution: ${window.devicePixelRatio}dppx)`)\r\n dprQuery.addEventListener('change', applySoon)\r\n ctx.effect(() => () => {\r\n viewportObserver.disconnect()\r\n dprQuery.removeEventListener('change', applySoon)\r\n sentinel.remove()\r\n }, 'dsh-any-background: viewport watch')\r\n\r\n // 5. Locale.\r\n ctx.effect(() => ctx.locale.register(NS, { zh, en }), 'dsh-any-background: i18n')\r\n\r\n // 6. Section injection.\r\n const sectionInject = (actions: any) => {\r\n bound = actions; syncBg()\r\n const [wh, ws, wl] = rColor()\r\n const [dh, ds, dv] = hslToHsv(wh, ws, wl)\r\n return {\r\n t: ctx.locale.bind(NS),\r\n hue: dh, sat: ds, lit: dv,\r\n setColor: (nh: number, ns: number, nl: number) => {\r\n const [sh, ss, sl] = hsvToHsl(nh, ns, nl)\r\n cfg.color = [sh, ss, sl]\r\n registerCustom(sh, ss, sl)\r\n applyWp(ctx)\r\n saveConfig()\r\n },\r\n setWp: (u: string | null) => {\r\n wpUrl = u\r\n cfg.bgState = { ...DEFAULT_CONFIG.bgState }\r\n applyWp(ctx); syncBg()\r\n void rpcCall('setWallpaper', { dataUrl: u })\r\n },\r\n setOp: (v: number) => { cfg.opacity = v; applyWp(ctx); syncBg(); saveConfig() },\r\n setWop: (v: number) => { cfg.wallpaperOpacity = v; applyWp(ctx); syncBg(); saveConfig() },\r\n setBl: (v: number) => { cfg.blur = v; applyWp(ctx); syncBg(); saveConfig() },\r\n setSop: (v: number) => { cfg.settingsOpacity = v; applySettingsOverrides(v); saveConfig() },\r\n }\r\n }\r\n ctx.slots.inject('settings.section', () => ctx.slots.register({\r\n name: 'settings.section', id: 'dsh-any-background', order: 35,\r\n label: () => ctx.locale.bind(NS)('nav'),\r\n locale: NS, store, inject: sectionInject,\r\n }, ThemeSection as any))\r\n\r\n // 7. Deferred boot restore: the theme service and the host settings scope\r\n // settle asynchronously after this apply, so the synchronous restore can be\r\n // observed mid-flight — a late host adoption resets the preference, or the\r\n // presenter re-applies over our overrides. Re-running the saved-color and\r\n // wallpaper restore a few ticks later guarantees the saved records land.\r\n const restoreSaved = (): void => {\r\n if (rHasColor()) {\r\n const [h, s, l] = rColor()\r\n registerCustom(h, s, l)\r\n }\r\n applyWp(ctx)\r\n }\r\n const restoreTimers = [300, 1500].map(delay => window.setTimeout(restoreSaved, delay))\r\n ctx.effect(() => () => { restoreTimers.forEach(id => window.clearTimeout(id)) }, 'dsh-any-background: boot restore')\r\n\r\n // 8. Theme watchdog: the theme service keeps only built-in preferences in\r\n // memory, so ANY host-scope adoption can silently drop the custom theme —\r\n // reverting the label colors (white/black) and the inner surfaces to the\r\n // system palette. While a color is saved, re-register and re-assert the\r\n // custom theme on a slow interval so the theme state always matches the\r\n // saved color and the active scheme, independent of which event resets it.\r\n const watchdogId = window.setInterval(() => {\r\n if (!rHasColor()) return\r\n const snapshot = ctx.theme.getTheme()\r\n let changed = false\r\n if (!snapshot.themes.some(t => t.id === CUSTOM_ID)) {\r\n const [h, s, l] = rColor()\r\n registerCustom(h, s, l)\r\n changed = true\r\n } else if (snapshot.preference !== CUSTOM_ID) {\r\n ctx.theme.setTheme(CUSTOM_ID)\r\n changed = true\r\n }\r\n if (changed) applyWp(ctx)\r\n }, 1000)\r\n ctx.effect(() => () => { window.clearInterval(watchdogId) }, 'dsh-any-background: theme watchdog')\r\n}\r\n"],"mappings":"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"}
1
+ {"version":3,"file":"client.js","names":["useRef","useState","useCallback","defineStore"],"sources":["../src/client/index.tsx"],"sourcesContent":["/**\r\n * dsh-any-background — browser half.\r\n *\r\n * Appearance plugin with:\r\n * 1. PS-style color wheel (hue ring + saturation/lightness square) for\r\n * real-time theme color selection with dynamic token generation.\r\n * 2. Background image editor modal with drag-to-pan and scroll-to-zoom\r\n * inside a viewport-proportional preview rectangle.\r\n * 3. Opacity / blur sliders with zero-lag direct DOM manipulation: the\r\n * homepage background opacity (主界面透明度) and the settings panel opacity\r\n * (设置界面透明度) are separate sliders.\r\n *\r\n * The color wheel is one canvas: a hue ring and an inscribed SL square.\r\n * Mouse interaction on either region regenerates the full theme token set\r\n * and applies it instantly via ctx.theme.setTheme().\r\n *\r\n * The bg editor modal shows a rectangle matching the viewport aspect ratio.\r\n * The image can be dragged and zoomed (mouse wheel) inside it. What you see\r\n * in the rectangle is exactly how the background appears on the page.\r\n */\r\nimport { createElement as h } from 'react'\r\nimport { useRef, useState, useEffect, useCallback } from 'react'\r\nimport { defineStore } from '@deepseek-ai/dsh-client-runtime/client'\r\n\r\nexport const name = 'dsh-any-background'\r\nexport const inject = ['slots', 'locale', 'theme', 'connection']\r\n\r\n// ── Interfaces ─────────────────────────────────────────────────────────────────\r\n\r\ninterface ThemeSnapshot {\r\n preference: string; revision: number\r\n active: { colorScheme: string; tokens: Record<string, string> }\r\n themes: Array<{ id: string; colorScheme: string; tokens: Record<string, string> }>\r\n}\r\ninterface ThemeService {\r\n getTheme(): ThemeSnapshot; setTheme(id: string): void\r\n register(def: { id: string; colorScheme: string; tokens: Record<string, string> }): () => void\r\n overrideTokens(source: string, overrides: Record<string, Record<string, string>>): () => void\r\n}\r\ninterface LocaleService {\r\n register(ns: string, dicts: { zh: Record<string, string>; en: Record<string, string> }): unknown\r\n bind(ns: string): (key: string) => string\r\n subscribe(cb: () => void): () => void; getSnapshot(): { active: string }\r\n}\r\ninterface SlotsService {\r\n inject(slot: string, register: () => unknown): void\r\n register(meta: Record<string, unknown>, component: () => unknown): unknown\r\n}\r\ninterface ConnectionService {\r\n rpc: { call(channel: string, endpoint: string, payload: unknown): Promise<unknown> }\r\n}\r\ninterface Ctx {\r\n effect(cb: () => unknown, label?: string): void\r\n on(event: string, cb: (...a: any[]) => void): () => void\r\n locale: LocaleService; slots: SlotsService; theme: ThemeService; connection: ConnectionService\r\n}\r\n\r\n// ── Constants ──────────────────────────────────────────────────────────────────\r\n\r\nconst NS = 'settings.anyBg'\r\nconst DEF_OP = 0.85; const DEF_BL = 0; const DEF_SOP = 1\r\nconst CUSTOM_ID = 'custom-color'\r\n\r\n// ── i18n ───────────────────────────────────────────────────────────────────────\r\n\r\nconst zh: Record<string, string> = {\r\n nav: '主题', subtitle: '自定义界面外观',\r\n colorTitle: '主题色', colorHint: '在色轮上选择色相,在方形中调整饱和度和明度',\r\n uiTitle: '界面',\r\n uiOpacity: '主界面透明度', uiOpacityHint: '拖动滑块调整主页界面背景的透明度',\r\n uiSop: '设置界面透明度', uiSopHint: '拖动滑块调整设置页界面背景的透明度',\r\n bgTitle: '背景图片', bgChoose: '选择图片', bgRemove: '移除图片',\r\n bgEdit: '编辑位置', wpOpacity: '壁纸透明度', bgBlur: '壁纸模糊',\r\n bgHint: '拖动滑块实时调整。点击背景图可打开编辑器调整位置和大小',\r\n editorTitle: '背景编辑器', editorHint: '拖动移动图片,滚轮缩放大小',\r\n editorCommit: '确认', editorCancel: '取消', editorReset: '重置',\r\n}\r\nconst en: Record<string, string> = {\r\n nav: 'Theme', subtitle: 'Customize appearance',\r\n colorTitle: 'Theme color', colorHint: 'Pick hue on the ring, adjust saturation & lightness in the square',\r\n uiTitle: 'Interface',\r\n uiOpacity: 'Main interface opacity', uiOpacityHint: 'Drag to adjust homepage interface background opacity',\r\n uiSop: 'Settings interface opacity', uiSopHint: 'Drag to adjust the settings page background opacity',\r\n bgTitle: 'Wallpaper', bgChoose: 'Choose image', bgRemove: 'Remove image',\r\n bgEdit: 'Edit position', wpOpacity: 'Wallpaper opacity', bgBlur: 'Wallpaper blur',\r\n bgHint: 'Drag sliders for real-time adjustment. Click the image to open the editor',\r\n editorTitle: 'Background editor', editorHint: 'Drag to move, scroll to zoom',\r\n editorCommit: 'Confirm', editorCancel: 'Cancel', editorReset: 'Reset',\r\n}\r\n\r\n// ── Persistence (file-backed via node half) ───────────────────────────────────\r\n// The node half owns `.dsh-any-background-data/` on the DSH data home. This\r\n// module keeps an in-memory ThemeConfig mirror + the wallpaper data URL, and\r\n// pushes changes to the node half over the dedicated `/dsh-any-background`\n// RPC channel (never the shared `/api`, so slash commands stay intact). Reads\r\n// fall back to defaults when the connection is unavailable or the file is\r\n// missing/malformed, so the UI never crashes on a broken store.\r\n\r\ninterface BgState { zoom: number; x: number; y: number; iw: number; ih: number }\r\ninterface ThemeConfig {\r\n color: [number, number, number] | null\r\n opacity: number\r\n settingsOpacity: number\r\n wallpaperOpacity: number\r\n blur: number\r\n bgState: BgState\r\n}\r\ninterface RpcResultLike { ok: boolean; value?: any; error?: any }\r\n\r\nconst DEFAULT_CONFIG: ThemeConfig = {\r\n color: null,\r\n opacity: 0.85,\r\n settingsOpacity: 1,\r\n wallpaperOpacity: 1,\r\n blur: 0,\r\n bgState: { zoom: 1, x: 0, y: 0, iw: 0, ih: 0 },\r\n}\r\n\r\nlet cfg: ThemeConfig = { ...DEFAULT_CONFIG, bgState: { ...DEFAULT_CONFIG.bgState } }\r\nlet wpUrl: string | null = null\r\nlet rpcCallFn: ((endpoint: string, payload: unknown) => Promise<RpcResultLike | undefined>) | null = null\r\n\r\nconst RPC_CHANNEL = '/dsh-any-background'\r\nconst RPC_NS = 'dshAnyBackground'\r\nconst rpcEndpoint = (method: string): string => `${RPC_NS}/${method}`\r\n\r\nasync function rpcCall(method: string, payload: unknown): Promise<any> {\r\n if (!rpcCallFn) return undefined\r\n try {\r\n const res = await rpcCallFn(rpcEndpoint(method), payload)\r\n if (res && res.ok === true) return res.value\r\n console.warn(`dsh-any-background: rpc \"${method}\" failed`, res?.error)\r\n return undefined\r\n } catch (e) {\r\n console.warn(`dsh-any-background: rpc \"${method}\" threw`, e)\r\n return undefined\r\n }\r\n}\r\n\r\n/** Move a possibly-absent partial config into the shape the UI reads. */\r\nfunction adoptConfig(raw: any): void {\r\n const c = (raw ?? {}) as Partial<ThemeConfig>\r\n const color = Array.isArray(c.color) && c.color.length === 3\r\n ? [c.color[0], c.color[1], c.color[2]] as [number, number, number]\r\n : null\r\n const bg = (c.bgState ?? {}) as Partial<BgState>\r\n cfg = {\r\n color,\r\n opacity: typeof c.opacity === 'number' ? c.opacity : DEFAULT_CONFIG.opacity,\r\n settingsOpacity: typeof c.settingsOpacity === 'number' ? c.settingsOpacity : DEFAULT_CONFIG.settingsOpacity,\r\n wallpaperOpacity: typeof c.wallpaperOpacity === 'number' ? c.wallpaperOpacity : DEFAULT_CONFIG.wallpaperOpacity,\r\n blur: typeof c.blur === 'number' ? c.blur : DEFAULT_CONFIG.blur,\r\n bgState: {\r\n zoom: typeof bg.zoom === 'number' ? bg.zoom : 1,\r\n x: typeof bg.x === 'number' ? bg.x : 0,\r\n y: typeof bg.y === 'number' ? bg.y : 0,\r\n iw: typeof bg.iw === 'number' && bg.iw > 0 ? bg.iw : 0,\r\n ih: typeof bg.ih === 'number' && bg.ih > 0 ? bg.ih : 0,\r\n },\r\n }\r\n}\r\n\r\n/** Persist the current in-memory config to the node half (fire-and-forget). */\r\nfunction saveConfig(): void {\r\n void rpcCall('writeConfig', { config: cfg })\r\n}\r\n\r\n/** Load the persisted theme (config + wallpaper) from the node half. */\r\nasync function loadPersisted(): Promise<void> {\r\n const data = await rpcCall('read', {})\r\n if (data) {\r\n if (data.config) adoptConfig(data.config)\r\n if (typeof data.wallpaper === 'string') wpUrl = data.wallpaper\r\n else if (data.wallpaper === null) wpUrl = null\r\n }\r\n}\r\n\r\nfunction rHasColor(): boolean { return cfg.color !== null }\r\nfunction rColor(): [number, number, number] { return cfg.color ?? [220, 0.55, 0.25] }\r\nfunction rWp(): string | null { return wpUrl }\r\nfunction rOp(): number { return typeof cfg.opacity === 'number' ? Math.min(1, Math.max(0, cfg.opacity)) : DEF_OP }\r\nfunction rWop(): number { return typeof cfg.wallpaperOpacity === 'number' ? Math.min(1, Math.max(0, cfg.wallpaperOpacity)) : 1 }\r\nfunction rBl(): number { return typeof cfg.blur === 'number' ? Math.min(60, Math.max(0, cfg.blur)) : DEF_BL }\r\nfunction rSop(): number { return typeof cfg.settingsOpacity === 'number' ? Math.min(1, Math.max(0, cfg.settingsOpacity)) : DEF_SOP }\r\nfunction rBgState(): BgState { return cfg.bgState }\r\n\r\n// ── HSV ↔ HSL ────────────────────────────────────────────────────────────────\r\n// The wheel works in HSV end to end: props and pickSL are HSV, the canvas\r\n// renders the HSV S-V plane directly. Storage and genTokens expect HSL, so\r\n// setColor converts HSV → HSL at the boundary; sectionInject converts stored\r\n// HSL → HSV for the initial wheel props. Conversions never stack.\r\n\r\nfunction hsvToHsl(h: number, s: number, v: number): [number, number, number] {\r\n const l = v * (1 - s / 2)\r\n const sl = l === 0 || l === 1 ? 0 : (v - l) / Math.min(l, 1 - l)\r\n return [h, sl, l]\r\n}\r\n\r\nfunction hslToHsv(h: number, s: number, l: number): [number, number, number] {\r\n const v = l + s * Math.min(l, 1 - l)\r\n const sv = v === 0 ? 0 : 2 * (1 - l / v)\r\n return [h, sv, v]\r\n}\r\n\r\n// ── Token generation from HSL ──────────────────────────────────────────────────\r\n\r\nfunction genTokens(hue: number, sat: number, lit: number): { colorScheme: 'light' | 'dark'; tokens: Record<string, string> } {\r\n const dark = lit < 0.55\r\n const h = (d: number) => ((hue + d) % 360 + 360) % 360\r\n const s = (d: number) => Math.max(0, Math.min(1, sat + d))\r\n const l = (d: number) => Math.max(0, Math.min(1, lit + d))\r\n const hsl = (hh: number, ss: number, ll: number) => `hsl(${Math.round(hh)},${Math.round(ss * 100)}%,${Math.round(ll * 100)}%)`\r\n const rgba = (hh: number, ss: number, ll: number, a: number) => {\r\n const c = `hsl(${Math.round(hh)},${Math.round(ss * 100)}%,${Math.round(ll * 100)}%)`\r\n void c; return `hsla(${Math.round(hh)},${Math.round(ss * 100)}%,${Math.round(ll * 100)}%,${a})`\r\n }\r\n\r\n if (dark) {\r\n return {\r\n colorScheme: 'dark',\r\n tokens: {\r\n '--dsw-alias-bg-base': hsl(h(0), s(0), l(-0.04)),\r\n '--dsw-alias-bg-layer-1': hsl(h(0), s(0), l(0.02)),\r\n '--dsw-alias-bg-layer-2': hsl(h(0), s(0), l(0.07)),\r\n '--dsw-alias-bg-layer-3': hsl(h(0), s(-0.05), l(0.12)),\r\n '--dsw-alias-bg-overlay': hsl(h(0), s(-0.05), l(0.12)),\r\n '--dsw-alias-border-l1': rgba(h(0), s(-0.1), l(0.18), 0.12),\r\n '--dsw-alias-border-l2': rgba(h(0), s(-0.1), l(0.22), 0.22),\r\n '--dsw-alias-label-primary': hsl(0, 0, 1),\r\n '--dsw-alias-label-secondary': hsl(0, 0, 1),\r\n '--dsw-alias-label-tertiary': hsl(0, 0, 1),\r\n // The harness's dimmer label tiers (placeholder text, model/permission\r\n // chevrons, disabled rows) must follow the dark scheme's light font\r\n // instead of staying neutral gray, or they read as \"always gray\".\r\n '--dsw-alias-label-caption': hsl(0, 0, 1),\r\n '--dsw-alias-label-dimmed': hsl(0, 0, 1),\r\n '--dsw-alias-label-quaternary': hsl(0, 0, 1),\r\n '--dsw-alias-brand-primary': hsl(h(0), s(0.1), Math.max(l(0.2), 0.5)),\r\n '--dsw-alias-brand-text': l(0.2) > 0.6 ? '#000' : '#fff',\r\n '--dsw-alias-button-primary-hover': hsl(h(0), s(0.1), Math.max(l(0.28), 0.58)),\r\n '--dsw-alias-button-primary-dimmed': hsl(h(0), s(0), l(0.07)),\r\n '--dsw-alias-button-elevated-fill': hsl(h(0), s(0), l(0.04)),\r\n '--dsw-alias-interactive-bg-hover': rgba(h(0), s(0), Math.max(l(0.15), 0.4), 0.12),\r\n '--dsw-alias-interactive-bg-active': rgba(h(0), s(0), Math.max(l(0.15), 0.4), 0.2),\r\n '--dsw-alias-markdown-code-block': hsl(h(0), s(0), l(-0.06)),\r\n '--dsw-alias-markdown-inline-code': hsl(h(0), s(0), l(0.04)),\r\n '--dsw-alias-state-error-primary': '#ff5c72',\r\n '--dsw-alias-state-success-primary': '#3ddc84',\r\n '--dsw-alias-state-warn-primary': '#ffb347',\r\n '--dsw-specific-sidebar-fill': hsl(h(0), s(0), l(-0.06)),\r\n '--dsw-specific-sidebar-nav-item-active': hsl(h(0), s(0), l(0.04)),\r\n '--dsw-specific-sidebar-nav-item-hover': hsl(h(0), s(0), l(0)),\r\n '--dsw-specific-input-major': hsl(h(0), s(0), l(0.02)),\r\n '--dsw-alias-scrollbar-bg-l1': hsl(h(0), s(-0.05), l(0.12)),\r\n '--dsw-alias-scrollbar-bg-l2': hsl(h(0), s(-0.05), l(0.16)),\r\n '--dsw-alias-scrollbar-hover-l1': hsl(h(0), s(-0.05), l(0.22)),\r\n '--dsw-alias-scrollbar-hover-l2': hsl(h(0), s(-0.05), l(0.22)),\r\n },\r\n }\r\n }\r\n return {\r\n colorScheme: 'light',\r\n tokens: {\r\n // Backgrounds track the picked color at its lightness — theme-colored,\r\n // with only mild desaturation so the surfaces stay readable.\r\n '--dsw-alias-bg-base': hsl(h(0), s(-0.08), l(0.03)),\r\n '--dsw-alias-bg-layer-1': hsl(h(0), s(-0.12), l(0.07)),\r\n '--dsw-alias-bg-layer-2': hsl(h(0), s(-0.1), l(-0.03)),\r\n '--dsw-alias-bg-layer-3': hsl(h(0), s(-0.08), l(-0.09)),\r\n '--dsw-alias-bg-overlay': hsl(h(0), s(-0.12), l(0.08)),\r\n '--dsw-alias-border-l1': rgba(h(0), s(-0.15), l(-0.35), 0.18),\r\n '--dsw-alias-border-l2': rgba(h(0), s(-0.15), l(-0.35), 0.3),\r\n // Text is pure black on light surfaces, pure white on dark.\r\n '--dsw-alias-label-primary': hsl(0, 0, 0),\r\n '--dsw-alias-label-secondary': hsl(0, 0, 0),\r\n '--dsw-alias-label-tertiary': hsl(0, 0, 0),\r\n // Same as above but for the light scheme: dimmer tiers go black so the\r\n // placeholder, chevrons, category captions and disabled rows follow the\r\n // theme's dark font instead of staying gray.\r\n '--dsw-alias-label-caption': hsl(0, 0, 0),\r\n '--dsw-alias-label-dimmed': hsl(0, 0, 0),\r\n '--dsw-alias-label-quaternary': hsl(0, 0, 0),\r\n '--dsw-alias-brand-primary': hsl(h(0), s(0.05), Math.min(l(-0.18), 0.45)),\r\n '--dsw-alias-brand-text': '#fff',\r\n '--dsw-alias-button-primary-hover': hsl(h(0), s(0.05), Math.min(l(-0.12), 0.5)),\r\n '--dsw-alias-button-primary-dimmed': hsl(h(0), s(-0.1), l(-0.03)),\r\n '--dsw-alias-button-elevated-fill': hsl(h(0), s(-0.1), l(0.1)),\r\n '--dsw-alias-interactive-bg-hover': rgba(h(0), s(0), l(-0.3), 0.08),\r\n '--dsw-alias-interactive-bg-active': rgba(h(0), s(0), l(-0.3), 0.14),\r\n '--dsw-alias-markdown-code-block': hsl(h(0), s(-0.1), l(-0.03)),\r\n '--dsw-alias-markdown-inline-code': hsl(h(0), s(-0.08), l(0.04)),\r\n '--dsw-specific-sidebar-fill': hsl(h(0), s(-0.1), l(-0.03)),\r\n '--dsw-specific-sidebar-nav-item-active': hsl(h(0), s(-0.08), l(0.05)),\r\n '--dsw-specific-sidebar-nav-item-hover': hsl(h(0), s(-0.12), l(0)),\r\n '--dsw-specific-input-major': hsl(h(0), s(-0.12), l(0.1)),\r\n '--dsw-alias-scrollbar-bg-l1': hsl(h(0), s(-0.1), l(-0.08)),\r\n '--dsw-alias-scrollbar-bg-l2': hsl(h(0), s(-0.08), l(-0.12)),\r\n '--dsw-alias-scrollbar-hover-l1': hsl(h(0), s(-0.08), l(-0.16)),\r\n '--dsw-alias-scrollbar-hover-l2': hsl(h(0), s(-0.08), l(-0.16)),\r\n },\r\n }\r\n}\r\n\r\n// ── Wallpaper layer (direct DOM) ───────────────────────────────────────────────\r\n\r\nlet wpEl: HTMLDivElement | null = null\r\nlet ctxRef: Ctx = null as any\r\n\r\nfunction toRgba(c: string, a: number): string {\r\n const hx = /^#([0-9a-f]{3}|[0-9a-f]{6})$/i.exec(c.trim())\r\n if (hx) { let d = hx[1]!; if (d.length === 3) d = d.split('').map(x => x + x).join(''); const n = parseInt(d, 16); return `rgba(${(n >> 16) & 255},${(n >> 8) & 255},${n & 255},${a})` }\r\n const rgb = /^rgba?\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)(?:\\s*,\\s*([\\d.]+))?\\s*\\)$/i.exec(c.trim())\r\n if (rgb) return `rgba(${rgb[1]},${rgb[2]},${rgb[3]},${a})`\r\n const hsl = /^hsla?\\(\\s*([\\d.]+)\\s*,\\s*([\\d.]+)%\\s*,\\s*([\\d.]+)%/i.exec(c.trim())\r\n if (hsl) return `hsla(${hsl[1]},${hsl[2]}%,${hsl[3]}%,${a})`\r\n return c.trim()\r\n}\r\n\r\nlet appliedTokenNames: string[] = []\r\n\r\n/** Remove every inline token this plugin wrote (teardown symmetry). */\r\nfunction clearCustomTokens(): void {\r\n for (const name of appliedTokenNames) document.body.style.removeProperty(name)\r\n appliedTokenNames = []\r\n}\r\n\r\n/**\r\n * Write the saved color's full token set as inline variables on body — the\r\n * same write surface the theme presenter owns, but derived DIRECTLY from the\r\n * saved pick, so the theme color never depends on the theme service's active\r\n * state or the presenter's timing. The bg-base and sidebar tokens are\r\n * re-emitted at the requested alpha; every other token (layers, labels,\r\n * borders, brand) is written verbatim. No reads: nothing can observe a stale\r\n * or reset theme value and leave the homepage on the system color.\r\n */\r\nfunction applyCustomTokens(op: number): void {\r\n const [h, s, l] = rColor()\r\n const { tokens } = genTokens(h, s, l)\r\n const sideOp = Math.min(1, op + 0.08)\r\n clearCustomTokens()\r\n // Drive the base-palette switch ourselves so tokens the plugin does not\r\n // override (the input surface, masks, static tokens) follow the picked\r\n // color's dark/light scheme even while the theme service preference is\r\n // being adopted/reset.\r\n if (l < 0.55) document.body.setAttribute('data-ds-dark-theme', '')\r\n else document.body.removeAttribute('data-ds-dark-theme')\r\n for (const [name, value] of Object.entries(tokens)) {\r\n let v = value\r\n if (name === '--dsw-alias-bg-base') v = toRgba(value, op)\r\n else if (name === '--dsw-specific-sidebar-fill') v = toRgba(value, sideOp)\r\n document.body.style.setProperty(name, v)\r\n appliedTokenNames.push(name)\r\n }\r\n}\r\n\r\n// ── Settings panel opacity ─────────────────────────────────────────────────────\r\n// The settings modal is the only aria-modal dialog that identifies itself with\r\n// aria-labelledby (ui-primitives' Modal and the image lightbox use aria-label),\r\n// so this selector scopes the translucency to the settings panel alone. The\r\n// panel surface is --dsw-alias-bg-layer-2, resolved here from body's computed\r\n// style (the theme presenter writes custom-theme tokens inline on body; the\r\n// base palettes declare the alias in the stylesheets) and re-emitted with an\r\n// alpha through a plugin-owned variable, so the panel keeps its current color\r\n// while fading toward whatever sits behind the modal.\r\n\r\nconst SETTINGS_PANEL_SEL = '[role=\"dialog\"][aria-modal=\"true\"][aria-labelledby]'\r\nconst SETTINGS_STYLE_RULE = `${SETTINGS_PANEL_SEL}{background:var(--dsh-any-bg-settings-surface,var(--dsw-alias-bg-layer-2))}`\r\n\r\nfunction applySettingsOverrides(op: number): void {\r\n if (op >= 1) {\r\n document.documentElement.style.removeProperty('--dsh-any-bg-settings-surface')\r\n return\r\n }\r\n // Derive the panel surface from the saved color's layer-2 token (not a\r\n // computed-style read), so the settings panel matches the homepage tint\r\n // without depending on the presenter or theme state.\r\n const [h, s, l] = rColor()\r\n const layer2 = genTokens(h, s, l).tokens['--dsw-alias-bg-layer-2']\r\n if (layer2 !== undefined) {\r\n document.documentElement.style.setProperty('--dsh-any-bg-settings-surface', toRgba(layer2, op))\r\n }\r\n}\r\n\r\nfunction applyWp(ctx: Ctx): void {\r\n const url = rWp()\r\n // Wallpaper element (only when image exists)\r\n if (!url) { wpEl?.remove(); wpEl = null } else {\r\n if (!wpEl || !document.body.contains(wpEl)) {\r\n wpEl = document.createElement('div')\r\n wpEl.style.cssText = 'position:fixed;inset:0;z-index:-1;pointer-events:none;background-repeat:no-repeat;'\r\n document.body.prepend(wpEl)\r\n }\r\n const bg = rBgState()\r\n wpEl.style.backgroundImage = `url(\"${url}\")`\r\n if (bg.iw > 0) {\r\n // Saved placement: contain-fit at zoom with the image CENTER pinned to\r\n // the committed fractional viewport point (x, y are center fractions,\r\n // 0.5 = viewport center — the editor commits the same anchor), so the\r\n // framed region survives viewport changes: window moves between screens,\r\n // aspect-ratio changes, and panel splitters re-derive a consistent view.\r\n const fit = Math.min(window.innerWidth / bg.iw, window.innerHeight / bg.ih)\r\n const w = bg.iw * fit * bg.zoom\r\n const h = bg.ih * fit * bg.zoom\r\n wpEl.style.backgroundSize = `${w}px ${h}px`\r\n wpEl.style.backgroundPosition = `${bg.x * window.innerWidth - w / 2}px ${bg.y * window.innerHeight - h / 2}px`\r\n } else {\r\n // Fresh image: match the editor's initial centered contain view.\r\n wpEl.style.backgroundSize = 'contain'\r\n wpEl.style.backgroundPosition = 'center'\r\n }\r\n const blur = rBl()\r\n wpEl.style.filter = blur > 0 ? `blur(${blur}px)` : 'none'\r\n wpEl.style.opacity = String(rWop())\r\n }\r\n // Theme color + opacity: write the full token set inline (self-contained),\r\n // then the settings panel surface.\r\n const op = rOp()\r\n applyCustomTokens(op)\r\n applySettingsOverrides(rSop())\r\n}\r\nfunction teardownWp(): void {\r\n wpEl?.remove(); wpEl = null\r\n clearCustomTokens()\r\n document.documentElement.style.removeProperty('--dsh-any-bg-settings-surface')\r\n}\r\n\r\n// ── Color Wheel (combined hue ring + SL square on single canvas) ───────────────\r\n\r\nconst WHEEL_SIZE = 220\r\nconst CX = WHEEL_SIZE / 2\r\nconst RING_OUTER = 106\r\nconst RING_INNER = 82\r\n// Square inscribed in the ring's inner circle: half-side = RING_INNER / √2,\r\n// so the four corners sit exactly on the inner edge of the hue ring.\r\nconst SQ_HALF = Math.round(RING_INNER / Math.SQRT2)\r\n\r\nfunction drawWheel(cvs: HTMLCanvasElement, hue: number, sat: number, lit: number): void {\r\n // Wheel coordinates are HSV (the S-V plane); props arrive in HSV from the\r\n // section. The HSL conversion happens at the setColor boundary.\r\n const c = cvs.getContext('2d')!\r\n c.clearRect(0, 0, WHEEL_SIZE, WHEEL_SIZE)\r\n // Hue ring\r\n for (let a = 0; a < 360; a++) {\r\n const r1 = (a - 90) * Math.PI / 180\r\n const r2 = (a + 1.5 - 90) * Math.PI / 180\r\n c.beginPath(); c.arc(CX, CX, RING_OUTER, r1, r2); c.arc(CX, CX, RING_INNER, r2, r1, true); c.closePath()\r\n c.fillStyle = `hsl(${a},100%,50%)`; c.fill()\r\n }\r\n // SL square inside ring (HSV S-V plane)\r\n const gx = CX - SQ_HALF, gy = CX - SQ_HALF, sz = SQ_HALF * 2\r\n c.fillStyle = '#fff'; c.fillRect(gx, gy, sz, sz)\r\n const gh = c.createLinearGradient(gx, 0, gx + sz, 0)\r\n gh.addColorStop(0, 'rgba(255,255,255,1)'); gh.addColorStop(1, `hsl(${hue},100%,50%)`)\r\n c.fillStyle = gh; c.fillRect(gx, gy, sz, sz)\r\n const gv = c.createLinearGradient(0, gy, 0, gy + sz)\r\n gv.addColorStop(0, 'rgba(0,0,0,0)'); gv.addColorStop(1, 'rgba(0,0,0,1)')\r\n c.fillStyle = gv; c.fillRect(gx, gy, sz, sz)\r\n // Hue marker on ring\r\n const hRad = (hue - 90) * Math.PI / 180\r\n const hR = (RING_OUTER + RING_INNER) / 2\r\n const hmx = CX + Math.cos(hRad) * hR, hmy = CX + Math.sin(hRad) * hR\r\n c.beginPath(); c.arc(hmx, hmy, 8, 0, Math.PI * 2)\r\n c.fillStyle = 'rgba(0,0,0,0.25)'; c.fill()\r\n c.beginPath(); c.arc(hmx, hmy, 6.5, 0, Math.PI * 2)\r\n c.strokeStyle = '#fff'; c.lineWidth = 2; c.stroke()\r\n // SL marker (HSV coordinates)\r\n const smx = gx + sat * sz, smy = gy + (1 - lit) * sz\r\n c.beginPath(); c.arc(smx, smy, 7, 0, Math.PI * 2)\r\n c.fillStyle = 'rgba(0,0,0,0.25)'; c.fill()\r\n c.beginPath(); c.arc(smx, smy, 5.5, 0, Math.PI * 2)\r\n c.strokeStyle = '#fff'; c.lineWidth = 2; c.stroke()\r\n c.beginPath(); c.arc(smx, smy, 3.5, 0, Math.PI * 2)\r\n c.strokeStyle = '#000'; c.lineWidth = 1; c.stroke()\r\n}\r\n\r\nfunction hitTest(x: number, y: number): 'ring' | 'square' | null {\r\n if (Math.abs(x - CX) <= SQ_HALF && Math.abs(y - CX) <= SQ_HALF) return 'square'\r\n const dx = x - CX, dy = y - CX\r\n const dist = Math.sqrt(dx * dx + dy * dy)\r\n if (dist >= RING_INNER - 4 && dist <= RING_OUTER + 4) return 'ring'\r\n return null\r\n}\r\n\r\nfunction pickHue(x: number, y: number): number {\r\n let angle = Math.atan2(y - CX, x - CX) * 180 / Math.PI + 90\r\n if (angle < 0) angle += 360\r\n return angle\r\n}\r\n\r\nfunction pickSL(x: number, y: number): [number, number] {\r\n const gx = CX - SQ_HALF, gy = CX - SQ_HALF, sz = SQ_HALF * 2\r\n return [\r\n Math.max(0, Math.min(1, (x - gx) / sz)),\r\n Math.max(0.02, Math.min(0.98, 1 - (y - gy) / sz)),\r\n ]\r\n}\r\n\r\nfunction ColorWheel({ hue, sat, lit, onChange }: {\r\n hue: number; sat: number; lit: number\r\n onChange: (h: number, s: number, l: number) => void\r\n}) {\r\n const cvsRef = useRef<HTMLCanvasElement>(null)\r\n // Internal HSV state: the slots host caches injected section props once, so\r\n // the canvas must redraw from interaction state instead of from props.\r\n const [col, setCol] = useState({ hue, sat, lit })\r\n const colRef = useRef(col)\r\n colRef.current = col\r\n\r\n // Adopt external changes (e.g. section remount after theme restore).\r\n useEffect(() => {\r\n setCol(c => (c.hue === hue && c.sat === sat && c.lit === lit ? c : { hue, sat, lit }))\r\n }, [hue, sat, lit])\r\n\r\n useEffect(() => { if (cvsRef.current) drawWheel(cvsRef.current, col.hue, col.sat, col.lit) }, [col])\r\n\r\n const apply = useCallback((nh: number, ns: number, nl: number) => {\r\n setCol({ hue: nh, sat: ns, lit: nl })\r\n onChange(nh, ns, nl)\r\n }, [onChange])\r\n\r\n const onDown = useCallback((e: React.MouseEvent<HTMLCanvasElement>) => {\r\n const r = cvsRef.current!.getBoundingClientRect()\r\n const x = e.clientX - r.left, y = e.clientY - r.top\r\n const region = hitTest(x, y)\r\n if (!region) return\r\n if (region === 'ring') {\r\n apply(pickHue(x, y), colRef.current.sat, colRef.current.lit)\r\n } else {\r\n const [s, l] = pickSL(x, y)\r\n apply(colRef.current.hue, s, l)\r\n }\r\n const onMove = (ev: MouseEvent) => {\r\n const rr = cvsRef.current!.getBoundingClientRect()\r\n const mx = ev.clientX - rr.left, my = ev.clientY - rr.top\r\n if (region === 'ring') {\r\n const d = Math.sqrt((mx - CX) ** 2 + (my - CX) ** 2)\r\n if (d >= RING_INNER - 10 && d <= RING_OUTER + 10) apply(pickHue(mx, my), colRef.current.sat, colRef.current.lit)\r\n } else {\r\n const [s, l] = pickSL(mx, my)\r\n apply(colRef.current.hue, s, l)\r\n }\r\n }\r\n const onUp = () => { document.removeEventListener('mousemove', onMove); document.removeEventListener('mouseup', onUp) }\r\n document.addEventListener('mousemove', onMove); document.addEventListener('mouseup', onUp)\r\n }, [apply])\r\n\r\n return <canvas ref={cvsRef} width={WHEEL_SIZE} height={WHEEL_SIZE} style={ST.wheelCanvas} onMouseDown={onDown} />\r\n}\r\n\r\n// ── Image compression ──────────────────────────────────────────────────────────\r\n\r\nfunction compress(img: HTMLImageElement, side: number, q: number): string {\r\n const s = Math.min(1, side / Math.max(img.width, img.height))\r\n const c = document.createElement('canvas')\r\n c.width = Math.max(1, Math.round(img.width * s)); c.height = Math.max(1, Math.round(img.height * s))\r\n c.getContext('2d')!.drawImage(img, 0, 0, c.width, c.height)\r\n return c.toDataURL('image/jpeg', q)\r\n}\r\nfunction readImg(file: File, cb: (url: string | null) => void): void {\r\n const r = new FileReader()\r\n r.onerror = () => cb(null)\r\n r.onload = () => {\r\n const img = new Image()\r\n img.onerror = () => cb(null)\r\n img.onload = () => {\r\n try { let u = compress(img, 1600, 0.75); if (u.length > 2e6) u = compress(img, 1000, 0.6); if (u.length > 2e6) u = compress(img, 800, 0.5); cb(u) } catch { cb(null) }\r\n }\r\n img.src = r.result as string\r\n }\r\n r.readAsDataURL(file)\r\n}\r\n\r\n// ── Styles ─────────────────────────────────────────────────────────────────────\r\n\r\nconst ST = {\r\n root: { display: 'flex', flexDirection: 'column' as const, gap: '20px', padding: '4px 0', maxWidth: '640px' },\r\n h2: { color: 'var(--dsw-alias-label-primary)', fontSize: '18px', fontWeight: 600, margin: 0 },\r\n sub: { color: 'var(--dsw-alias-label-tertiary)', fontSize: '13px' },\r\n hr: { height: '1px', background: 'var(--dsw-alias-border-l2)', border: 'none', margin: '4px 0' },\r\n label: { color: 'var(--dsw-alias-label-primary)', fontSize: '16px', fontWeight: 600, marginBottom: '8px' },\r\n hint: { color: 'var(--dsw-alias-label-tertiary)', fontSize: '12px', lineHeight: '18px', marginTop: '4px' },\r\n colorHint: { color: 'var(--dsw-alias-label-tertiary)', fontSize: '12px', lineHeight: '18px', marginTop: '7px', textAlign: 'center' as const },\r\n wheelCanvas: { cursor: 'crosshair', borderRadius: '50%' },\r\n center: { display: 'flex', justifyContent: 'center' },\r\n btnGroup: { display: 'flex', justifyContent: 'center', marginTop: '10px' },\r\n row: { display: 'flex', alignItems: 'center', gap: '10px', flexWrap: 'wrap' as const },\r\n sliderBlock: { display: 'flex', flexDirection: 'column' as const, gap: '4px' },\r\n sliderRow: { display: 'flex', alignItems: 'center', gap: '10px' },\r\n sliderLabel: { color: 'var(--dsw-alias-label-secondary)', fontSize: '13px' },\r\n smallHint: { color: 'var(--dsw-alias-label-tertiary)', fontSize: '11px', lineHeight: '16px' },\r\n slider: { flex: 1, accentColor: 'var(--dsw-alias-brand-primary)', minWidth: '160px' },\r\n sliderVal: { color: 'var(--dsw-alias-label-secondary)', fontSize: '12px', whiteSpace: 'nowrap' as const, width: '44px', textAlign: 'right' as const },\r\n btn: { height: '32px', padding: '0 14px', borderRadius: '8px', border: '1px solid var(--dsw-alias-border-l2)', background: 'var(--dsw-alias-button-elevated-fill)', color: 'var(--dsw-alias-label-primary)', cursor: 'pointer', fontSize: '13px', font: 'inherit', boxSizing: 'border-box' as const },\r\n btnDanger: { color: 'var(--dsw-alias-state-error-primary)' },\r\n btnPrimary: { background: 'var(--dsw-alias-brand-primary)', color: 'var(--dsw-alias-brand-text)', border: 'none' },\r\n preview: { width: '368px', height: '225px', objectFit: 'cover' as const, borderRadius: '6px', border: '1px solid var(--dsw-alias-border-l2)', cursor: 'pointer' },\r\n sliders: { display: 'flex', flexDirection: 'column' as const, gap: '12px', marginTop: '8px' },\r\n // Modal\r\n overlay: { position: 'fixed' as const, inset: 0, zIndex: 9999, background: 'rgba(0,0,0,0.7)', display: 'flex', flexDirection: 'column' as const, alignItems: 'center', justifyContent: 'center', gap: '12px' },\r\n modalTitle: { color: '#fff', fontSize: '16px', fontWeight: 500 },\r\n modalHint: { color: 'rgba(255,255,255,0.6)', fontSize: '12px' },\r\n previewRect: { position: 'relative' as const, overflow: 'hidden', border: '2px solid rgba(255,255,255,0.3)', borderRadius: '8px', background: '#000', cursor: 'grab' },\r\n previewImg: { position: 'absolute' as const, transformOrigin: '0 0', pointerEvents: 'none' as const },\r\n modalBtns: { display: 'flex', gap: '10px' },\r\n}\r\n\r\n// ── Background Editor Modal ────────────────────────────────────────────────────\r\n\r\nfunction BgEditor({ url, t, onClose, onCommit }: {\r\n url: string; t: (key: string) => string; onClose: () => void\r\n onCommit: (zoom: number, x: number, y: number, iw: number, ih: number) => void\r\n}) {\r\n const pw = Math.min(window.innerWidth * 0.75, 860)\r\n const ph = Math.round(pw * window.innerHeight / window.innerWidth)\r\n const saved = rBgState()\r\n const [zoom, setZoom] = useState(saved.iw > 0 ? saved.zoom : 1)\r\n const [pos, setPos] = useState(saved.iw > 0 ? { x: saved.x * pw, y: saved.y * ph } : { x: 0, y: 0 })\r\n const [imgSize, setImgSize] = useState({ w: 0, h: 0 })\r\n const containerRef = useRef<HTMLDivElement>(null)\r\n const imgRef = useRef<HTMLImageElement>(null)\r\n const dragRef = useRef({ active: false, sx: 0, sy: 0, spx: 0, spy: 0 })\r\n\r\n useEffect(() => {\r\n const img = new Image()\r\n img.onload = () => {\r\n const scale = Math.min(pw / img.width, ph / img.height)\r\n const w = img.width * scale, h = img.height * scale\r\n setImgSize({ w, h })\r\n const s = rBgState()\r\n if (s.iw > 0 && s.iw === img.width && s.ih === img.height) {\r\n setZoom(s.zoom)\r\n // Saved x, y are CENTER fractions of the preview: the image center\r\n // lands at (x·pw, y·ph), so the top-left comes from subtracting half\r\n // the displayed (zoom-scaled) image size.\r\n setPos({ x: s.x * pw - w * s.zoom / 2, y: s.y * ph - h * s.zoom / 2 })\r\n } else {\r\n setZoom(1)\r\n setPos({ x: (pw - w) / 2, y: (ph - h) / 2 })\r\n }\r\n }\r\n img.src = url\r\n }, [url, pw, ph])\r\n\r\n const onDown = useCallback((e: React.MouseEvent) => {\r\n e.preventDefault()\r\n dragRef.current = { active: true, sx: e.clientX, sy: e.clientY, spx: pos.x, spy: pos.y }\r\n const onMove = (ev: MouseEvent) => {\r\n if (!dragRef.current.active) return\r\n setPos({ x: dragRef.current.spx + ev.clientX - dragRef.current.sx, y: dragRef.current.spy + ev.clientY - dragRef.current.sy })\r\n }\r\n const onUp = () => { dragRef.current.active = false; document.removeEventListener('mousemove', onMove); document.removeEventListener('mouseup', onUp) }\r\n document.addEventListener('mousemove', onMove); document.addEventListener('mouseup', onUp)\r\n }, [pos])\r\n\r\n const onWheelCb = useCallback((e: WheelEvent) => {\r\n e.preventDefault()\r\n const rect = containerRef.current!.getBoundingClientRect()\r\n const mx = e.clientX - rect.left, my = e.clientY - rect.top\r\n const factor = e.deltaY > 0 ? 0.92 : 1.08\r\n const nz = Math.max(0.1, Math.min(10, zoom * factor))\r\n const nx = mx - (mx - pos.x) * (nz / zoom)\r\n const ny = my - (my - pos.y) * (nz / zoom)\r\n setZoom(nz); setPos({ x: nx, y: ny })\r\n }, [zoom, pos])\r\n\r\n useEffect(() => {\r\n const el = containerRef.current\r\n if (!el) return\r\n el.addEventListener('wheel', onWheelCb, { passive: false })\r\n return () => el.removeEventListener('wheel', onWheelCb)\r\n }, [onWheelCb])\r\n\r\n const resetView = useCallback(() => {\r\n if (imgSize.w === 0) return\r\n setZoom(1); setPos({ x: (pw - imgSize.w) / 2, y: (ph - imgSize.h) / 2 })\r\n }, [pw, ph, imgSize])\r\n\r\n return (\r\n <div style={ST.overlay} onClick={e => { if (e.target === e.currentTarget) onClose() }}>\r\n <div style={ST.modalTitle}>{t('editorTitle')}</div>\r\n <div ref={containerRef} style={{ ...ST.previewRect, width: pw, height: ph }} onMouseDown={onDown}>\r\n <img ref={imgRef} src={url} alt=\"\" draggable={false} style={{\r\n ...ST.previewImg, width: imgSize.w, height: imgSize.h,\r\n transform: `translate(${pos.x}px,${pos.y}px) scale(${zoom})`,\r\n }} />\r\n </div>\r\n <div style={ST.modalHint}>{t('editorHint')}</div>\r\n <div style={ST.modalBtns}>\r\n <button style={ST.btn} onClick={resetView}>{t('editorReset')}</button>\r\n <button style={ST.btn} onClick={onClose}>{t('editorCancel')}</button>\r\n <button style={{ ...ST.btn, ...ST.btnPrimary }} onClick={() => onCommit(zoom, (pos.x + imgSize.w * zoom / 2) / pw, (pos.y + imgSize.h * zoom / 2) / ph, imgRef.current?.naturalWidth ?? 0, imgRef.current?.naturalHeight ?? 0)}>{t('editorCommit')}</button>\r\n </div>\r\n </div>\r\n )\r\n}\r\n\r\n// ── Uncontrolled slider ────────────────────────────────────────────────────────\r\n\r\nfunction LiveSlider({ min, max, step, def, fmt, onInput, onChange }: {\r\n min: number; max: number; step: number; def: number\r\n fmt: (v: number) => string; onInput: (v: number) => void; onChange: (v: number) => void\r\n}) {\r\n const valRef = useRef<HTMLSpanElement>(null)\r\n return (\r\n <div style={ST.sliderRow}>\r\n <input type=\"range\" min={min} max={max} step={step} defaultValue={def} style={ST.slider}\r\n onInput={e => { const v = Number((e.target as HTMLInputElement).value); onInput(v); if (valRef.current) valRef.current.textContent = fmt(v) }}\r\n onChange={e => onChange(Number((e.target as HTMLInputElement).value))} />\r\n <span ref={valRef} style={ST.sliderVal}>{fmt(def)}</span>\r\n </div>\r\n )\r\n}\r\n\r\n// ── Theme Section ──────────────────────────────────────────────────────────────\r\n\r\nfunction ThemeSection(props: any) {\r\n const { t, hue, sat, lit, setColor, url, setWp, setOp, setWop, setBl, setSop, useStore } = props\r\n const storeUrl = useStore((s: any) => s.url)\r\n const fileRef = useRef<HTMLInputElement>(null)\r\n const [editorOpen, setEditorOpen] = useState(false)\r\n\r\n return (\r\n <div style={ST.root}>\r\n <div><h2 style={ST.h2}>{t('nav')}</h2><div style={ST.sub}>{t('subtitle')}</div></div>\r\n\r\n {/* Theme color */}\r\n <div>\r\n <div style={ST.label}>{t('colorTitle')}</div>\r\n <div style={ST.center}><ColorWheel hue={hue} sat={sat} lit={lit} onChange={setColor} /></div>\r\n <div style={ST.colorHint}>{t('colorHint')}</div>\r\n </div>\r\n\r\n <hr style={ST.hr} />\r\n\r\n {/* Interface: homepage + settings opacity, each its own slider */}\r\n <div>\r\n <div style={ST.label}>{t('uiTitle')}</div>\r\n <div style={ST.sliders}>\r\n <div style={ST.sliderBlock}>\r\n <div style={ST.sliderLabel}>{t('uiOpacity')}</div>\r\n <div style={ST.smallHint}>{t('uiOpacityHint')}</div>\r\n <LiveSlider min={0} max={100} step={1} def={Math.round(rOp() * 100)}\r\n fmt={v => `${v}%`}\r\n onInput={v => { const op = v / 100; cfg.opacity = op; applyCustomTokens(op); saveConfig() }}\r\n onChange={v => setOp(v / 100)} />\r\n </div>\r\n <div style={ST.sliderBlock}>\r\n <div style={ST.sliderLabel}>{t('uiSop')}</div>\r\n <div style={ST.smallHint}>{t('uiSopHint')}</div>\r\n <LiveSlider min={0} max={100} step={1} def={Math.round(rSop() * 100)}\r\n fmt={v => `${v}%`}\r\n onInput={v => { const op = v / 100; cfg.settingsOpacity = op; applySettingsOverrides(op); saveConfig() }}\r\n onChange={v => setSop(v / 100)} />\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <hr style={ST.hr} />\r\n\r\n {/* Background image */}\r\n <div>\r\n <div style={ST.label}>{t('bgTitle')}</div>\r\n <div style={ST.center}>{storeUrl ? <img src={storeUrl} alt=\"\" style={ST.preview} onClick={() => setEditorOpen(true)} /> : null}</div>\r\n <div style={ST.btnGroup}>\r\n <div style={ST.row}>\r\n <button type=\"button\" style={ST.btn} onClick={() => fileRef.current?.click()}>{t('bgChoose')}</button>\r\n {storeUrl ? <button type=\"button\" style={ST.btn} onClick={() => setEditorOpen(true)}>{t('bgEdit')}</button> : null}\r\n {storeUrl ? <button type=\"button\" style={{ ...ST.btn, ...ST.btnDanger }} onClick={() => setWp(null)}>{t('bgRemove')}</button> : null}\r\n <input ref={fileRef} type=\"file\" accept=\"image/*\" style={{ display: 'none' }} onChange={e => {\r\n const f = e.target.files?.[0]; if (!f) return\r\n readImg(f, d => { if (d) setWp(d); e.target.value = '' })\r\n }} />\r\n </div>\r\n </div>\r\n <div style={ST.sliders}>\r\n <div style={ST.sliderBlock}>\r\n <div style={ST.sliderLabel}>{t('wpOpacity')}</div>\r\n <LiveSlider min={0} max={100} step={1} def={Math.round(rWop() * 100)}\r\n fmt={v => `${v}%`}\r\n onInput={v => { const op = v / 100; cfg.wallpaperOpacity = op; if (wpEl) wpEl.style.opacity = String(op); saveConfig() }}\r\n onChange={v => setWop(v / 100)} />\r\n </div>\r\n <div style={ST.sliderBlock}>\r\n <div style={ST.sliderLabel}>{t('bgBlur')}</div>\r\n <LiveSlider min={0} max={60} step={1} def={rBl()}\r\n fmt={v => `${v}px`}\r\n onInput={v => { cfg.blur = v; if (wpEl) wpEl.style.filter = v > 0 ? `blur(${v}px)` : 'none'; saveConfig() }}\r\n onChange={v => setBl(v)} />\r\n </div>\r\n </div>\r\n <div style={ST.hint}>{t('bgHint')}</div>\r\n </div>\r\n\r\n {/* Background editor modal */}\r\n {editorOpen && storeUrl ? (\r\n <BgEditor url={storeUrl} t={t} onClose={() => setEditorOpen(false)}\r\n onCommit={(z, x, y, iw, ih) => { cfg.bgState = { zoom: z, x, y, iw, ih }; applyWp(ctxRef); saveConfig(); setEditorOpen(false) }} />\r\n ) : null}\r\n </div>\r\n )\r\n}\r\n\r\n// ── Plugin entry ───────────────────────────────────────────────────────────────\r\n\r\nexport function apply(ctx: Ctx): void {\r\n ctxRef = ctx\r\n // Bind the dedicated `/dsh-any-background` RPC caller so the persistence\r\n // module can reach the node half's file-backed store.\r\n rpcCallFn = (endpoint: string, payload: unknown) =>\r\n ctx.connection.rpc.call(RPC_CHANNEL, endpoint, payload).then((res: any) => res as RpcResultLike | undefined)\r\n\r\n // 1. Restore custom color and register as a skin. The saved color's\r\n // lightness decides the scheme — a dark pick gets white text, a light pick\r\n // black text — so both the theme color and the dark/light text follow the\r\n // picked color.\r\n const [initH, initS, initL] = rColor()\r\n let customDispose: (() => void) | null = null\r\n // registerCustom takes HSL (the storage/wheel space and genTokens space).\r\n const registerCustom = (h: number, s: number, l: number) => {\r\n customDispose?.()\r\n try {\r\n const { colorScheme, tokens } = genTokens(h, s, l)\r\n customDispose = ctx.theme.register({ id: CUSTOM_ID, colorScheme, tokens })\r\n } catch {\r\n // A live registration from an earlier apply pass (HMR swap that could\r\n // not run this fiber's disposer) cannot be torn down here; keep it and\r\n // activate it below. Without this the duplicate-id throw would abort\r\n // apply and skip the wallpaper/opacity restore.\r\n customDispose = null\r\n }\r\n ctx.theme.setTheme(CUSTOM_ID)\r\n }\r\n // Restore saved color on boot.\r\n if (rHasColor()) registerCustom(initH, initS, initL)\r\n ctx.effect(() => () => { customDispose?.() }, 'dsh-any-background: skin dispose')\r\n\r\n // 2. Gradient CSS (for custom dark themes).\r\n let styleEl: HTMLStyleElement | undefined\r\n if (typeof document !== 'undefined') {\r\n styleEl = document.createElement('style')\r\n styleEl.dataset.plugin = 'dsh-any-background'\r\n styleEl.textContent = `body[data-ds-dark-theme=\"${CUSTOM_ID}\"]::before{content:'';position:fixed;inset:0;z-index:-1;pointer-events:none;background:radial-gradient(ellipse 80% 60% at 50% 0%,rgba(255,255,255,0.03) 0%,transparent 60%)}${SETTINGS_STYLE_RULE}`\r\n document.head.appendChild(styleEl)\r\n }\r\n ctx.effect(() => () => { styleEl?.parentNode?.removeChild(styleEl) }, 'dsh-any-background: gradient')\r\n\r\n // 3. State store.\r\n let rev = 0\r\n const store = defineStore({\r\n init: () => ({ url: null as string | null, rev: -1 }),\r\n actions: { syncBg: (d: any, url: string | null, r: number) => { if (r <= d.rev) return; d.url = url; d.rev = r } },\r\n })\r\n let bound: any\r\n const syncBg = () => { rev++; bound?.syncBg(rWp(), rev) }\r\n\r\n // 4. Wallpaper.\r\n applyWp(ctx); syncBg()\r\n // Load the file-backed theme from the node half and re-apply once it lands\r\n // (the node store may be absent or unreachable at this instant; defaults are\r\n // already applied above, and the deferred restore below re-asserts too).\r\n void loadPersisted().then(() => { applyWp(ctx); syncBg() })\r\n ctx.effect(() => () => { teardownWp() }, 'dsh-any-background: wp cleanup')\r\n ctx.effect(() => ctx.on('theme/change', () => {\r\n // The theme service persists only built-in preferences; the custom theme's\r\n // preference lives in memory, so a host-scope adoption can silently reset\r\n // it. While a color is saved, re-assert the custom theme so it stays\r\n // active. Guard on registry presence — registerCustom disposes the old\r\n // skin before re-registering, and during that transient the registry lacks\r\n // CUSTOM_ID, so asserting there would throw.\r\n if (rHasColor()) {\r\n const snapshot = ctx.theme.getTheme()\r\n if (snapshot.preference !== CUSTOM_ID && snapshot.themes.some(t => t.id === CUSTOM_ID)) {\r\n ctx.theme.setTheme(CUSTOM_ID)\r\n }\r\n }\r\n applyWp(ctx)\r\n }), 'dsh-any-background: theme change')\r\n // The wallpaper's inline size/position are absolute pixels computed for the\r\n // viewport at apply time, so a stale viewport leaves them misplaced.\r\n // Watch the viewport itself: a fixed inset:0 sentinel's box always equals\r\n // the viewport, so a ResizeObserver on it fires for ANY viewport change\r\n // (window resize, moving between monitors, panel splitters, zoom) where\r\n // window.resize can be missed; a resolution media query catches DPI-only\r\n // moves between differently scaled screens. All re-applies are coalesced to\r\n // one per animation frame. Re-running applyWp recomputes the contain-fit\r\n // scale and the fractional offsets for the new viewport (the editor's model).\r\n let frame = 0\r\n const applySoon = (): void => {\r\n if (frame !== 0) return\r\n frame = requestAnimationFrame(() => { frame = 0; applyWp(ctx) })\r\n }\r\n const sentinel = document.createElement('div')\r\n sentinel.style.cssText = 'position:fixed;inset:0;pointer-events:none;visibility:hidden'\r\n document.body.append(sentinel)\r\n const viewportObserver = new ResizeObserver(applySoon)\r\n viewportObserver.observe(sentinel)\r\n const dprQuery = window.matchMedia(`(resolution: ${window.devicePixelRatio}dppx)`)\r\n dprQuery.addEventListener('change', applySoon)\r\n ctx.effect(() => () => {\r\n viewportObserver.disconnect()\r\n dprQuery.removeEventListener('change', applySoon)\r\n sentinel.remove()\r\n }, 'dsh-any-background: viewport watch')\r\n\r\n // 5. Locale.\r\n ctx.effect(() => ctx.locale.register(NS, { zh, en }), 'dsh-any-background: i18n')\r\n\r\n // 6. Section injection.\r\n const sectionInject = (actions: any) => {\r\n bound = actions; syncBg()\r\n const [wh, ws, wl] = rColor()\r\n const [dh, ds, dv] = hslToHsv(wh, ws, wl)\r\n return {\r\n t: ctx.locale.bind(NS),\r\n hue: dh, sat: ds, lit: dv,\r\n setColor: (nh: number, ns: number, nl: number) => {\r\n const [sh, ss, sl] = hsvToHsl(nh, ns, nl)\r\n cfg.color = [sh, ss, sl]\r\n registerCustom(sh, ss, sl)\r\n applyWp(ctx)\r\n saveConfig()\r\n },\r\n setWp: (u: string | null) => {\r\n wpUrl = u\r\n cfg.bgState = { ...DEFAULT_CONFIG.bgState }\r\n applyWp(ctx); syncBg()\r\n void rpcCall('setWallpaper', { dataUrl: u })\r\n },\r\n setOp: (v: number) => { cfg.opacity = v; applyWp(ctx); syncBg(); saveConfig() },\r\n setWop: (v: number) => { cfg.wallpaperOpacity = v; applyWp(ctx); syncBg(); saveConfig() },\r\n setBl: (v: number) => { cfg.blur = v; applyWp(ctx); syncBg(); saveConfig() },\r\n setSop: (v: number) => { cfg.settingsOpacity = v; applySettingsOverrides(v); saveConfig() },\r\n }\r\n }\r\n ctx.slots.inject('settings.section', () => ctx.slots.register({\r\n name: 'settings.section', id: 'dsh-any-background', order: 35,\r\n label: () => ctx.locale.bind(NS)('nav'),\r\n locale: NS, store, inject: sectionInject,\r\n }, ThemeSection as any))\r\n\r\n // 7. Deferred boot restore: the theme service and the host settings scope\r\n // settle asynchronously after this apply, so the synchronous restore can be\r\n // observed mid-flight — a late host adoption resets the preference, or the\r\n // presenter re-applies over our overrides. Re-running the saved-color and\r\n // wallpaper restore a few ticks later guarantees the saved records land.\r\n const restoreSaved = (): void => {\r\n if (rHasColor()) {\r\n const [h, s, l] = rColor()\r\n registerCustom(h, s, l)\r\n }\r\n applyWp(ctx)\r\n }\r\n const restoreTimers = [300, 1500].map(delay => window.setTimeout(restoreSaved, delay))\r\n ctx.effect(() => () => { restoreTimers.forEach(id => window.clearTimeout(id)) }, 'dsh-any-background: boot restore')\r\n\r\n // 8. Theme watchdog: the theme service keeps only built-in preferences in\r\n // memory, so ANY host-scope adoption can silently drop the custom theme —\r\n // reverting the label colors (white/black) and the inner surfaces to the\r\n // system palette. While a color is saved, re-register and re-assert the\r\n // custom theme on a slow interval so the theme state always matches the\r\n // saved color and the active scheme, independent of which event resets it.\r\n const watchdogId = window.setInterval(() => {\r\n if (!rHasColor()) return\r\n const snapshot = ctx.theme.getTheme()\r\n let changed = false\r\n if (!snapshot.themes.some(t => t.id === CUSTOM_ID)) {\r\n const [h, s, l] = rColor()\r\n registerCustom(h, s, l)\r\n changed = true\r\n } else if (snapshot.preference !== CUSTOM_ID) {\r\n ctx.theme.setTheme(CUSTOM_ID)\r\n changed = true\r\n }\r\n if (changed) applyWp(ctx)\r\n }, 1000)\r\n ctx.effect(() => () => { window.clearInterval(watchdogId) }, 'dsh-any-background: theme watchdog')\r\n}\r\n"],"mappings":"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"}
package/lib/index.js CHANGED
@@ -6,7 +6,8 @@ import { dshHomePath } from "@deepseek-ai/dsh-home-paths";
6
6
  *
7
7
  * The browser client cannot touch the filesystem, so this half owns the
8
8
  * `.dsh-any-background-data/` store under the DSH data home and exposes a
9
- * small RPC surface over the shared `/api` channel. The client reads the
9
+ * small RPC surface over the dedicated `/dsh-any-background` channel (never
10
+ * the shared `/api`, so slash commands stay intact). The client reads the
10
11
  * persisted theme on boot and writes it back on every setting change.
11
12
  *
12
13
  * Storage layout:
@@ -129,7 +130,7 @@ async function writeWallpaper(dataUrl) {
129
130
  }
130
131
  const NS = "dshAnyBackground";
131
132
  function apply(ctx) {
132
- const dispose = ctx.connection.rpc.intercept("/api", (ep) => ep.startsWith(`${NS}/`), async (ep, payload) => {
133
+ const dispose = ctx.connection.rpc.handle("/dsh-any-background", async (ep, payload) => {
133
134
  const method = ep.slice(`${NS}/`.length);
134
135
  try {
135
136
  switch (method) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-any-background",
3
- "version": "0.1.4",
3
+ "version": "0.1.6",
4
4
  "description": "Appearance plugin for DeepSeek Harness: custom theme color (PS-style color wheel), background wallpaper with opacity/blur controls, and separate main/settings interface opacity.",
5
5
  "keywords": [
6
6
  "deepseek-harness",