Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ba74d3515b |
@@ -47,6 +47,7 @@ Web client (`--preview` and friends in `web/src/styles.css`):
|
|||||||
| The canvas | A `preview` chip, top right, and a dashed inset ring. |
|
| The canvas | A `preview` chip, top right, and a dashed inset ring. |
|
||||||
| A throwaway tab | Dashed border, italic label. |
|
| A throwaway tab | Dashed border, italic label. |
|
||||||
| The sidebar row being previewed | Filled with the preview hue, over whatever open state the row already had — but the row of the session already showing in the pane keeps its accent fill, since previewing it changes nothing on screen. |
|
| The sidebar row being previewed | Filled with the preview hue, over whatever open state the row already had — but the row of the session already showing in the pane keeps its accent fill, since previewing it changes nothing on screen. |
|
||||||
|
| The sidebar row of the session the operator picked | Keeps its accent fill for the whole preview. A preview never moves the accent; only opening another session does. |
|
||||||
| A hovered sidebar row, and the keyboard cursor on a session | A lighter wash of the same hue, because both are what previews a row. |
|
| A hovered sidebar row, and the keyboard cursor on a session | A lighter wash of the same hue, because both are what previews a row. |
|
||||||
|
|
||||||
Rows say it with fill, not with an edge — see the tier ladder in
|
Rows say it with fill, not with an edge — see the tier ladder in
|
||||||
|
|||||||
+17
-3
@@ -215,6 +215,20 @@ export function createMultiView(opts: MultiViewOptions): MultiView {
|
|||||||
return fl?.sessionId ?? null;
|
return fl?.sessionId ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** The session the operator actually picked — what `focusedLeafSession()`
|
||||||
|
* would return with the preview undone. A preview moves the active tab and
|
||||||
|
* its focus, but it is a view: the accent stays on the row the operator
|
||||||
|
* chose until they choose another (docs/PREVIEW.md). */
|
||||||
|
function realFocusedSession(): string | null {
|
||||||
|
const p = preview;
|
||||||
|
if (!p) return focusedLeafSession();
|
||||||
|
const tab = layout.tabs.find((t) => t.id === p.prevActiveTabId) ?? activeTab(layout);
|
||||||
|
const leafId =
|
||||||
|
p.prevFocus && p.prevFocus.tabId === tab.id ? p.prevFocus.leafId : tab.focusedLeafId;
|
||||||
|
const fl = leafId ? findLeaf(tab.root, leafId) : null;
|
||||||
|
return fl?.sessionId ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
/** Update focus styling + pool focus + sidebar highlights without rebuilding
|
/** Update focus styling + pool focus + sidebar highlights without rebuilding
|
||||||
* the DOM (cheap path for click-to-focus). */
|
* the DOM (cheap path for click-to-focus). */
|
||||||
function syncFocus(): void {
|
function syncFocus(): void {
|
||||||
@@ -233,7 +247,7 @@ export function createMultiView(opts: MultiViewOptions): MultiView {
|
|||||||
if (!preview) pool.setFocus(focusedLeafSession());
|
if (!preview) pool.setFocus(focusedLeafSession());
|
||||||
sidebar.setHighlights({
|
sidebar.setHighlights({
|
||||||
open: realOpenSessions(),
|
open: realOpenSessions(),
|
||||||
focused: focusedLeafSession(),
|
focused: realFocusedSession(),
|
||||||
});
|
});
|
||||||
// The row the preview came from wears the same colour, so the sidebar and
|
// The row the preview came from wears the same colour, so the sidebar and
|
||||||
// the pane read as one thing rather than two unrelated highlights.
|
// the pane read as one thing rather than two unrelated highlights.
|
||||||
@@ -608,7 +622,7 @@ export function createMultiView(opts: MultiViewOptions): MultiView {
|
|||||||
{ focus: !preview && !quietRender },
|
{ focus: !preview && !quietRender },
|
||||||
);
|
);
|
||||||
if (!preview) pool.setFocus(focused.sessionId ?? null);
|
if (!preview) pool.setFocus(focused.sessionId ?? null);
|
||||||
sidebar.setHighlights({ open: realOpenSessions(), focused: focused.sessionId ?? null });
|
sidebar.setHighlights({ open: realOpenSessions(), focused: realFocusedSession() });
|
||||||
sidebar.setPreview(preview?.sessionId ?? null);
|
sidebar.setPreview(preview?.sessionId ?? null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -817,7 +831,7 @@ export function createMultiView(opts: MultiViewOptions): MultiView {
|
|||||||
openSessions: realOpenSessions,
|
openSessions: realOpenSessions,
|
||||||
beginSessionDrag,
|
beginSessionDrag,
|
||||||
render,
|
render,
|
||||||
focusedSessionId: focusedLeafSession,
|
focusedSessionId: realFocusedSession,
|
||||||
previewSession,
|
previewSession,
|
||||||
previewedSessionId: () => preview?.sessionId ?? null,
|
previewedSessionId: () => preview?.sessionId ?? null,
|
||||||
};
|
};
|
||||||
|
|||||||
+33
-1
@@ -47,12 +47,20 @@ function fakePool(): Spy {
|
|||||||
|
|
||||||
/** Last value the controller pushed to `SidebarHandle.setPreview`. */
|
/** Last value the controller pushed to `SidebarHandle.setPreview`. */
|
||||||
const previewRow: { id: string | null } = { id: null };
|
const previewRow: { id: string | null } = { id: null };
|
||||||
|
/** Last highlights the controller pushed to `SidebarHandle.setHighlights`. */
|
||||||
|
const rowHighlights: { open: Set<string>; focused: string | null } = {
|
||||||
|
open: new Set(),
|
||||||
|
focused: null,
|
||||||
|
};
|
||||||
|
|
||||||
function fakeSidebar(): SidebarHandle {
|
function fakeSidebar(): SidebarHandle {
|
||||||
return {
|
return {
|
||||||
el: document.createElement("aside"),
|
el: document.createElement("aside"),
|
||||||
setActive() {},
|
setActive() {},
|
||||||
setHighlights() {},
|
setHighlights(h) {
|
||||||
|
rowHighlights.open = h.open;
|
||||||
|
rowHighlights.focused = h.focused;
|
||||||
|
},
|
||||||
setPreview(id: string | null) {
|
setPreview(id: string | null) {
|
||||||
previewRow.id = id;
|
previewRow.id = id;
|
||||||
},
|
},
|
||||||
@@ -95,6 +103,8 @@ describe("sidebar preview", () => {
|
|||||||
stubFetch();
|
stubFetch();
|
||||||
document.body.replaceChildren();
|
document.body.replaceChildren();
|
||||||
previewRow.id = null;
|
previewRow.id = null;
|
||||||
|
rowHighlights.open = new Set();
|
||||||
|
rowHighlights.focused = null;
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
@@ -134,6 +144,28 @@ describe("sidebar preview", () => {
|
|||||||
expect(mv.el.querySelectorAll(".mv-pane.is-preview")).toHaveLength(0);
|
expect(mv.el.querySelectorAll(".mv-pane.is-preview")).toHaveLength(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("leaves the accent on the session the pane actually holds", () => {
|
||||||
|
const layout = twoTabs();
|
||||||
|
const spy = fakePool();
|
||||||
|
const mv = makeMv(layout, spy.pool);
|
||||||
|
expect(rowHighlights.focused).toBe("s2");
|
||||||
|
|
||||||
|
// Walking past other rows never moves the accent off what the operator
|
||||||
|
// picked: only a real open does (docs/PREVIEW.md).
|
||||||
|
mv.previewSession("s1");
|
||||||
|
expect(rowHighlights.focused).toBe("s2");
|
||||||
|
expect(mv.focusedSessionId()).toBe("s2");
|
||||||
|
|
||||||
|
mv.previewSession("s9");
|
||||||
|
expect(rowHighlights.focused).toBe("s2");
|
||||||
|
|
||||||
|
mv.previewSession(null);
|
||||||
|
expect(rowHighlights.focused).toBe("s2");
|
||||||
|
|
||||||
|
mv.openSession("s1");
|
||||||
|
expect(rowHighlights.focused).toBe("s1");
|
||||||
|
});
|
||||||
|
|
||||||
it("shows a session no pane holds in a throwaway tab that leaves no trace", () => {
|
it("shows a session no pane holds in a throwaway tab that leaves no trace", () => {
|
||||||
const layout = twoTabs();
|
const layout = twoTabs();
|
||||||
const before = serializeLayout(layout);
|
const before = serializeLayout(layout);
|
||||||
|
|||||||
Reference in New Issue
Block a user