497 lines
29 KiB
JavaScript
497 lines
29 KiB
JavaScript
// 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;
|
||
}
|
||
});
|