@mingxy/opencode-mascot 0.4.25 → 0.4.27
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/package.json
CHANGED
|
@@ -4,7 +4,7 @@ import { createSignal } from "solid-js";
|
|
|
4
4
|
import type { JSX } from "@opentui/solid";
|
|
5
5
|
import type { MascotPack } from "../core/types";
|
|
6
6
|
import { createAnimatedRenderer } from "../core/ascii-renderer";
|
|
7
|
-
import { onCelebrate, onVersion } from "../core/celebration-bus";
|
|
7
|
+
import { onCelebrate, onVersion, onScatter } from "../core/celebration-bus";
|
|
8
8
|
|
|
9
9
|
interface HomeMascotProps {
|
|
10
10
|
mascots: Record<string, MascotPack>;
|
|
@@ -55,6 +55,10 @@ export function HomeMascot(props: HomeMascotProps): JSX.Element {
|
|
|
55
55
|
setTimeout(() => setZBoost(false), 3500);
|
|
56
56
|
});
|
|
57
57
|
|
|
58
|
+
onScatter(() => {
|
|
59
|
+
renderers[currentName()].scatterIn();
|
|
60
|
+
});
|
|
61
|
+
|
|
58
62
|
const stopDrag = () => {
|
|
59
63
|
isDragging = false;
|
|
60
64
|
renderers[currentName()].setDragging(false);
|
|
@@ -4,7 +4,7 @@ import { createSignal, onCleanup } from "solid-js";
|
|
|
4
4
|
import type { JSX } from "@opentui/solid";
|
|
5
5
|
import type { MascotPack, MascotState } from "../core/types";
|
|
6
6
|
import { createAnimatedRenderer } from "../core/ascii-renderer";
|
|
7
|
-
import { onCelebrate, onVersion } from "../core/celebration-bus";
|
|
7
|
+
import { onCelebrate, onVersion, onScatter } from "../core/celebration-bus";
|
|
8
8
|
|
|
9
9
|
interface SidebarMascotProps {
|
|
10
10
|
mascots: Record<string, MascotPack>;
|
|
@@ -185,6 +185,10 @@ export function SidebarMascot(props: SidebarMascotProps): JSX.Element {
|
|
|
185
185
|
setTimeout(() => setZBoost(false), 3500);
|
|
186
186
|
});
|
|
187
187
|
|
|
188
|
+
onScatter(() => {
|
|
189
|
+
renderers[currentName()].scatterIn();
|
|
190
|
+
});
|
|
191
|
+
|
|
188
192
|
return (
|
|
189
193
|
<box
|
|
190
194
|
position="absolute"
|
|
@@ -52,6 +52,7 @@ export function createAnimatedRenderer(pack: MascotPack): {
|
|
|
52
52
|
celebrateUpdate: (newVersion: string) => void;
|
|
53
53
|
bounce: () => void;
|
|
54
54
|
showVersion: (version: string) => void;
|
|
55
|
+
scatterIn: () => void;
|
|
55
56
|
} {
|
|
56
57
|
const anim = { ...DEFAULT_ANIM, ...pack.animations };
|
|
57
58
|
const fg = pack.colors?.defaultFg || undefined;
|
|
@@ -68,10 +69,12 @@ export function createAnimatedRenderer(pack: MascotPack): {
|
|
|
68
69
|
const [flashColor, setFlashColor] = createSignal<string | null>(null);
|
|
69
70
|
const [dragMsg, setDragMsg] = createSignal<string | null>(null);
|
|
70
71
|
const [zzz, setZzz] = createSignal<string | null>(null);
|
|
72
|
+
const [scatter, setScatter] = createSignal<{ dx: number; dy: number }[] | null>(null);
|
|
71
73
|
|
|
72
74
|
let flashTimer: ReturnType<typeof setInterval> | null = null;
|
|
73
75
|
let dragMsgTimer: ReturnType<typeof setInterval> | null = null;
|
|
74
76
|
let zzzTimer: ReturnType<typeof setInterval> | null = null;
|
|
77
|
+
let scatterTimer: ReturnType<typeof setInterval> | null = null;
|
|
75
78
|
let bounceTimers: ReturnType<typeof setTimeout>[] = [];
|
|
76
79
|
let celebrateTimers: ReturnType<typeof setTimeout>[] = [];
|
|
77
80
|
let versionTimer: ReturnType<typeof setTimeout> | null = null;
|
|
@@ -95,6 +98,10 @@ export function createAnimatedRenderer(pack: MascotPack): {
|
|
|
95
98
|
if (versionTimer) { clearTimeout(versionTimer); versionTimer = null; }
|
|
96
99
|
setCelebrate(null);
|
|
97
100
|
};
|
|
101
|
+
const stopScatter = () => {
|
|
102
|
+
if (scatterTimer) { clearInterval(scatterTimer); scatterTimer = null; }
|
|
103
|
+
setScatter(null);
|
|
104
|
+
};
|
|
98
105
|
|
|
99
106
|
const stopAllAnimations = () => {
|
|
100
107
|
stopFlash();
|
|
@@ -266,6 +273,7 @@ export function createAnimatedRenderer(pack: MascotPack): {
|
|
|
266
273
|
stopBounce();
|
|
267
274
|
stopCelebrate();
|
|
268
275
|
stopVersion();
|
|
276
|
+
stopScatter();
|
|
269
277
|
if (zzzTimer) { clearInterval(zzzTimer); zzzTimer = null; }
|
|
270
278
|
});
|
|
271
279
|
|
|
@@ -281,6 +289,7 @@ export function createAnimatedRenderer(pack: MascotPack): {
|
|
|
281
289
|
flashColor();
|
|
282
290
|
dragMsg();
|
|
283
291
|
zzz();
|
|
292
|
+
scatter();
|
|
284
293
|
|
|
285
294
|
for (const [, [get]] of extraSignals) {
|
|
286
295
|
get();
|
|
@@ -317,14 +326,15 @@ export function createAnimatedRenderer(pack: MascotPack): {
|
|
|
317
326
|
const left = offset > 0 ? offset : 0;
|
|
318
327
|
const cel = celebrate();
|
|
319
328
|
const dm = dragMsg();
|
|
329
|
+
const sc = scatter();
|
|
320
330
|
|
|
321
331
|
return (
|
|
322
332
|
<box flexDirection="column" alignItems="flex-start" left={left} top={top}>
|
|
323
333
|
{cel ? <box position="absolute" top={-1} left={0}><text fg={flashColor() ?? fg}>{cel.text}</text></box> : null}
|
|
324
334
|
{dm ? <box position="absolute" top={-1} left={0}><text fg="#FF4081">{dm}</text></box> : null}
|
|
325
335
|
{zzz() ? <box position="absolute" top={-1} left={0}><text fg={flashColor() ?? fg}>{zzz()}</text></box> : null}
|
|
326
|
-
{lines.map((line: string) => (
|
|
327
|
-
<text fg={flashColor() ?? fg}>{line}</text>
|
|
336
|
+
{lines.map((line: string, i: number) => (
|
|
337
|
+
<text fg={flashColor() ?? fg} left={sc?.[i]?.dx ?? 0} top={sc?.[i]?.dy ?? 0}>{line}</text>
|
|
328
338
|
))}
|
|
329
339
|
</box>
|
|
330
340
|
);
|
|
@@ -355,10 +365,10 @@ export function createAnimatedRenderer(pack: MascotPack): {
|
|
|
355
365
|
|
|
356
366
|
if (s === "sleeping") {
|
|
357
367
|
let phase = 1;
|
|
358
|
-
setZzz("
|
|
368
|
+
setZzz("zᶻ...");
|
|
359
369
|
zzzTimer = setInterval(() => {
|
|
360
370
|
phase = (phase % 3) + 1;
|
|
361
|
-
setZzz("ᶻ".repeat(phase));
|
|
371
|
+
setZzz("z" + "ᶻ".repeat(phase) + "...");
|
|
362
372
|
}, 1500);
|
|
363
373
|
} else {
|
|
364
374
|
if (zzzTimer) { clearInterval(zzzTimer); zzzTimer = null; }
|
|
@@ -433,7 +443,25 @@ export function createAnimatedRenderer(pack: MascotPack): {
|
|
|
433
443
|
setJumpOffset(-3);
|
|
434
444
|
bounceTimers.push(setTimeout(() => setJumpOffset(-2), 150));
|
|
435
445
|
bounceTimers.push(setTimeout(() => setJumpOffset(-1), 300));
|
|
436
|
-
bounceTimers.push(setTimeout(() => {
|
|
446
|
+
bounceTimers.push(setTimeout(() => {
|
|
447
|
+
setJumpOffset(0);
|
|
448
|
+
bounceTimers = [];
|
|
449
|
+
if (Math.random() < 0.3) {
|
|
450
|
+
fallApart();
|
|
451
|
+
}
|
|
452
|
+
}, 450));
|
|
453
|
+
};
|
|
454
|
+
|
|
455
|
+
const fallApart = () => {
|
|
456
|
+
const lineCount = getFrameLines(pack, "default").length;
|
|
457
|
+
const offsets = Array.from({ length: lineCount }, (_, i) => ({
|
|
458
|
+
dx: Math.floor((Math.random() - 0.3) * 20),
|
|
459
|
+
dy: i === 0 ? 2 : Math.floor(Math.random() * 3) + 1,
|
|
460
|
+
}));
|
|
461
|
+
setScatter(offsets);
|
|
462
|
+
bounceTimers.push(setTimeout(() => {
|
|
463
|
+
scatterIn();
|
|
464
|
+
}, 1500));
|
|
437
465
|
};
|
|
438
466
|
|
|
439
467
|
const showVersion = (version: string) => {
|
|
@@ -442,5 +470,31 @@ export function createAnimatedRenderer(pack: MascotPack): {
|
|
|
442
470
|
versionTimer = setTimeout(() => { setCelebrate(null); versionTimer = null; }, 3000);
|
|
443
471
|
};
|
|
444
472
|
|
|
445
|
-
|
|
473
|
+
const scatterIn = () => {
|
|
474
|
+
stopScatter();
|
|
475
|
+
const lineCount = getFrameLines(pack, "default").length;
|
|
476
|
+
const offsets = Array.from({ length: lineCount }, () => ({
|
|
477
|
+
dx: Math.floor((Math.random() - 0.5) * 30),
|
|
478
|
+
dy: Math.floor((Math.random() - 0.5) * 12),
|
|
479
|
+
}));
|
|
480
|
+
setScatter(offsets);
|
|
481
|
+
|
|
482
|
+
let ticks = 0;
|
|
483
|
+
const MAX_TICKS = 15;
|
|
484
|
+
scatterTimer = setInterval(() => {
|
|
485
|
+
ticks++;
|
|
486
|
+
if (ticks >= MAX_TICKS) {
|
|
487
|
+
setScatter(offsets.map(() => ({ dx: 0, dy: 0 })));
|
|
488
|
+
stopScatter();
|
|
489
|
+
return;
|
|
490
|
+
}
|
|
491
|
+
const t = ticks / MAX_TICKS;
|
|
492
|
+
setScatter(offsets.map(o => ({
|
|
493
|
+
dx: Math.round(o.dx * (1 - t)),
|
|
494
|
+
dy: Math.round(o.dy * (1 - t)),
|
|
495
|
+
})));
|
|
496
|
+
}, 80);
|
|
497
|
+
};
|
|
498
|
+
|
|
499
|
+
return { element, setState, toggleWalk, setDragging, celebrateUpdate, bounce, showVersion, scatterIn };
|
|
446
500
|
}
|
|
@@ -2,6 +2,7 @@ const bus = new EventTarget();
|
|
|
2
2
|
|
|
3
3
|
const CELEBRATE_EVENT = "mascot:celebrate";
|
|
4
4
|
const VERSION_EVENT = "mascot:version";
|
|
5
|
+
const SCATTER_EVENT = "mascot:scatter";
|
|
5
6
|
|
|
6
7
|
export function emitCelebrate(newVersion: string): void {
|
|
7
8
|
bus.dispatchEvent(new CustomEvent(CELEBRATE_EVENT, { detail: { newVersion } }));
|
|
@@ -28,3 +29,13 @@ export function onVersion(handler: (version: string) => void): () => void {
|
|
|
28
29
|
bus.addEventListener(VERSION_EVENT, listener);
|
|
29
30
|
return () => bus.removeEventListener(VERSION_EVENT, listener);
|
|
30
31
|
}
|
|
32
|
+
|
|
33
|
+
export function emitScatter(): void {
|
|
34
|
+
bus.dispatchEvent(new CustomEvent(SCATTER_EVENT));
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function onScatter(handler: () => void): () => void {
|
|
38
|
+
const listener = () => { handler(); };
|
|
39
|
+
bus.addEventListener(SCATTER_EVENT, listener);
|
|
40
|
+
return () => bus.removeEventListener(SCATTER_EVENT, listener);
|
|
41
|
+
}
|
package/tui.tsx
CHANGED
|
@@ -7,7 +7,7 @@ import { loadAllMascots } from "./src/core/mascot-loader"
|
|
|
7
7
|
import { SidebarMascot } from "./src/components/sidebar-mascot"
|
|
8
8
|
import { HomeMascot } from "./src/components/home-mascot"
|
|
9
9
|
import { checkAndUpdate } from "./src/core/updater"
|
|
10
|
-
import { emitCelebrate, emitVersion } from "./src/core/celebration-bus"
|
|
10
|
+
import { emitCelebrate, emitVersion, emitScatter } from "./src/core/celebration-bus"
|
|
11
11
|
|
|
12
12
|
const __filename = fileURLToPath(import.meta.url);
|
|
13
13
|
const __dirname = dirname(__filename);
|
|
@@ -38,7 +38,8 @@ const tui: TuiPlugin = async (api, _options) => {
|
|
|
38
38
|
emitCelebrate(newVersion);
|
|
39
39
|
}).catch(() => {});
|
|
40
40
|
|
|
41
|
-
setTimeout(() =>
|
|
41
|
+
setTimeout(() => emitScatter(), 100);
|
|
42
|
+
setTimeout(() => emitVersion(pluginVersion), 2000);
|
|
42
43
|
}
|
|
43
44
|
|
|
44
45
|
const plugin: TuiPluginModule = {
|