diff --git a/src/components/ai-edition/CursorPane.levels.test.tsx b/src/components/ai-edition/CursorPane.levels.test.tsx index bc714e2f7..480f1d8ed 100644 --- a/src/components/ai-edition/CursorPane.levels.test.tsx +++ b/src/components/ai-edition/CursorPane.levels.test.tsx @@ -6,8 +6,18 @@ import { LOCALE_STORAGE_KEY } from "@/i18n/config"; import { assetSchema, clipSchema, createEmptyDocument } from "@/lib/ai-edition/schema"; import { useProjectStore } from "@/lib/ai-edition/store/projectStore"; import { type NativeCursorType, nativeBridgeClient } from "@/native"; +import { setCurrentNativeViewId } from "@/native/nativeCompositorStore"; import { CursorPane } from "./RightPanes"; +const compositor = vi.hoisted(() => ({ + setCompositorParam: vi.fn(async () => undefined), +})); + +vi.mock("@/native/compositorViewClient", async (importOriginal) => ({ + ...(await importOriginal()), + setCompositorParam: compositor.setCompositorParam, +})); + beforeEach(() => { const store = new Map([[LOCALE_STORAGE_KEY, "en"]]); Object.defineProperty(globalThis, "localStorage", { @@ -187,7 +197,33 @@ describe("CursorPane size", () => { it("is a slider from the default up to four times it", () => { renderWithCursor({ cursorSize: 4.5 }); const slider = screen.getByRole("slider", { name: "Size" }) as HTMLInputElement; - expect([slider.min, slider.max, slider.value]).toEqual(["1.5", "6", "4.5"]); + expect([slider.min, slider.max, slider.value]).toEqual(["150", "600", "450"]); + }); + + // #1436: the value is a scale, so the pixels it draws depend on the output size. + it("shows its value as a percentage, and stores the scale", () => { + renderWithCursor({ cursorSize: 4.5 }); + expect(screen.getByText("450%")).toBeTruthy(); + + const slider = screen.getByRole("slider", { name: "Size" }); + fireEvent.change(slider, { target: { value: "345" } }); + fireEvent.mouseUp(slider); + + expect(useProjectStore.getState().document?.legacyEditor).toMatchObject({ cursorSize: 3.45 }); + expect(screen.getByText("345%")).toBeTruthy(); + }); + + it("sends the native preview the scale, not the percentage", () => { + setCurrentNativeViewId(7); + try { + renderWithCursor({ cursorSize: 4.5 }); + fireEvent.change(screen.getByRole("slider", { name: "Size" }), { target: { value: "345" } }); + + expect(compositor.setCompositorParam).toHaveBeenCalledWith(7, "cursorSize", 3.45); + expect(compositor.setCompositorParam).not.toHaveBeenCalledWith(7, "cursorSize", 345); + } finally { + setCurrentNativeViewId(null); + } }); }); diff --git a/src/components/ai-edition/RightPanes.tsx b/src/components/ai-edition/RightPanes.tsx index 1e0c67410..32cbcd1e8 100644 --- a/src/components/ai-edition/RightPanes.tsx +++ b/src/components/ai-edition/RightPanes.tsx @@ -3867,15 +3867,16 @@ export function CursorPane() { `SETTING_BOUNDS` keeps both ends sane. */} { - setLive({ cursor: { size: v } }); - if (isNativeCompositorActive()) setNativeParam("cursorSize", v); + setLive({ cursor: { size: v / 100 } }); + if (isNativeCompositorActive()) setNativeParam("cursorSize", v / 100); }} onCommit={() => void commit()} />