pi-caveman 1.0.11 → 1.0.12
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/extensions/caveman.ts +26 -22
- package/package.json +1 -1
package/extensions/caveman.ts
CHANGED
|
@@ -212,6 +212,7 @@ export default function caveman(pi: ExtensionAPI) {
|
|
|
212
212
|
let config: CavemanConfig = { ...DEFAULT_CONFIG };
|
|
213
213
|
let timer: ReturnType<typeof setInterval> | null = null;
|
|
214
214
|
let frameIndex = 0;
|
|
215
|
+
let animationGeneration = 0;
|
|
215
216
|
let isActive = false;
|
|
216
217
|
let configLoadPromise: Promise<void> | null = null;
|
|
217
218
|
|
|
@@ -230,6 +231,7 @@ export default function caveman(pi: ExtensionAPI) {
|
|
|
230
231
|
// -- Animation helpers --
|
|
231
232
|
|
|
232
233
|
function stopAnimation() {
|
|
234
|
+
animationGeneration++;
|
|
233
235
|
if (timer) {
|
|
234
236
|
clearInterval(timer);
|
|
235
237
|
timer = null;
|
|
@@ -240,32 +242,34 @@ export default function caveman(pi: ExtensionAPI) {
|
|
|
240
242
|
function syncStatus(ctx: Pick<ExtensionContext, "ui">) {
|
|
241
243
|
stopAnimation();
|
|
242
244
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
245
|
+
const generation = animationGeneration;
|
|
246
|
+
const anim = level === "off" ? null : ANIMATIONS[level];
|
|
247
|
+
const renderFrame = () => {
|
|
248
|
+
if (generation !== animationGeneration) return false;
|
|
249
|
+
try {
|
|
250
|
+
if (!anim || !config.showStatus) {
|
|
251
|
+
ctx.ui.setStatus("caveman", "");
|
|
252
|
+
return false;
|
|
253
|
+
}
|
|
251
254
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
+
// Hosts like pi-web-ui may expose setStatus without a TUI theme.
|
|
256
|
+
const theme = ctx.ui.theme;
|
|
257
|
+
if (!theme?.fg) return false;
|
|
258
|
+
const frame = anim.frames[frameIndex % anim.frames.length]!;
|
|
259
|
+
ctx.ui.setStatus("caveman", frame + " " + theme.fg("muted", "caveman level: ") + theme.fg("text", anim.label));
|
|
260
|
+
frameIndex++;
|
|
261
|
+
return true;
|
|
262
|
+
} catch (error) {
|
|
263
|
+
// Timer callbacks run outside Pi's event-handler error boundary.
|
|
264
|
+
stopAnimation();
|
|
265
|
+
if (!(error instanceof Error) || !error.message.includes("stale after session replacement")) throw error;
|
|
266
|
+
return false;
|
|
267
|
+
}
|
|
255
268
|
};
|
|
256
269
|
|
|
257
|
-
if (
|
|
258
|
-
|
|
259
|
-
return;
|
|
270
|
+
if (renderFrame() && isActive && anim) {
|
|
271
|
+
timer = setInterval(renderFrame, anim.interval);
|
|
260
272
|
}
|
|
261
|
-
|
|
262
|
-
const renderFrame = () => {
|
|
263
|
-
setFrame(anim.frames[frameIndex % anim.frames.length]!);
|
|
264
|
-
frameIndex++;
|
|
265
|
-
};
|
|
266
|
-
|
|
267
|
-
renderFrame();
|
|
268
|
-
timer = setInterval(renderFrame, anim.interval);
|
|
269
273
|
}
|
|
270
274
|
|
|
271
275
|
// -- Restore state on session load --
|
package/package.json
CHANGED