Fix agent pet scale rendering
This commit is contained in:
parent
c72c8a423b
commit
5ae609429c
3 changed files with 25 additions and 10 deletions
|
|
@ -1,6 +1,6 @@
|
|||
import { BrowserWindow } from "electron";
|
||||
|
||||
import { getAppStateSnapshot } from "./app-state.js";
|
||||
import { getAppStateSnapshot, type PetScaleValue } 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";
|
||||
|
|
@ -84,11 +84,12 @@ export function closeAllAgentPets(): void {
|
|||
|
||||
export function refreshAgentPetContent(): void {
|
||||
debug("pet.agent", "refresh all content", { activeWindows: agentPetWindows.size, petIds: [...agentPetWindows.keys()] });
|
||||
const scale = getPreferredPetScale();
|
||||
for (const [petId, window] of agentPetWindows.entries()) {
|
||||
if (!window.isDestroyed()) {
|
||||
const display = transientDisplays.get(petId) ?? null;
|
||||
const badge = statusBadges.get(petId) ?? null;
|
||||
void loadExplicitPetContent(window, petId, display, badge, getCurrentDismissToken(petId, display, badge));
|
||||
void loadExplicitPetContent(window, petId, display, badge, getCurrentDismissToken(petId, display, badge), scale);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -103,7 +104,7 @@ function handleBubbleDismissed(petId: string, dismissToken: string): void {
|
|||
clearAgentDisplay(petId);
|
||||
const window = agentPetWindows.get(petId);
|
||||
if (window && !window.isDestroyed()) {
|
||||
void loadExplicitPetContent(window, petId, null, null);
|
||||
void loadExplicitPetContent(window, petId, null, null, undefined, getPreferredPetScale());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -114,7 +115,9 @@ function getOrCreateAgentPetWindow(petId: string): BrowserWindow {
|
|||
return existing;
|
||||
}
|
||||
|
||||
const pet = getAppStateSnapshot().pets.installed.find((candidate) => candidate.id === petId);
|
||||
const state = getAppStateSnapshot();
|
||||
const scale = state.preferences.petScale as PetScaleValue;
|
||||
const pet = state.pets.installed.find((candidate) => candidate.id === petId);
|
||||
if (!pet) throw new Error(`Installed pet is unavailable: ${petId}`);
|
||||
const offset = agentPetWindows.size + 1;
|
||||
const initial = getDefaultPetInitialPosition(defaultPetWindowSize);
|
||||
|
|
@ -123,6 +126,7 @@ function getOrCreateAgentPetWindow(petId: string): BrowserWindow {
|
|||
const window = createAgentPetWindow({
|
||||
petId,
|
||||
displayName: pet.displayName,
|
||||
scale,
|
||||
position: { x: initial.x - offset * 36, y: initial.y - offset * 24 },
|
||||
display,
|
||||
badge,
|
||||
|
|
@ -177,12 +181,12 @@ function setAgentDisplay(petId: string, display: PetTransientDisplay): void {
|
|||
const window = agentPetWindows.get(petId);
|
||||
if (window && !window.isDestroyed()) {
|
||||
const badge = statusBadges.get(petId) ?? null;
|
||||
void loadExplicitPetContent(window, petId, null, badge, getCurrentDismissToken(petId, null, badge));
|
||||
void loadExplicitPetContent(window, petId, null, badge, getCurrentDismissToken(petId, null, badge), getPreferredPetScale());
|
||||
}
|
||||
}, displayDurationMs);
|
||||
transientTimers.set(petId, timer);
|
||||
const window = agentPetWindows.get(petId);
|
||||
if (window && !window.isDestroyed()) void loadExplicitPetContent(window, petId, preparedDisplay, statusBadges.get(petId) ?? null, preparedDisplay.dismissToken);
|
||||
if (window && !window.isDestroyed()) void loadExplicitPetContent(window, petId, preparedDisplay, statusBadges.get(petId) ?? null, preparedDisplay.dismissToken, getPreferredPetScale());
|
||||
}
|
||||
|
||||
function clearAgentDisplay(petId: string): void {
|
||||
|
|
@ -226,7 +230,7 @@ function setStatusBadge(petId: string, reaction: OpenPetsReaction): void {
|
|||
const window = agentPetWindows.get(petId);
|
||||
if (window && !window.isDestroyed()) {
|
||||
const display = transientDisplays.get(petId) ?? null;
|
||||
void loadExplicitPetContent(window, petId, display, null, getCurrentDismissToken(petId, display, null));
|
||||
void loadExplicitPetContent(window, petId, display, null, getCurrentDismissToken(petId, display, null), getPreferredPetScale());
|
||||
}
|
||||
}, isBusyStatusBadgeReaction(reaction) ? busyStatusBadgeMs : transientDisplayMs);
|
||||
statusBadgeTimers.set(petId, timer);
|
||||
|
|
@ -247,3 +251,7 @@ function isBusyStatusBadgeReaction(reaction: OpenPetsReaction): boolean {
|
|||
function getCurrentDismissToken(petId: string, display: PetTransientDisplay | null, badge: PetStatusBadgeReaction | null): string | undefined {
|
||||
return display?.dismissToken ?? (badge ? String(displayGenerations.get(petId) ?? 0) : undefined);
|
||||
}
|
||||
|
||||
function getPreferredPetScale(): PetScaleValue {
|
||||
return getAppStateSnapshot().preferences.petScale as PetScaleValue;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -213,6 +213,11 @@ assert.match(petWindowSource, /html\[data-motion-state=\"\$\{motion\}\"\] \$\{se
|
|||
assert.match(petWindowSource, /\.sprite, \.installed-sprite, \.bubble/, "reduced-motion CSS must include built-in and installed sprites.");
|
||||
assert.match(petWindowSource, /function createAgentPetWindow[\s\S]*?installMotionStatePublisher\(window\)/, "agent pet windows must publish motion state so dragged non-default pets run.");
|
||||
assert.match(petWindowSource, /loadExplicitPetContent[\s\S]*?state\.preferences\.petScale/, "explicit agent pet windows must use the saved pet scale preference.");
|
||||
assert.match(petWindowSource, /interface AgentPetWindowOptions[\s\S]*?readonly scale: PetScaleValue/, "new agent pet windows must receive the current pet scale explicitly for their first render.");
|
||||
assert.match(petWindowSource, /loadExplicitPetContent\(window, options\.petId, options\.display, options\.badge, dismissToken, options\.scale\)/, "agent pet first render must not fall back to the medium default scale.");
|
||||
assert.match(agentPetControllerSourceForLogging, /function getPreferredPetScale\(\): PetScaleValue/, "agent pet reloads must share one explicit saved scale helper.");
|
||||
assert.match(agentPetControllerSourceForLogging, /loadExplicitPetContent\(window, petId, display, badge, getCurrentDismissToken\(petId, display, badge\), scale\)/, "agent pet refreshes must pass the saved pet scale explicitly.");
|
||||
assert.match(agentPetControllerSourceForLogging, /loadExplicitPetContent\(window, petId, preparedDisplay, statusBadges\.get\(petId\) \?\? null, preparedDisplay\.dismissToken, getPreferredPetScale\(\)\)/, "agent pet transient updates must pass the saved pet scale explicitly.");
|
||||
assert.match(mappingDoc, /\| 3 \| `waving` \| `waving`, Claude `Notification`\. \|/, "mapping docs must describe waving animation row and notification mapping.");
|
||||
assert.match(mappingDoc, /reaction-animation-mapping\.ts/, "mapping docs must reference the shared reaction animation mapping source of truth.");
|
||||
assert.match(mappingDoc, /overrid/i, "mapping docs must mention that reaction animation defaults can be overridden in Settings.");
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ export interface DefaultPetWindowOptions {
|
|||
export interface AgentPetWindowOptions {
|
||||
readonly petId: string;
|
||||
readonly displayName: string;
|
||||
readonly scale: PetScaleValue;
|
||||
readonly position: Point;
|
||||
readonly display: PetTransientDisplay | null;
|
||||
readonly badge: PetStatusBadgeReaction | null;
|
||||
|
|
@ -86,7 +87,7 @@ export function createAgentPetWindow(options: AgentPetWindowOptions, dismissToke
|
|||
installMousePassthroughAndDrag(window, options.onBubbleDismissed);
|
||||
installMotionStatePublisher(window);
|
||||
installPetContextMenu(window, { label: "Close pet", click: options.onCloseRequested });
|
||||
void loadExplicitPetContent(window, options.petId, options.display, options.badge, dismissToken);
|
||||
void loadExplicitPetContent(window, options.petId, options.display, options.badge, dismissToken, options.scale);
|
||||
return window;
|
||||
}
|
||||
|
||||
|
|
@ -378,7 +379,7 @@ export async function loadDefaultPetContent(window: BrowserWindow, paused: boole
|
|||
});
|
||||
}
|
||||
|
||||
export async function loadExplicitPetContent(window: BrowserWindow, petId: string, display: PetTransientDisplay | null = null, badge: PetStatusBadgeReaction | null = null, dismissToken?: string): Promise<void> {
|
||||
export async function loadExplicitPetContent(window: BrowserWindow, petId: string, display: PetTransientDisplay | null = null, badge: PetStatusBadgeReaction | null = null, dismissToken?: string, scaleOverride?: PetScaleValue): Promise<void> {
|
||||
const sequence = allocateWindowLoadSequence(window);
|
||||
try {
|
||||
const state = getAppStateSnapshot();
|
||||
|
|
@ -387,7 +388,8 @@ export async function loadExplicitPetContent(window: BrowserWindow, petId: strin
|
|||
throw new Error(`Cannot render explicit pet: ${petId}`);
|
||||
}
|
||||
debug("pet.window", "explicit content render begin", { windowId: window.id, sequence, petId, displayName: pet.displayName, hasDisplay: Boolean(display), reaction: display?.reaction, hasMessage: Boolean(display?.message), badge });
|
||||
const render = await createInstalledPetRender(pet.id, pet.displayName, false, display, state.preferences.petScale as PetScaleValue, badge, `explicit:${pet.id}`, dismissToken);
|
||||
const scale = scaleOverride ?? state.preferences.petScale as PetScaleValue;
|
||||
const render = await createInstalledPetRender(pet.id, pet.displayName, false, display, scale, badge, `explicit:${pet.id}`, dismissToken);
|
||||
if (tryUpdateLoadedPetContent(window, render, `explicit-${pet.id}`, sequence)) return;
|
||||
await loadPetHtmlFile(window, render.html, `explicit-${pet.id}`, sequence);
|
||||
petWindowRenderCache.set(window, render.cacheKey);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue