Skip to content

Commit 97366d2

Browse files
committed
refactor(desktop): retire obsolete Astryx workarounds
Astryx now owns the resize-handle hit area and ChatLayout flex contract that Maka still overrode. Remove those stale compatibility rules, delete the compositor-sensitive E2E that duplicated vendor behavior, and retain only the product-owned sidebar geometry check.\n\nGenerated-by: OpenAI Codex
1 parent b1ec289 commit 97366d2

6 files changed

Lines changed: 7 additions & 150 deletions

File tree

apps/desktop/e2e/sidebar-geometry.spec.ts

Lines changed: 6 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -18,47 +18,20 @@
1818
*/
1919

2020
/*
21-
* Locks the two invariants of the Astryx sidenav column that live only in
22-
* hand-tuned CSS and were, before this file, verified by nothing (#3834):
23-
*
24-
* 1. Geometry — `.maka-sidenav-motion { height: 100% }` (shell-layout.css).
25-
* Without a definite height the wrapper grows to its unclipped content and
26-
* the footer leaves the window. `sidenav footer stays inside the window`
27-
* is the lock shell-layout.css's comment already names by this path.
28-
*
29-
* 2. The resize handle — the two workaround rules that keep it grabbable:
30-
* `top: var(--h-titlebar)` (shell-layout.css) and `transform: none
31-
* !important` (sidebar.css, the Astryx hitAreaOffsetX fix). A regression
32-
* in either leaves a column that looks right and simply cannot be dragged.
33-
* `resize handle drag ...` grabs the handle at its vertical centre — the
34-
* exact point the bug left ungrabbable — and asserts the width changes.
35-
*
36-
* Both run on `projectSidebarWindow`: the only fixture that boots the shell
37-
* expanded (so the handle is mounted) with a populated, overflowing list (60
38-
* sessions, so the footer has content to be pushed past). It opens with the
39-
* search modal over an inert shell, so dismiss it first — the same first step
40-
* sidebar-project-row.spec.ts takes.
21+
* Locks `.maka-sidenav-motion { height: 100% }` in shell-layout.css. Without a
22+
* definite height, the sidenav grows to its unclipped content and pushes the
23+
* footer below the window. `projectSidebarWindow` supplies the overflowing
24+
* session list needed to expose that regression.
4125
*/
4226

4327
import { expect, test } from './fixtures';
44-
import {
45-
SESSION_LIST_EXPANDED_MAX_WIDTH,
46-
SESSION_LIST_EXPANDED_MIN_WIDTH,
47-
} from '../src/renderer/features/session-navigation/testing';
48-
import type { Locator, Page } from '@playwright/test';
28+
import type { Page } from '@playwright/test';
4929

