@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
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare const XIAOHEI_HOST_SELECTORS: {
|
|
2
|
+
readonly sidebar: "[data-slot='sidebar']";
|
|
3
|
+
readonly sidebarShell: "#root [data-slot='sidebar'] > div";
|
|
4
|
+
readonly sidebarColumn: "#root :has(> [data-slot='sidebar'])";
|
|
5
|
+
readonly composerCard: "#root [data-composer-card='true']";
|
|
6
|
+
readonly composerHeroMark: "#root .xiaohei-brand-mark[data-brand-context='hero']";
|
|
7
|
+
readonly composerHeroRow: "[class*='_headline']";
|
|
8
|
+
};
|
|
9
|
+
//# sourceMappingURL=host-contract.d.ts.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/** Keep stable DSH selectors in one compatibility boundary. */
|
|
2
|
+
const sidebar = "[data-slot='sidebar']";
|
|
3
|
+
export const XIAOHEI_HOST_SELECTORS = {
|
|
4
|
+
sidebar,
|
|
5
|
+
sidebarShell: `#root ${sidebar} > div`,
|
|
6
|
+
// The shell holds its expanded width while its contents fade. Only the
|
|
7
|
+
// outer layout column represents the currently visible animated width.
|
|
8
|
+
sidebarColumn: `#root :has(> ${sidebar})`,
|
|
9
|
+
composerCard: "#root [data-composer-card='true']",
|
|
10
|
+
composerHeroMark: "#root .xiaohei-brand-mark[data-brand-context='hero']",
|
|
11
|
+
composerHeroRow: "[class*='_headline']",
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=host-contract.js.map
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** A listener that reconciles plugin-owned DOM after the DSH host tree changes. */
|
|
2
|
+
export type XiaoheiHostDomListener = () => void;
|
|
3
|
+
/**
|
|
4
|
+
* Share one batched body observer across all runtime theme behaviours.
|
|
5
|
+
*
|
|
6
|
+
* The Host owns the React tree and may replace slots at any time. Theme modules
|
|
7
|
+
* subscribe here instead of observing the full document independently. The
|
|
8
|
+
* first subscriber creates the observer and the last cleanup disconnects it.
|
|
9
|
+
*/
|
|
10
|
+
export declare function subscribeXiaoheiHostDom(doc: Document, listener: XiaoheiHostDomListener): () => void;
|
|
11
|
+
//# sourceMappingURL=host-dom.d.ts.map
|
package/lib/host-dom.js
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
const hubs = new WeakMap();
|
|
2
|
+
/**
|
|
3
|
+
* Share one batched body observer across all runtime theme behaviours.
|
|
4
|
+
*
|
|
5
|
+
* The Host owns the React tree and may replace slots at any time. Theme modules
|
|
6
|
+
* subscribe here instead of observing the full document independently. The
|
|
7
|
+
* first subscriber creates the observer and the last cleanup disconnects it.
|
|
8
|
+
*/
|
|
9
|
+
export function subscribeXiaoheiHostDom(doc, listener) {
|
|
10
|
+
const win = doc.defaultView;
|
|
11
|
+
if (doc.body === undefined || win === null || typeof win.MutationObserver !== 'function') {
|
|
12
|
+
return () => { };
|
|
13
|
+
}
|
|
14
|
+
let hub = hubs.get(doc);
|
|
15
|
+
if (hub === undefined) {
|
|
16
|
+
const listeners = new Set();
|
|
17
|
+
const nextHub = {
|
|
18
|
+
listeners,
|
|
19
|
+
queued: false,
|
|
20
|
+
};
|
|
21
|
+
const flush = () => {
|
|
22
|
+
nextHub.queued = false;
|
|
23
|
+
if (hubs.get(doc) !== nextHub)
|
|
24
|
+
return;
|
|
25
|
+
for (const subscriber of [...listeners]) {
|
|
26
|
+
try {
|
|
27
|
+
subscriber();
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
win.setTimeout(() => { throw error; }, 0);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
nextHub.observer = new win.MutationObserver(() => {
|
|
35
|
+
if (nextHub.queued)
|
|
36
|
+
return;
|
|
37
|
+
nextHub.queued = true;
|
|
38
|
+
queueMicrotask(flush);
|
|
39
|
+
});
|
|
40
|
+
nextHub.observer.observe(doc.body, { childList: true, subtree: true });
|
|
41
|
+
hubs.set(doc, nextHub);
|
|
42
|
+
hub = nextHub;
|
|
43
|
+
}
|
|
44
|
+
hub.listeners.add(listener);
|
|
45
|
+
let subscribed = true;
|
|
46
|
+
return () => {
|
|
47
|
+
if (!subscribed)
|
|
48
|
+
return;
|
|
49
|
+
subscribed = false;
|
|
50
|
+
const activeHub = hubs.get(doc);
|
|
51
|
+
if (activeHub === undefined)
|
|
52
|
+
return;
|
|
53
|
+
activeHub.listeners.delete(listener);
|
|
54
|
+
if (activeHub.listeners.size > 0)
|
|
55
|
+
return;
|
|
56
|
+
activeHub.observer?.disconnect();
|
|
57
|
+
hubs.delete(doc);
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=host-dom.js.map
|
package/lib/loading-heixiu.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { XIAOHEI_LOADING_HEIXIU_BLINK, XIAOHEI_LOADING_HEIXIU_OPEN, } from './generated-loading-assets.js';
|
|
2
|
+
import { subscribeXiaoheiHostDom } from './host-dom.js';
|
|
2
3
|
export const XIAOHEI_PLUGIN_LOADING_STYLE_ID = 'dsh-theme-xiaohei/plugin-loading-style';
|
|
3
4
|
export const XIAOHEI_PLUGIN_LOADING_CLASS = 'xiaohei-plugin-loader__track';
|
|
4
5
|
const LOADING_HINTS = new Set(['Loading plugins...', 'Loading plugins…']);
|
|
@@ -250,11 +251,10 @@ export function installXiaoheiPluginLoading(doc = typeof document === 'undefined
|
|
|
250
251
|
});
|
|
251
252
|
};
|
|
252
253
|
sync();
|
|
253
|
-
const
|
|
254
|
-
observer.observe(doc.body, { childList: true, subtree: true });
|
|
254
|
+
const unsubscribeHostDom = subscribeXiaoheiHostDom(doc, queueSync);
|
|
255
255
|
return () => {
|
|
256
256
|
disposed = true;
|
|
257
|
-
|
|
257
|
+
unsubscribeHostDom();
|
|
258
258
|
clearCard();
|
|
259
259
|
style.remove();
|
|
260
260
|
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
interface XiaoheiBrandMarkProps {
|
|
2
|
+
size: number;
|
|
3
|
+
className?: string | undefined;
|
|
4
|
+
}
|
|
5
|
+
/** Official sidebar brand occupant with a compact, lifecycle-safe metallic shader. */
|
|
6
|
+
export declare function XiaoheiMetallicBrandMark({ size, className }: XiaoheiBrandMarkProps): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
/** Official sidebar brand-name occupant paired with the Xiaohei mark. */
|
|
8
|
+
export declare function XiaoheiBrandName(): import("react/jsx-runtime").JSX.Element;
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=metallic-brand-mark.d.ts.map
|
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useRef, useState } from 'react';
|
|
3
|
+
import { XIAOHEI_BRAND_AVATAR } from './generated-identity.js';
|
|
4
|
+
// Native wide/rail switches remount this slot. A tiny navigation mark does not
|
|
5
|
+
// need a fresh GPU context and shader compilation on every toggle.
|
|
6
|
+
let sidebarMetallicSnapshot;
|
|
7
|
+
const VERTEX_SHADER = `#version 300 es
|
|
8
|
+
precision highp float;
|
|
9
|
+
in vec2 a_position;
|
|
10
|
+
out vec2 vP;
|
|
11
|
+
void main(){vP=a_position*.5+.5;gl_Position=vec4(a_position,0.,1.);}`;
|
|
12
|
+
/* Adapted from React Bits MetallicPaint. The source avatar is already a
|
|
13
|
+
* transparent tonal map, so the expensive browser-side depth solve is not
|
|
14
|
+
* needed for this compact brand mark. */
|
|
15
|
+
const FRAGMENT_SHADER = `#version 300 es
|
|
16
|
+
precision highp float;
|
|
17
|
+
in vec2 vP;
|
|
18
|
+
out vec4 oC;
|
|
19
|
+
uniform sampler2D u_tex;
|
|
20
|
+
uniform float u_time,u_ratio,u_imgRatio,u_seed,u_scale,u_refract,u_blur,u_liquid;
|
|
21
|
+
uniform float u_bright,u_contrast,u_angle,u_fresnel,u_sharp,u_wave,u_noise,u_chroma;
|
|
22
|
+
uniform float u_distort,u_contour;
|
|
23
|
+
uniform vec3 u_lightColor,u_darkColor,u_tint;
|
|
24
|
+
|
|
25
|
+
vec3 sC,sM;
|
|
26
|
+
|
|
27
|
+
vec3 pW(vec3 v){
|
|
28
|
+
vec3 i=floor(v),f=fract(v),s=sign(fract(v*.5)-.5),h=fract(sM*i+i.yzx),c=f*(f-1.);
|
|
29
|
+
return s*c*((h*16.-4.)*c-1.);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
vec3 aF(vec3 b,vec3 c){return pW(b+c.zxy-pW(b.zxy+c.yzx)+pW(b.yzx+c.xyz));}
|
|
33
|
+
vec3 lM(vec3 s,vec3 p){return(p+aF(s,p))*.5;}
|
|
34
|
+
|
|
35
|
+
vec2 fA(){
|
|
36
|
+
vec2 c=vP-.5;
|
|
37
|
+
c.x*=u_ratio>u_imgRatio?u_ratio/u_imgRatio:1.;
|
|
38
|
+
c.y*=u_ratio>u_imgRatio?1.:u_imgRatio/u_ratio;
|
|
39
|
+
return vec2(c.x+.5,.5-c.y);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
vec2 rot(vec2 p,float r){float c=cos(r),s=sin(r);return vec2(p.x*c+p.y*s,p.y*c-p.x*s);}
|
|
43
|
+
|
|
44
|
+
float bM(vec2 c,float t){
|
|
45
|
+
vec2 l=smoothstep(vec2(0.),vec2(t),c),u=smoothstep(vec2(0.),vec2(t),1.-c);
|
|
46
|
+
return l.x*l.y*u.x*u.y;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
float mG(float hi,float lo,float t,float sh,float cv){
|
|
50
|
+
sh*=(2.-u_sharp);
|
|
51
|
+
float ci=smoothstep(.15,.85,cv),r=lo;
|
|
52
|
+
float e1=.08/u_scale;
|
|
53
|
+
r=mix(r,hi,smoothstep(0.,sh*1.5,t));
|
|
54
|
+
r=mix(r,lo,smoothstep(e1-sh,e1+sh,t));
|
|
55
|
+
float e2=e1+.05/u_scale*(1.-ci*.35);
|
|
56
|
+
r=mix(r,hi,smoothstep(e2-sh,e2+sh,t));
|
|
57
|
+
float e3=e2+.025/u_scale*(1.-ci*.45);
|
|
58
|
+
r=mix(r,lo,smoothstep(e3-sh,e3+sh,t));
|
|
59
|
+
float e4=e1+.1/u_scale;
|
|
60
|
+
r=mix(r,hi,smoothstep(e4-sh,e4+sh,t));
|
|
61
|
+
float rm=1.-e4,gT=clamp((t-e4)/rm,0.,1.);
|
|
62
|
+
r=mix(r,mix(hi,lo,smoothstep(0.,1.,gT)),smoothstep(e4-sh*.5,e4+sh*.5,t));
|
|
63
|
+
return r;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
void main(){
|
|
67
|
+
sC=fract(vec3(.7548,.5698,.4154)*(u_seed+17.31))+.5;
|
|
68
|
+
sM=fract(sC.zxy-sC.yzx*1.618);
|
|
69
|
+
vec2 sc=vec2(vP.x*u_ratio,1.-vP.y);
|
|
70
|
+
float angleRad=u_angle*3.14159/180.;
|
|
71
|
+
sc=rot(sc-.5,angleRad)+.5;
|
|
72
|
+
sc=clamp(sc,0.,1.);
|
|
73
|
+
float sl=sc.x-sc.y,an=u_time*.001;
|
|
74
|
+
vec2 iC=fA();
|
|
75
|
+
vec4 texSample=texture(u_tex,iC);
|
|
76
|
+
float dp=texSample.r;
|
|
77
|
+
float shapeMask=texSample.a;
|
|
78
|
+
vec3 hi=u_lightColor*u_bright;
|
|
79
|
+
vec3 lo=u_darkColor*(2.-u_bright);
|
|
80
|
+
lo.b+=smoothstep(.6,1.4,sc.x+sc.y)*.08;
|
|
81
|
+
vec2 fC=sc-.5;
|
|
82
|
+
float rd=length(fC+vec2(0.,sl*.15));
|
|
83
|
+
vec2 ag=rot(fC,(.22-sl*.18)*3.14159);
|
|
84
|
+
float cv=1.-pow(rd*1.65,1.15);
|
|
85
|
+
cv*=pow(sc.y,.35);
|
|
86
|
+
float vs=shapeMask;
|
|
87
|
+
vs*=bM(iC,.01);
|
|
88
|
+
float fr=pow(1.-cv,u_fresnel)*.3;
|
|
89
|
+
vs=min(vs+fr*vs,1.);
|
|
90
|
+
float mT=an*.0625;
|
|
91
|
+
vec3 wO=vec3(-1.05,1.35,1.55);
|
|
92
|
+
vec3 wA=aF(vec3(31.,73.,56.),mT+wO)*.22*u_wave;
|
|
93
|
+
vec3 wB=aF(vec3(24.,64.,42.),mT-wO.yzx)*.22*u_wave;
|
|
94
|
+
vec2 nC=sc*45.*u_noise;
|
|
95
|
+
nC+=aF(sC.zxy,an*.17*sC.yzx-sc.yxy*.35).xy*18.*u_wave;
|
|
96
|
+
vec3 tC=vec3(.00041,.00053,.00076)*mT+wB*nC.x+wA*nC.y;
|
|
97
|
+
tC=lM(sC,tC);
|
|
98
|
+
tC=lM(sC+1.618,tC);
|
|
99
|
+
float tb=sin(tC.x*3.14159)*.5+.5;
|
|
100
|
+
tb=tb*2.-1.;
|
|
101
|
+
float noiseVal=pW(vec3(sc*8.+an,an*.5)).x;
|
|
102
|
+
float edgeFactor=smoothstep(0.,.5,dp)*smoothstep(1.,.5,dp);
|
|
103
|
+
float lD=dp+(1.-dp)*u_liquid*tb;
|
|
104
|
+
lD+=noiseVal*u_distort*.15*edgeFactor;
|
|
105
|
+
float rB=clamp(1.-cv,0.,1.);
|
|
106
|
+
float fl=ag.x+sl;
|
|
107
|
+
fl+=noiseVal*sl*u_distort*edgeFactor;
|
|
108
|
+
fl*=mix(1.,1.-dp*.5,u_contour);
|
|
109
|
+
fl-=dp*u_contour*.8;
|
|
110
|
+
float eI=smoothstep(0.,1.,lD)*smoothstep(1.,0.,lD);
|
|
111
|
+
fl-=tb*sl*1.8*eI;
|
|
112
|
+
float cA=cv*clamp(pow(sc.y,.12),.25,1.);
|
|
113
|
+
fl*=.12+(1.05-lD)*cA;
|
|
114
|
+
fl*=smoothstep(1.,.65,lD);
|
|
115
|
+
float vA1=smoothstep(.08,.18,sc.y)*smoothstep(.38,.18,sc.y);
|
|
116
|
+
float vA2=smoothstep(.08,.18,1.-sc.y)*smoothstep(.38,.18,1.-sc.y);
|
|
117
|
+
fl+=vA1*.16+vA2*.025;
|
|
118
|
+
fl*=.45+pow(sc.y,2.)*.55;
|
|
119
|
+
fl*=u_scale;
|
|
120
|
+
fl-=an;
|
|
121
|
+
float rO=rB+cv*tb*.025;
|
|
122
|
+
float vM1=smoothstep(-.12,.18,sc.y)*smoothstep(.48,.08,sc.y);
|
|
123
|
+
float cM1=smoothstep(.35,.55,cv)*smoothstep(.95,.35,cv);
|
|
124
|
+
rO+=vM1*cM1*4.5;
|
|
125
|
+
rO-=sl;
|
|
126
|
+
float bO=rB*1.25;
|
|
127
|
+
float vM2=smoothstep(-.02,.35,sc.y)*smoothstep(.75,.08,sc.y);
|
|
128
|
+
float cM2=smoothstep(.35,.55,cv)*smoothstep(.75,.35,cv);
|
|
129
|
+
bO+=vM2*cM2*.9;
|
|
130
|
+
bO-=lD*.18;
|
|
131
|
+
rO*=u_refract*u_chroma;
|
|
132
|
+
bO*=u_refract*u_chroma;
|
|
133
|
+
float sf=u_blur;
|
|
134
|
+
float rP=fract(fl+rO);
|
|
135
|
+
float rC=mG(hi.r,lo.r,rP,sf+.018+u_refract*cv*.025,cv);
|
|
136
|
+
float gP=fract(fl);
|
|
137
|
+
float gC=mG(hi.g,lo.g,gP,sf+.008/max(.01,1.-sl),cv);
|
|
138
|
+
float bP=fract(fl-bO);
|
|
139
|
+
float bC=mG(hi.b,lo.b,bP,sf+.008,cv);
|
|
140
|
+
vec3 col=vec3(rC,gC,bC);
|
|
141
|
+
col=(col-.5)*u_contrast+.5;
|
|
142
|
+
col=clamp(col,0.,1.);
|
|
143
|
+
col=mix(col,1.-min(vec3(1.),(1.-col)/max(u_tint,vec3(.001))),length(u_tint-1.)*.5);
|
|
144
|
+
col=clamp(col,0.,1.);
|
|
145
|
+
oC=vec4(col*vs,vs);
|
|
146
|
+
}`;
|
|
147
|
+
const UNIFORM_NAMES = [
|
|
148
|
+
'u_tex', 'u_time', 'u_ratio', 'u_imgRatio', 'u_seed', 'u_scale', 'u_refract',
|
|
149
|
+
'u_blur', 'u_liquid', 'u_bright', 'u_contrast', 'u_angle', 'u_fresnel',
|
|
150
|
+
'u_sharp', 'u_wave', 'u_noise', 'u_chroma', 'u_distort', 'u_contour',
|
|
151
|
+
'u_lightColor', 'u_darkColor', 'u_tint',
|
|
152
|
+
];
|
|
153
|
+
function compileShader(gl, type, source) {
|
|
154
|
+
const shader = gl.createShader(type);
|
|
155
|
+
if (shader === null)
|
|
156
|
+
return undefined;
|
|
157
|
+
gl.shaderSource(shader, source);
|
|
158
|
+
gl.compileShader(shader);
|
|
159
|
+
if (gl.getShaderParameter(shader, gl.COMPILE_STATUS) === true)
|
|
160
|
+
return shader;
|
|
161
|
+
gl.deleteShader(shader);
|
|
162
|
+
return undefined;
|
|
163
|
+
}
|
|
164
|
+
function setRgb(gl, location, color) {
|
|
165
|
+
gl.uniform3f(location, color[0], color[1], color[2]);
|
|
166
|
+
}
|
|
167
|
+
/** Official sidebar brand occupant with a compact, lifecycle-safe metallic shader. */
|
|
168
|
+
export function XiaoheiMetallicBrandMark({ size, className }) {
|
|
169
|
+
const canvasRef = useRef(null);
|
|
170
|
+
const [ready, setReady] = useState(false);
|
|
171
|
+
const visualSize = Math.max(24, size + 4);
|
|
172
|
+
const context = size >= 32 ? 'hero' : 'sidebar';
|
|
173
|
+
const [snapshot, setSnapshot] = useState(context === 'sidebar' ? sidebarMetallicSnapshot : undefined);
|
|
174
|
+
useEffect(() => {
|
|
175
|
+
if (snapshot !== undefined)
|
|
176
|
+
return;
|
|
177
|
+
const canvas = canvasRef.current;
|
|
178
|
+
if (canvas === null)
|
|
179
|
+
return;
|
|
180
|
+
const gl = canvas.getContext('webgl2', {
|
|
181
|
+
alpha: true,
|
|
182
|
+
antialias: true,
|
|
183
|
+
powerPreference: 'low-power',
|
|
184
|
+
premultipliedAlpha: true,
|
|
185
|
+
});
|
|
186
|
+
if (gl === null)
|
|
187
|
+
return;
|
|
188
|
+
const vertex = compileShader(gl, gl.VERTEX_SHADER, VERTEX_SHADER);
|
|
189
|
+
const fragment = compileShader(gl, gl.FRAGMENT_SHADER, FRAGMENT_SHADER);
|
|
190
|
+
if (vertex === undefined || fragment === undefined) {
|
|
191
|
+
if (vertex !== undefined)
|
|
192
|
+
gl.deleteShader(vertex);
|
|
193
|
+
if (fragment !== undefined)
|
|
194
|
+
gl.deleteShader(fragment);
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
const program = gl.createProgram();
|
|
198
|
+
const buffer = gl.createBuffer();
|
|
199
|
+
if (program === null || buffer === null) {
|
|
200
|
+
gl.deleteShader(vertex);
|
|
201
|
+
gl.deleteShader(fragment);
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
gl.attachShader(program, vertex);
|
|
205
|
+
gl.attachShader(program, fragment);
|
|
206
|
+
gl.linkProgram(program);
|
|
207
|
+
gl.deleteShader(vertex);
|
|
208
|
+
gl.deleteShader(fragment);
|
|
209
|
+
if (gl.getProgramParameter(program, gl.LINK_STATUS) !== true) {
|
|
210
|
+
gl.deleteBuffer(buffer);
|
|
211
|
+
gl.deleteProgram(program);
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
const uniforms = Object.fromEntries(UNIFORM_NAMES.map(name => [name, gl.getUniformLocation(program, name)]));
|
|
215
|
+
const pixelRatio = Math.min(window.devicePixelRatio || 1, 2);
|
|
216
|
+
const renderSize = Math.max(96, Math.ceil(visualSize * pixelRatio * 2));
|
|
217
|
+
canvas.width = renderSize;
|
|
218
|
+
canvas.height = renderSize;
|
|
219
|
+
gl.viewport(0, 0, renderSize, renderSize);
|
|
220
|
+
gl.useProgram(program);
|
|
221
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
|
|
222
|
+
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]), gl.STATIC_DRAW);
|
|
223
|
+
const position = gl.getAttribLocation(program, 'a_position');
|
|
224
|
+
gl.enableVertexAttribArray(position);
|
|
225
|
+
gl.vertexAttribPointer(position, 2, gl.FLOAT, false, 0, 0);
|
|
226
|
+
gl.uniform1f(uniforms.u_ratio, 1);
|
|
227
|
+
gl.uniform1f(uniforms.u_imgRatio, 1);
|
|
228
|
+
gl.uniform1f(uniforms.u_seed, 42);
|
|
229
|
+
gl.uniform1f(uniforms.u_scale, 3.2);
|
|
230
|
+
gl.uniform1f(uniforms.u_refract, 0.012);
|
|
231
|
+
gl.uniform1f(uniforms.u_blur, 0.018);
|
|
232
|
+
gl.uniform1f(uniforms.u_liquid, 0.58);
|
|
233
|
+
gl.uniform1f(uniforms.u_bright, 1.35);
|
|
234
|
+
gl.uniform1f(uniforms.u_contrast, 1.08);
|
|
235
|
+
gl.uniform1f(uniforms.u_angle, -12);
|
|
236
|
+
gl.uniform1f(uniforms.u_fresnel, 0.8);
|
|
237
|
+
gl.uniform1f(uniforms.u_sharp, 1.15);
|
|
238
|
+
gl.uniform1f(uniforms.u_wave, 0.65);
|
|
239
|
+
gl.uniform1f(uniforms.u_noise, 0.45);
|
|
240
|
+
gl.uniform1f(uniforms.u_chroma, 0.7);
|
|
241
|
+
gl.uniform1f(uniforms.u_distort, 0.35);
|
|
242
|
+
gl.uniform1f(uniforms.u_contour, 0.38);
|
|
243
|
+
setRgb(gl, uniforms.u_lightColor, [0.96, 0.97, 0.95]);
|
|
244
|
+
setRgb(gl, uniforms.u_darkColor, [0.025, 0.04, 0.045]);
|
|
245
|
+
setRgb(gl, uniforms.u_tint, [0.84, 0.92, 0.89]);
|
|
246
|
+
let disposed = false;
|
|
247
|
+
let visible = true;
|
|
248
|
+
let animationFrame;
|
|
249
|
+
let lastFrame = 0;
|
|
250
|
+
let metallicTime = 1450;
|
|
251
|
+
const reduceMotion = window.matchMedia('(prefers-reduced-motion: reduce)');
|
|
252
|
+
const texture = gl.createTexture();
|
|
253
|
+
const image = new Image();
|
|
254
|
+
const draw = () => {
|
|
255
|
+
gl.uniform1f(uniforms.u_time, metallicTime);
|
|
256
|
+
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
|
|
257
|
+
};
|
|
258
|
+
const render = (now) => {
|
|
259
|
+
if (disposed)
|
|
260
|
+
return;
|
|
261
|
+
if (visible && document.visibilityState !== 'hidden' && now - lastFrame >= 40) {
|
|
262
|
+
const delta = lastFrame === 0 ? 0 : Math.min(80, now - lastFrame);
|
|
263
|
+
lastFrame = now;
|
|
264
|
+
metallicTime += delta * 0.11;
|
|
265
|
+
draw();
|
|
266
|
+
}
|
|
267
|
+
animationFrame = window.requestAnimationFrame(render);
|
|
268
|
+
};
|
|
269
|
+
image.onload = () => {
|
|
270
|
+
if (disposed || texture === null)
|
|
271
|
+
return;
|
|
272
|
+
gl.activeTexture(gl.TEXTURE0);
|
|
273
|
+
gl.bindTexture(gl.TEXTURE_2D, texture);
|
|
274
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
|
275
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
|
276
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
|
277
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
278
|
+
gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false);
|
|
279
|
+
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
|
|
280
|
+
gl.uniform1i(uniforms.u_tex, 0);
|
|
281
|
+
draw();
|
|
282
|
+
if (context === 'sidebar') {
|
|
283
|
+
sidebarMetallicSnapshot = canvas.toDataURL();
|
|
284
|
+
setSnapshot(sidebarMetallicSnapshot);
|
|
285
|
+
return;
|
|
286
|
+
}
|
|
287
|
+
setReady(true);
|
|
288
|
+
if (!reduceMotion.matches)
|
|
289
|
+
animationFrame = window.requestAnimationFrame(render);
|
|
290
|
+
};
|
|
291
|
+
image.src = XIAOHEI_BRAND_AVATAR;
|
|
292
|
+
const visibilityObserver = typeof IntersectionObserver === 'function'
|
|
293
|
+
? new IntersectionObserver(entries => {
|
|
294
|
+
visible = entries.some(entry => entry.isIntersecting);
|
|
295
|
+
if (visible)
|
|
296
|
+
lastFrame = 0;
|
|
297
|
+
})
|
|
298
|
+
: undefined;
|
|
299
|
+
visibilityObserver?.observe(canvas);
|
|
300
|
+
return () => {
|
|
301
|
+
disposed = true;
|
|
302
|
+
if (animationFrame !== undefined)
|
|
303
|
+
window.cancelAnimationFrame(animationFrame);
|
|
304
|
+
visibilityObserver?.disconnect();
|
|
305
|
+
if (texture !== null)
|
|
306
|
+
gl.deleteTexture(texture);
|
|
307
|
+
gl.deleteBuffer(buffer);
|
|
308
|
+
gl.deleteProgram(program);
|
|
309
|
+
gl.getExtension('WEBGL_lose_context')?.loseContext();
|
|
310
|
+
};
|
|
311
|
+
}, [visualSize, context, snapshot]);
|
|
312
|
+
const geometry = {
|
|
313
|
+
'--xiaohei-brand-mark-size': `${visualSize}px`,
|
|
314
|
+
};
|
|
315
|
+
return (_jsxs("span", { className: className === undefined ? 'xiaohei-brand-mark' : `${className} xiaohei-brand-mark`, "data-brand-context": context, "data-metallic-ready": ready || snapshot !== undefined ? 'true' : 'false', style: geometry, "aria-hidden": "true", children: [_jsx("img", { className: "xiaohei-brand-mark__fallback", src: XIAOHEI_BRAND_AVATAR, alt: "" }), snapshot !== undefined
|
|
316
|
+
? _jsx("img", { className: "xiaohei-brand-mark__metal", src: snapshot, alt: "" })
|
|
317
|
+
: _jsx("canvas", { className: "xiaohei-brand-mark__metal", ref: canvasRef })] }));
|
|
318
|
+
}
|
|
319
|
+
/** Official sidebar brand-name occupant paired with the Xiaohei mark. */
|
|
320
|
+
export function XiaoheiBrandName() {
|
|
321
|
+
return _jsx("span", { className: "xiaohei-brand-name", children: "\u7F57\u5C0F\u9ED1 \u00B7 \u5996\u7075\u4F1A\u9986" });
|
|
322
|
+
}
|
|
323
|
+
//# sourceMappingURL=metallic-brand-mark.js.map
|
package/lib/plugin.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ClientContext } from '@deepseek-ai/
|
|
1
|
+
import type { Context as ClientContext } from '@deepseek-ai/cordis';
|
|
2
2
|
/** Boot decoration has no service dependency; the full theme waits below. */
|
|
3
3
|
export declare const inject: string[];
|
|
4
4
|
/** Shade DSH's native appearance modes without replacing its preference UI. */
|
package/lib/plugin.js
CHANGED
|
@@ -1,22 +1,39 @@
|
|
|
1
1
|
import { bindXiaoheiAppearance } from './appearance.js';
|
|
2
|
-
import { installXiaoheiBlink } from './blink.js';
|
|
3
2
|
import { installXiaoheiChrome } from './chrome.js';
|
|
4
|
-
import {
|
|
5
|
-
import { installXiaoheiHeixiuInteractions } from './heixiu-interactions.js';
|
|
3
|
+
import { installXiaoheiComposerSendHeixiu } from './composer-send-heixiu.js';
|
|
6
4
|
import { installXiaoheiPluginLoading } from './loading-heixiu.js';
|
|
7
|
-
import { installXiaoheiPortalTransit } from './portal.js';
|
|
8
|
-
import { installXiaoheiIdleReactions } from './reactions.js';
|
|
9
5
|
import { installXiaoheiScene } from './scene.js';
|
|
10
6
|
import { installXiaoheiSidebarGlass } from './sidebar-glass.js';
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
7
|
+
import { installXiaoheiWallpaperCharacter } from './scene/wallpaper-character.js';
|
|
8
|
+
import { installComposerBloub } from './bloub-heixiu/runtime.js';
|
|
9
|
+
import { bindHeixiuSessions, createHeixiuSignals } from './bloub-heixiu/signals.js';
|
|
13
10
|
import { XIAOHEI_THEME_TOKEN_OVERRIDES } from './theme.js';
|
|
11
|
+
import { XiaoheiBrandName, XiaoheiMetallicBrandMark } from './metallic-brand-mark.js';
|
|
14
12
|
/** Boot decoration has no service dependency; the full theme waits below. */
|
|
15
13
|
export const inject = [];
|
|
16
14
|
/** Shade DSH's native appearance modes without replacing its preference UI. */
|
|
17
15
|
export function apply(ctx) {
|
|
18
16
|
ctx.effect(installXiaoheiPluginLoading, 'xiaohei-theme: replace plugin spinner with hopping Heixiu');
|
|
19
|
-
ctx.inject(['
|
|
17
|
+
ctx.inject(['slots'], readyCtx => {
|
|
18
|
+
const disposeSidebarMark = readyCtx.slots.inject('sidebar.brand.mark', () => readyCtx.slots.register({
|
|
19
|
+
name: 'sidebar.brand.mark',
|
|
20
|
+
priority: -20,
|
|
21
|
+
}, XiaoheiMetallicBrandMark));
|
|
22
|
+
const disposeSidebarName = readyCtx.slots.inject('sidebar.brand.name', () => readyCtx.slots.register({
|
|
23
|
+
name: 'sidebar.brand.name',
|
|
24
|
+
priority: -20,
|
|
25
|
+
}, XiaoheiBrandName));
|
|
26
|
+
const disposeHeroMark = readyCtx.slots.inject('conversation.hero.brand.mark', () => readyCtx.slots.register({
|
|
27
|
+
name: 'conversation.hero.brand.mark',
|
|
28
|
+
priority: -20,
|
|
29
|
+
}, XiaoheiMetallicBrandMark));
|
|
30
|
+
return () => {
|
|
31
|
+
disposeHeroMark();
|
|
32
|
+
disposeSidebarName();
|
|
33
|
+
disposeSidebarMark();
|
|
34
|
+
};
|
|
35
|
+
});
|
|
36
|
+
ctx.inject(['theme'], (readyCtx) => installXiaoheiTheme(readyCtx));
|
|
20
37
|
}
|
|
21
38
|
/** Mount the complete theme only after its runtime services become available. */
|
|
22
39
|
function installXiaoheiTheme(ctx) {
|
|
@@ -25,14 +42,12 @@ function installXiaoheiTheme(ctx) {
|
|
|
25
42
|
}, 'xiaohei-theme: shade native Light / Dark / System palettes');
|
|
26
43
|
ctx.effect(() => bindXiaoheiAppearance(ctx), 'xiaohei-theme: follow resolved appearance');
|
|
27
44
|
ctx.effect(installXiaoheiChrome, 'xiaohei-theme: install spirit control skin');
|
|
28
|
-
ctx.effect(
|
|
45
|
+
ctx.effect(installXiaoheiComposerSendHeixiu, 'xiaohei-theme: turn the native send action into blinking Heixiu');
|
|
46
|
+
ctx.effect(installXiaoheiScene, 'xiaohei-theme: install paired atmosphere');
|
|
29
47
|
ctx.effect(installXiaoheiSidebarGlass, 'xiaohei-theme: install isolated sidebar glass');
|
|
30
|
-
ctx.effect(
|
|
31
|
-
|
|
32
|
-
ctx.effect(
|
|
33
|
-
ctx.
|
|
34
|
-
ctx.effect(installXiaoheiBlink, 'xiaohei-theme: synchronize complete-frame blinking');
|
|
35
|
-
ctx.effect(installXiaoheiIdleReactions, 'xiaohei-theme: install sparse idle reactions');
|
|
36
|
-
ctx.effect(() => bindXiaoheiSessionState(ctx.sessions), 'xiaohei-theme: follow current session agent state');
|
|
48
|
+
ctx.effect(installXiaoheiWallpaperCharacter, 'xiaohei-theme: place responsive character poses');
|
|
49
|
+
const heixiuSignals = createHeixiuSignals();
|
|
50
|
+
ctx.effect(() => installComposerBloub(undefined, heixiuSignals), 'xiaohei-theme: mount bloub Heixiu beside composer');
|
|
51
|
+
ctx.inject(['sessions'], ready => bindHeixiuSessions(ready.sessions, heixiuSignals));
|
|
37
52
|
}
|
|
38
53
|
//# sourceMappingURL=plugin.js.map
|
package/lib/portal.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { XIAOHEI_HEIXIU_BLINK, XIAOHEI_HEIXIU_OPEN } from './generated-keyart.js';
|
|
2
2
|
import { XIAOHEI_PORTAL_CSS } from './chrome/portal.js';
|
|
3
|
-
import {
|
|
3
|
+
import { subscribeXiaoheiHostDom } from './host-dom.js';
|
|
4
|
+
import { XIAOHEI_HOST_SELECTORS } from './host-contract.js';
|
|
5
|
+
import { XIAOHEI_SCENE_LAYER_ID, XIAOHEI_SCENE_WORLD_CLASS } from './scene.js';
|
|
4
6
|
export const XIAOHEI_PORTAL_STYLE_ID = 'dsh-theme-xiaohei/portal-style';
|
|
5
7
|
export const XIAOHEI_PORTAL_LAYER_ID = 'dsh-theme-xiaohei/portal-layer';
|
|
6
8
|
export const XIAOHEI_PORTAL_DURATION_MS = 2600;
|
|
@@ -63,9 +65,9 @@ export function installXiaoheiPortalTransit(doc = typeof document === 'undefined
|
|
|
63
65
|
const scene = doc.getElementById(XIAOHEI_SCENE_LAYER_ID);
|
|
64
66
|
if (scene === null)
|
|
65
67
|
return false;
|
|
66
|
-
const veil = scene.querySelector('.xiaohei-scene__veil');
|
|
67
68
|
if (layer.parentElement !== scene) {
|
|
68
|
-
scene.
|
|
69
|
+
const world = scene.querySelector(`.${XIAOHEI_SCENE_WORLD_CLASS}`);
|
|
70
|
+
scene.insertBefore(layer, world?.nextSibling ?? scene.firstChild);
|
|
69
71
|
}
|
|
70
72
|
return true;
|
|
71
73
|
};
|
|
@@ -146,25 +148,24 @@ export function installXiaoheiPortalTransit(doc = typeof document === 'undefined
|
|
|
146
148
|
visitsStarted = true;
|
|
147
149
|
scheduleVisit(true);
|
|
148
150
|
};
|
|
149
|
-
let
|
|
151
|
+
let unsubscribeHostDom = () => { };
|
|
150
152
|
if (mount()) {
|
|
151
153
|
startVisits();
|
|
152
154
|
}
|
|
153
155
|
else {
|
|
154
|
-
|
|
156
|
+
unsubscribeHostDom = subscribeXiaoheiHostDom(doc, () => {
|
|
155
157
|
if (!mount())
|
|
156
158
|
return;
|
|
157
|
-
|
|
159
|
+
unsubscribeHostDom();
|
|
158
160
|
startVisits();
|
|
159
161
|
});
|
|
160
|
-
mountObserver.observe(doc.body, { childList: true });
|
|
161
162
|
}
|
|
162
163
|
return () => {
|
|
163
164
|
disposed = true;
|
|
164
165
|
clearTimer(animationTimer);
|
|
165
166
|
clearTimer(visitTimer);
|
|
166
167
|
endInteraction();
|
|
167
|
-
|
|
168
|
+
unsubscribeHostDom();
|
|
168
169
|
if (layer.dataset.running === 'true')
|
|
169
170
|
dispatchPortalActivity(doc, false);
|
|
170
171
|
layer.remove();
|
|
@@ -201,8 +202,8 @@ function choosePortalPoints(doc) {
|
|
|
201
202
|
const win = doc.defaultView;
|
|
202
203
|
const width = Math.max(640, win?.innerWidth ?? 1280);
|
|
203
204
|
const height = Math.max(480, win?.innerHeight ?? 720);
|
|
204
|
-
const sidebarRight = doc.querySelector(
|
|
205
|
-
const composerRect = doc.querySelector(
|
|
205
|
+
const sidebarRight = doc.querySelector(XIAOHEI_HOST_SELECTORS.sidebar)?.getBoundingClientRect().right ?? 0;
|
|
206
|
+
const composerRect = doc.querySelector(XIAOHEI_HOST_SELECTORS.composerCard)?.getBoundingClientRect();
|
|
206
207
|
const contentLeft = composerRect?.left ?? width * 0.37;
|
|
207
208
|
const contentRight = composerRect?.right ?? width * 0.77;
|
|
208
209
|
const leftMin = Math.max(sidebarRight + 80, 90);
|
package/lib/reactions.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { XIAOHEI_IDLE_EAR_LEFT, XIAOHEI_IDLE_EAR_RIGHT, XIAOHEI_IDLE_TAIL, } from './generated-keyart.js';
|
|
2
2
|
import { XIAOHEI_REACTION_CSS } from './chrome/reactions.js';
|
|
3
|
+
import { subscribeXiaoheiHostDom } from './host-dom.js';
|
|
3
4
|
import { XIAOHEI_HEIXIU_GREETING_EVENT, } from './heixiu-interactions.js';
|
|
4
5
|
import { XIAOHEI_PORTAL_PROXIMITY_EVENT, } from './portal.js';
|
|
5
6
|
export const XIAOHEI_REACTION_STYLE_ID = 'dsh-theme-xiaohei/reaction-style';
|
|
@@ -332,8 +333,7 @@ export function installXiaoheiIdleReactions(doc = typeof document === 'undefined
|
|
|
332
333
|
scheduleIdleTail();
|
|
333
334
|
syncPointerEarLoop();
|
|
334
335
|
};
|
|
335
|
-
const
|
|
336
|
-
mountObserver.observe(doc.body, { childList: true, subtree: true });
|
|
336
|
+
const unsubscribeHostDom = subscribeXiaoheiHostDom(doc, attach);
|
|
337
337
|
const stateObserver = new win.MutationObserver(onStateChange);
|
|
338
338
|
stateObserver.observe(doc.documentElement, {
|
|
339
339
|
attributes: true,
|
|
@@ -356,7 +356,7 @@ export function installXiaoheiIdleReactions(doc = typeof document === 'undefined
|
|
|
356
356
|
clearHeixiuInteraction();
|
|
357
357
|
clearTimer(idleTailTimer);
|
|
358
358
|
clearReaction();
|
|
359
|
-
|
|
359
|
+
unsubscribeHostDom();
|
|
360
360
|
stateObserver.disconnect();
|
|
361
361
|
doc.removeEventListener('pointermove', onPointerMove);
|
|
362
362
|
doc.removeEventListener('pointerleave', clearPointer);
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare const XIAOHEI_SYLVA_AVATAR_MARKER = "data-xiaohei-avatar-model";
|
|
2
|
+
/** Inject the renderer-sharing 2.5D avatar without editing registered ThreeUI files. */
|
|
3
|
+
export declare function injectXiaoheiSylvaAvatarModel(source: string): string;
|
|
4
|
+
/** Prepare the detached iframe so the avatar exists on its first WebGL boot. */
|
|
5
|
+
export declare function prepareXiaoheiSylvaAvatarFrame(frame: HTMLIFrameElement): boolean;
|
|
6
|
+
//# sourceMappingURL=avatar-model.d.ts.map
|