dsh-skin-galactic-opera 0.1.9 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +17 -0
- package/README.md +26 -0
- package/lib/client.js +63 -6
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,23 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this package will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## 0.2.1 - 2026-09-04
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
|
|
9
|
+
- Documents the recommended DSH compatibility range in both English and Simplified Chinese README sections.
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
- Aligns click pulse and scanner target effects with the clicked position after Shadow DOM decor isolation.
|
|
14
|
+
|
|
15
|
+
## 0.2.0 - 2026-09-04
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
|
|
19
|
+
- Pauses skin animation work while the page is hidden to reduce background CPU/GPU usage.
|
|
20
|
+
- Suspends telemetry scans while the page is hidden, then forces an immediate refresh plus a short follow-up when the page becomes visible again.
|
|
21
|
+
|
|
5
22
|
## 0.1.9 - 2026-09-03
|
|
6
23
|
|
|
7
24
|
### Changed
|
package/README.md
CHANGED
|
@@ -41,6 +41,19 @@ It uses generic sci-fi visual language: deep-space backgrounds, neon HUD chrome,
|
|
|
41
41
|
- Uses Shadow DOM for the decorative layer to reduce interference from host application styles.
|
|
42
42
|
- Respects `prefers-reduced-motion: reduce` by disabling major animations.
|
|
43
43
|
|
|
44
|
+
### Compatibility
|
|
45
|
+
|
|
46
|
+
Recommended DSH version: **`0.1.0-rc.7` or newer**.
|
|
47
|
+
|
|
48
|
+
Known incompatible versions:
|
|
49
|
+
|
|
50
|
+
- `0.0.1-rc.1`
|
|
51
|
+
- `0.0.1-rc.2`
|
|
52
|
+
|
|
53
|
+
These early versions of `@deepseek-ai/dsh-client-ui-theme` do not expose `theme.overrideTokens()`, which this skin uses for its token override layer.
|
|
54
|
+
|
|
55
|
+
Versions from `0.0.1-rc.3` onward include the required theme APIs in static inspection, but DSH releases before `0.1.0-rc.7` are not actively tested by this package. If you are using an older DSH release, upgrade DSH first before reporting skin issues.
|
|
56
|
+
|
|
44
57
|
### Telemetry panel
|
|
45
58
|
|
|
46
59
|
When DSH Web exposes bottom status/usage data, the skin keeps the original UI layout in place and mirrors the detected global telemetry into a non-interactive bottom-right HUD panel.
|
|
@@ -193,6 +206,19 @@ DSH Web GUI 的非官方电影感太空歌剧暗色皮肤插件。
|
|
|
193
206
|
- 装饰层使用 Shadow DOM,减少宿主应用样式对行星、扫描盘、点击脉冲等几何形态的污染。
|
|
194
207
|
- 遵循 `prefers-reduced-motion: reduce`,会关闭主要动画。
|
|
195
208
|
|
|
209
|
+
### 兼容性
|
|
210
|
+
|
|
211
|
+
推荐 DSH 版本:**`0.1.0-rc.7` 或更新版本**。
|
|
212
|
+
|
|
213
|
+
已知不兼容版本:
|
|
214
|
+
|
|
215
|
+
- `0.0.1-rc.1`
|
|
216
|
+
- `0.0.1-rc.2`
|
|
217
|
+
|
|
218
|
+
这些早期版本的 `@deepseek-ai/dsh-client-ui-theme` 不提供 `theme.overrideTokens()`,而本皮肤需要它来应用主题 token 覆盖层。
|
|
219
|
+
|
|
220
|
+
从 `0.0.1-rc.3` 开始,静态检查显示已具备本插件需要的 theme API;但 `0.1.0-rc.7` 之前的 DSH 版本本包不会主动测试。如果你正在使用更早的 DSH 版本,建议先升级 DSH,再反馈皮肤兼容问题。
|
|
221
|
+
|
|
196
222
|
### Telemetry 面板
|
|
197
223
|
|
|
198
224
|
当 DSH Web 暴露底部状态/用量信息时,皮肤会保留原始 UI 布局,并将检测到的全局 telemetry 镜像到右下角的非交互 HUD 面板中。
|
package/lib/client.js
CHANGED
|
@@ -11,6 +11,7 @@ window.__ModuleLoader__.load({
|
|
|
11
11
|
const STYLE_ID = "dsh-skin-galactic-opera-style";
|
|
12
12
|
const DECOR_ID = "dsh-skin-galactic-opera-decor";
|
|
13
13
|
const DECOR_HOST_CLASS = "dsh-skin-galactic-opera-decor-host";
|
|
14
|
+
const PAGE_HIDDEN_CLASS = "dsh-skin-galactic-opera-page-hidden";
|
|
14
15
|
const CSS_TAG_ID = `${PLUGIN_ID}/global.css`;
|
|
15
16
|
|
|
16
17
|
const TOKENS = Object.freeze({
|
|
@@ -170,6 +171,16 @@ body.dsh-skin-galactic-opera.dsh-skin-galactic-opera-input-active :is(.dsh-skin-
|
|
|
170
171
|
opacity: 0.16 !important;
|
|
171
172
|
}
|
|
172
173
|
|
|
174
|
+
body.dsh-skin-galactic-opera.dsh-skin-galactic-opera-page-hidden::before,
|
|
175
|
+
body.dsh-skin-galactic-opera.dsh-skin-galactic-opera-page-hidden::after,
|
|
176
|
+
body.dsh-skin-galactic-opera.dsh-skin-galactic-opera-page-hidden #root::before,
|
|
177
|
+
body.dsh-skin-galactic-opera.dsh-skin-galactic-opera-page-hidden .dsh-skin-galactic-opera-decor::before,
|
|
178
|
+
body.dsh-skin-galactic-opera.dsh-skin-galactic-opera-page-hidden .dsh-skin-galactic-opera-decor *,
|
|
179
|
+
body.dsh-skin-galactic-opera.dsh-skin-galactic-opera-page-hidden .dsh-skin-galactic-opera-decor *::before,
|
|
180
|
+
body.dsh-skin-galactic-opera.dsh-skin-galactic-opera-page-hidden .dsh-skin-galactic-opera-decor *::after {
|
|
181
|
+
animation-play-state: paused !important;
|
|
182
|
+
}
|
|
183
|
+
|
|
173
184
|
body.dsh-skin-galactic-opera #root > *,
|
|
174
185
|
body.dsh-skin-galactic-opera main,
|
|
175
186
|
body.dsh-skin-galactic-opera aside,
|
|
@@ -1149,6 +1160,7 @@ body.dsh-skin-galactic-opera .dsh-skin-telemetry-value-full {
|
|
|
1149
1160
|
return `${CSS
|
|
1150
1161
|
.replace(/body\.dsh-skin-galactic-opera\.dsh-skin-galactic-opera-input-active\s+/g, ":host-context(body.dsh-skin-galactic-opera.dsh-skin-galactic-opera-input-active) ")
|
|
1151
1162
|
.replace(/body\.dsh-skin-galactic-opera\.dsh-skin-galactic-opera-hyperspace\s+/g, ":host-context(body.dsh-skin-galactic-opera.dsh-skin-galactic-opera-hyperspace) ")
|
|
1163
|
+
.replace(/body\.dsh-skin-galactic-opera\.dsh-skin-galactic-opera-page-hidden\s+/g, ":host-context(body.dsh-skin-galactic-opera.dsh-skin-galactic-opera-page-hidden) ")
|
|
1152
1164
|
.replace(/body\.dsh-skin-galactic-opera\s+/g, "")}
|
|
1153
1165
|
|
|
1154
1166
|
.dsh-skin-galactic-opera-decor {
|
|
@@ -1158,6 +1170,11 @@ body.dsh-skin-galactic-opera .dsh-skin-telemetry-value-full {
|
|
|
1158
1170
|
height: auto !important;
|
|
1159
1171
|
z-index: auto !important;
|
|
1160
1172
|
}
|
|
1173
|
+
|
|
1174
|
+
.dsh-skin-pulse,
|
|
1175
|
+
.dsh-skin-scanner-target {
|
|
1176
|
+
position: absolute !important;
|
|
1177
|
+
}
|
|
1161
1178
|
`;
|
|
1162
1179
|
}
|
|
1163
1180
|
|
|
@@ -1249,6 +1266,20 @@ body.dsh-skin-galactic-opera .dsh-skin-telemetry-value-full {
|
|
|
1249
1266
|
}
|
|
1250
1267
|
|
|
1251
1268
|
const EDITABLE_CONTENT_SELECTOR = `[contenteditable]:not([contenteditable="false"])`;
|
|
1269
|
+
|
|
1270
|
+
function installVisibilityState() {
|
|
1271
|
+
if (typeof document === "undefined" || typeof window === "undefined") return () => {};
|
|
1272
|
+
const syncVisibilityClass = () => {
|
|
1273
|
+
document.body.classList.toggle(PAGE_HIDDEN_CLASS, document.hidden);
|
|
1274
|
+
};
|
|
1275
|
+
syncVisibilityClass();
|
|
1276
|
+
document.addEventListener("visibilitychange", syncVisibilityClass);
|
|
1277
|
+
return () => {
|
|
1278
|
+
document.removeEventListener("visibilitychange", syncVisibilityClass);
|
|
1279
|
+
document.body.classList.remove(PAGE_HIDDEN_CLASS);
|
|
1280
|
+
};
|
|
1281
|
+
}
|
|
1282
|
+
|
|
1252
1283
|
let reducedMotionQuery;
|
|
1253
1284
|
let reducedMotionMatches = false;
|
|
1254
1285
|
let reducedMotionListener;
|
|
@@ -1313,6 +1344,12 @@ body.dsh-skin-galactic-opera .dsh-skin-telemetry-value-full {
|
|
|
1313
1344
|
const decorLayer = getDecorLayer(decor);
|
|
1314
1345
|
const scanner = decorRoot?.querySelector?.(".dsh-skin-scanner");
|
|
1315
1346
|
const scannerTarget = decorRoot?.querySelector?.(".dsh-skin-scanner-target");
|
|
1347
|
+
const useDecorLocalCoordinates = decor.shadowRoot !== null && decorLayer instanceof HTMLElement;
|
|
1348
|
+
const toDecorPoint = (clientX, clientY) => {
|
|
1349
|
+
if (!useDecorLocalCoordinates) return { x: clientX, y: clientY };
|
|
1350
|
+
const rect = decorLayer.getBoundingClientRect();
|
|
1351
|
+
return { x: clientX - rect.left, y: clientY - rect.top };
|
|
1352
|
+
};
|
|
1316
1353
|
const pulseColors = ["rgba(125,227,255,0.94)", "rgba(255,207,92,0.92)", "rgba(255,71,120,0.88)"];
|
|
1317
1354
|
const updatePointer = () => {
|
|
1318
1355
|
frame = 0;
|
|
@@ -1345,8 +1382,9 @@ body.dsh-skin-galactic-opera .dsh-skin-telemetry-value-full {
|
|
|
1345
1382
|
const scannerRadius = Math.max(10, Math.min(rect.width, rect.height) * 0.38);
|
|
1346
1383
|
const projectedRadius = Math.min(1, distance / maxDistance) * scannerRadius;
|
|
1347
1384
|
const angle = Math.atan2(dy, dx);
|
|
1348
|
-
|
|
1349
|
-
document.body.style.setProperty("--dsh-skin-scanner-dot-
|
|
1385
|
+
const scannerDot = toDecorPoint(scannerCenterX + Math.cos(angle) * projectedRadius, scannerCenterY + Math.sin(angle) * projectedRadius);
|
|
1386
|
+
document.body.style.setProperty("--dsh-skin-scanner-dot-x", `${Math.round(scannerDot.x)}px`);
|
|
1387
|
+
document.body.style.setProperty("--dsh-skin-scanner-dot-y", `${Math.round(scannerDot.y)}px`);
|
|
1350
1388
|
scannerTarget.removeAttribute("data-ping");
|
|
1351
1389
|
// Force the double-flash animation to restart on repeated clicks at the same point.
|
|
1352
1390
|
void scannerTarget.offsetWidth;
|
|
@@ -1393,8 +1431,9 @@ body.dsh-skin-galactic-opera .dsh-skin-telemetry-value-full {
|
|
|
1393
1431
|
pulse.className = "dsh-skin-pulse";
|
|
1394
1432
|
setImportantStyle(pulse, "border-radius", "50%");
|
|
1395
1433
|
setImportantStyle(pulse, "box-sizing", "border-box");
|
|
1396
|
-
|
|
1397
|
-
pulse.style.setProperty("--dsh-skin-pulse-
|
|
1434
|
+
const pulsePoint = toDecorPoint(event.clientX, event.clientY);
|
|
1435
|
+
pulse.style.setProperty("--dsh-skin-pulse-x", `${Math.round(pulsePoint.x)}px`);
|
|
1436
|
+
pulse.style.setProperty("--dsh-skin-pulse-y", `${Math.round(pulsePoint.y)}px`);
|
|
1398
1437
|
pulse.style.setProperty("--dsh-skin-pulse-color", pulseColors[pulseIndex % pulseColors.length]);
|
|
1399
1438
|
pulseIndex += 1;
|
|
1400
1439
|
if (decorLayer instanceof Element) decorLayer.appendChild(pulse);
|
|
@@ -1676,7 +1715,7 @@ body.dsh-skin-galactic-opera .dsh-skin-telemetry-value-full {
|
|
|
1676
1715
|
const update = ({ ignorePause = false } = {}) => {
|
|
1677
1716
|
frame = 0;
|
|
1678
1717
|
frameIgnoresTelemetryPause = false;
|
|
1679
|
-
if (!ignorePause && isTelemetryPaused()) return;
|
|
1718
|
+
if (document.hidden || (!ignorePause && isTelemetryPaused())) return;
|
|
1680
1719
|
let nextSources = currentSources;
|
|
1681
1720
|
let text = getSourcesText(nextSources);
|
|
1682
1721
|
const needsFullScan = forceTelemetryRescan || telemetryRefreshesSinceFullScan >= TELEMETRY_FULL_RESCAN_UPDATES || !areCachedSourcesUsable();
|
|
@@ -1696,7 +1735,7 @@ body.dsh-skin-galactic-opera .dsh-skin-telemetry-value-full {
|
|
|
1696
1735
|
renderPanel(text);
|
|
1697
1736
|
};
|
|
1698
1737
|
const schedule = ({ delay = TELEMETRY_UPDATE_DELAY, force = false, ignorePause = false } = {}) => {
|
|
1699
|
-
if (!ignorePause && isTelemetryPaused()) return;
|
|
1738
|
+
if (document.hidden || (!ignorePause && isTelemetryPaused())) return;
|
|
1700
1739
|
if (force) forceTelemetryRescan = true;
|
|
1701
1740
|
if (frame !== 0) {
|
|
1702
1741
|
if (!force && delay >= TELEMETRY_UPDATE_DELAY) return;
|
|
@@ -1778,6 +1817,20 @@ body.dsh-skin-galactic-opera .dsh-skin-telemetry-value-full {
|
|
|
1778
1817
|
forceTelemetryRescan = true;
|
|
1779
1818
|
schedule();
|
|
1780
1819
|
};
|
|
1820
|
+
const onTelemetryVisibilityChange = () => {
|
|
1821
|
+
if (document.hidden) {
|
|
1822
|
+
if (frame !== 0) {
|
|
1823
|
+
window.clearTimeout(frame);
|
|
1824
|
+
frame = 0;
|
|
1825
|
+
}
|
|
1826
|
+
frameIgnoresTelemetryPause = false;
|
|
1827
|
+
for (const timer of telemetryNavigationTimers) window.clearTimeout(timer);
|
|
1828
|
+
telemetryNavigationTimers.clear();
|
|
1829
|
+
return;
|
|
1830
|
+
}
|
|
1831
|
+
schedule({ delay: 0, force: true, ignorePause: true });
|
|
1832
|
+
setTelemetryNavigationTimer(() => schedule({ delay: 0, force: true, ignorePause: true }), TELEMETRY_NAV_FOLLOWUP_DELAY);
|
|
1833
|
+
};
|
|
1781
1834
|
const observer = typeof MutationObserver === "undefined" ? undefined : new MutationObserver((mutations) => {
|
|
1782
1835
|
if (mutations.every(isSkinOwnedMutation)) return;
|
|
1783
1836
|
if (isTelemetryPaused() && mutations.some(isPotentialTelemetryNavigationMutation)) {
|
|
@@ -1790,6 +1843,7 @@ body.dsh-skin-galactic-opera .dsh-skin-telemetry-value-full {
|
|
|
1790
1843
|
schedule();
|
|
1791
1844
|
observer?.observe(document.body, { childList: true, subtree: true, characterData: true });
|
|
1792
1845
|
window.addEventListener("resize", onTelemetryResize, { passive: true });
|
|
1846
|
+
document.addEventListener("visibilitychange", onTelemetryVisibilityChange);
|
|
1793
1847
|
window.addEventListener("popstate", checkTelemetryLocation, { passive: true });
|
|
1794
1848
|
window.addEventListener("hashchange", checkTelemetryLocation, { passive: true });
|
|
1795
1849
|
document.addEventListener("click", onTelemetryNavigationClick, true);
|
|
@@ -1800,6 +1854,7 @@ body.dsh-skin-galactic-opera .dsh-skin-telemetry-value-full {
|
|
|
1800
1854
|
if (telemetryPushState !== undefined && window.history.pushState === telemetryPushState) window.history.pushState = originalPushState;
|
|
1801
1855
|
if (telemetryReplaceState !== undefined && window.history.replaceState === telemetryReplaceState) window.history.replaceState = originalReplaceState;
|
|
1802
1856
|
window.removeEventListener("resize", onTelemetryResize);
|
|
1857
|
+
document.removeEventListener("visibilitychange", onTelemetryVisibilityChange);
|
|
1803
1858
|
window.removeEventListener("popstate", checkTelemetryLocation);
|
|
1804
1859
|
window.removeEventListener("hashchange", checkTelemetryLocation);
|
|
1805
1860
|
document.removeEventListener("click", onTelemetryNavigationClick, true);
|
|
@@ -1821,12 +1876,14 @@ body.dsh-skin-galactic-opera .dsh-skin-telemetry-value-full {
|
|
|
1821
1876
|
ctx.effect(() => {
|
|
1822
1877
|
const style = ensureStyle();
|
|
1823
1878
|
if (typeof document !== "undefined") document.body.classList.add("dsh-skin-galactic-opera");
|
|
1879
|
+
const disposeVisibilityState = installVisibilityState();
|
|
1824
1880
|
const decor = ensureDecor();
|
|
1825
1881
|
const disposeInteractions = installInteractions(decor);
|
|
1826
1882
|
const disposeTelemetryPanel = installTelemetryPanel();
|
|
1827
1883
|
return () => {
|
|
1828
1884
|
disposeTelemetryPanel();
|
|
1829
1885
|
disposeInteractions();
|
|
1886
|
+
disposeVisibilityState();
|
|
1830
1887
|
disposeReducedMotionCache();
|
|
1831
1888
|
if (typeof document !== "undefined") document.body.classList.remove("dsh-skin-galactic-opera");
|
|
1832
1889
|
decor?.remove();
|