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

497 lines
29 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

// 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;
}
});