dsh-any-background 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +170 -0
- package/README.zh.md +169 -0
- package/cordis.patch.yml +8 -0
- package/lib/client.js +1248 -0
- package/lib/client.js.map +1 -0
- package/lib/index.js +12 -0
- package/lib/invariant.js +19 -0
- package/package.json +82 -0
package/lib/client.js
ADDED
|
@@ -0,0 +1,1248 @@
|
|
|
1
|
+
window.__ModuleLoader__.load({
|
|
2
|
+
id: "dsh-any-background",
|
|
3
|
+
factory: (require) => {
|
|
4
|
+
var module = { exports: {} };
|
|
5
|
+
var exports = module.exports;
|
|
6
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
7
|
+
let react = require("react");
|
|
8
|
+
let _deepseek_ai_dsh_client_runtime_client = require("@deepseek-ai/dsh-client-runtime/client");
|
|
9
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
10
|
+
//#region src/client/index.tsx
|
|
11
|
+
const name = "dsh-any-background";
|
|
12
|
+
const inject = [
|
|
13
|
+
"slots",
|
|
14
|
+
"locale",
|
|
15
|
+
"theme"
|
|
16
|
+
];
|
|
17
|
+
const NS = "settings.anyBg";
|
|
18
|
+
const LS_COLOR = "dsh-any-background:color";
|
|
19
|
+
const LS_WP = "dsh-any-background:wallpaper";
|
|
20
|
+
const LS_OP = "dsh-any-background:opacity";
|
|
21
|
+
const LS_WOP = "dsh-any-background:wallpaper-opacity";
|
|
22
|
+
const LS_BL = "dsh-any-background:blur";
|
|
23
|
+
const LS_BG = "dsh-any-background:bgState";
|
|
24
|
+
const LS_SOP = "dsh-any-background:settings-opacity";
|
|
25
|
+
const DEF_OP = .85;
|
|
26
|
+
const DEF_BL = 0;
|
|
27
|
+
const DEF_SOP = 1;
|
|
28
|
+
const CUSTOM_ID = "custom-color";
|
|
29
|
+
const zh = {
|
|
30
|
+
nav: "主题",
|
|
31
|
+
subtitle: "自定义界面外观",
|
|
32
|
+
colorTitle: "主题色",
|
|
33
|
+
colorHint: "在色轮上选择色相,在方形中调整饱和度和明度",
|
|
34
|
+
uiTitle: "界面",
|
|
35
|
+
uiOpacity: "主界面透明度",
|
|
36
|
+
uiOpacityHint: "拖动滑块调整主页界面背景的透明度",
|
|
37
|
+
uiSop: "设置界面透明度",
|
|
38
|
+
uiSopHint: "拖动滑块调整设置页界面背景的透明度",
|
|
39
|
+
bgTitle: "背景图片",
|
|
40
|
+
bgChoose: "选择图片",
|
|
41
|
+
bgRemove: "移除图片",
|
|
42
|
+
bgEdit: "编辑位置",
|
|
43
|
+
wpOpacity: "壁纸透明度",
|
|
44
|
+
bgBlur: "壁纸模糊",
|
|
45
|
+
bgHint: "拖动滑块实时调整。点击背景图可打开编辑器调整位置和大小",
|
|
46
|
+
editorTitle: "背景编辑器",
|
|
47
|
+
editorHint: "拖动移动图片,滚轮缩放大小",
|
|
48
|
+
editorCommit: "确认",
|
|
49
|
+
editorCancel: "取消",
|
|
50
|
+
editorReset: "重置"
|
|
51
|
+
};
|
|
52
|
+
const en = {
|
|
53
|
+
nav: "Theme",
|
|
54
|
+
subtitle: "Customize appearance",
|
|
55
|
+
colorTitle: "Theme color",
|
|
56
|
+
colorHint: "Pick hue on the ring, adjust saturation & lightness in the square",
|
|
57
|
+
uiTitle: "Interface",
|
|
58
|
+
uiOpacity: "Main interface opacity",
|
|
59
|
+
uiOpacityHint: "Drag to adjust homepage interface background opacity",
|
|
60
|
+
uiSop: "Settings interface opacity",
|
|
61
|
+
uiSopHint: "Drag to adjust the settings page background opacity",
|
|
62
|
+
bgTitle: "Wallpaper",
|
|
63
|
+
bgChoose: "Choose image",
|
|
64
|
+
bgRemove: "Remove image",
|
|
65
|
+
bgEdit: "Edit position",
|
|
66
|
+
wpOpacity: "Wallpaper opacity",
|
|
67
|
+
bgBlur: "Wallpaper blur",
|
|
68
|
+
bgHint: "Drag sliders for real-time adjustment. Click the image to open the editor",
|
|
69
|
+
editorTitle: "Background editor",
|
|
70
|
+
editorHint: "Drag to move, scroll to zoom",
|
|
71
|
+
editorCommit: "Confirm",
|
|
72
|
+
editorCancel: "Cancel",
|
|
73
|
+
editorReset: "Reset"
|
|
74
|
+
};
|
|
75
|
+
function rLS(k) {
|
|
76
|
+
try {
|
|
77
|
+
const v = localStorage.getItem(k);
|
|
78
|
+
return typeof v === "string" ? v : null;
|
|
79
|
+
} catch {
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
function wLS(k, v) {
|
|
84
|
+
try {
|
|
85
|
+
v === null ? localStorage.removeItem(k) : localStorage.setItem(k, v);
|
|
86
|
+
} catch (e) {
|
|
87
|
+
console.warn(`dsh-any-background: localStorage write failed for "${k}"`, e);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
function rColor() {
|
|
91
|
+
try {
|
|
92
|
+
const v = JSON.parse(rLS(LS_COLOR) || "");
|
|
93
|
+
if (Array.isArray(v) && v.length === 3) return v;
|
|
94
|
+
} catch {}
|
|
95
|
+
return [
|
|
96
|
+
220,
|
|
97
|
+
.55,
|
|
98
|
+
.25
|
|
99
|
+
];
|
|
100
|
+
}
|
|
101
|
+
function rWp() {
|
|
102
|
+
const v = rLS(LS_WP);
|
|
103
|
+
return v?.length ? v : null;
|
|
104
|
+
}
|
|
105
|
+
function rOp() {
|
|
106
|
+
const v = rLS(LS_OP);
|
|
107
|
+
if (!v) return DEF_OP;
|
|
108
|
+
const n = +v;
|
|
109
|
+
return isFinite(n) ? Math.min(1, Math.max(0, n)) : DEF_OP;
|
|
110
|
+
}
|
|
111
|
+
function rWop() {
|
|
112
|
+
const v = rLS(LS_WOP);
|
|
113
|
+
if (!v) return 1;
|
|
114
|
+
const n = +v;
|
|
115
|
+
return isFinite(n) ? Math.min(1, Math.max(0, n)) : 1;
|
|
116
|
+
}
|
|
117
|
+
function rBl() {
|
|
118
|
+
const v = rLS(LS_BL);
|
|
119
|
+
if (!v) return DEF_BL;
|
|
120
|
+
const n = +v;
|
|
121
|
+
return isFinite(n) ? Math.min(60, Math.max(0, n)) : DEF_BL;
|
|
122
|
+
}
|
|
123
|
+
function rSop() {
|
|
124
|
+
const v = rLS(LS_SOP);
|
|
125
|
+
if (!v) return DEF_SOP;
|
|
126
|
+
const n = +v;
|
|
127
|
+
return isFinite(n) ? Math.min(1, Math.max(0, n)) : DEF_SOP;
|
|
128
|
+
}
|
|
129
|
+
function rBgState() {
|
|
130
|
+
try {
|
|
131
|
+
const v = JSON.parse(rLS(LS_BG) || "");
|
|
132
|
+
if (v && typeof v.zoom === "number" && typeof v.iw === "number" && v.iw > 0 && v.ih > 0) return v;
|
|
133
|
+
} catch {}
|
|
134
|
+
return {
|
|
135
|
+
zoom: 1,
|
|
136
|
+
x: 0,
|
|
137
|
+
y: 0,
|
|
138
|
+
iw: 0,
|
|
139
|
+
ih: 0
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
function hsvToHsl(h, s, v) {
|
|
143
|
+
const l = v * (1 - s / 2);
|
|
144
|
+
return [
|
|
145
|
+
h,
|
|
146
|
+
l === 0 || l === 1 ? 0 : (v - l) / Math.min(l, 1 - l),
|
|
147
|
+
l
|
|
148
|
+
];
|
|
149
|
+
}
|
|
150
|
+
function hslToHsv(h, s, l) {
|
|
151
|
+
const v = l + s * Math.min(l, 1 - l);
|
|
152
|
+
return [
|
|
153
|
+
h,
|
|
154
|
+
v === 0 ? 0 : 2 * (1 - l / v),
|
|
155
|
+
v
|
|
156
|
+
];
|
|
157
|
+
}
|
|
158
|
+
function genTokens(hue, sat, lit) {
|
|
159
|
+
const dark = lit < .55;
|
|
160
|
+
const h = (d) => ((hue + d) % 360 + 360) % 360;
|
|
161
|
+
const s = (d) => Math.max(0, Math.min(1, sat + d));
|
|
162
|
+
const l = (d) => Math.max(0, Math.min(1, lit + d));
|
|
163
|
+
const hsl = (hh, ss, ll) => `hsl(${Math.round(hh)},${Math.round(ss * 100)}%,${Math.round(ll * 100)}%)`;
|
|
164
|
+
const rgba = (hh, ss, ll, a) => {
|
|
165
|
+
`${Math.round(hh)}${Math.round(ss * 100)}${Math.round(ll * 100)}`;
|
|
166
|
+
return `hsla(${Math.round(hh)},${Math.round(ss * 100)}%,${Math.round(ll * 100)}%,${a})`;
|
|
167
|
+
};
|
|
168
|
+
if (dark) return {
|
|
169
|
+
colorScheme: "dark",
|
|
170
|
+
tokens: {
|
|
171
|
+
"--dsw-alias-bg-base": hsl(h(0), s(0), l(-.04)),
|
|
172
|
+
"--dsw-alias-bg-layer-1": hsl(h(0), s(0), l(.02)),
|
|
173
|
+
"--dsw-alias-bg-layer-2": hsl(h(0), s(0), l(.07)),
|
|
174
|
+
"--dsw-alias-bg-layer-3": hsl(h(0), s(-.05), l(.12)),
|
|
175
|
+
"--dsw-alias-bg-overlay": hsl(h(0), s(-.05), l(.12)),
|
|
176
|
+
"--dsw-alias-border-l1": rgba(h(0), s(-.1), l(.18), .12),
|
|
177
|
+
"--dsw-alias-border-l2": rgba(h(0), s(-.1), l(.22), .22),
|
|
178
|
+
"--dsw-alias-label-primary": hsl(0, 0, 1),
|
|
179
|
+
"--dsw-alias-label-secondary": hsl(0, 0, 1),
|
|
180
|
+
"--dsw-alias-label-tertiary": hsl(0, 0, 1),
|
|
181
|
+
"--dsw-alias-brand-primary": hsl(h(0), s(.1), Math.max(l(.2), .5)),
|
|
182
|
+
"--dsw-alias-brand-text": l(.2) > .6 ? "#000" : "#fff",
|
|
183
|
+
"--dsw-alias-button-primary-hover": hsl(h(0), s(.1), Math.max(l(.28), .58)),
|
|
184
|
+
"--dsw-alias-button-primary-dimmed": hsl(h(0), s(0), l(.07)),
|
|
185
|
+
"--dsw-alias-button-elevated-fill": hsl(h(0), s(0), l(.04)),
|
|
186
|
+
"--dsw-alias-interactive-bg-hover": rgba(h(0), s(0), Math.max(l(.15), .4), .12),
|
|
187
|
+
"--dsw-alias-interactive-bg-active": rgba(h(0), s(0), Math.max(l(.15), .4), .2),
|
|
188
|
+
"--dsw-alias-markdown-code-block": hsl(h(0), s(0), l(-.06)),
|
|
189
|
+
"--dsw-alias-markdown-inline-code": hsl(h(0), s(0), l(.04)),
|
|
190
|
+
"--dsw-alias-state-error-primary": "#ff5c72",
|
|
191
|
+
"--dsw-alias-state-success-primary": "#3ddc84",
|
|
192
|
+
"--dsw-alias-state-warn-primary": "#ffb347",
|
|
193
|
+
"--dsw-specific-sidebar-fill": hsl(h(0), s(0), l(-.06)),
|
|
194
|
+
"--dsw-specific-sidebar-nav-item-active": hsl(h(0), s(0), l(.04)),
|
|
195
|
+
"--dsw-specific-sidebar-nav-item-hover": hsl(h(0), s(0), l(0)),
|
|
196
|
+
"--dsw-specific-input-major": hsl(h(0), s(0), l(.02)),
|
|
197
|
+
"--dsw-alias-scrollbar-bg-l1": hsl(h(0), s(-.05), l(.12)),
|
|
198
|
+
"--dsw-alias-scrollbar-bg-l2": hsl(h(0), s(-.05), l(.16)),
|
|
199
|
+
"--dsw-alias-scrollbar-hover-l1": hsl(h(0), s(-.05), l(.22)),
|
|
200
|
+
"--dsw-alias-scrollbar-hover-l2": hsl(h(0), s(-.05), l(.22))
|
|
201
|
+
}
|
|
202
|
+
};
|
|
203
|
+
return {
|
|
204
|
+
colorScheme: "light",
|
|
205
|
+
tokens: {
|
|
206
|
+
"--dsw-alias-bg-base": hsl(h(0), s(-.08), l(.03)),
|
|
207
|
+
"--dsw-alias-bg-layer-1": hsl(h(0), s(-.12), l(.07)),
|
|
208
|
+
"--dsw-alias-bg-layer-2": hsl(h(0), s(-.1), l(-.03)),
|
|
209
|
+
"--dsw-alias-bg-layer-3": hsl(h(0), s(-.08), l(-.09)),
|
|
210
|
+
"--dsw-alias-bg-overlay": hsl(h(0), s(-.12), l(.08)),
|
|
211
|
+
"--dsw-alias-border-l1": rgba(h(0), s(-.15), l(-.35), .18),
|
|
212
|
+
"--dsw-alias-border-l2": rgba(h(0), s(-.15), l(-.35), .3),
|
|
213
|
+
"--dsw-alias-label-primary": hsl(0, 0, 0),
|
|
214
|
+
"--dsw-alias-label-secondary": hsl(0, 0, 0),
|
|
215
|
+
"--dsw-alias-label-tertiary": hsl(0, 0, 0),
|
|
216
|
+
"--dsw-alias-brand-primary": hsl(h(0), s(.05), Math.min(l(-.18), .45)),
|
|
217
|
+
"--dsw-alias-brand-text": "#fff",
|
|
218
|
+
"--dsw-alias-button-primary-hover": hsl(h(0), s(.05), Math.min(l(-.12), .5)),
|
|
219
|
+
"--dsw-alias-button-primary-dimmed": hsl(h(0), s(-.1), l(-.03)),
|
|
220
|
+
"--dsw-alias-button-elevated-fill": hsl(h(0), s(-.1), l(.1)),
|
|
221
|
+
"--dsw-alias-interactive-bg-hover": rgba(h(0), s(0), l(-.3), .08),
|
|
222
|
+
"--dsw-alias-interactive-bg-active": rgba(h(0), s(0), l(-.3), .14),
|
|
223
|
+
"--dsw-alias-markdown-code-block": hsl(h(0), s(-.1), l(-.03)),
|
|
224
|
+
"--dsw-alias-markdown-inline-code": hsl(h(0), s(-.08), l(.04)),
|
|
225
|
+
"--dsw-specific-sidebar-fill": hsl(h(0), s(-.1), l(-.03)),
|
|
226
|
+
"--dsw-specific-sidebar-nav-item-active": hsl(h(0), s(-.08), l(.05)),
|
|
227
|
+
"--dsw-specific-sidebar-nav-item-hover": hsl(h(0), s(-.12), l(0)),
|
|
228
|
+
"--dsw-specific-input-major": hsl(h(0), s(-.12), l(.1)),
|
|
229
|
+
"--dsw-alias-scrollbar-bg-l1": hsl(h(0), s(-.1), l(-.08)),
|
|
230
|
+
"--dsw-alias-scrollbar-bg-l2": hsl(h(0), s(-.08), l(-.12)),
|
|
231
|
+
"--dsw-alias-scrollbar-hover-l1": hsl(h(0), s(-.08), l(-.16)),
|
|
232
|
+
"--dsw-alias-scrollbar-hover-l2": hsl(h(0), s(-.08), l(-.16))
|
|
233
|
+
}
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
let wpEl = null;
|
|
237
|
+
let ctxRef = null;
|
|
238
|
+
function toRgba(c, a) {
|
|
239
|
+
const hx = /^#([0-9a-f]{3}|[0-9a-f]{6})$/i.exec(c.trim());
|
|
240
|
+
if (hx) {
|
|
241
|
+
let d = hx[1];
|
|
242
|
+
if (d.length === 3) d = d.split("").map((x) => x + x).join("");
|
|
243
|
+
const n = parseInt(d, 16);
|
|
244
|
+
return `rgba(${n >> 16 & 255},${n >> 8 & 255},${n & 255},${a})`;
|
|
245
|
+
}
|
|
246
|
+
const rgb = /^rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)(?:\s*,\s*([\d.]+))?\s*\)$/i.exec(c.trim());
|
|
247
|
+
if (rgb) return `rgba(${rgb[1]},${rgb[2]},${rgb[3]},${a})`;
|
|
248
|
+
const hsl = /^hsla?\(\s*([\d.]+)\s*,\s*([\d.]+)%\s*,\s*([\d.]+)%/i.exec(c.trim());
|
|
249
|
+
if (hsl) return `hsla(${hsl[1]},${hsl[2]}%,${hsl[3]}%,${a})`;
|
|
250
|
+
return c.trim();
|
|
251
|
+
}
|
|
252
|
+
let appliedTokenNames = [];
|
|
253
|
+
/** Remove every inline token this plugin wrote (teardown symmetry). */
|
|
254
|
+
function clearCustomTokens() {
|
|
255
|
+
for (const name of appliedTokenNames) document.body.style.removeProperty(name);
|
|
256
|
+
appliedTokenNames = [];
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Write the saved color's full token set as inline variables on body — the
|
|
260
|
+
* same write surface the theme presenter owns, but derived DIRECTLY from the
|
|
261
|
+
* saved pick, so the theme color never depends on the theme service's active
|
|
262
|
+
* state or the presenter's timing. The bg-base and sidebar tokens are
|
|
263
|
+
* re-emitted at the requested alpha; every other token (layers, labels,
|
|
264
|
+
* borders, brand) is written verbatim. No reads: nothing can observe a stale
|
|
265
|
+
* or reset theme value and leave the homepage on the system color.
|
|
266
|
+
*/
|
|
267
|
+
function applyCustomTokens(op) {
|
|
268
|
+
const [h, s, l] = rColor();
|
|
269
|
+
const { tokens } = genTokens(h, s, l);
|
|
270
|
+
const sideOp = Math.min(1, op + .08);
|
|
271
|
+
clearCustomTokens();
|
|
272
|
+
if (l < .55) document.body.setAttribute("data-ds-dark-theme", "");
|
|
273
|
+
else document.body.removeAttribute("data-ds-dark-theme");
|
|
274
|
+
for (const [name, value] of Object.entries(tokens)) {
|
|
275
|
+
let v = value;
|
|
276
|
+
if (name === "--dsw-alias-bg-base") v = toRgba(value, op);
|
|
277
|
+
else if (name === "--dsw-specific-sidebar-fill") v = toRgba(value, sideOp);
|
|
278
|
+
document.body.style.setProperty(name, v);
|
|
279
|
+
appliedTokenNames.push(name);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
const SETTINGS_STYLE_RULE = `[role="dialog"][aria-modal="true"][aria-labelledby]{background:var(--dsh-any-bg-settings-surface,var(--dsw-alias-bg-layer-2))}`;
|
|
283
|
+
function applySettingsOverrides(op) {
|
|
284
|
+
if (op >= 1) {
|
|
285
|
+
document.documentElement.style.removeProperty("--dsh-any-bg-settings-surface");
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
288
|
+
const [h, s, l] = rColor();
|
|
289
|
+
const layer2 = genTokens(h, s, l).tokens["--dsw-alias-bg-layer-2"];
|
|
290
|
+
if (layer2 !== void 0) document.documentElement.style.setProperty("--dsh-any-bg-settings-surface", toRgba(layer2, op));
|
|
291
|
+
}
|
|
292
|
+
function applyWp(ctx) {
|
|
293
|
+
const url = rWp();
|
|
294
|
+
if (!url) {
|
|
295
|
+
wpEl?.remove();
|
|
296
|
+
wpEl = null;
|
|
297
|
+
} else {
|
|
298
|
+
if (!wpEl || !document.body.contains(wpEl)) {
|
|
299
|
+
wpEl = document.createElement("div");
|
|
300
|
+
wpEl.style.cssText = "position:fixed;inset:0;z-index:-1;pointer-events:none;background-repeat:no-repeat;";
|
|
301
|
+
document.body.prepend(wpEl);
|
|
302
|
+
}
|
|
303
|
+
const bg = rBgState();
|
|
304
|
+
wpEl.style.backgroundImage = `url("${url}")`;
|
|
305
|
+
if (bg.iw > 0) {
|
|
306
|
+
const fit = Math.min(window.innerWidth / bg.iw, window.innerHeight / bg.ih);
|
|
307
|
+
const w = bg.iw * fit * bg.zoom;
|
|
308
|
+
const h = bg.ih * fit * bg.zoom;
|
|
309
|
+
wpEl.style.backgroundSize = `${w}px ${h}px`;
|
|
310
|
+
wpEl.style.backgroundPosition = `${bg.x * window.innerWidth - w / 2}px ${bg.y * window.innerHeight - h / 2}px`;
|
|
311
|
+
} else {
|
|
312
|
+
wpEl.style.backgroundSize = "contain";
|
|
313
|
+
wpEl.style.backgroundPosition = "center";
|
|
314
|
+
}
|
|
315
|
+
const blur = rBl();
|
|
316
|
+
wpEl.style.filter = blur > 0 ? `blur(${blur}px)` : "none";
|
|
317
|
+
wpEl.style.opacity = String(rWop());
|
|
318
|
+
}
|
|
319
|
+
applyCustomTokens(rOp());
|
|
320
|
+
applySettingsOverrides(rSop());
|
|
321
|
+
}
|
|
322
|
+
function teardownWp() {
|
|
323
|
+
wpEl?.remove();
|
|
324
|
+
wpEl = null;
|
|
325
|
+
clearCustomTokens();
|
|
326
|
+
document.documentElement.style.removeProperty("--dsh-any-bg-settings-surface");
|
|
327
|
+
}
|
|
328
|
+
const WHEEL_SIZE = 220;
|
|
329
|
+
const CX = WHEEL_SIZE / 2;
|
|
330
|
+
const RING_OUTER = 106;
|
|
331
|
+
const RING_INNER = 82;
|
|
332
|
+
const SQ_HALF = Math.round(RING_INNER / Math.SQRT2);
|
|
333
|
+
function drawWheel(cvs, hue, sat, lit) {
|
|
334
|
+
const c = cvs.getContext("2d");
|
|
335
|
+
c.clearRect(0, 0, WHEEL_SIZE, WHEEL_SIZE);
|
|
336
|
+
for (let a = 0; a < 360; a++) {
|
|
337
|
+
const r1 = (a - 90) * Math.PI / 180;
|
|
338
|
+
const r2 = (a + 1.5 - 90) * Math.PI / 180;
|
|
339
|
+
c.beginPath();
|
|
340
|
+
c.arc(CX, CX, RING_OUTER, r1, r2);
|
|
341
|
+
c.arc(CX, CX, RING_INNER, r2, r1, true);
|
|
342
|
+
c.closePath();
|
|
343
|
+
c.fillStyle = `hsl(${a},100%,50%)`;
|
|
344
|
+
c.fill();
|
|
345
|
+
}
|
|
346
|
+
const gx = CX - SQ_HALF, gy = CX - SQ_HALF, sz = SQ_HALF * 2;
|
|
347
|
+
c.fillStyle = "#fff";
|
|
348
|
+
c.fillRect(gx, gy, sz, sz);
|
|
349
|
+
const gh = c.createLinearGradient(gx, 0, gx + sz, 0);
|
|
350
|
+
gh.addColorStop(0, "rgba(255,255,255,1)");
|
|
351
|
+
gh.addColorStop(1, `hsl(${hue},100%,50%)`);
|
|
352
|
+
c.fillStyle = gh;
|
|
353
|
+
c.fillRect(gx, gy, sz, sz);
|
|
354
|
+
const gv = c.createLinearGradient(0, gy, 0, gy + sz);
|
|
355
|
+
gv.addColorStop(0, "rgba(0,0,0,0)");
|
|
356
|
+
gv.addColorStop(1, "rgba(0,0,0,1)");
|
|
357
|
+
c.fillStyle = gv;
|
|
358
|
+
c.fillRect(gx, gy, sz, sz);
|
|
359
|
+
const hRad = (hue - 90) * Math.PI / 180;
|
|
360
|
+
const hR = 188 / 2;
|
|
361
|
+
const hmx = CX + Math.cos(hRad) * hR, hmy = CX + Math.sin(hRad) * hR;
|
|
362
|
+
c.beginPath();
|
|
363
|
+
c.arc(hmx, hmy, 8, 0, Math.PI * 2);
|
|
364
|
+
c.fillStyle = "rgba(0,0,0,0.25)";
|
|
365
|
+
c.fill();
|
|
366
|
+
c.beginPath();
|
|
367
|
+
c.arc(hmx, hmy, 6.5, 0, Math.PI * 2);
|
|
368
|
+
c.strokeStyle = "#fff";
|
|
369
|
+
c.lineWidth = 2;
|
|
370
|
+
c.stroke();
|
|
371
|
+
const smx = gx + sat * sz, smy = gy + (1 - lit) * sz;
|
|
372
|
+
c.beginPath();
|
|
373
|
+
c.arc(smx, smy, 7, 0, Math.PI * 2);
|
|
374
|
+
c.fillStyle = "rgba(0,0,0,0.25)";
|
|
375
|
+
c.fill();
|
|
376
|
+
c.beginPath();
|
|
377
|
+
c.arc(smx, smy, 5.5, 0, Math.PI * 2);
|
|
378
|
+
c.strokeStyle = "#fff";
|
|
379
|
+
c.lineWidth = 2;
|
|
380
|
+
c.stroke();
|
|
381
|
+
c.beginPath();
|
|
382
|
+
c.arc(smx, smy, 3.5, 0, Math.PI * 2);
|
|
383
|
+
c.strokeStyle = "#000";
|
|
384
|
+
c.lineWidth = 1;
|
|
385
|
+
c.stroke();
|
|
386
|
+
}
|
|
387
|
+
function hitTest(x, y) {
|
|
388
|
+
if (Math.abs(x - CX) <= SQ_HALF && Math.abs(y - CX) <= SQ_HALF) return "square";
|
|
389
|
+
const dx = x - CX, dy = y - CX;
|
|
390
|
+
const dist = Math.sqrt(dx * dx + dy * dy);
|
|
391
|
+
if (dist >= RING_INNER - 4 && dist <= 110) return "ring";
|
|
392
|
+
return null;
|
|
393
|
+
}
|
|
394
|
+
function pickHue(x, y) {
|
|
395
|
+
let angle = Math.atan2(y - CX, x - CX) * 180 / Math.PI + 90;
|
|
396
|
+
if (angle < 0) angle += 360;
|
|
397
|
+
return angle;
|
|
398
|
+
}
|
|
399
|
+
function pickSL(x, y) {
|
|
400
|
+
const gx = CX - SQ_HALF, gy = CX - SQ_HALF, sz = SQ_HALF * 2;
|
|
401
|
+
return [Math.max(0, Math.min(1, (x - gx) / sz)), Math.max(.02, Math.min(.98, 1 - (y - gy) / sz))];
|
|
402
|
+
}
|
|
403
|
+
function ColorWheel({ hue, sat, lit, onChange }) {
|
|
404
|
+
const cvsRef = (0, react.useRef)(null);
|
|
405
|
+
const [col, setCol] = (0, react.useState)({
|
|
406
|
+
hue,
|
|
407
|
+
sat,
|
|
408
|
+
lit
|
|
409
|
+
});
|
|
410
|
+
const colRef = (0, react.useRef)(col);
|
|
411
|
+
colRef.current = col;
|
|
412
|
+
(0, react.useEffect)(() => {
|
|
413
|
+
setCol((c) => c.hue === hue && c.sat === sat && c.lit === lit ? c : {
|
|
414
|
+
hue,
|
|
415
|
+
sat,
|
|
416
|
+
lit
|
|
417
|
+
});
|
|
418
|
+
}, [
|
|
419
|
+
hue,
|
|
420
|
+
sat,
|
|
421
|
+
lit
|
|
422
|
+
]);
|
|
423
|
+
(0, react.useEffect)(() => {
|
|
424
|
+
if (cvsRef.current) drawWheel(cvsRef.current, col.hue, col.sat, col.lit);
|
|
425
|
+
}, [col]);
|
|
426
|
+
const apply = (0, react.useCallback)((nh, ns, nl) => {
|
|
427
|
+
setCol({
|
|
428
|
+
hue: nh,
|
|
429
|
+
sat: ns,
|
|
430
|
+
lit: nl
|
|
431
|
+
});
|
|
432
|
+
onChange(nh, ns, nl);
|
|
433
|
+
}, [onChange]);
|
|
434
|
+
const onDown = (0, react.useCallback)((e) => {
|
|
435
|
+
const r = cvsRef.current.getBoundingClientRect();
|
|
436
|
+
const x = e.clientX - r.left, y = e.clientY - r.top;
|
|
437
|
+
const region = hitTest(x, y);
|
|
438
|
+
if (!region) return;
|
|
439
|
+
if (region === "ring") apply(pickHue(x, y), colRef.current.sat, colRef.current.lit);
|
|
440
|
+
else {
|
|
441
|
+
const [s, l] = pickSL(x, y);
|
|
442
|
+
apply(colRef.current.hue, s, l);
|
|
443
|
+
}
|
|
444
|
+
const onMove = (ev) => {
|
|
445
|
+
const rr = cvsRef.current.getBoundingClientRect();
|
|
446
|
+
const mx = ev.clientX - rr.left, my = ev.clientY - rr.top;
|
|
447
|
+
if (region === "ring") {
|
|
448
|
+
const d = Math.sqrt((mx - CX) ** 2 + (my - CX) ** 2);
|
|
449
|
+
if (d >= RING_INNER - 10 && d <= 116) apply(pickHue(mx, my), colRef.current.sat, colRef.current.lit);
|
|
450
|
+
} else {
|
|
451
|
+
const [s, l] = pickSL(mx, my);
|
|
452
|
+
apply(colRef.current.hue, s, l);
|
|
453
|
+
}
|
|
454
|
+
};
|
|
455
|
+
const onUp = () => {
|
|
456
|
+
document.removeEventListener("mousemove", onMove);
|
|
457
|
+
document.removeEventListener("mouseup", onUp);
|
|
458
|
+
};
|
|
459
|
+
document.addEventListener("mousemove", onMove);
|
|
460
|
+
document.addEventListener("mouseup", onUp);
|
|
461
|
+
}, [apply]);
|
|
462
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("canvas", {
|
|
463
|
+
ref: cvsRef,
|
|
464
|
+
width: WHEEL_SIZE,
|
|
465
|
+
height: WHEEL_SIZE,
|
|
466
|
+
style: ST.wheelCanvas,
|
|
467
|
+
onMouseDown: onDown
|
|
468
|
+
});
|
|
469
|
+
}
|
|
470
|
+
function compress(img, side, q) {
|
|
471
|
+
const s = Math.min(1, side / Math.max(img.width, img.height));
|
|
472
|
+
const c = document.createElement("canvas");
|
|
473
|
+
c.width = Math.max(1, Math.round(img.width * s));
|
|
474
|
+
c.height = Math.max(1, Math.round(img.height * s));
|
|
475
|
+
c.getContext("2d").drawImage(img, 0, 0, c.width, c.height);
|
|
476
|
+
return c.toDataURL("image/jpeg", q);
|
|
477
|
+
}
|
|
478
|
+
function readImg(file, cb) {
|
|
479
|
+
const r = new FileReader();
|
|
480
|
+
r.onerror = () => cb(null);
|
|
481
|
+
r.onload = () => {
|
|
482
|
+
const img = new Image();
|
|
483
|
+
img.onerror = () => cb(null);
|
|
484
|
+
img.onload = () => {
|
|
485
|
+
try {
|
|
486
|
+
let u = compress(img, 1600, .75);
|
|
487
|
+
if (u.length > 2e6) u = compress(img, 1e3, .6);
|
|
488
|
+
if (u.length > 2e6) u = compress(img, 800, .5);
|
|
489
|
+
cb(u);
|
|
490
|
+
} catch {
|
|
491
|
+
cb(null);
|
|
492
|
+
}
|
|
493
|
+
};
|
|
494
|
+
img.src = r.result;
|
|
495
|
+
};
|
|
496
|
+
r.readAsDataURL(file);
|
|
497
|
+
}
|
|
498
|
+
const ST = {
|
|
499
|
+
root: {
|
|
500
|
+
display: "flex",
|
|
501
|
+
flexDirection: "column",
|
|
502
|
+
gap: "20px",
|
|
503
|
+
padding: "4px 0",
|
|
504
|
+
maxWidth: "640px"
|
|
505
|
+
},
|
|
506
|
+
h2: {
|
|
507
|
+
color: "var(--dsw-alias-label-primary)",
|
|
508
|
+
fontSize: "18px",
|
|
509
|
+
fontWeight: 600,
|
|
510
|
+
margin: 0
|
|
511
|
+
},
|
|
512
|
+
sub: {
|
|
513
|
+
color: "var(--dsw-alias-label-tertiary)",
|
|
514
|
+
fontSize: "13px"
|
|
515
|
+
},
|
|
516
|
+
hr: {
|
|
517
|
+
height: "1px",
|
|
518
|
+
background: "var(--dsw-alias-border-l2)",
|
|
519
|
+
border: "none",
|
|
520
|
+
margin: "4px 0"
|
|
521
|
+
},
|
|
522
|
+
label: {
|
|
523
|
+
color: "var(--dsw-alias-label-primary)",
|
|
524
|
+
fontSize: "16px",
|
|
525
|
+
fontWeight: 600,
|
|
526
|
+
marginBottom: "8px"
|
|
527
|
+
},
|
|
528
|
+
hint: {
|
|
529
|
+
color: "var(--dsw-alias-label-tertiary)",
|
|
530
|
+
fontSize: "12px",
|
|
531
|
+
lineHeight: "18px",
|
|
532
|
+
marginTop: "4px"
|
|
533
|
+
},
|
|
534
|
+
colorHint: {
|
|
535
|
+
color: "var(--dsw-alias-label-tertiary)",
|
|
536
|
+
fontSize: "12px",
|
|
537
|
+
lineHeight: "18px",
|
|
538
|
+
marginTop: "7px",
|
|
539
|
+
textAlign: "center"
|
|
540
|
+
},
|
|
541
|
+
wheelCanvas: {
|
|
542
|
+
cursor: "crosshair",
|
|
543
|
+
borderRadius: "50%"
|
|
544
|
+
},
|
|
545
|
+
center: {
|
|
546
|
+
display: "flex",
|
|
547
|
+
justifyContent: "center"
|
|
548
|
+
},
|
|
549
|
+
btnGroup: {
|
|
550
|
+
display: "flex",
|
|
551
|
+
justifyContent: "center",
|
|
552
|
+
marginTop: "10px"
|
|
553
|
+
},
|
|
554
|
+
row: {
|
|
555
|
+
display: "flex",
|
|
556
|
+
alignItems: "center",
|
|
557
|
+
gap: "10px",
|
|
558
|
+
flexWrap: "wrap"
|
|
559
|
+
},
|
|
560
|
+
sliderBlock: {
|
|
561
|
+
display: "flex",
|
|
562
|
+
flexDirection: "column",
|
|
563
|
+
gap: "4px"
|
|
564
|
+
},
|
|
565
|
+
sliderRow: {
|
|
566
|
+
display: "flex",
|
|
567
|
+
alignItems: "center",
|
|
568
|
+
gap: "10px"
|
|
569
|
+
},
|
|
570
|
+
sliderLabel: {
|
|
571
|
+
color: "var(--dsw-alias-label-secondary)",
|
|
572
|
+
fontSize: "13px"
|
|
573
|
+
},
|
|
574
|
+
smallHint: {
|
|
575
|
+
color: "var(--dsw-alias-label-tertiary)",
|
|
576
|
+
fontSize: "11px",
|
|
577
|
+
lineHeight: "16px"
|
|
578
|
+
},
|
|
579
|
+
slider: {
|
|
580
|
+
flex: 1,
|
|
581
|
+
accentColor: "var(--dsw-alias-brand-primary)",
|
|
582
|
+
minWidth: "160px"
|
|
583
|
+
},
|
|
584
|
+
sliderVal: {
|
|
585
|
+
color: "var(--dsw-alias-label-secondary)",
|
|
586
|
+
fontSize: "12px",
|
|
587
|
+
whiteSpace: "nowrap",
|
|
588
|
+
width: "44px",
|
|
589
|
+
textAlign: "right"
|
|
590
|
+
},
|
|
591
|
+
btn: {
|
|
592
|
+
height: "32px",
|
|
593
|
+
padding: "0 14px",
|
|
594
|
+
borderRadius: "8px",
|
|
595
|
+
border: "1px solid var(--dsw-alias-border-l2)",
|
|
596
|
+
background: "var(--dsw-alias-button-elevated-fill)",
|
|
597
|
+
color: "var(--dsw-alias-label-primary)",
|
|
598
|
+
cursor: "pointer",
|
|
599
|
+
fontSize: "13px",
|
|
600
|
+
font: "inherit",
|
|
601
|
+
boxSizing: "border-box"
|
|
602
|
+
},
|
|
603
|
+
btnDanger: { color: "var(--dsw-alias-state-error-primary)" },
|
|
604
|
+
btnPrimary: {
|
|
605
|
+
background: "var(--dsw-alias-brand-primary)",
|
|
606
|
+
color: "var(--dsw-alias-brand-text)",
|
|
607
|
+
border: "none"
|
|
608
|
+
},
|
|
609
|
+
preview: {
|
|
610
|
+
width: "368px",
|
|
611
|
+
height: "225px",
|
|
612
|
+
objectFit: "cover",
|
|
613
|
+
borderRadius: "6px",
|
|
614
|
+
border: "1px solid var(--dsw-alias-border-l2)",
|
|
615
|
+
cursor: "pointer"
|
|
616
|
+
},
|
|
617
|
+
sliders: {
|
|
618
|
+
display: "flex",
|
|
619
|
+
flexDirection: "column",
|
|
620
|
+
gap: "12px",
|
|
621
|
+
marginTop: "8px"
|
|
622
|
+
},
|
|
623
|
+
overlay: {
|
|
624
|
+
position: "fixed",
|
|
625
|
+
inset: 0,
|
|
626
|
+
zIndex: 9999,
|
|
627
|
+
background: "rgba(0,0,0,0.7)",
|
|
628
|
+
display: "flex",
|
|
629
|
+
flexDirection: "column",
|
|
630
|
+
alignItems: "center",
|
|
631
|
+
justifyContent: "center",
|
|
632
|
+
gap: "12px"
|
|
633
|
+
},
|
|
634
|
+
modalTitle: {
|
|
635
|
+
color: "#fff",
|
|
636
|
+
fontSize: "16px",
|
|
637
|
+
fontWeight: 500
|
|
638
|
+
},
|
|
639
|
+
modalHint: {
|
|
640
|
+
color: "rgba(255,255,255,0.6)",
|
|
641
|
+
fontSize: "12px"
|
|
642
|
+
},
|
|
643
|
+
previewRect: {
|
|
644
|
+
position: "relative",
|
|
645
|
+
overflow: "hidden",
|
|
646
|
+
border: "2px solid rgba(255,255,255,0.3)",
|
|
647
|
+
borderRadius: "8px",
|
|
648
|
+
background: "#000",
|
|
649
|
+
cursor: "grab"
|
|
650
|
+
},
|
|
651
|
+
previewImg: {
|
|
652
|
+
position: "absolute",
|
|
653
|
+
transformOrigin: "0 0",
|
|
654
|
+
pointerEvents: "none"
|
|
655
|
+
},
|
|
656
|
+
modalBtns: {
|
|
657
|
+
display: "flex",
|
|
658
|
+
gap: "10px"
|
|
659
|
+
}
|
|
660
|
+
};
|
|
661
|
+
function BgEditor({ url, t, onClose, onCommit }) {
|
|
662
|
+
const pw = Math.min(window.innerWidth * .75, 860);
|
|
663
|
+
const ph = Math.round(pw * window.innerHeight / window.innerWidth);
|
|
664
|
+
const saved = rBgState();
|
|
665
|
+
const [zoom, setZoom] = (0, react.useState)(saved.iw > 0 ? saved.zoom : 1);
|
|
666
|
+
const [pos, setPos] = (0, react.useState)(saved.iw > 0 ? {
|
|
667
|
+
x: saved.x * pw,
|
|
668
|
+
y: saved.y * ph
|
|
669
|
+
} : {
|
|
670
|
+
x: 0,
|
|
671
|
+
y: 0
|
|
672
|
+
});
|
|
673
|
+
const [imgSize, setImgSize] = (0, react.useState)({
|
|
674
|
+
w: 0,
|
|
675
|
+
h: 0
|
|
676
|
+
});
|
|
677
|
+
const containerRef = (0, react.useRef)(null);
|
|
678
|
+
const imgRef = (0, react.useRef)(null);
|
|
679
|
+
const dragRef = (0, react.useRef)({
|
|
680
|
+
active: false,
|
|
681
|
+
sx: 0,
|
|
682
|
+
sy: 0,
|
|
683
|
+
spx: 0,
|
|
684
|
+
spy: 0
|
|
685
|
+
});
|
|
686
|
+
(0, react.useEffect)(() => {
|
|
687
|
+
const img = new Image();
|
|
688
|
+
img.onload = () => {
|
|
689
|
+
const scale = Math.min(pw / img.width, ph / img.height);
|
|
690
|
+
const w = img.width * scale, h = img.height * scale;
|
|
691
|
+
setImgSize({
|
|
692
|
+
w,
|
|
693
|
+
h
|
|
694
|
+
});
|
|
695
|
+
const s = rBgState();
|
|
696
|
+
if (s.iw > 0 && s.iw === img.width && s.ih === img.height) {
|
|
697
|
+
setZoom(s.zoom);
|
|
698
|
+
setPos({
|
|
699
|
+
x: s.x * pw - w * s.zoom / 2,
|
|
700
|
+
y: s.y * ph - h * s.zoom / 2
|
|
701
|
+
});
|
|
702
|
+
} else {
|
|
703
|
+
setZoom(1);
|
|
704
|
+
setPos({
|
|
705
|
+
x: (pw - w) / 2,
|
|
706
|
+
y: (ph - h) / 2
|
|
707
|
+
});
|
|
708
|
+
}
|
|
709
|
+
};
|
|
710
|
+
img.src = url;
|
|
711
|
+
}, [
|
|
712
|
+
url,
|
|
713
|
+
pw,
|
|
714
|
+
ph
|
|
715
|
+
]);
|
|
716
|
+
const onDown = (0, react.useCallback)((e) => {
|
|
717
|
+
e.preventDefault();
|
|
718
|
+
dragRef.current = {
|
|
719
|
+
active: true,
|
|
720
|
+
sx: e.clientX,
|
|
721
|
+
sy: e.clientY,
|
|
722
|
+
spx: pos.x,
|
|
723
|
+
spy: pos.y
|
|
724
|
+
};
|
|
725
|
+
const onMove = (ev) => {
|
|
726
|
+
if (!dragRef.current.active) return;
|
|
727
|
+
setPos({
|
|
728
|
+
x: dragRef.current.spx + ev.clientX - dragRef.current.sx,
|
|
729
|
+
y: dragRef.current.spy + ev.clientY - dragRef.current.sy
|
|
730
|
+
});
|
|
731
|
+
};
|
|
732
|
+
const onUp = () => {
|
|
733
|
+
dragRef.current.active = false;
|
|
734
|
+
document.removeEventListener("mousemove", onMove);
|
|
735
|
+
document.removeEventListener("mouseup", onUp);
|
|
736
|
+
};
|
|
737
|
+
document.addEventListener("mousemove", onMove);
|
|
738
|
+
document.addEventListener("mouseup", onUp);
|
|
739
|
+
}, [pos]);
|
|
740
|
+
const onWheelCb = (0, react.useCallback)((e) => {
|
|
741
|
+
e.preventDefault();
|
|
742
|
+
const rect = containerRef.current.getBoundingClientRect();
|
|
743
|
+
const mx = e.clientX - rect.left, my = e.clientY - rect.top;
|
|
744
|
+
const factor = e.deltaY > 0 ? .92 : 1.08;
|
|
745
|
+
const nz = Math.max(.1, Math.min(10, zoom * factor));
|
|
746
|
+
const nx = mx - (mx - pos.x) * (nz / zoom);
|
|
747
|
+
const ny = my - (my - pos.y) * (nz / zoom);
|
|
748
|
+
setZoom(nz);
|
|
749
|
+
setPos({
|
|
750
|
+
x: nx,
|
|
751
|
+
y: ny
|
|
752
|
+
});
|
|
753
|
+
}, [zoom, pos]);
|
|
754
|
+
(0, react.useEffect)(() => {
|
|
755
|
+
const el = containerRef.current;
|
|
756
|
+
if (!el) return;
|
|
757
|
+
el.addEventListener("wheel", onWheelCb, { passive: false });
|
|
758
|
+
return () => el.removeEventListener("wheel", onWheelCb);
|
|
759
|
+
}, [onWheelCb]);
|
|
760
|
+
const resetView = (0, react.useCallback)(() => {
|
|
761
|
+
if (imgSize.w === 0) return;
|
|
762
|
+
setZoom(1);
|
|
763
|
+
setPos({
|
|
764
|
+
x: (pw - imgSize.w) / 2,
|
|
765
|
+
y: (ph - imgSize.h) / 2
|
|
766
|
+
});
|
|
767
|
+
}, [
|
|
768
|
+
pw,
|
|
769
|
+
ph,
|
|
770
|
+
imgSize
|
|
771
|
+
]);
|
|
772
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
773
|
+
style: ST.overlay,
|
|
774
|
+
onClick: (e) => {
|
|
775
|
+
if (e.target === e.currentTarget) onClose();
|
|
776
|
+
},
|
|
777
|
+
children: [
|
|
778
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
779
|
+
style: ST.modalTitle,
|
|
780
|
+
children: t("editorTitle")
|
|
781
|
+
}),
|
|
782
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
783
|
+
ref: containerRef,
|
|
784
|
+
style: {
|
|
785
|
+
...ST.previewRect,
|
|
786
|
+
width: pw,
|
|
787
|
+
height: ph
|
|
788
|
+
},
|
|
789
|
+
onMouseDown: onDown,
|
|
790
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
|
|
791
|
+
ref: imgRef,
|
|
792
|
+
src: url,
|
|
793
|
+
alt: "",
|
|
794
|
+
draggable: false,
|
|
795
|
+
style: {
|
|
796
|
+
...ST.previewImg,
|
|
797
|
+
width: imgSize.w,
|
|
798
|
+
height: imgSize.h,
|
|
799
|
+
transform: `translate(${pos.x}px,${pos.y}px) scale(${zoom})`
|
|
800
|
+
}
|
|
801
|
+
})
|
|
802
|
+
}),
|
|
803
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
804
|
+
style: ST.modalHint,
|
|
805
|
+
children: t("editorHint")
|
|
806
|
+
}),
|
|
807
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
808
|
+
style: ST.modalBtns,
|
|
809
|
+
children: [
|
|
810
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
811
|
+
style: ST.btn,
|
|
812
|
+
onClick: resetView,
|
|
813
|
+
children: t("editorReset")
|
|
814
|
+
}),
|
|
815
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
816
|
+
style: ST.btn,
|
|
817
|
+
onClick: onClose,
|
|
818
|
+
children: t("editorCancel")
|
|
819
|
+
}),
|
|
820
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
821
|
+
style: {
|
|
822
|
+
...ST.btn,
|
|
823
|
+
...ST.btnPrimary
|
|
824
|
+
},
|
|
825
|
+
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),
|
|
826
|
+
children: t("editorCommit")
|
|
827
|
+
})
|
|
828
|
+
]
|
|
829
|
+
})
|
|
830
|
+
]
|
|
831
|
+
});
|
|
832
|
+
}
|
|
833
|
+
function LiveSlider({ min, max, step, def, fmt, onInput, onChange }) {
|
|
834
|
+
const valRef = (0, react.useRef)(null);
|
|
835
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
836
|
+
style: ST.sliderRow,
|
|
837
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
838
|
+
type: "range",
|
|
839
|
+
min,
|
|
840
|
+
max,
|
|
841
|
+
step,
|
|
842
|
+
defaultValue: def,
|
|
843
|
+
style: ST.slider,
|
|
844
|
+
onInput: (e) => {
|
|
845
|
+
const v = Number(e.target.value);
|
|
846
|
+
onInput(v);
|
|
847
|
+
if (valRef.current) valRef.current.textContent = fmt(v);
|
|
848
|
+
},
|
|
849
|
+
onChange: (e) => onChange(Number(e.target.value))
|
|
850
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
851
|
+
ref: valRef,
|
|
852
|
+
style: ST.sliderVal,
|
|
853
|
+
children: fmt(def)
|
|
854
|
+
})]
|
|
855
|
+
});
|
|
856
|
+
}
|
|
857
|
+
function ThemeSection(props) {
|
|
858
|
+
const { t, hue, sat, lit, setColor, url, setWp, setOp, setWop, setBl, setSop, useStore } = props;
|
|
859
|
+
const storeUrl = useStore((s) => s.url);
|
|
860
|
+
const fileRef = (0, react.useRef)(null);
|
|
861
|
+
const [editorOpen, setEditorOpen] = (0, react.useState)(false);
|
|
862
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
863
|
+
style: ST.root,
|
|
864
|
+
children: [
|
|
865
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", {
|
|
866
|
+
style: ST.h2,
|
|
867
|
+
children: t("nav")
|
|
868
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
869
|
+
style: ST.sub,
|
|
870
|
+
children: t("subtitle")
|
|
871
|
+
})] }),
|
|
872
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [
|
|
873
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
874
|
+
style: ST.label,
|
|
875
|
+
children: t("colorTitle")
|
|
876
|
+
}),
|
|
877
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
878
|
+
style: ST.center,
|
|
879
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ColorWheel, {
|
|
880
|
+
hue,
|
|
881
|
+
sat,
|
|
882
|
+
lit,
|
|
883
|
+
onChange: setColor
|
|
884
|
+
})
|
|
885
|
+
}),
|
|
886
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
887
|
+
style: ST.colorHint,
|
|
888
|
+
children: t("colorHint")
|
|
889
|
+
})
|
|
890
|
+
] }),
|
|
891
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("hr", { style: ST.hr }),
|
|
892
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
893
|
+
style: ST.label,
|
|
894
|
+
children: t("uiTitle")
|
|
895
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
896
|
+
style: ST.sliders,
|
|
897
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
898
|
+
style: ST.sliderBlock,
|
|
899
|
+
children: [
|
|
900
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
901
|
+
style: ST.sliderLabel,
|
|
902
|
+
children: t("uiOpacity")
|
|
903
|
+
}),
|
|
904
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
905
|
+
style: ST.smallHint,
|
|
906
|
+
children: t("uiOpacityHint")
|
|
907
|
+
}),
|
|
908
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(LiveSlider, {
|
|
909
|
+
min: 0,
|
|
910
|
+
max: 100,
|
|
911
|
+
step: 1,
|
|
912
|
+
def: Math.round(rOp() * 100),
|
|
913
|
+
fmt: (v) => `${v}%`,
|
|
914
|
+
onInput: (v) => {
|
|
915
|
+
const op = v / 100;
|
|
916
|
+
wLS(LS_OP, String(op));
|
|
917
|
+
applyCustomTokens(op);
|
|
918
|
+
},
|
|
919
|
+
onChange: (v) => setOp(v / 100)
|
|
920
|
+
})
|
|
921
|
+
]
|
|
922
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
923
|
+
style: ST.sliderBlock,
|
|
924
|
+
children: [
|
|
925
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
926
|
+
style: ST.sliderLabel,
|
|
927
|
+
children: t("uiSop")
|
|
928
|
+
}),
|
|
929
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
930
|
+
style: ST.smallHint,
|
|
931
|
+
children: t("uiSopHint")
|
|
932
|
+
}),
|
|
933
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(LiveSlider, {
|
|
934
|
+
min: 0,
|
|
935
|
+
max: 100,
|
|
936
|
+
step: 1,
|
|
937
|
+
def: Math.round(rSop() * 100),
|
|
938
|
+
fmt: (v) => `${v}%`,
|
|
939
|
+
onInput: (v) => {
|
|
940
|
+
const op = v / 100;
|
|
941
|
+
wLS(LS_SOP, String(op));
|
|
942
|
+
applySettingsOverrides(op);
|
|
943
|
+
},
|
|
944
|
+
onChange: (v) => setSop(v / 100)
|
|
945
|
+
})
|
|
946
|
+
]
|
|
947
|
+
})]
|
|
948
|
+
})] }),
|
|
949
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("hr", { style: ST.hr }),
|
|
950
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [
|
|
951
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
952
|
+
style: ST.label,
|
|
953
|
+
children: t("bgTitle")
|
|
954
|
+
}),
|
|
955
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
956
|
+
style: ST.center,
|
|
957
|
+
children: storeUrl ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
|
|
958
|
+
src: storeUrl,
|
|
959
|
+
alt: "",
|
|
960
|
+
style: ST.preview,
|
|
961
|
+
onClick: () => setEditorOpen(true)
|
|
962
|
+
}) : null
|
|
963
|
+
}),
|
|
964
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
965
|
+
style: ST.btnGroup,
|
|
966
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
967
|
+
style: ST.row,
|
|
968
|
+
children: [
|
|
969
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
970
|
+
type: "button",
|
|
971
|
+
style: ST.btn,
|
|
972
|
+
onClick: () => fileRef.current?.click(),
|
|
973
|
+
children: t("bgChoose")
|
|
974
|
+
}),
|
|
975
|
+
storeUrl ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
976
|
+
type: "button",
|
|
977
|
+
style: ST.btn,
|
|
978
|
+
onClick: () => setEditorOpen(true),
|
|
979
|
+
children: t("bgEdit")
|
|
980
|
+
}) : null,
|
|
981
|
+
storeUrl ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
982
|
+
type: "button",
|
|
983
|
+
style: {
|
|
984
|
+
...ST.btn,
|
|
985
|
+
...ST.btnDanger
|
|
986
|
+
},
|
|
987
|
+
onClick: () => setWp(null),
|
|
988
|
+
children: t("bgRemove")
|
|
989
|
+
}) : null,
|
|
990
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
991
|
+
ref: fileRef,
|
|
992
|
+
type: "file",
|
|
993
|
+
accept: "image/*",
|
|
994
|
+
style: { display: "none" },
|
|
995
|
+
onChange: (e) => {
|
|
996
|
+
const f = e.target.files?.[0];
|
|
997
|
+
if (!f) return;
|
|
998
|
+
readImg(f, (d) => {
|
|
999
|
+
if (d) setWp(d);
|
|
1000
|
+
e.target.value = "";
|
|
1001
|
+
});
|
|
1002
|
+
}
|
|
1003
|
+
})
|
|
1004
|
+
]
|
|
1005
|
+
})
|
|
1006
|
+
}),
|
|
1007
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1008
|
+
style: ST.sliders,
|
|
1009
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1010
|
+
style: ST.sliderBlock,
|
|
1011
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1012
|
+
style: ST.sliderLabel,
|
|
1013
|
+
children: t("wpOpacity")
|
|
1014
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LiveSlider, {
|
|
1015
|
+
min: 0,
|
|
1016
|
+
max: 100,
|
|
1017
|
+
step: 1,
|
|
1018
|
+
def: Math.round(rWop() * 100),
|
|
1019
|
+
fmt: (v) => `${v}%`,
|
|
1020
|
+
onInput: (v) => {
|
|
1021
|
+
const op = v / 100;
|
|
1022
|
+
wLS(LS_WOP, String(op));
|
|
1023
|
+
if (wpEl) wpEl.style.opacity = String(op);
|
|
1024
|
+
},
|
|
1025
|
+
onChange: (v) => setWop(v / 100)
|
|
1026
|
+
})]
|
|
1027
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1028
|
+
style: ST.sliderBlock,
|
|
1029
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1030
|
+
style: ST.sliderLabel,
|
|
1031
|
+
children: t("bgBlur")
|
|
1032
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LiveSlider, {
|
|
1033
|
+
min: 0,
|
|
1034
|
+
max: 60,
|
|
1035
|
+
step: 1,
|
|
1036
|
+
def: rBl(),
|
|
1037
|
+
fmt: (v) => `${v}px`,
|
|
1038
|
+
onInput: (v) => {
|
|
1039
|
+
wLS(LS_BL, String(v));
|
|
1040
|
+
if (wpEl) wpEl.style.filter = v > 0 ? `blur(${v}px)` : "none";
|
|
1041
|
+
},
|
|
1042
|
+
onChange: (v) => setBl(v)
|
|
1043
|
+
})]
|
|
1044
|
+
})]
|
|
1045
|
+
}),
|
|
1046
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1047
|
+
style: ST.hint,
|
|
1048
|
+
children: t("bgHint")
|
|
1049
|
+
})
|
|
1050
|
+
] }),
|
|
1051
|
+
editorOpen && storeUrl ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BgEditor, {
|
|
1052
|
+
url: storeUrl,
|
|
1053
|
+
t,
|
|
1054
|
+
onClose: () => setEditorOpen(false),
|
|
1055
|
+
onCommit: (z, x, y, iw, ih) => {
|
|
1056
|
+
wLS(LS_BG, JSON.stringify({
|
|
1057
|
+
zoom: z,
|
|
1058
|
+
x,
|
|
1059
|
+
y,
|
|
1060
|
+
iw,
|
|
1061
|
+
ih
|
|
1062
|
+
}));
|
|
1063
|
+
applyWp(ctxRef);
|
|
1064
|
+
setEditorOpen(false);
|
|
1065
|
+
}
|
|
1066
|
+
}) : null
|
|
1067
|
+
]
|
|
1068
|
+
});
|
|
1069
|
+
}
|
|
1070
|
+
function apply(ctx) {
|
|
1071
|
+
ctxRef = ctx;
|
|
1072
|
+
const [initH, initS, initL] = rColor();
|
|
1073
|
+
let customDispose = null;
|
|
1074
|
+
const registerCustom = (h, s, l) => {
|
|
1075
|
+
customDispose?.();
|
|
1076
|
+
try {
|
|
1077
|
+
const { colorScheme, tokens } = genTokens(h, s, l);
|
|
1078
|
+
customDispose = ctx.theme.register({
|
|
1079
|
+
id: CUSTOM_ID,
|
|
1080
|
+
colorScheme,
|
|
1081
|
+
tokens
|
|
1082
|
+
});
|
|
1083
|
+
} catch {
|
|
1084
|
+
customDispose = null;
|
|
1085
|
+
}
|
|
1086
|
+
ctx.theme.setTheme(CUSTOM_ID);
|
|
1087
|
+
};
|
|
1088
|
+
if (rLS(LS_COLOR)) registerCustom(initH, initS, initL);
|
|
1089
|
+
ctx.effect(() => () => {
|
|
1090
|
+
customDispose?.();
|
|
1091
|
+
}, "dsh-any-background: skin dispose");
|
|
1092
|
+
let styleEl;
|
|
1093
|
+
if (typeof document !== "undefined") {
|
|
1094
|
+
styleEl = document.createElement("style");
|
|
1095
|
+
styleEl.dataset.plugin = "dsh-any-background";
|
|
1096
|
+
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}`;
|
|
1097
|
+
document.head.appendChild(styleEl);
|
|
1098
|
+
}
|
|
1099
|
+
ctx.effect(() => () => {
|
|
1100
|
+
styleEl?.parentNode?.removeChild(styleEl);
|
|
1101
|
+
}, "dsh-any-background: gradient");
|
|
1102
|
+
let rev = 0;
|
|
1103
|
+
const store = (0, _deepseek_ai_dsh_client_runtime_client.defineStore)({
|
|
1104
|
+
init: () => ({
|
|
1105
|
+
url: null,
|
|
1106
|
+
rev: -1
|
|
1107
|
+
}),
|
|
1108
|
+
actions: { syncBg: (d, url, r) => {
|
|
1109
|
+
if (r <= d.rev) return;
|
|
1110
|
+
d.url = url;
|
|
1111
|
+
d.rev = r;
|
|
1112
|
+
} }
|
|
1113
|
+
});
|
|
1114
|
+
let bound;
|
|
1115
|
+
const syncBg = () => {
|
|
1116
|
+
rev++;
|
|
1117
|
+
bound?.syncBg(rWp(), rev);
|
|
1118
|
+
};
|
|
1119
|
+
applyWp(ctx);
|
|
1120
|
+
syncBg();
|
|
1121
|
+
ctx.effect(() => () => {
|
|
1122
|
+
teardownWp();
|
|
1123
|
+
}, "dsh-any-background: wp cleanup");
|
|
1124
|
+
ctx.effect(() => ctx.on("theme/change", () => {
|
|
1125
|
+
if (rLS(LS_COLOR)) {
|
|
1126
|
+
const snapshot = ctx.theme.getTheme();
|
|
1127
|
+
if (snapshot.preference !== CUSTOM_ID && snapshot.themes.some((t) => t.id === CUSTOM_ID)) ctx.theme.setTheme(CUSTOM_ID);
|
|
1128
|
+
}
|
|
1129
|
+
applyWp(ctx);
|
|
1130
|
+
}), "dsh-any-background: theme change");
|
|
1131
|
+
let frame = 0;
|
|
1132
|
+
const applySoon = () => {
|
|
1133
|
+
if (frame !== 0) return;
|
|
1134
|
+
frame = requestAnimationFrame(() => {
|
|
1135
|
+
frame = 0;
|
|
1136
|
+
applyWp(ctx);
|
|
1137
|
+
});
|
|
1138
|
+
};
|
|
1139
|
+
const sentinel = document.createElement("div");
|
|
1140
|
+
sentinel.style.cssText = "position:fixed;inset:0;pointer-events:none;visibility:hidden";
|
|
1141
|
+
document.body.append(sentinel);
|
|
1142
|
+
const viewportObserver = new ResizeObserver(applySoon);
|
|
1143
|
+
viewportObserver.observe(sentinel);
|
|
1144
|
+
const dprQuery = window.matchMedia(`(resolution: ${window.devicePixelRatio}dppx)`);
|
|
1145
|
+
dprQuery.addEventListener("change", applySoon);
|
|
1146
|
+
ctx.effect(() => () => {
|
|
1147
|
+
viewportObserver.disconnect();
|
|
1148
|
+
dprQuery.removeEventListener("change", applySoon);
|
|
1149
|
+
sentinel.remove();
|
|
1150
|
+
}, "dsh-any-background: viewport watch");
|
|
1151
|
+
ctx.effect(() => ctx.locale.register(NS, {
|
|
1152
|
+
zh,
|
|
1153
|
+
en
|
|
1154
|
+
}), "dsh-any-background: i18n");
|
|
1155
|
+
const sectionInject = (actions) => {
|
|
1156
|
+
bound = actions;
|
|
1157
|
+
syncBg();
|
|
1158
|
+
const [wh, ws, wl] = rColor();
|
|
1159
|
+
const [dh, ds, dv] = hslToHsv(wh, ws, wl);
|
|
1160
|
+
return {
|
|
1161
|
+
t: ctx.locale.bind(NS),
|
|
1162
|
+
hue: dh,
|
|
1163
|
+
sat: ds,
|
|
1164
|
+
lit: dv,
|
|
1165
|
+
setColor: (nh, ns, nl) => {
|
|
1166
|
+
const [sh, ss, sl] = hsvToHsl(nh, ns, nl);
|
|
1167
|
+
wLS(LS_COLOR, JSON.stringify([
|
|
1168
|
+
sh,
|
|
1169
|
+
ss,
|
|
1170
|
+
sl
|
|
1171
|
+
]));
|
|
1172
|
+
registerCustom(sh, ss, sl);
|
|
1173
|
+
applyWp(ctx);
|
|
1174
|
+
},
|
|
1175
|
+
setWp: (u) => {
|
|
1176
|
+
wLS(LS_WP, u);
|
|
1177
|
+
wLS(LS_BG, null);
|
|
1178
|
+
applyWp(ctx);
|
|
1179
|
+
syncBg();
|
|
1180
|
+
},
|
|
1181
|
+
setOp: (v) => {
|
|
1182
|
+
wLS(LS_OP, String(v));
|
|
1183
|
+
applyWp(ctx);
|
|
1184
|
+
syncBg();
|
|
1185
|
+
},
|
|
1186
|
+
setWop: (v) => {
|
|
1187
|
+
wLS(LS_WOP, String(v));
|
|
1188
|
+
applyWp(ctx);
|
|
1189
|
+
syncBg();
|
|
1190
|
+
},
|
|
1191
|
+
setBl: (v) => {
|
|
1192
|
+
wLS(LS_BL, String(v));
|
|
1193
|
+
applyWp(ctx);
|
|
1194
|
+
syncBg();
|
|
1195
|
+
},
|
|
1196
|
+
setSop: (v) => {
|
|
1197
|
+
wLS(LS_SOP, String(v));
|
|
1198
|
+
applySettingsOverrides(v);
|
|
1199
|
+
}
|
|
1200
|
+
};
|
|
1201
|
+
};
|
|
1202
|
+
ctx.slots.inject("settings.section", () => ctx.slots.register({
|
|
1203
|
+
name: "settings.section",
|
|
1204
|
+
id: "dsh-any-background",
|
|
1205
|
+
order: 35,
|
|
1206
|
+
label: () => ctx.locale.bind(NS)("nav"),
|
|
1207
|
+
locale: NS,
|
|
1208
|
+
store,
|
|
1209
|
+
inject: sectionInject
|
|
1210
|
+
}, ThemeSection));
|
|
1211
|
+
const restoreSaved = () => {
|
|
1212
|
+
if (rLS(LS_COLOR)) {
|
|
1213
|
+
const [h, s, l] = rColor();
|
|
1214
|
+
registerCustom(h, s, l);
|
|
1215
|
+
}
|
|
1216
|
+
applyWp(ctx);
|
|
1217
|
+
};
|
|
1218
|
+
const restoreTimers = [300, 1500].map((delay) => window.setTimeout(restoreSaved, delay));
|
|
1219
|
+
ctx.effect(() => () => {
|
|
1220
|
+
restoreTimers.forEach((id) => window.clearTimeout(id));
|
|
1221
|
+
}, "dsh-any-background: boot restore");
|
|
1222
|
+
const watchdogId = window.setInterval(() => {
|
|
1223
|
+
if (!rLS(LS_COLOR)) return;
|
|
1224
|
+
const snapshot = ctx.theme.getTheme();
|
|
1225
|
+
let changed = false;
|
|
1226
|
+
if (!snapshot.themes.some((t) => t.id === CUSTOM_ID)) {
|
|
1227
|
+
const [h, s, l] = rColor();
|
|
1228
|
+
registerCustom(h, s, l);
|
|
1229
|
+
changed = true;
|
|
1230
|
+
} else if (snapshot.preference !== CUSTOM_ID) {
|
|
1231
|
+
ctx.theme.setTheme(CUSTOM_ID);
|
|
1232
|
+
changed = true;
|
|
1233
|
+
}
|
|
1234
|
+
if (changed) applyWp(ctx);
|
|
1235
|
+
}, 1e3);
|
|
1236
|
+
ctx.effect(() => () => {
|
|
1237
|
+
window.clearInterval(watchdogId);
|
|
1238
|
+
}, "dsh-any-background: theme watchdog");
|
|
1239
|
+
}
|
|
1240
|
+
//#endregion
|
|
1241
|
+
exports.apply = apply;
|
|
1242
|
+
exports.inject = inject;
|
|
1243
|
+
exports.name = name;
|
|
1244
|
+
return module.exports;
|
|
1245
|
+
}
|
|
1246
|
+
});
|
|
1247
|
+
|
|
1248
|
+
//# sourceMappingURL=client.js.map
|