50-
async function revealPopulatedSidebar(page: Page): Promise<Locator> {
30+
async function revealPopulatedSidebar(page: Page): Promise<void> {
5131
await page.keyboard.press('Escape');
5232
await expect(page.locator('[data-maka-contract="search-modal"]')).not.toBeVisible();
5333
const sidebar = page.getByRole('navigation', { name: '任务列表' });
5434
await expect(sidebar).toBeVisible();
55-
return sidebar;
56-
}
57-
58-
async function wrapperWidth(wrapper: Locator): Promise<number> {
59-
const box = await wrapper.boundingBox();
60-
if (!box) throw new Error('sidenav wrapper (.maka-sidenav-motion) has no visible bounds');
61-
return box.width;
6235
}
6336

6437
test('sidenav footer stays inside the window under an overflowing list', async ({
@@ -98,67 +71,3 @@ test('sidenav footer stays inside the window under an overflowing list', async (
9871
expect(wrapperBox!.y + wrapperBox!.height).toBeLessThanOrEqual(innerHeight + 1);
9972
expect(footerBox!.y + footerBox!.height).toBeLessThanOrEqual(innerHeight + 1);
10073
});
101-
102-
test('resize handle drag from its vertical centre changes the column width', async ({
103-
projectSidebarWindow: page,
104-
}) => {
105-
await revealPopulatedSidebar(page);
106-
107-
const handle = page.getByTestId('astryx-sidenav-resize-handle');
108-
await expect(handle).toBeVisible();
109-
const wrapper = page.locator('.maka-sidenav-motion');
110-
111-
const initialWidth = await wrapperWidth(wrapper);
112-
expect(initialWidth).toBeGreaterThanOrEqual(SESSION_LIST_EXPANDED_MIN_WIDTH);
113-
expect(initialWidth).toBeLessThanOrEqual(SESSION_LIST_EXPANDED_MAX_WIDTH);
114-
115-
// Grab the vertical centre. The Astryx hitAreaOffsetX bug leaves only the top
116-
// half grabbable, so the centre no-ops unless sidebar.css's `transform: none
117-
// !important` is applied — this point is the regression probe for that rule.
118-
// Let locator actionability resolve the handle's live centre before reading
119-
// its endpoint; replaying a box captured before that wait can miss a moving
120-
// 16px handle under load.
121-
await handle.hover();
122-
const handleBox = await handle.boundingBox();
123-
if (!handleBox) throw new Error('resize handle has no visible bounds');
124-
const grabX = handleBox.x + handleBox.width / 2;
125-
const grabY = handleBox.y + handleBox.height / 2;
126-
127-
await page.mouse.down();
128-
129-
// Astryx flags the separator while a drag is in flight; shell-layout.css keys
130-
// its transition-suppression (`:has([data-resizing])`) on it, so the width
131-
// tracks the pointer live rather than easing behind it. Check the second the
132-
// pointer goes down, so a missed grab fails directly instead of timing out on
133-
// an unrelated width assertion.
134-
await expect(handle).toHaveAttribute('data-resizing', /.*/);
135-
await page.mouse.move(grabX + 80, grabY, { steps: 20 });
136-
await expect.poll(() => wrapperWidth(wrapper)).toBeGreaterThan(initialWidth + 40);
137-
await page.mouse.up();
138-
await expect(handle).not.toHaveAttribute('data-resizing', /.*/);
139-
140-
const widenedWidth = await wrapperWidth(wrapper);
141-
expect(widenedWidth).toBeGreaterThan(initialWidth + 40);
142-
expect(widenedWidth).toBeLessThanOrEqual(SESSION_LIST_EXPANDED_MAX_WIDTH + 1);
143-
144-
// Drag the other way to prove the handle also narrows the column, grabbing
145-
// the centre again at the handle's new right-edge position.
146-
await handle.hover();
147-
const widenedHandleBox = await handle.boundingBox();
148-
if (!widenedHandleBox) throw new Error('resize handle lost its bounds after widening');
149-
const shrinkX = widenedHandleBox.x + widenedHandleBox.width / 2;
150-
const shrinkY = widenedHandleBox.y + widenedHandleBox.height / 2;
151-
152-
await page.mouse.down();
153-
await expect(handle).toHaveAttribute('data-resizing', /.*/);
154-
// Undo the 80px widening. Keeping the reverse drag symmetric means every
155-
// width accepted by the precondition stays above the collapsible region.
156-
await page.mouse.move(shrinkX - 80, shrinkY, { steps: 20 });
157-
await expect.poll(() => wrapperWidth(wrapper)).toBeLessThan(widenedWidth - 40);
158-
await page.mouse.up();
159-
await expect(handle).not.toHaveAttribute('data-resizing', /.*/);
160-
161-
const narrowedWidth = await wrapperWidth(wrapper);
162-
expect(narrowedWidth).toBeLessThan(widenedWidth - 40);
163-
expect(narrowedWidth).toBeGreaterThanOrEqual(SESSION_LIST_EXPANDED_MIN_WIDTH);
164-
});

apps/desktop/src/renderer/features/session-navigation/testing.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,6 @@ export {
5151
} from './model/session-selection.js';
5252
export {
5353
readSessionListViewMode,
54-
SESSION_LIST_EXPANDED_MAX_WIDTH,
55-
SESSION_LIST_EXPANDED_MIN_WIDTH,
5654
writeSessionListViewMode,
5755
} from './model/session-list-layout.js';
5856
export { createSessionRailLayoutStore } from './model/session-rail-layout-store.js';

apps/desktop/src/renderer/styles/chat-header.css

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -201,21 +201,6 @@
201201
overscroll-behavior: contain;
202202
}
203203

204-
/*
205-
* Compatibility with Astryx #2573 until its fixed ChatLayout ships in a
206-
* stable package. Published 0.2.0 gives the message area min-height: 100%,
207-
* then adds the in-flow dock below it, creating a dock-height phantom range.
208-
* These are the upstream flex contracts and can be removed on that upgrade.
209-
*/
210-
.maka-chat-layout > :first-child {
211-
min-height: 0;
212-
flex: 1 0 auto;
213-
}
214-
215-
.maka-chat-layout > :last-child {
216-
flex-shrink: 0;
217-
}
218-
219204
.maka-chat-shell {
220205
position: relative;
221206
min-height: 0;

apps/desktop/src/renderer/styles/module-pages/module-shell.css

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -65,18 +65,6 @@
6565
background: var(--muted);
6666
}
6767

68-
/* The ResizeHandle's wider hit area is absolutely positioned with a vendor
69-
bug: it gets the pill's translateY(-50%) centering without the pill's
70-
top:50%, so the full-height strip lands shifted half its height upward —
71-
over the page header, where it swallows the toolbar's clicks (技能 / MCP
72-
with the inspector open; 定时任务 has the same latent strip). Drop the
73-
stray translate. The !important is load-bearing: the vendor injects the
74-
transform unlayered with :not(#\#) escalation, which beats any layered
75-
product rule. */
76-
.maka-module-page .astryx-resize-handle > :not(.astryx-resize-handle-pill) {
77-
transform: none !important;
78-
}
79-
8068
/* The page's one control bar: module switch on the left, this page's view +
8169
filters on the right. It is the last row of the Layout header.
8270

apps/desktop/src/renderer/styles/shell-layout.css

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -79,11 +79,7 @@
7979
Keyed on the sidenav handle's own testid, not on the class: every Astryx
8080
ResizeHandle carries that class, and a page's own inspector handle is a
8181
`position: relative` flex item, so the same `top` shoved its divider 36px
82-
down the page — it started below the header's rule instead of meeting it.
83-
84-
e2e/sidebar-geometry.spec.ts drags this handle from its vertical centre and
85-
asserts the column width changes, so this rule and sidebar.css's grab-zone
86-
fix both fail loudly if the handle stops being grabbable. */
82+
down the page — it started below the header's rule instead of meeting it. */
8783
.maka-shell-astryx [data-testid="astryx-sidenav-resize-handle"] {
8884
top: var(--h-titlebar);
8985
}

apps/desktop/src/renderer/styles/sidebar.css

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -25,25 +25,6 @@
2525
height: 100%;
2626
}
2727

28-
/*
29-
* Astryx 0.2.0 ResizeHandle: when pillPlacement is not "center", hitAreaOffsetX
30-
* applies translateY(-50%) without a matching top: 50%. The grab zone then only
31-
* covers the top half of the handle, so a pointer drag at the vertical center
32-
* (where the pill sits) hits the handle root — which has no pointerdown — and
33-
* no-ops. SideNav uses pillPlacement="end" (sub-pixel X bias) and mounts the
34-
* handle as a sibling of <nav.maka-session-panel>, not a descendant — target the
35-
* handle test id. Remove once Astryx fixes hitAreaOffsetX.
36-
*
37-
* e2e/sidebar-geometry.spec.ts drags the handle from its vertical centre — the
38-
* half this fix restores — and asserts the column resizes, so removing this
39-
* before Astryx is fixed fails loudly instead of silently killing the grab.
40-
*/
41-
[data-testid="astryx-sidenav-resize-handle"] > div:not(.astryx-resize-handle-pill) {
42-
/* !important: Astryx StyleX injects the bad transform unlayered, which
43-
otherwise beats every rule in @layer maka.legacy. */
44-
transform: none !important;
45-
}
46-
4728
.maka-session-list {
4829
min-width: 0;
4930
max-width: 100%;

0 commit comments

Comments
 (0)