@lemoncat7/dsh-theme-xiaohei 0.3.0-alpha.23 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +39 -17
- package/THIRD_PARTY_NOTICES.md +41 -0
- package/lib/appearance.js +26 -10
- package/lib/blink.js +3 -3
- package/lib/bloub-heixiu/ambient.d.ts +3 -0
- package/lib/bloub-heixiu/ambient.js +12 -0
- package/lib/bloub-heixiu/character.d.ts +33 -0
- package/lib/bloub-heixiu/character.js +124 -0
- package/lib/bloub-heixiu/effects.d.ts +4 -0
- package/lib/bloub-heixiu/effects.js +91 -0
- package/lib/bloub-heixiu/flight.d.ts +15 -0
- package/lib/bloub-heixiu/flight.js +66 -0
- package/lib/bloub-heixiu/follow.d.ts +13 -0
- package/lib/bloub-heixiu/follow.js +23 -0
- package/lib/bloub-heixiu/layout.d.ts +18 -0
- package/lib/bloub-heixiu/layout.js +12 -0
- package/lib/bloub-heixiu/renderer.d.ts +16 -0
- package/lib/bloub-heixiu/renderer.js +94 -0
- package/lib/bloub-heixiu/runtime.d.ts +6 -0
- package/lib/bloub-heixiu/runtime.js +395 -0
- package/lib/bloub-heixiu/signals.d.ts +17 -0
- package/lib/bloub-heixiu/signals.js +53 -0
- package/lib/bloub-heixiu/styles.d.ts +2 -0
- package/lib/bloub-heixiu/styles.js +98 -0
- package/lib/chrome/accessibility.d.ts +1 -1
- package/lib/chrome/accessibility.js +5 -13
- package/lib/chrome/composer-avatar.d.ts +10 -0
- package/lib/chrome/composer-avatar.js +599 -0
- package/lib/chrome/composer-send-heixiu.d.ts +3 -0
- package/lib/chrome/composer-send-heixiu.js +143 -0
- package/lib/chrome/composer.d.ts +2 -2
- package/lib/chrome/composer.js +84 -95
- package/lib/chrome/controls.d.ts +8 -0
- package/lib/chrome/controls.js +348 -0
- package/lib/chrome/conversation-messages.d.ts +1 -1
- package/lib/chrome/conversation-messages.js +207 -9
- package/lib/chrome/conversation.d.ts +1 -1
- package/lib/chrome/conversation.js +6 -0
- package/lib/chrome/identity.js +4 -18
- package/lib/chrome/portal.d.ts +1 -1
- package/lib/chrome/portal.js +1 -1
- package/lib/chrome/sidebar.d.ts +1 -1
- package/lib/chrome/sidebar.js +134 -153
- package/lib/chrome/tokens.d.ts +1 -1
- package/lib/chrome/tokens.js +121 -68
- package/lib/chrome/workspace.d.ts +2 -2
- package/lib/chrome/workspace.js +35 -254
- package/lib/chrome.js +4 -0
- package/lib/client.d.ts +5 -12
- package/lib/client.js +6262 -4455
- package/lib/composer-avatar.d.ts +18 -0
- package/lib/composer-avatar.js +441 -0
- package/lib/composer-send-heixiu.d.ts +8 -0
- package/lib/composer-send-heixiu.js +133 -0
- package/lib/gaze.js +3 -3
- package/lib/generated-backgrounds.d.ts +14 -0
- package/lib/generated-backgrounds.js +14 -0
- package/lib/generated-character-motion.d.ts +4 -0
- package/lib/generated-character-motion.js +2 -0
- package/lib/generated-identity.d.ts +1 -0
- package/lib/generated-identity.js +1 -0
- package/lib/generated-keyart.d.ts +18 -3
- package/lib/generated-keyart.js +18 -3
- package/lib/host-contract.d.ts +9 -0
- package/lib/host-contract.js +13 -0
- package/lib/host-dom.d.ts +11 -0
- package/lib/host-dom.js +60 -0
- package/lib/loading-heixiu.js +3 -3
- package/lib/metallic-brand-mark.d.ts +10 -0
- package/lib/metallic-brand-mark.js +323 -0
- package/lib/plugin.d.ts +1 -1
- package/lib/plugin.js +31 -16
- package/lib/portal.js +11 -10
- package/lib/reactions.js +3 -3
- package/lib/scene/avatar-model.d.ts +6 -0
- package/lib/scene/avatar-model.js +646 -0
- package/lib/scene/avatar-motion.d.ts +3 -0
- package/lib/scene/avatar-motion.js +799 -0
- package/lib/scene/character-idle.d.ts +17 -0
- package/lib/scene/character-idle.js +65 -0
- package/lib/scene/character-layout.d.ts +24 -0
- package/lib/scene/character-layout.js +51 -0
- package/lib/scene/character-motion-clock.d.ts +18 -0
- package/lib/scene/character-motion-clock.js +57 -0
- package/lib/scene/character-motion-types.d.ts +12 -0
- package/lib/scene/character-motion-types.js +2 -0
- package/lib/scene/character-motion.d.ts +6 -0
- package/lib/scene/character-motion.js +126 -0
- package/lib/scene/character-poses.d.ts +26 -0
- package/lib/scene/character-poses.js +11 -0
- package/lib/scene/character-rig-renderer.d.ts +4 -0
- package/lib/scene/character-rig-renderer.js +85 -0
- package/lib/scene/character-rig.d.ts +20 -0
- package/lib/scene/character-rig.js +53 -0
- package/lib/scene/heixiu-feedback.d.ts +1 -1
- package/lib/scene/heixiu-feedback.js +0 -17
- package/lib/scene/pointer-bridge.d.ts +21 -0
- package/lib/scene/pointer-bridge.js +155 -0
- package/lib/scene/runtime.d.ts +12 -0
- package/lib/scene/runtime.js +87 -0
- package/lib/scene/styles.d.ts +7 -0
- package/lib/scene/styles.js +75 -0
- package/lib/scene/sylva-performance.d.ts +11 -0
- package/lib/scene/sylva-performance.js +58 -0
- package/lib/scene/wallpaper-character-styles.d.ts +3 -0
- package/lib/scene/wallpaper-character-styles.js +53 -0
- package/lib/scene/wallpaper-character.d.ts +4 -0
- package/lib/scene/wallpaper-character.js +213 -0
- package/lib/scene.d.ts +7 -13
- package/lib/scene.js +7 -1023
- package/lib/sidebar-glass.js +99 -36
- package/lib/sidebar-heixiu-roaming.js +5 -5
- package/lib/sidebar-reveal.d.ts +8 -0
- package/lib/sidebar-reveal.js +51 -0
- package/lib/state.d.ts +14 -2
- package/lib/state.js +12 -4
- package/lib/theme.js +2 -2
- package/lib/vendor/bloub/decor.d.ts +114 -0
- package/lib/vendor/bloub/decor.js +198 -0
- package/lib/vendor/bloub/engine.d.ts +213 -0
- package/lib/vendor/bloub/engine.js +452 -0
- package/lib/vendor/bloub/expressions.d.ts +35 -0
- package/lib/vendor/bloub/expressions.js +143 -0
- package/lib/vendor/bloub/eyefit.d.ts +75 -0
- package/lib/vendor/bloub/eyefit.js +393 -0
- package/lib/vendor/bloub/face.d.ts +63 -0
- package/lib/vendor/bloub/face.js +106 -0
- package/lib/vendor/bloub/math.d.ts +22 -0
- package/lib/vendor/bloub/math.js +36 -0
- package/lib/vendor/bloub/profiles.d.ts +8 -0
- package/lib/vendor/bloub/profiles.js +20 -0
- package/lib/vendor/bloub/repere.d.ts +30 -0
- package/lib/vendor/bloub/repere.js +32 -0
- package/lib/vendor/bloub/shape.d.ts +80 -0
- package/lib/vendor/bloub/shape.js +268 -0
- package/lib/vendor/bloub/skins.d.ts +36 -0
- package/lib/vendor/bloub/skins.js +74 -0
- package/lib/vendor/bloub/states.d.ts +87 -0
- package/lib/vendor/bloub/states.js +468 -0
- package/package.json +23 -6
- package/lib/appearance.d.ts.map +0 -1
- package/lib/appearance.js.map +0 -1
- package/lib/blink.d.ts.map +0 -1
- package/lib/blink.js.map +0 -1
- package/lib/boot-appearance.d.ts.map +0 -1
- package/lib/boot-appearance.js.map +0 -1
- package/lib/boot-loader.d.ts.map +0 -1
- package/lib/boot-loader.js.map +0 -1
- package/lib/chrome/accessibility.d.ts.map +0 -1
- package/lib/chrome/accessibility.js.map +0 -1
- package/lib/chrome/blink.d.ts.map +0 -1
- package/lib/chrome/blink.js.map +0 -1
- package/lib/chrome/composer.d.ts.map +0 -1
- package/lib/chrome/composer.js.map +0 -1
- package/lib/chrome/conversation-messages.d.ts.map +0 -1
- package/lib/chrome/conversation-messages.js.map +0 -1
- package/lib/chrome/conversation.d.ts.map +0 -1
- package/lib/chrome/conversation.js.map +0 -1
- package/lib/chrome/frames.d.ts.map +0 -1
- package/lib/chrome/frames.js.map +0 -1
- package/lib/chrome/gaze.d.ts.map +0 -1
- package/lib/chrome/gaze.js.map +0 -1
- package/lib/chrome/identity.d.ts.map +0 -1
- package/lib/chrome/identity.js.map +0 -1
- package/lib/chrome/overlays.d.ts.map +0 -1
- package/lib/chrome/overlays.js.map +0 -1
- package/lib/chrome/portal.d.ts.map +0 -1
- package/lib/chrome/portal.js.map +0 -1
- package/lib/chrome/reactions.d.ts.map +0 -1
- package/lib/chrome/reactions.js.map +0 -1
- package/lib/chrome/sidebar.d.ts.map +0 -1
- package/lib/chrome/sidebar.js.map +0 -1
- package/lib/chrome/tokens.d.ts.map +0 -1
- package/lib/chrome/tokens.js.map +0 -1
- package/lib/chrome/workspace.d.ts.map +0 -1
- package/lib/chrome/workspace.js.map +0 -1
- package/lib/chrome.d.ts.map +0 -1
- package/lib/chrome.js.map +0 -1
- package/lib/client.d.ts.map +0 -1
- package/lib/client.js.map +0 -7
- package/lib/gaze.d.ts.map +0 -1
- package/lib/gaze.js.map +0 -1
- package/lib/generated-identity.d.ts.map +0 -1
- package/lib/generated-identity.js.map +0 -1
- package/lib/generated-keyart.d.ts.map +0 -1
- package/lib/generated-keyart.js.map +0 -1
- package/lib/generated-loading-assets.d.ts.map +0 -1
- package/lib/generated-loading-assets.js.map +0 -1
- package/lib/generated-sidebar-assets.d.ts +0 -4
- package/lib/generated-sidebar-assets.d.ts.map +0 -1
- package/lib/generated-sidebar-assets.js +0 -4
- package/lib/generated-sidebar-assets.js.map +0 -1
- package/lib/heixiu-interactions.d.ts.map +0 -1
- package/lib/heixiu-interactions.js.map +0 -1
- package/lib/index.d.ts.map +0 -1
- package/lib/index.js.map +0 -1
- package/lib/loading-heixiu.d.ts.map +0 -1
- package/lib/loading-heixiu.js.map +0 -1
- package/lib/plugin.d.ts.map +0 -1
- package/lib/plugin.js.map +0 -1
- package/lib/portal.d.ts.map +0 -1
- package/lib/portal.js.map +0 -1
- package/lib/reactions.d.ts.map +0 -1
- package/lib/reactions.js.map +0 -1
- package/lib/scene/heixiu-feedback.d.ts.map +0 -1
- package/lib/scene/heixiu-feedback.js.map +0 -1
- package/lib/scene/heixiu-interactions.d.ts.map +0 -1
- package/lib/scene/heixiu-interactions.js.map +0 -1
- package/lib/scene/state-transitions.d.ts.map +0 -1
- package/lib/scene/state-transitions.js.map +0 -1
- package/lib/scene.d.ts.map +0 -1
- package/lib/scene.js.map +0 -1
- package/lib/sidebar-glass.d.ts.map +0 -1
- package/lib/sidebar-glass.js.map +0 -1
- package/lib/sidebar-heixiu-escape.d.ts.map +0 -1
- package/lib/sidebar-heixiu-escape.js.map +0 -1
- package/lib/sidebar-heixiu-roaming.d.ts.map +0 -1
- package/lib/sidebar-heixiu-roaming.js.map +0 -1
- package/lib/state.d.ts.map +0 -1
- package/lib/state.js.map +0 -1
- package/lib/theme.d.ts.map +0 -1
- package/lib/theme.js.map +0 -1
package/lib/sidebar-glass.js
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
import { XIAOHEI_SCENE_LAYER_ID } from './scene.js';
|
|
2
|
-
import {
|
|
1
|
+
import { XIAOHEI_SCENE_LAYER_ID, XIAOHEI_SCENE_WORLD_CLASS } from './scene.js';
|
|
2
|
+
import { subscribeXiaoheiHostDom } from './host-dom.js';
|
|
3
|
+
import { XIAOHEI_HOST_SELECTORS } from './host-contract.js';
|
|
4
|
+
import { createSidebarReveal } from './sidebar-reveal.js';
|
|
3
5
|
/** Stable id for the paint-only glass surface behind DSH's native sidebar. */
|
|
4
6
|
export const XIAOHEI_SIDEBAR_GLASS_ID = 'dsh-theme-xiaohei/sidebar-glass';
|
|
5
|
-
const SIDEBAR_SHELL_SELECTOR = "#root [data-slot='sidebar'] > div";
|
|
6
7
|
const HORIZONTAL_INSET_START = 7;
|
|
7
8
|
const HORIZONTAL_INSET_END = 7;
|
|
8
9
|
const VERTICAL_INSET = 8;
|
|
10
|
+
const RESIZE_SETTLE_MS = 120;
|
|
9
11
|
/** Keep the visual surface inside the native sidebar without changing layout. */
|
|
10
12
|
export function resolveXiaoheiSidebarGlassBounds(rect) {
|
|
11
13
|
return {
|
|
@@ -28,52 +30,109 @@ export function installXiaoheiSidebarGlass(doc = typeof document === 'undefined'
|
|
|
28
30
|
const win = browserWindow;
|
|
29
31
|
let disposed = false;
|
|
30
32
|
let glass;
|
|
31
|
-
let
|
|
33
|
+
let sidebarColumn;
|
|
32
34
|
let animationFrame;
|
|
35
|
+
let resizeSettleTimer;
|
|
36
|
+
let resizing = false;
|
|
37
|
+
let appliedBounds;
|
|
38
|
+
let geometryDirty = true;
|
|
39
|
+
const reveal = createSidebarReveal(doc);
|
|
40
|
+
const clearResizeState = () => {
|
|
41
|
+
if (resizeSettleTimer !== undefined)
|
|
42
|
+
win.clearTimeout(resizeSettleTimer);
|
|
43
|
+
resizeSettleTimer = undefined;
|
|
44
|
+
resizing = false;
|
|
45
|
+
doc.documentElement.removeAttribute('data-xiaohei-sidebar-resizing');
|
|
46
|
+
};
|
|
47
|
+
const markResizeActivity = () => {
|
|
48
|
+
if (glass === undefined)
|
|
49
|
+
return;
|
|
50
|
+
if (!resizing) {
|
|
51
|
+
resizing = true;
|
|
52
|
+
doc.documentElement.setAttribute('data-xiaohei-sidebar-resizing', '');
|
|
53
|
+
}
|
|
54
|
+
if (resizeSettleTimer !== undefined)
|
|
55
|
+
win.clearTimeout(resizeSettleTimer);
|
|
56
|
+
resizeSettleTimer = win.setTimeout(() => {
|
|
57
|
+
resizeSettleTimer = undefined;
|
|
58
|
+
resizing = false;
|
|
59
|
+
doc.documentElement.removeAttribute('data-xiaohei-sidebar-resizing');
|
|
60
|
+
}, RESIZE_SETTLE_MS);
|
|
61
|
+
};
|
|
33
62
|
const resizeObserver = typeof win.ResizeObserver === 'function'
|
|
34
|
-
? new win.ResizeObserver(() =>
|
|
63
|
+
? new win.ResizeObserver(() => {
|
|
64
|
+
if (disposed)
|
|
65
|
+
return;
|
|
66
|
+
// RO runs after host layout and before paint. Update the independent
|
|
67
|
+
// paint layer now, not in next frame's RAF (which visibly trails).
|
|
68
|
+
const changed = applyBounds();
|
|
69
|
+
geometryDirty = false;
|
|
70
|
+
if (changed)
|
|
71
|
+
markResizeActivity();
|
|
72
|
+
})
|
|
35
73
|
: undefined;
|
|
36
74
|
const applyBounds = () => {
|
|
37
|
-
if (glass === undefined ||
|
|
38
|
-
return;
|
|
39
|
-
const bounds = resolveXiaoheiSidebarGlassBounds(
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
75
|
+
if (glass === undefined || sidebarColumn === undefined)
|
|
76
|
+
return false;
|
|
77
|
+
const bounds = resolveXiaoheiSidebarGlassBounds(sidebarColumn.getBoundingClientRect());
|
|
78
|
+
reveal.resize(bounds.width + HORIZONTAL_INSET_START + HORIZONTAL_INSET_END);
|
|
79
|
+
const changed = appliedBounds !== undefined && (bounds.left !== appliedBounds.left || bounds.top !== appliedBounds.top ||
|
|
80
|
+
bounds.width !== appliedBounds.width || bounds.height !== appliedBounds.height);
|
|
81
|
+
if (bounds.left !== appliedBounds?.left) {
|
|
82
|
+
glass.style.setProperty('--xiaohei-sidebar-glass-left', `${bounds.left}px`);
|
|
83
|
+
}
|
|
84
|
+
if (bounds.top !== appliedBounds?.top) {
|
|
85
|
+
glass.style.setProperty('--xiaohei-sidebar-glass-top', `${bounds.top}px`);
|
|
86
|
+
}
|
|
87
|
+
if (bounds.width !== appliedBounds?.width) {
|
|
88
|
+
glass.style.setProperty('--xiaohei-sidebar-glass-width', `${bounds.width}px`);
|
|
89
|
+
}
|
|
90
|
+
if (bounds.height !== appliedBounds?.height) {
|
|
91
|
+
glass.style.setProperty('--xiaohei-sidebar-glass-height', `${bounds.height}px`);
|
|
92
|
+
}
|
|
93
|
+
appliedBounds = bounds;
|
|
94
|
+
return changed;
|
|
44
95
|
};
|
|
45
96
|
const reconcile = () => {
|
|
46
97
|
if (disposed)
|
|
47
98
|
return;
|
|
48
99
|
const sceneLayer = doc.getElementById(XIAOHEI_SCENE_LAYER_ID);
|
|
49
|
-
const
|
|
50
|
-
if (
|
|
100
|
+
const nextSidebarColumn = doc.querySelector(XIAOHEI_HOST_SELECTORS.sidebarColumn) ?? undefined;
|
|
101
|
+
if (nextSidebarColumn !== sidebarColumn) {
|
|
51
102
|
resizeObserver?.disconnect();
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
103
|
+
sidebarColumn = nextSidebarColumn;
|
|
104
|
+
geometryDirty = true;
|
|
105
|
+
if (sidebarColumn !== undefined)
|
|
106
|
+
resizeObserver?.observe(sidebarColumn);
|
|
55
107
|
}
|
|
56
|
-
if (sceneLayer === null ||
|
|
108
|
+
if (sceneLayer === null || sidebarColumn === undefined) {
|
|
109
|
+
reveal.setColumn(undefined);
|
|
110
|
+
clearResizeState();
|
|
57
111
|
glass?.remove();
|
|
58
112
|
glass = undefined;
|
|
113
|
+
appliedBounds = undefined;
|
|
114
|
+
geometryDirty = true;
|
|
59
115
|
return;
|
|
60
116
|
}
|
|
117
|
+
reveal.setColumn(sidebarColumn);
|
|
61
118
|
if (glass === undefined || glass.parentElement !== sceneLayer) {
|
|
62
119
|
doc.getElementById(XIAOHEI_SIDEBAR_GLASS_ID)?.remove();
|
|
63
120
|
glass = doc.createElement('div');
|
|
64
121
|
glass.id = XIAOHEI_SIDEBAR_GLASS_ID;
|
|
65
122
|
glass.setAttribute('aria-hidden', 'true');
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
123
|
+
appliedBounds = undefined;
|
|
124
|
+
geometryDirty = true;
|
|
125
|
+
const world = sceneLayer.querySelector(`.${XIAOHEI_SCENE_WORLD_CLASS}`);
|
|
126
|
+
// null is meaningful here: insertBefore(node, null) appends after a
|
|
127
|
+
// last-child wallpaper. Falling back to firstChild hides glass UNDER it.
|
|
128
|
+
sceneLayer.insertBefore(glass, world !== null ? world.nextSibling : sceneLayer.firstChild);
|
|
129
|
+
}
|
|
130
|
+
// Streamed text mutates the host tree frequently. Recheck slot identity,
|
|
131
|
+
// but do not force layout unless sidebar geometry actually changed.
|
|
132
|
+
if (geometryDirty) {
|
|
133
|
+
applyBounds();
|
|
134
|
+
geometryDirty = false;
|
|
75
135
|
}
|
|
76
|
-
applyBounds();
|
|
77
136
|
};
|
|
78
137
|
function scheduleReconcile() {
|
|
79
138
|
if (disposed || animationFrame !== undefined)
|
|
@@ -83,23 +142,27 @@ export function installXiaoheiSidebarGlass(doc = typeof document === 'undefined'
|
|
|
83
142
|
reconcile();
|
|
84
143
|
});
|
|
85
144
|
}
|
|
86
|
-
const
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
145
|
+
const unsubscribeHostDom = subscribeXiaoheiHostDom(doc, scheduleReconcile);
|
|
146
|
+
const onViewportResize = () => {
|
|
147
|
+
geometryDirty = true;
|
|
148
|
+
scheduleReconcile();
|
|
149
|
+
};
|
|
150
|
+
win.addEventListener('resize', onViewportResize, { passive: true });
|
|
91
151
|
scheduleReconcile();
|
|
92
152
|
return () => {
|
|
93
153
|
disposed = true;
|
|
94
154
|
if (animationFrame !== undefined)
|
|
95
155
|
win.cancelAnimationFrame(animationFrame);
|
|
96
156
|
animationFrame = undefined;
|
|
97
|
-
|
|
157
|
+
unsubscribeHostDom();
|
|
98
158
|
resizeObserver?.disconnect();
|
|
99
|
-
|
|
159
|
+
reveal.dispose();
|
|
160
|
+
win.removeEventListener('resize', onViewportResize);
|
|
161
|
+
clearResizeState();
|
|
100
162
|
glass?.remove();
|
|
101
163
|
glass = undefined;
|
|
102
|
-
|
|
164
|
+
sidebarColumn = undefined;
|
|
165
|
+
appliedBounds = undefined;
|
|
103
166
|
};
|
|
104
167
|
}
|
|
105
168
|
//# sourceMappingURL=sidebar-glass.js.map
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { createXiaoheiSidebarEscapeController, XIAOHEI_SIDEBAR_ESCAPE_CSS, } from './sidebar-heixiu-escape.js';
|
|
2
|
+
import { subscribeXiaoheiHostDom } from './host-dom.js';
|
|
3
|
+
import { XIAOHEI_HOST_SELECTORS } from './host-contract.js';
|
|
2
4
|
export const XIAOHEI_SIDEBAR_ROAMING_STYLE_ID = 'dsh-theme-xiaohei/sidebar-heixiu-roaming-style';
|
|
3
5
|
const SIDEBAR_HEIXIU_SELECTOR = '.xiaohei-scene__heixiu--sidebar';
|
|
4
|
-
const SIDEBAR_SELECTOR = "[data-slot='sidebar']";
|
|
5
6
|
const INTERACTIVE_SELECTOR = [
|
|
6
7
|
'button',
|
|
7
8
|
'a[href]',
|
|
@@ -200,7 +201,7 @@ export function installXiaoheiSidebarHeixiuRoaming(doc = typeof document === 'un
|
|
|
200
201
|
if (disposed)
|
|
201
202
|
return;
|
|
202
203
|
const nextCreature = doc.querySelector(SIDEBAR_HEIXIU_SELECTOR) ?? undefined;
|
|
203
|
-
const nextHost = doc.querySelector(
|
|
204
|
+
const nextHost = doc.querySelector(XIAOHEI_HOST_SELECTORS.sidebar)?.firstElementChild;
|
|
204
205
|
const nextHostElement = nextHost instanceof win.HTMLElement ? nextHost : undefined;
|
|
205
206
|
if (nextCreature === creature && nextHostElement === host)
|
|
206
207
|
return;
|
|
@@ -266,8 +267,7 @@ export function installXiaoheiSidebarHeixiuRoaming(doc = typeof document === 'un
|
|
|
266
267
|
hostResizeObserver?.observe(host);
|
|
267
268
|
};
|
|
268
269
|
bind();
|
|
269
|
-
const
|
|
270
|
-
observer.observe(doc.body, { childList: true, subtree: true });
|
|
270
|
+
const unsubscribeHostDom = subscribeXiaoheiHostDom(doc, queueBind);
|
|
271
271
|
doc.addEventListener('visibilitychange', resumeOrPause);
|
|
272
272
|
win.addEventListener('resize', resumeOrPause, { passive: true });
|
|
273
273
|
reducedMotion.addEventListener('change', resumeOrPause);
|
|
@@ -276,7 +276,7 @@ export function installXiaoheiSidebarHeixiuRoaming(doc = typeof document === 'un
|
|
|
276
276
|
disposed = true;
|
|
277
277
|
escapeController.dispose();
|
|
278
278
|
clearTimer();
|
|
279
|
-
|
|
279
|
+
unsubscribeHostDom();
|
|
280
280
|
hostStateObserver.disconnect();
|
|
281
281
|
hostResizeObserver?.disconnect();
|
|
282
282
|
doc.removeEventListener('visibilitychange', resumeOrPause);
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** Synchronize native wide content with the visible column, without changing
|
|
2
|
+
* Host layout/state or adding a competing animation timer. */
|
|
3
|
+
export declare function createSidebarReveal(doc: Document): {
|
|
4
|
+
setColumn(column: HTMLElement | undefined): void;
|
|
5
|
+
resize(nextWidth: number): void;
|
|
6
|
+
dispose(): void;
|
|
7
|
+
};
|
|
8
|
+
//# sourceMappingURL=sidebar-reveal.d.ts.map
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/** Synchronize native wide content with the visible column, without changing
|
|
2
|
+
* Host layout/state or adding a competing animation timer. */
|
|
3
|
+
export function createSidebarReveal(doc) {
|
|
4
|
+
let shell;
|
|
5
|
+
let observer;
|
|
6
|
+
let phase = '', width = 0, waiting = false;
|
|
7
|
+
const attribute = 'data-xiaohei-sidebar-reveal';
|
|
8
|
+
const readPhase = () => shell?.className.includes('_collapsed') ? 'rail'
|
|
9
|
+
: shell?.className.includes('_fading') ? 'closing' : 'wide';
|
|
10
|
+
const apply = () => {
|
|
11
|
+
if (!shell)
|
|
12
|
+
return;
|
|
13
|
+
// The Host freezes its shell at the requested width during grid motion.
|
|
14
|
+
// Reading the inline target does not force a layout.
|
|
15
|
+
const target = Number.parseFloat(shell.style.width);
|
|
16
|
+
if (waiting && phase === 'wide' && (!Number.isFinite(target) || width >= target - 2))
|
|
17
|
+
waiting = false;
|
|
18
|
+
const value = waiting ? 'waiting' : 'ready';
|
|
19
|
+
if (shell.getAttribute(attribute) !== value)
|
|
20
|
+
shell.setAttribute(attribute, value);
|
|
21
|
+
};
|
|
22
|
+
const changed = () => {
|
|
23
|
+
const next = readPhase();
|
|
24
|
+
if (next === 'wide' && phase !== 'wide')
|
|
25
|
+
waiting = true;
|
|
26
|
+
if (next === 'rail')
|
|
27
|
+
waiting = false;
|
|
28
|
+
phase = next;
|
|
29
|
+
apply();
|
|
30
|
+
};
|
|
31
|
+
return {
|
|
32
|
+
setColumn(column) {
|
|
33
|
+
const next = column?.querySelector?.("[data-slot='sidebar'] > div") ?? undefined;
|
|
34
|
+
if (next === shell)
|
|
35
|
+
return;
|
|
36
|
+
observer?.disconnect();
|
|
37
|
+
shell?.removeAttribute(attribute);
|
|
38
|
+
shell = next;
|
|
39
|
+
waiting = false;
|
|
40
|
+
phase = readPhase();
|
|
41
|
+
if (!shell)
|
|
42
|
+
return;
|
|
43
|
+
observer = new doc.defaultView.MutationObserver(changed);
|
|
44
|
+
observer.observe(shell, { attributes: true, attributeFilter: ['class', 'style'] });
|
|
45
|
+
apply();
|
|
46
|
+
},
|
|
47
|
+
resize(nextWidth) { width = nextWidth; apply(); },
|
|
48
|
+
dispose() { observer?.disconnect(); shell?.removeAttribute(attribute); shell = undefined; },
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=sidebar-reveal.js.map
|
package/lib/state.d.ts
CHANGED
|
@@ -1,9 +1,21 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ISessions, SessionSnapshot, SessionSummary } from '@deepseek-ai/dsh-api-session-controller/client';
|
|
2
2
|
export declare const XIAOHEI_STATE_ATTRIBUTE = "data-xiaohei-state";
|
|
3
3
|
export declare const XIAOHEI_COMPLETE_DURATION_MS = 1600;
|
|
4
4
|
export type XiaoheiState = 'idle' | 'thinking' | 'streaming' | 'tool' | 'waiting' | 'complete' | 'error';
|
|
5
5
|
/** Resolve one official DSH snapshot using the theme's visible-state priority. */
|
|
6
|
-
export declare function resolveXiaoheiState(snapshot:
|
|
6
|
+
export declare function resolveXiaoheiState(snapshot: SessionSnapshot | LegacySessionActivity | undefined, summary: SessionSummary | undefined): Exclude<XiaoheiState, 'complete'>;
|
|
7
|
+
interface LegacySessionActivity {
|
|
8
|
+
removed: boolean;
|
|
9
|
+
openState: 'cold' | 'loading' | 'open' | 'error';
|
|
10
|
+
openError: unknown | null;
|
|
11
|
+
promptError: unknown | null;
|
|
12
|
+
lastAgentError: unknown | null;
|
|
13
|
+
pending: readonly unknown[];
|
|
14
|
+
runningCalls: readonly unknown[];
|
|
15
|
+
partial: unknown | null;
|
|
16
|
+
running: boolean;
|
|
17
|
+
}
|
|
7
18
|
/** Mirror the selected Session's official detailed state onto the theme root. */
|
|
8
19
|
export declare function bindXiaoheiSessionState(sessions: Pick<ISessions, 'list' | 'binding'>, doc?: Document | undefined, completeDurationMs?: number): () => void;
|
|
20
|
+
export {};
|
|
9
21
|
//# sourceMappingURL=state.d.ts.map
|
package/lib/state.js
CHANGED
|
@@ -9,20 +9,28 @@ export function resolveXiaoheiState(snapshot, summary) {
|
|
|
9
9
|
|| snapshot.promptError !== null
|
|
10
10
|
|| snapshot.lastAgentError !== null)
|
|
11
11
|
return 'error';
|
|
12
|
-
|
|
12
|
+
const pending = 'pending' in snapshot
|
|
13
|
+
? snapshot.pending
|
|
14
|
+
: [...snapshot.queue, ...snapshot.pendingSubmissions];
|
|
15
|
+
const runningCalls = 'runningCalls' in snapshot ? snapshot.runningCalls : [];
|
|
16
|
+
const partial = 'partial' in snapshot ? snapshot.partial : null;
|
|
17
|
+
if (pending.length > 0 || legacyPendingInteraction(summary) !== undefined)
|
|
13
18
|
return 'waiting';
|
|
14
|
-
if (
|
|
19
|
+
if (runningCalls.length > 0)
|
|
15
20
|
return 'tool';
|
|
16
|
-
if (snapshot.running &&
|
|
21
|
+
if (snapshot.running && partial !== null)
|
|
17
22
|
return 'streaming';
|
|
18
23
|
if (snapshot.running)
|
|
19
24
|
return 'thinking';
|
|
20
25
|
return 'idle';
|
|
21
26
|
}
|
|
22
|
-
if (summary
|
|
27
|
+
if (legacyPendingInteraction(summary) !== undefined)
|
|
23
28
|
return 'waiting';
|
|
24
29
|
return summary?.running === true ? 'thinking' : 'idle';
|
|
25
30
|
}
|
|
31
|
+
function legacyPendingInteraction(summary) {
|
|
32
|
+
return summary?.pendingInteraction;
|
|
33
|
+
}
|
|
26
34
|
/** Mirror the selected Session's official detailed state onto the theme root. */
|
|
27
35
|
export function bindXiaoheiSessionState(sessions, doc = typeof document === 'undefined' ? undefined : document, completeDurationMs = XIAOHEI_COMPLETE_DURATION_MS) {
|
|
28
36
|
if (doc === undefined)
|
package/lib/theme.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
export const XIAOHEI_DAWN_THEME_ID = 'xiaohei-dawn';
|
|
3
3
|
export const XIAOHEI_NIGHT_THEME_ID = 'xiaohei-night';
|
|
4
4
|
const DAWN_TOKENS = {
|
|
5
|
-
'--dsw-alias-bg-base': '
|
|
5
|
+
'--dsw-alias-bg-base': 'transparent',
|
|
6
6
|
'--dsw-alias-bg-layer-1': 'rgb(232 237 243 / 82%)',
|
|
7
7
|
'--dsw-alias-bg-layer-2': 'rgb(238 242 247 / 90%)',
|
|
8
8
|
'--dsw-alias-bg-layer-3': 'rgb(244 247 250 / 96%)',
|
|
@@ -84,7 +84,7 @@ const DAWN_TOKENS = {
|
|
|
84
84
|
'--dsw-specific-tip': '#E3EBEA',
|
|
85
85
|
};
|
|
86
86
|
const NIGHT_TOKENS = {
|
|
87
|
-
'--dsw-alias-bg-base': '
|
|
87
|
+
'--dsw-alias-bg-base': 'transparent',
|
|
88
88
|
'--dsw-alias-bg-layer-1': 'rgb(20 27 29 / 74%)',
|
|
89
89
|
'--dsw-alias-bg-layer-2': 'rgb(25 33 35 / 86%)',
|
|
90
90
|
'--dsw-alias-bg-layer-3': 'rgb(31 40 42 / 94%)',
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
export interface DotRender {
|
|
2
|
+
x: number;
|
|
3
|
+
y: number;
|
|
4
|
+
r: number;
|
|
5
|
+
opacity: number;
|
|
6
|
+
/** couleur explicite ; par defaut le rendu prend celle du corps */
|
|
7
|
+
color?: string;
|
|
8
|
+
/**
|
|
9
|
+
* Brume de profondeur : 0 = fondu dans le fond, 1 = couleur du corps pleine.
|
|
10
|
+
* Le melange se fait au rendu, qui seul connait la couleur choisie.
|
|
11
|
+
*/
|
|
12
|
+
depth?: number;
|
|
13
|
+
/**
|
|
14
|
+
* Forme non circulaire, en unites de rayon de boule et centree sur l'origine
|
|
15
|
+
* (le point du "!" penche est une goutte, pas un disque). Quand elle est
|
|
16
|
+
* fournie, `r` n'est plus utilise pour le trace.
|
|
17
|
+
*/
|
|
18
|
+
d?: string;
|
|
19
|
+
/** rotation appliquee a `d`, en degres */
|
|
20
|
+
rot?: number;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Ce qu'un etat declare : la geometrie de l'arc reste en unites de rayon de
|
|
24
|
+
* boule, c'est le moteur (seul a connaitre l'echelle du viewBox) qui la
|
|
25
|
+
* rasterise. Sans ca les etats devraient connaitre le viewBox.
|
|
26
|
+
*/
|
|
27
|
+
export interface ArcSpec {
|
|
28
|
+
id: string;
|
|
29
|
+
seed: ArcSeed;
|
|
30
|
+
t: number;
|
|
31
|
+
opacity: number;
|
|
32
|
+
}
|
|
33
|
+
export interface ArcRender {
|
|
34
|
+
id: string;
|
|
35
|
+
/** portion devant le corps */
|
|
36
|
+
front: string;
|
|
37
|
+
/** portion derriere le corps (dessinee avant, donc masquee par la silhouette) */
|
|
38
|
+
back: string;
|
|
39
|
+
width: number;
|
|
40
|
+
opacity: number;
|
|
41
|
+
/** degrade de teinte le long du trace */
|
|
42
|
+
grad: {
|
|
43
|
+
x1: number;
|
|
44
|
+
y1: number;
|
|
45
|
+
x2: number;
|
|
46
|
+
y2: number;
|
|
47
|
+
stops: string[];
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
export interface ArcSeed {
|
|
51
|
+
/** demi-grand axe, en unites de rayon de boule */
|
|
52
|
+
a: number;
|
|
53
|
+
/** aplatissement b/a : mesure <= 0.45, les plans d'orbite sont vus par la tranche */
|
|
54
|
+
k: number;
|
|
55
|
+
/** inclinaison du grand axe a l'ecran, radians */
|
|
56
|
+
tilt: number;
|
|
57
|
+
/** tours par seconde */
|
|
58
|
+
speed: number;
|
|
59
|
+
phase: number;
|
|
60
|
+
/** fraction du tour reellement tracee */
|
|
61
|
+
sweep: number;
|
|
62
|
+
hue: number;
|
|
63
|
+
hueSpan: number;
|
|
64
|
+
width: number;
|
|
65
|
+
cx: number;
|
|
66
|
+
cy: number;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Projette un cercle 3D incline en orthographique.
|
|
70
|
+
*
|
|
71
|
+
* Le cercle vit dans le plan engendre par u (dans l'ecran) et v (qui plonge
|
|
72
|
+
* dans la profondeur). La composante z sert a couper l'arc en deux : la moitie
|
|
73
|
+
* arriere est dessinee avant le corps, donc occultee par lui. C'est ce vrai tri
|
|
74
|
+
* en profondeur qui fait lire les anneaux comme des orbites et pas comme un
|
|
75
|
+
* dessin plat.
|
|
76
|
+
*/
|
|
77
|
+
export declare function arcRender(seed: ArcSeed, t: number, scale: number, id: string, opacity?: number): ArcRender;
|
|
78
|
+
/**
|
|
79
|
+
* 6 anneaux, demi-grand axe 1.30-1.40 (donc nettement plus grands que la
|
|
80
|
+
* boule), aplatissement toujours <= 0.45, epaisseur 0.055, ~3.3 tours/s.
|
|
81
|
+
*/
|
|
82
|
+
export declare const RINGS: ArcSeed[];
|
|
83
|
+
/**
|
|
84
|
+
* Bouquet d'arcs emboites qui balaie le triangle juste avant les orbites.
|
|
85
|
+
* Vus quasiment par la tranche (d'ou la forme en epingle a cheveux), rmax 1.37.
|
|
86
|
+
*/
|
|
87
|
+
export declare const SWOOSH: ArcSeed[];
|
|
88
|
+
/** x mesures : -0.557 / -0.013 / +0.532, y = 0. */
|
|
89
|
+
export declare const DOT_X: readonly [-0.557, -0.013, 0.532];
|
|
90
|
+
export declare const DOT_R = 0.165;
|
|
91
|
+
export declare const DOT_PEAK = 1.25;
|
|
92
|
+
/**
|
|
93
|
+
* Les particules ne partent pas en ligne droite : elles spiralent vers le
|
|
94
|
+
* centre (rayon x0.75 par frame, angle +100 deg/s) en grossissant, et passent
|
|
95
|
+
* derriere le noyau ou elles sont avalees.
|
|
96
|
+
*/
|
|
97
|
+
export declare function particles(t: number, scale: number): DotRender[];
|
|
98
|
+
export declare const COMET_RIBBONS: ArcSeed[];
|
|
99
|
+
/** Rayon du point de la comete, mesure a 0.129. */
|
|
100
|
+
export declare const COMET_DOT = 0.129;
|
|
101
|
+
/** Bleu releve au pixel. */
|
|
102
|
+
export declare const NOTIF_BLUE = "#2496e8";
|
|
103
|
+
/** La pastille est posee exactement sur la circonference, a -42deg. */
|
|
104
|
+
export declare const NOTIF_ANGLE = -42;
|
|
105
|
+
export declare const NOTIF_DIST = 1.003;
|
|
106
|
+
/** Rayon au repos ; le pop culmine 14 % au-dessus. */
|
|
107
|
+
export declare const NOTIF_R = 0.15;
|
|
108
|
+
export declare const NOTIF_POP = 1.14;
|
|
109
|
+
/**
|
|
110
|
+
* L'encoche est un disque concentrique a la pastille, soustrait du corps.
|
|
111
|
+
* La marge est constante (0.054 R) et suit l'echelle du corps.
|
|
112
|
+
*/
|
|
113
|
+
export declare const NOTIF_MARGIN = 0.054;
|
|
114
|
+
//# sourceMappingURL=decor.d.ts.map
|