nex_docus/.dsh-plugins/pet-dock/lib/client.js

497 lines
29 KiB
JavaScript
Raw Normal View History

2026-08-25 02:17:40 +00:00
// Native client bundle for @nex/pet-dock
// Registered into shell.overlay + settings.section.
// Plain CJS factory consumed by the browser ModuleLoader; only `react` (a platform seed) is required.
window.__ModuleLoader__.load({
id: "@nex/pet-dock",
factory: (require) => {
var module = { exports: {} };
var exports = module.exports;
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
let react = require("react");
// ---- stylesheet -------------------------------------------------------
var cssId = "@nex/pet-dock/pet.css";
function claimStyles() {
if (typeof document === "undefined") return;
if (document.querySelector('style[data-plugin-css="' + cssId + '"]')) return;
var tag = document.createElement("style");
tag.dataset.plugin = "@nex/pet-dock";
tag.dataset.pluginCss = cssId;
tag.textContent = css;
document.head.appendChild(tag);
}
var css = `
.pet-float {
position: fixed;
top: 50%;
right: 14px;
transform: translateY(-50%);
z-index: 2147483000;
pointer-events: none;
font-family: var(--dsw-alias-font, system-ui, 'Segoe UI', sans-serif);
}
.pet-float * { box-sizing: border-box; }
.pet-outer {
pointer-events: auto;
display: flex;
flex-direction: column;
align-items: flex-end;
gap: 10px;
}
.pet-avatar {
width: 64px; height: 64px; border-radius: 50%; border: none; cursor: pointer;
display: flex; align-items: center; justify-content: center; font-size: 32px;
background: var(--dsw-alias-bg-overlay, #fff);
box-shadow: 0 4px 18px rgba(0,0,0,.18), inset 0 0 0 1px var(--dsw-alias-border-l1, rgba(0,0,0,.08));
animation: pet-bob 3s ease-in-out infinite;
}
@keyframes pet-bob { 0%,100%{transform:translateY(0);} 50%{transform:translateY(-6px);} }
.pet-window {
width: 220px;
background: var(--dsw-alias-bg-layer-1, #fff);
border-radius: 20px;
box-shadow: 0 18px 50px rgba(0,0,0,.26), inset 0 0 0 1px var(--dsw-alias-border-l1, rgba(0,0,0,.06));
overflow: hidden;
transform-origin: bottom right;
animation: pet-grow .3s cubic-bezier(.34,1.45,.64,1) both;
}
@keyframes pet-grow { 0%{opacity:0;transform:scale(.7) translateX(12px);} 100%{opacity:1;transform:scale(1) translateX(0);} }
.pet-head { display:flex; align-items:center; justify-content:space-between; padding:10px 12px 4px; }
.pet-name { font-weight:700; font-size:14px; color:var(--dsw-alias-label-primary,#222); }
.pet-name small { font-weight:500; color:var(--dsw-alias-label-secondary,#888); margin-left:6px; }
.pet-stage { height: 176px; display:flex; align-items:center; justify-content:space-between; padding:0 6px; position:relative; }
.pet-stage .stage-ground { position:absolute; bottom:12px; left:24%; right:24%; height:9px; border-radius:50%; background:radial-gradient(ellipse at center, rgba(0,0,0,.10), transparent 70%); }
.pet-stage .figure-wrap { position:absolute; left:0; right:0; top:0; bottom:0; display:flex; align-items:flex-end; justify-content:center; padding-bottom:18px; cursor:pointer; }
.pet-stage .figure-wrap:hover .pet-figure { transform: translateY(-6px) scale(1.06); }
.pet-stage .figure-wrap .tap-tip { position:absolute; top:4px; left:0; right:0; text-align:center; font-size:10px; color:var(--dsw-alias-label-secondary,#888); opacity:.75; pointer-events:none; }
.pet-arrow {
position:relative; z-index:2; width:30px; height:30px; border-radius:50%;
border:1px solid var(--dsw-alias-border-l1, rgba(0,0,0,.08));
background:var(--dsw-alias-bg-overlay,#fff); color:var(--dsw-alias-label-secondary,#888);
font-size:16px; line-height:1; cursor:pointer; display:flex; align-items:center; justify-content:center;
}
.pet-arrow:hover { background:var(--dsw-alias-bg-layer-2,#f3f4f8); color:var(--dsw-alias-brand-primary,#6c5ce7); transform:scale(1.1); }
.pet-status { text-align:center; font-size:11px; color:var(--dsw-alias-label-secondary,#888); padding:0 8px 10px; }
.pet-hint { text-align:center; font-size:10px; color:var(--dsw-alias-label-secondary,#888); padding:0 8px 8px; opacity:.7; }
.pet-figure { position:relative; transition:transform .25s ease; animation:body-bob 2.6s ease-in-out infinite; filter:drop-shadow(0 8px 10px rgba(0,0,0,.14)); }
@keyframes body-bob { 0%,100%{transform:translateY(0);} 50%{transform:translateY(-7px);} }
.p-eye { position:absolute; width:11px; height:11px; background:#222; border-radius:50%; animation:blink 4.2s steps(1) infinite; }
.p-eye::after { content:''; position:absolute; left:2px; top:1px; width:4px; height:4px; background:#fff; border-radius:50%; }
.p-eye.p-eyeB { background:#1e7a4d; }
@keyframes blink { 0%,88%,100%{transform:scaleY(1);} 92%,96%{transform:scaleY(.1);} }
@keyframes tail-wag { 0%,100%{transform:rotate(0);} 50%{transform:rotate(-16deg);} }
@keyframes dog-wag { 0%,100%{transform:rotate(-12deg);} 50%{transform:rotate(16deg);} }
@keyframes ear-flop { 0%,100%{transform:rotate(8deg);} 50%{transform:rotate(3deg);} }
@keyframes ear-flop-r { 0%,100%{transform:rotate(-8deg);} 50%{transform:rotate(-3deg);} }
.cow { position:relative; width:118px; height:122px; transform:scale(1.02); }
.cow-head { position:absolute; left:14px; top:14px; width:90px; height:82px; background:#fdfdfb; border-radius:46% 46% 40% 40%; box-shadow:inset 0 -10px 18px rgba(0,0,0,.05); }
.cow-patch { position:absolute; background:#3a3a42; border-radius:50%; }
.cow-patch.p1 { left:24px; top:5px; width:34px; height:22px; transform:rotate(12deg); }
.cow-patch.p2 { left:6px; top:34px; width:24px; height:17px; transform:rotate(-18deg); }
.cow-patch.p3 { right:12px; top:10px; width:17px; height:21px; transform:rotate(24deg); }
.cow-patch.p4 { right:2px; top:46px; width:20px; height:14px; background:#cfcfe0; transform:rotate(10deg); }
.cow-patch.p5 { left:9px; bottom:4px; width:17px; height:22px; background:#cfcfe0; transform:rotate(-22deg); }
.cow-ear { position:absolute; top:18px; width:24px; height:38px; background:#f0ede4; border-radius:50%; }
.cow-ear.l { left:1px; transform:rotate(-18deg); }
.cow-ear.r { right:1px; transform:rotate(18deg); }
.cow-ear::after { content:''; position:absolute; inset:6px 5px; background:#e8b7b0; border-radius:50%; }
.cow-horn { position:absolute; top:3px; width:0; height:0; border-left:9px solid transparent; border-right:9px solid transparent; border-bottom:19px solid #e4b983; }
.cow-horn.l { left:22px; transform:rotate(-24deg); }
.cow-horn.r { right:22px; transform:rotate(24deg); }
.cow-eye.l { left:20px; top:40px; z-index:2; }
.cow-eye.r { right:16px; top:42px; z-index:2; }
.cow-muzzle { position:absolute; left:25px; bottom:7px; width:40px; height:28px; background:#f2b6ad; border-radius:50%; }
.cow-muzzle::before, .cow-muzzle::after { content:''; position:absolute; top:8px; width:7px; height:9px; background:#d9837a; border-radius:50%; }
.cow-muzzle::before { left:8px; } .cow-muzzle::after { right:8px; }
.cow-body { position:absolute; left:14px; bottom:6px; width:90px; height:42px; background:#fdfdfb; border-radius:50% 50% 44% 44%; }
.cow-spot { position:absolute; background:#3a3a42; border-radius:50%; }
.cow-spot.s1 { left:2px; top:3px; width:21px; height:15px; transform:rotate(-14deg); }
.cow-spot.s2 { left:26px; top:2px; width:24px; height:15px; transform:rotate(8deg); }
.cow-spot.s3 { right:3px; top:8px; width:16px; height:15px; transform:rotate(-24deg); }
.cow-spot.s4 { left:11px; bottom:1px; width:15px; height:17px; background:#cfcfe0; transform:rotate(18deg); }
.cow-spot.s5 { right:13px; bottom:1px; width:17px; height:15px; background:#cfcfe0; transform:rotate(-8deg); }
.cow-leg { position:absolute; bottom:-8px; width:13px; height:21px; background:#efe7da; border-radius:4px; }
.cow-leg.l1 { left:16px; } .cow-leg.l2 { left:42px; }
.cow-leg.r1 { left:68px; } .cow-leg.r2 { left:92px; }
.cow-tail { position:absolute; right:2px; bottom:10px; width:34px; height:9px; border-radius:8px; background:#3a3a42; transform-origin:left center; animation:tail-wag 1.8s ease-in-out infinite; }
.cat { position:relative; width:112px; height:122px; transform:scale(1.04); }
.cat-head { position:absolute; left:16px; top:14px; width:80px; height:78px; background:linear-gradient(160deg,#ffb34d,#f79a35); border-radius:48% 48% 44% 44%; }
.cat-ear { position:absolute; top:0; width:0; height:0; border-left:15px solid transparent; border-right:15px solid transparent; border-bottom:28px solid #f79a35; }
.cat-ear.l { left:20px; transform:rotate(-14deg); }
.cat-ear.r { right:20px; transform:rotate(14deg); }
.cat-ear::after { content:''; position:absolute; left:-9px; top:11px; width:0; height:0; border-left:9px solid transparent; border-right:9px solid transparent; border-bottom:17px solid #ffc9d4; }
.cat-stripe { position:absolute; background:#e07f1f; border-radius:8px; }
.cat-stripe.s1 { left:24px; top:12px; width:7px; height:17px; transform:rotate(8deg); }
.cat-stripe.s2 { left:36px; top:9px; width:7px; height:19px; }
.cat-stripe.s3 { right:24px; top:12px; width:7px; height:17px; transform:rotate(-8deg); }
.cat-eye.l { left:22px; top:40px; background:#1e7a4d; }
.cat-eye.r { right:22px; top:40px; background:#1e7a4d; }
.cat-muzzle { position:absolute; left:29px; top:58px; width:22px; height:18px; background:#ffe9c9; border-radius:50%; }
.cat-nose { position:absolute; left:40px; top:52px; width:11px; height:7px; background:#f176a8; border-radius:50%; }
.cat-whisker { position:absolute; top:60px; width:20px; height:2px; background:rgba(0,0,0,.35); border-radius:2px; }
.cat-whisker.w1 { left:1px; transform:rotate(10deg); }
.cat-whisker.w2 { left:12px; top:68px; transform:rotate(-6deg); }
.cat-whisker.w3 { right:1px; transform:rotate(-10deg); }
.cat-whisker.w4 { right:12px; top:68px; transform:rotate(6deg); }
.cat-body { position:absolute; left:22px; bottom:7px; width:68px; height:42px; background:linear-gradient(160deg,#ffb34d,#f79a35); border-radius:48% 48% 42% 42%; }
.cat-belly { position:absolute; left:33px; bottom:7px; width:47px; height:36px; background:#fff3df; border-radius:48% 48% 42% 42%; }
.cat-paw { position:absolute; bottom:-5px; width:16px; height:13px; background:#f79a35; border-radius:50%; }
.cat-paw.p1 { left:27px; } .cat-paw.p2 { left:69px; }
.cat-tail { position:absolute; right:4px; bottom:8px; width:30px; height:11px; background:linear-gradient(180deg,#ffb34d 0%,#d9782b 100%); border-radius:8px 6px 6px 8px; transform-origin:left bottom; transform:rotate(-14deg); animation:tail-wag 2.2s ease-in-out infinite; }
.dog { position:relative; width:112px; height:124px; transform:scale(1.04); }
.dog-head { position:absolute; left:16px; top:16px; width:80px; height:76px; background:linear-gradient(160deg,#eebc83,#d99c5b); border-radius:48% 48% 44% 44%; }
.dog-ear { position:absolute; width:24px; height:36px; background:linear-gradient(180deg,#b9783d,#9c6230); border-radius:50% 50% 18px 18px; }
.dog-ear.l { left:6px; top:4px; transform-origin: top center; animation:ear-flop 2.6s ease-in-out infinite; }
.dog-ear.r { right:6px; top:4px; transform-origin: top center; animation:ear-flop-r 2.6s ease-in-out infinite; }
.dog-ear::after { content:''; position:absolute; left:7px; top:12px; width:10px; height:16px; background:#e8b6a0; border-radius:50%; }
.dog-snout { position:absolute; left:27px; top:56px; width:26px; height:18px; background:#f6e6cf; border-radius:50%; }
.dog-nose { position:absolute; left:39px; top:52px; width:13px; height:10px; background:#3a3028; border-radius:50%; }
.dog-mouth { position:absolute; left:37px; top:62px; width:16px; height:8px; border-bottom:2.5px solid #8a5a3a; border-radius:0 0 50% 50%; }
.dog-eye.l { left:30px; top:38px; }
.dog-eye.r { right:30px; top:38px; }
.dog-blush { position:absolute; top:50px; width:13px; height:8px; background:rgba(255,140,160,.5); border-radius:50%; }
.dog-blush.l { left:22px; } .dog-blush.r { right:22px; }
.dog-body { position:absolute; left:22px; bottom:7px; width:68px; height:44px; background:linear-gradient(160deg,#eebc83,#d99c5b); border-radius:48% 48% 42% 42%; }
.dog-belly { position:absolute; left:32px; bottom:7px; width:48px; height:36px; background:#f6e6cf; border-radius:48% 48% 42% 42%; }
.dog-paw { position:absolute; bottom:-5px; width:17px; height:14px; background:#d99c5b; border-radius:50%; }
.dog-paw.p1 { left:26px; } .dog-paw.p2 { left:69px; }
.dog-tail { position:absolute; right:3px; bottom:8px; width:30px; height:12px; background:linear-gradient(180deg,#eebc83 0%,#c08145 100%); border-radius:6px 7px 7px 6px; transform-origin:left bottom; transform:rotate(18deg); animation:dog-wag .8s ease-in-out infinite; }
.dog-tag { position:absolute; left:44px; bottom:16px; width:10px; height:10px; background:#ffd76a; border-radius:50%; box-shadow:0 0 0 2px #e6b84d; }
.pet-center { position:fixed; inset:0; z-index:2147483999; display:flex; align-items:center; justify-content:center; background:radial-gradient(120% 120% at 50% 40%, rgba(0,0,0,.10), transparent 70%); }
.pet-center .big-figure { cursor:pointer; filter:drop-shadow(0 16px 34px rgba(0,0,0,.28)); animation:center-in .55s cubic-bezier(.3,1.6,.5,1) both; }
.pet-center .big-figure.playing { animation:center-in .55s cubic-bezier(.3,1.6,.5,1) both, happy-dance 1.3s ease-in-out .4s infinite; }
.pet-center .big-figure.leaving { animation:center-out .55s cubic-bezier(.6,-0.1,.9,1) both; }
.pet-center .big-scale { transform:scale(calc(50vmin / 150px)); transform-origin:center; }
.pet-center .center-hint { position:absolute; bottom:14%; text-align:center; font-size:clamp(13px, 2.2vmin, 22px); font-weight:600; color:var(--dsw-alias-label-primary,#222); animation:hint-in .4s ease both; }
@keyframes center-in { 0%{opacity:0;transform:scale(.1);} 60%{transform:scale(1.15);} 100%{opacity:1;transform:scale(1);} }
@keyframes happy-dance { 0%,100%{transform:translateY(0) rotate(0) scale(1);} 25%{transform:translateY(-4%) rotate(-5deg) scale(1.02);} 50%{transform:translateY(0) rotate(0) scale(1);} 75%{transform:translateY(-4%) rotate(5deg) scale(1.02);} }
@keyframes center-out { 0%{opacity:1;transform:scale(1);} 100%{opacity:0;transform:scale(.06) translate(60vw, 0);} }
@keyframes hint-in { 0%{opacity:0;transform:translateY(8px);} 100%{opacity:1;transform:translateY(0);} }
/* ---- settings page ---- */
.pet-settings { display:flex; flex-direction:column; gap:12px; padding:4px 2px; }
.pet-settings-title { margin:0; font-size:16px; font-weight:600; color:var(--dsw-alias-label-primary,#222); }
.pet-settings-desc { margin:0; font-size:12px; color:var(--dsw-alias-label-secondary,#888); }
.pet-settings-row {
display:flex; align-items:center; gap:12px; padding:10px 12px;
border:1px solid var(--dsw-alias-border-l1, rgba(0,0,0,.08));
border-radius:12px; background:var(--dsw-alias-bg-layer-2,#f7f7fa);
}
.pet-settings-row.off { opacity:.55; }
.pet-settings-emoji { font-size:26px; flex:none; width:36px; text-align:center; }
.pet-settings-name {
flex:1; min-width:0; height:32px; border-radius:8px;
border:1px solid var(--dsw-alias-border-l2, rgba(0,0,0,.14));
background:var(--dsw-alias-bg-overlay,#fff); color:var(--dsw-alias-label-primary,#222);
padding:0 10px; font-size:13px; outline:none;
}
.pet-settings-name:focus { border-color:var(--dsw-alias-brand-primary,#6c5ce7); }
.pet-settings-name:disabled { background:var(--dsw-alias-bg-layer-2,#f0f0f4); color:var(--dsw-alias-label-secondary,#999); }
.pet-settings-switch { display:flex; align-items:center; gap:6px; cursor:pointer; font-size:12px; color:var(--dsw-alias-label-secondary,#888); white-space:nowrap; }
.pet-settings-switch input { width:15px; height:15px; accent-color:var(--dsw-alias-brand-primary,#6c5ce7); cursor:pointer; }
`;
// ---- data ---------------------------------------------------------------
var STORAGE_KEY = 'pet-dock:config';
var DEFAULT_PETS = [
{ kind: 'cow', name: '哞哞', emoji: '🐮', sub: '奶牛' },
{ kind: 'cat', name: '喵喵', emoji: '🐱', sub: '小猫' },
{ kind: 'dog', name: '汪汪', emoji: '🐶', sub: '小狗' },
];
function defaultConfig() {
var cfg = { enabled: {}, names: {} };
DEFAULT_PETS.forEach(function (p) { cfg.enabled[p.kind] = true; cfg.names[p.kind] = p.name; });
return cfg;
}
function loadConfig() {
try {
var raw = localStorage.getItem(STORAGE_KEY);
if (raw) {
var parsed = JSON.parse(raw);
if (parsed && typeof parsed === 'object') return parsed;
}
} catch (e) {}
return defaultConfig();
}
function saveConfig(cfg) {
try { localStorage.setItem(STORAGE_KEY, JSON.stringify(cfg)); } catch (e) {}
}
function activePets() {
var cfg = loadConfig();
return DEFAULT_PETS.filter(function (p) { return cfg.enabled && cfg.enabled[p.kind] !== false; })
.map(function (p) {
var name = (cfg.names && cfg.names[p.kind]) || p.name;
return { kind: p.kind, name: name, emoji: p.emoji, sub: p.sub };
});
}
// ---- shared timing helper (browser-native; avoids service timing issues) ---
function later(fn, ms) {
var id = setTimeout(fn, ms);
return function () { clearTimeout(id); };
}
function PetFigure(_a) {
var pet = _a.pet;
var el = react.createElement;
if (pet.kind === 'cow') {
return el('div', { className: 'cow' },
el('div', { className: 'cow-tail' }),
el('div', { className: 'cow-body' },
el('div', { className: 'cow-spot s1' }),
el('div', { className: 'cow-spot s2' }),
el('div', { className: 'cow-spot s3' }),
el('div', { className: 'cow-spot s4' }),
el('div', { className: 'cow-spot s5' })),
el('div', { className: 'cow-leg l1' }),
el('div', { className: 'cow-leg l2' }),
el('div', { className: 'cow-leg r1' }),
el('div', { className: 'cow-leg r2' }),
el('div', { className: 'cow-horn l' }),
el('div', { className: 'cow-horn r' }),
el('div', { className: 'cow-ear l' }),
el('div', { className: 'cow-ear r' }),
el('div', { className: 'cow-head' },
el('div', { className: 'cow-patch p1' }),
el('div', { className: 'cow-patch p2' }),
el('div', { className: 'cow-patch p3' }),
el('div', { className: 'cow-patch p4' }),
el('div', { className: 'cow-patch p5' }),
el('div', { className: 'cow-muzzle' }),
el('div', { className: 'p-eye cow-eye l' }),
el('div', { className: 'p-eye cow-eye r' })));
}
if (pet.kind === 'cat') {
return el('div', { className: 'cat' },
el('div', { className: 'cat-tail' }),
el('div', { className: 'cat-body' }),
el('div', { className: 'cat-belly' }),
el('div', { className: 'cat-paw p1' }),
el('div', { className: 'cat-paw p2' }),
el('div', { className: 'cat-ear l' }),
el('div', { className: 'cat-ear r' }),
el('div', { className: 'cat-head' },
el('div', { className: 'cat-stripe s1' }),
el('div', { className: 'cat-stripe s2' }),
el('div', { className: 'cat-stripe s3' }),
el('div', { className: 'p-eye cat-eye l' }),
el('div', { className: 'p-eye cat-eye r' }),
el('div', { className: 'cat-muzzle' }),
el('div', { className: 'cat-nose' }),
el('div', { className: 'cat-whisker w1' }),
el('div', { className: 'cat-whisker w2' }),
el('div', { className: 'cat-whisker w3' }),
el('div', { className: 'cat-whisker w4' })));
}
return el('div', { className: 'dog' },
el('div', { className: 'dog-tail' }),
el('div', { className: 'dog-body' }),
el('div', { className: 'dog-belly' }),
el('div', { className: 'dog-paw p1' }),
el('div', { className: 'dog-paw p2' }),
el('div', { className: 'dog-ear l' }),
el('div', { className: 'dog-ear r' }),
el('div', { className: 'dog-tag' }),
el('div', { className: 'dog-head' },
el('div', { className: 'p-eye dog-eye l' }),
el('div', { className: 'p-eye dog-eye r' }),
el('div', { className: 'dog-blush l' }),
el('div', { className: 'dog-blush r' }),
el('div', { className: 'dog-snout' }),
el('div', { className: 'dog-nose' }),
el('div', { className: 'dog-mouth' })));
}
function PetWindow(props) {
var el = react.createElement;
var pet = props.pet, onPrev = props.onPrev, onNext = props.onNext, onPlay = props.onPlay, disabled = props.disabled;
return el('div', { className: 'pet-window' },
el('div', { className: 'pet-head' },
el('div', { className: 'pet-name' },
pet.emoji + ' ' + pet.name,
el('small', null, pet.sub))),
el('div', { className: 'pet-stage' },
el('div', { className: 'stage-ground' }),
el('div', { className: 'figure-wrap', onClick: onPlay, title: '点击互动' },
el('div', { className: 'tap-tip' }, '点击我互动 ✨'),
el('div', { className: 'pet-figure' }, el(PetFigure, { pet: pet }))),
el('button', { className: 'pet-arrow', onClick: onPrev, title: '上一个', disabled: disabled }, ''),
el('button', { className: 'pet-arrow', onClick: onNext, title: '下一个', disabled: disabled }, '')),
el('div', { className: 'pet-status' }, '正在努力陪着你工作…'),
el('div', { className: 'pet-hint' }, '点击宠物,放大到屏幕中央互动'));
}
function CenterReveal(props) {
var el = react.createElement;
var pet = props.pet, leaving = props.leaving, onExit = props.onExit;
return el('div', { className: 'pet-center', onClick: onExit },
el('div', {
className: 'big-figure' + (leaving ? ' leaving' : ' playing'),
onClick: onExit
},
el('div', { className: 'big-scale' }, el(PetFigure, { pet: pet }))),
el('div', { className: 'center-hint' },
leaving ? '回到窗口…' : pet.emoji + ' ' + pet.name + ' 来找你玩啦!点击返回'));
}
// ---- settings page ------------------------------------------------------
function SettingsView() {
var el = react.createElement;
var useState = react.useState;
var _a = useState(0), tick = _a[0], setTick = _a[1];
var useEffect = react.useEffect;
useEffect(function () {
function onChange() { setTick(function (t) { return t + 1; }); }
if (typeof window !== 'undefined' && window.addEventListener) {
window.addEventListener('pet-dock:config', onChange);
return function () { window.removeEventListener('pet-dock:config', onChange); };
}
}, []);
var cfg = loadConfig();
return el('div', { className: 'pet-settings' },
el('h3', { className: 'pet-settings-title' }, 'PetDock 宠物'),
el('p', { className: 'pet-settings-desc' }, '勾选要启用的形象,并为每只宠物自定义名字。'),
DEFAULT_PETS.map(function (p) {
var enabled = cfg.enabled && cfg.enabled[p.kind] !== false;
var name = (cfg.names && cfg.names[p.kind]) || p.name;
return el('div', { className: 'pet-settings-row' + (enabled ? '' : ' off'), key: p.kind },
el('span', { className: 'pet-settings-emoji' }, p.emoji),
el('input', {
className: 'pet-settings-name',
value: name,
disabled: !enabled,
placeholder: p.name,
onChange: function (e) {
var next = loadConfig();
next.names = next.names || {};
next.names[p.kind] = e.target.value;
saveConfig(next);
notifyConfig();
}
}),
el('label', { className: 'pet-settings-switch' },
el('input', {
type: 'checkbox',
checked: enabled,
onChange: function (e) {
var next = loadConfig();
next.enabled = next.enabled || {};
next.enabled[p.kind] = !!e.target.checked;
saveConfig(next);
notifyConfig();
}
}),
el('span', null, enabled ? '已启用' : '已停用')));
}));
}
function notifyConfig() {
if (typeof window !== 'undefined' && window.dispatchEvent) {
try { window.dispatchEvent(new Event('pet-dock:config')); } catch (e) {}
}
}
function apply(ctx) {
claimStyles();
var slots = ctx.slots;
slots.inject('settings.section', function () {
return slots.register(
{ name: 'settings.section', id: 'pet-dock', order: 50, label: 'PetDock' },
SettingsView);
});
slots.inject('shell.overlay', function () {
return slots.register(
{ name: 'shell.overlay', id: 'pet-dock' },
function () {
var useState = react.useState;
var useEffect = react.useEffect;
var _a = useState(0), index = _a[0], setIndex = _a[1];
var _b = useState(false), open = _b[0], setOpen = _b[1];
var _c = useState(false), switching = _c[0], setSwitching = _c[1];
var _d = useState(false), playing = _d[0], setPlaying = _d[1];
var _e = useState(false), leaving = _e[0], setLeaving = _e[1];
var _f = useState(0), tick = _f[0], setTick = _f[1];
useEffect(function () {
function onChange() { setTick(function (t) { return t + 1; }); }
if (typeof window !== 'undefined' && window.addEventListener) {
window.addEventListener('pet-dock:config', onChange);
return function () { window.removeEventListener('pet-dock:config', onChange); };
}
}, []);
var pets = activePets();
var safeIndex = pets.length === 0 ? 0 : (index >= pets.length ? 0 : index);
var pet = pets.length === 0 ? null : pets[safeIndex];
var single = pets.length <= 1;
var cycle = function (dir) {
if (playing || pets.length === 0) return;
setSwitching(true);
later(function () {
setIndex(function (i) {
if (pets.length === 0) return 0;
var base = i >= pets.length ? 0 : i;
return (base + dir + pets.length) % pets.length;
});
setSwitching(false);
setOpen(true);
}, 180);
};
var play = function () {
if (!pet || playing) return;
setPlaying(true);
setLeaving(false);
later(function () {
setLeaving(true);
later(function () {
setPlaying(false);
setLeaving(false);
setOpen(false);
}, 560);
}, 1900);
};
var exit = function () {
if (!playing) return;
setLeaving(true);
later(function () {
setPlaying(false);
setLeaving(false);
setOpen(false);
}, 560);
};
var el = react.createElement;
var dock = null;
if (pet) {
dock = el('div', {
className: 'pet-float',
onMouseEnter: function () { if (!playing) setOpen(true); },
onMouseLeave: function () { if (!playing) setOpen(false); }
},
el('div', { className: 'pet-outer' },
open
? el(PetWindow, { pet: pet, switching: switching, disabled: single, onPrev: function () { return cycle(-1); }, onNext: function () { return cycle(1); }, onPlay: play })
: el('button', { className: 'pet-avatar', title: pet.name }, pet.emoji)));
}
var center = playing && pet
? el(CenterReveal, { pet: pet, leaving: leaving, onExit: exit })
: null;
return el(react.Fragment, null, dock, center);
});
});
}
var inject = ["slots"];
module.exports = { apply: apply, inject: inject };
return module.exports;
}
});