mirror of
https://github.com/esengine/DeepSeek-Reasonix.git
synced 2026-11-07 10:45:59 -10:00
fix(studio): a line-width preset wins over a width the column was dragged to
The width a hand set is kept in --flow-w and outranks the stylesheet, so once the reading column had been dragged, choosing the full-width preset changed --doc but not the column and did nothing. Choosing a preset now drops the dragged width.
This commit is contained in:
1 parent
8c669ebe61
commit
d28a6089fc
7 files changed
+110
-2
No files matched your search
@@ -161,6 +161,7 @@ jobs:
|
||||
node perf/rowhit.mjs
|
||||
node perf/flowgrip-quiet.mjs
|
||||
node perf/flow-narrow.mjs
|
||||
node perf/flow-preset.mjs
|
||||
node perf/tab-pip.mjs
|
||||
node perf/context-card-hover.mjs
|
||||
node perf/sessquick.mjs
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
// A line-width preset still works on a column a hand has already dragged: the
|
||||
// dragged width outranks the stylesheet, so choosing a preset has to drop it.
|
||||
import assert from "node:assert/strict";
|
||||
import { chromium } from "playwright";
|
||||
|
||||
const PAGE = process.env.PERF_URL ?? "http://localhost:4399/perf.html?pref=zh&turns=3";
|
||||
const browser = await chromium.launch();
|
||||
try {
|
||||
const page = await browser.newPage({ viewport: { width: 1900, height: 900 } });
|
||||
const errors = [];
|
||||
page.on("pageerror", (error) => errors.push(error.message));
|
||||
await page.goto(PAGE, { waitUntil: "networkidle" });
|
||||
await page.waitForSelector(".flowgrip-l");
|
||||
const flow = () => page.locator(".flow").first().evaluate((el) => Math.round(el.getBoundingClientRect().width));
|
||||
const readable = await flow();
|
||||
const box = await page.locator(".flowgrip-l").boundingBox();
|
||||
await page.mouse.move(box.x + 3, box.y + box.height / 2);
|
||||
await page.mouse.down();
|
||||
await page.mouse.move(box.x + 3 - 60, box.y + box.height / 2, { steps: 6 });
|
||||
await page.mouse.up();
|
||||
await page.waitForTimeout(200);
|
||||
const dragged = await flow();
|
||||
assert.ok(dragged > readable, `the hand widened the column (${readable} -> ${dragged})`);
|
||||
|
||||
const choose = async (name) => {
|
||||
await page.evaluate(() => document.querySelector('[data-action="chrome.settings"]')?.click());
|
||||
await page.waitForSelector(".prefs-nav button");
|
||||
await page.locator(".prefs-nav button", { hasText: "外观" }).first().click();
|
||||
await page.locator('[data-action="appearance.measure"]', { hasText: new RegExp(`^${name}$`) }).click();
|
||||
await page.keyboard.press("Escape");
|
||||
await page.waitForTimeout(400);
|
||||
return flow();
|
||||
};
|
||||
const full = await choose("铺满窗口");
|
||||
assert.ok(full > dragged, `the full-width preset widens a dragged column (${dragged} -> ${full})`);
|
||||
const standard = await choose("适宜阅读");
|
||||
assert.equal(standard, readable, `the reading preset returns to the readable measure (${full} -> ${standard})`);
|
||||
assert.deepEqual(errors, []);
|
||||
console.log(`PASS a preset overrides a dragged width: ${readable} -> ${dragged} (dragged) -> ${full} (full) -> ${standard} (reading)`);
|
||||
} finally {
|
||||
await browser.close();
|
||||
}
|
||||
@@ -26,6 +26,7 @@ import { SendShortcut } from "./SendShortcut";
|
||||
import { KeysSheet } from "./KeysSheet";
|
||||
import { SessionTabsSetting } from "./SessionTabsSetting";
|
||||
import { EscStopSetting } from "./EscStopSetting";
|
||||
import { forgetDraggedWidth } from "./FlowResizer";
|
||||
import { PageSleepSetting } from "./PageSleepSetting";
|
||||
import { ThemeImport } from "./ThemeImport";
|
||||
import { ThemeRemove } from "./ThemeRemove";
|
||||
@@ -365,7 +366,7 @@ export function Appearance({ port, theme, onTheme, contrast, onContrast, weight,
|
||||
<div className="seg" data-text role="group" aria-label={t("正文行宽")}>
|
||||
{MEASURES.map(([id, name, why]) => (
|
||||
<button key={id} data-action="appearance.measure" data-value={id}
|
||||
aria-pressed={(look.width || "standard") === id} title={t(why)} onClick={() => set({ width: id })}>
|
||||
aria-pressed={(look.width || "standard") === id} title={t(why)} onClick={() => { forgetDraggedWidth(); set({ width: id }); }}>
|
||||
{t(name)}
|
||||
</button>
|
||||
))}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
import { act, cleanup, fireEvent, render, renderHook } from "@testing-library/react";
|
||||
import "./testkit";
|
||||
import { barsFit, flowCeiling, flowFloor, flowMin, FlowGrips, useColumn, type Column } from "./FlowResizer";
|
||||
import { barsFit, flowCeiling, flowFloor, flowMin, forgetDraggedWidth, FlowGrips, useColumn, type Column } from "./FlowResizer";
|
||||
|
||||
const RAIL_MIN = 232;
|
||||
const DOCK_MIN = 320;
|
||||
@@ -219,3 +219,16 @@ describe("the keys walk the same path the hand does", () => {
|
||||
expect(press("l", "ArrowRight", false, 760)).toEqual([748]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("a line-width preset answers for the dragged width", () => {
|
||||
it("forgets what a hand set, in storage and in every mounted column", () => {
|
||||
localStorage.clear();
|
||||
localStorage.setItem("rx-flow-w", "900");
|
||||
const { result } = renderHook(() => useColumn(316, 316, RAIL_MIN, DOCK_MIN));
|
||||
expect(result.current.dragged).toBe(900);
|
||||
act(() => forgetDraggedWidth());
|
||||
expect(result.current.dragged).toBe(0);
|
||||
expect(localStorage.getItem("rx-flow-w")).toBeNull();
|
||||
expect(result.current.width).toBe(result.current.floor);
|
||||
});
|
||||
});
|
||||
@@ -21,6 +21,16 @@ const NARROWEST = 640;
|
||||
* the kernel's config. */
|
||||
export const FLOW_KEY = "rx-flow-w";
|
||||
|
||||
const forgetters = new Set<() => void>();
|
||||
|
||||
/** A line-width preset and a hand on the grips answer the same question, and
|
||||
* the width a hand set outranks the stylesheet, so choosing a preset has to
|
||||
* drop it or the choice changes nothing on a column that was ever dragged. */
|
||||
export function forgetDraggedWidth() {
|
||||
try { localStorage.removeItem(FLOW_KEY); } catch { /* storage is a convenience */ }
|
||||
forgetters.forEach((forget) => forget());
|
||||
}
|
||||
|
||||
const clamp = (v: number, lo: number, hi: number) => Math.min(hi, Math.max(lo, v));
|
||||
|
||||
/** What the column may grow to: the window, less the room the two sidebars need
|
||||
@@ -97,6 +107,11 @@ export function useColumn(railW: number, dockW: number, railMin: number, dockMin
|
||||
});
|
||||
const [room, setRoom] = useState(() => document.body.clientWidth);
|
||||
useEffect(() => onRoomWidth(setRoom), []);
|
||||
useEffect(() => {
|
||||
const forget = () => setDragged(0);
|
||||
forgetters.add(forget);
|
||||
return () => { forgetters.delete(forget); };
|
||||
}, []);
|
||||
|
||||
const floor = flowFloor(room, railMin, dockMin);
|
||||
const min = flowMin(room, railMin, dockMin);
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
// @vitest-environment jsdom
|
||||
import { afterEach, beforeEach, expect, it, vi } from "vitest";
|
||||
import { cleanup, render, screen } from "@testing-library/react";
|
||||
import userEvent from "@testing-library/user-event";
|
||||
import "./testkit";
|
||||
import { Appearance } from "./Appearance";
|
||||
import { FLOW_KEY } from "./FlowResizer";
|
||||
import { MockPort } from "../port/mock";
|
||||
import { boot, STORAGE } from "../i18n";
|
||||
import type { AgentPort } from "../port/port";
|
||||
|
||||
beforeEach(() => {
|
||||
localStorage.setItem(STORAGE, "zh");
|
||||
boot();
|
||||
vi.spyOn(HTMLCanvasElement.prototype, "getContext").mockReturnValue(null);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
cleanup();
|
||||
localStorage.clear();
|
||||
vi.restoreAllMocks();
|
||||
});
|
||||
|
||||
function panel(width: string) {
|
||||
return <Appearance port={new MockPort() as unknown as AgentPort} theme="light" onTheme={() => {}} contrast="" onContrast={() => {}}
|
||||
weight="" onWeight={() => {}} look={{ width } as never} onLook={() => {}} reloadThemes={() => {}} />;
|
||||
}
|
||||
|
||||
it.each(["铺满窗口", "适宜阅读"])("choosing %s drops the width a hand dragged the reading column to", async (name) => {
|
||||
localStorage.setItem(FLOW_KEY, "900");
|
||||
render(panel(name === "铺满窗口" ? "standard" : "full"));
|
||||
await userEvent.click(await screen.findByRole("button", { name }));
|
||||
expect(localStorage.getItem(FLOW_KEY)).toBeNull();
|
||||
});
|
||||
@@ -0,0 +1,2 @@
|
||||
- 修复:拖动过正文栏之后,在设置里选「铺满窗口」或「适宜阅读」不再没有反应;选了预设就以预设为准,丢掉之前拖出来的宽度。关联 #14411。
|
||||
- Fixed: choosing the full-width or reading preset in Settings did nothing once the column had been dragged; a preset now wins and drops the width you dragged. Refs #14411.
|
||||
Reference in new issue
Block a user