Extend speech bubble duration
This commit is contained in:
parent
fec746d62f
commit
5372a5c513
4 changed files with 18 additions and 6 deletions
|
|
@ -4,7 +4,7 @@ import { getAppStateSnapshot } from "./app-state.js";
|
|||
import { defaultPetWindowSize, getDefaultPetInitialPosition } from "./display.js";
|
||||
import { debug, info } from "./logger.js";
|
||||
import { transientDisplayMs, type OpenPetsReaction } from "./local-ipc-protocol.js";
|
||||
import { clearTransientReaction, createAgentPetWindow, getTransientReactionAnimationMs, loadExplicitPetContent, mergePetTransientDisplay, setPetReactionState, type PetStatusBadgeReaction, type PetTransientDisplay } from "./pet-window.js";
|
||||
import { clearTransientReaction, createAgentPetWindow, getTransientDisplayDurationMs, getTransientReactionAnimationMs, loadExplicitPetContent, mergePetTransientDisplay, setPetReactionState, type PetStatusBadgeReaction, type PetTransientDisplay } from "./pet-window.js";
|
||||
|
||||
const agentPetWindows = new Map<string, BrowserWindow>();
|
||||
const transientDisplays = new Map<string, PetTransientDisplay>();
|
||||
|
|
@ -129,7 +129,8 @@ function setAgentDisplay(petId: string, display: PetTransientDisplay): void {
|
|||
if (existingAnimationTimer) clearTimeout(existingAnimationTimer);
|
||||
|
||||
const animationMs = getTransientReactionAnimationMs(preparedDisplay);
|
||||
if (animationMs !== null && animationMs < transientDisplayMs) {
|
||||
const displayDurationMs = getTransientDisplayDurationMs(preparedDisplay);
|
||||
if (animationMs !== null && animationMs < displayDurationMs) {
|
||||
const animationTimer = setTimeout(() => {
|
||||
const current = transientDisplays.get(petId);
|
||||
if (!current) return;
|
||||
|
|
@ -150,7 +151,7 @@ function setAgentDisplay(petId: string, display: PetTransientDisplay): void {
|
|||
transientAnimationTimers.delete(petId);
|
||||
const window = agentPetWindows.get(petId);
|
||||
if (window && !window.isDestroyed()) void loadExplicitPetContent(window, petId, null, statusBadges.get(petId) ?? null);
|
||||
}, transientDisplayMs);
|
||||
}, displayDurationMs);
|
||||
transientTimers.set(petId, timer);
|
||||
const window = agentPetWindows.get(petId);
|
||||
if (window && !window.isDestroyed()) void loadExplicitPetContent(window, petId, preparedDisplay, statusBadges.get(petId) ?? null);
|
||||
|
|
|
|||
|
|
@ -105,6 +105,9 @@ assert.match(reactionMessagesSource, /satisfies Record<OpenPetsReaction, readonl
|
|||
assert.match(petWindowSource, /pickReactionMessage\(display\.reaction\)/, "reaction-only bubbles must render randomized messages instead of raw lowercase reaction ids.");
|
||||
assert.match(petWindowSource, /function preparePetTransientDisplay/, "reaction-only bubbles must prepare a stable random message before rerenders.");
|
||||
assert.match(petWindowSource, /function mergePetTransientDisplay/, "reaction-only events must not replace an active explicit message bubble.");
|
||||
assert.match(petWindowSource, /function getTransientDisplayDurationMs[\s\S]*?12_000[\s\S]*?message\.length \* 70/, "speech bubbles must stay visible longer for longer messages without becoming permanent.");
|
||||
assert.match(defaultPetControllerSource, /getTransientDisplayDurationMs\(transientDisplay\)/, "default pet speech bubble timeout must be length-aware.");
|
||||
assert.match(agentPetControllerSourceForLogging, /getTransientDisplayDurationMs\(preparedDisplay\)/, "agent pet speech bubble timeout must be length-aware.");
|
||||
assert.match(petWindowSource, /function getTransientReactionAnimationMs/, "finite reaction animations must expose their own shorter lifetime.");
|
||||
assert.match(petWindowSource, /function clearTransientReaction/, "finite reaction animations must be clearable while the bubble remains visible.");
|
||||
assert.match(petWindowSource, /webContents\.send\("openpets:pet-reaction-state"/, "finite reaction animations must clear sprite state without reloading the bubble.");
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import { getAppStateSnapshot, getDefaultPetPosition, resetDefaultPetPosition, se
|
|||
import { defaultPetWindowSize, getDefaultPetInitialPosition } from "./display.js";
|
||||
import { debug, info } from "./logger.js";
|
||||
import { transientDisplayMs, type OpenPetsReaction } from "./local-ipc-protocol.js";
|
||||
import { clearTransientReaction, createDefaultPetWindow, getSafeDefaultPetPosition, getTransientReactionAnimationMs, loadDefaultPetContent, mergePetTransientDisplay, readWindowPosition, setPetReactionState, type PetStatusBadgeReaction, type PetTransientDisplay } from "./pet-window.js";
|
||||
import { clearTransientReaction, createDefaultPetWindow, getSafeDefaultPetPosition, getTransientDisplayDurationMs, getTransientReactionAnimationMs, loadDefaultPetContent, mergePetTransientDisplay, readWindowPosition, setPetReactionState, type PetStatusBadgeReaction, type PetTransientDisplay } from "./pet-window.js";
|
||||
|
||||
let defaultPetWindow: BrowserWindow | null = null;
|
||||
let paused = false;
|
||||
|
|
@ -149,7 +149,8 @@ function setTransientDisplay(display: PetTransientDisplay): void {
|
|||
}
|
||||
|
||||
const animationMs = getTransientReactionAnimationMs(transientDisplay);
|
||||
if (animationMs !== null && animationMs < transientDisplayMs) {
|
||||
const displayDurationMs = getTransientDisplayDurationMs(transientDisplay);
|
||||
if (animationMs !== null && animationMs < displayDurationMs) {
|
||||
transientAnimationTimeout = setTimeout(() => {
|
||||
if (!transientDisplay) return;
|
||||
transientDisplay = clearTransientReaction(transientDisplay);
|
||||
|
|
@ -166,7 +167,7 @@ function setTransientDisplay(display: PetTransientDisplay): void {
|
|||
transientAnimationTimeout = null;
|
||||
}
|
||||
refreshDefaultPetContent();
|
||||
}, transientDisplayMs);
|
||||
}, displayDurationMs);
|
||||
|
||||
refreshDefaultPetContent();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -359,6 +359,13 @@ export function getTransientReactionAnimationMs(display: PetTransientDisplay): n
|
|||
return typeof iterations === "number" ? row.durationMs * iterations : null;
|
||||
}
|
||||
|
||||
export function getTransientDisplayDurationMs(display: PetTransientDisplay): number {
|
||||
const baseMs = display.reaction === "success" || display.reaction === "error" ? 5_000 : 4_000;
|
||||
const message = display.message ?? display.reactionMessage;
|
||||
if (!message) return baseMs;
|
||||
return Math.min(12_000, Math.max(baseMs, message.length * 70));
|
||||
}
|
||||
|
||||
export function clearTransientReaction(display: PetTransientDisplay): PetTransientDisplay {
|
||||
if (!display.reaction) return display;
|
||||
return { ...display, reaction: undefined };
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue