Fixes from live GUI testing: readability width counts the window's chat list (wraps to a grid instead of cramming), embedded conversation uses the stock row-flex wrapper so the composer stays at the bottom, composer status strips stay on one line

This commit is contained in:
Agent committed 2026-10-21 19:30:06 +00:00
1 parent f931abd470
commit 3445b2b972
2 files changed
+23 -9

No files matched your search

+11 -6
View File
@@ -113,8 +113,11 @@ window.__ModuleLoader__.load({
.dcs-dot{width:6px;height:6px;border-radius:50%;flex:none;background:transparent}
.dcs-dot.open{background:#3b82f6}
.dcs-dot.run{background:#22c55e}
.dcs-conv{flex:1;min-width:0;min-height:0;display:flex;flex-direction:column;position:relative;overflow:hidden}
.dcs-conv > *{flex:1;min-height:0}
.dcs-conv{flex:1;min-width:0;min-height:0;height:100%;display:flex;position:relative;overflow:hidden}
/* Composer status strips that wrap into one item per line in a narrow window keep to one scrollable line here. */
.dcs-win [data-omniroute-quotas]{flex-wrap:nowrap!important;justify-content:flex-start!important;overflow-x:auto;scrollbar-width:none;min-width:0}
.dcs-win [data-omniroute-quotas]::-webkit-scrollbar{display:none}
.dcs-win [data-omniroute-quotas] > *{flex:none!important}
.dcs-empty{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:10px;padding:24px;text-align:center;color:var(--dsw-alias-label-secondary)}
.dcs-chips{display:flex;flex-wrap:wrap;gap:6px;justify-content:center;max-width:640px}
.dcs-msg{padding:16px;color:var(--dsw-alias-label-tertiary)}
@@ -131,7 +134,7 @@ window.__ModuleLoader__.load({
.dcs-prev{border:1px dashed var(--dsw-alias-border-l1);border-radius:10px;overflow:hidden;background:var(--dsw-alias-bg-base)}
.dcs-prev-scale{transform-origin:0 0;pointer-events:none}
.dcs-mock{display:flex;flex-direction:column;min-width:0;min-height:0;border:1px solid var(--dsw-alias-border-l1);border-radius:10px;overflow:hidden;background:var(--dsw-alias-bg-base)}
.dcs-mline{height:10px;border-radius:5px;background:var(--dsw-alias-bg-l2);margin:8px 12px}
.dcs-mline{height:10px;border-radius:5px;background:var(--dsw-alias-border-l1,rgba(127,127,127,.3));margin:8px 12px}
.dcs-mline.me{margin-left:40%;background:rgba(59,130,246,.28)}
.dcs-minput{margin:auto 12px 12px;height:34px;border:1px solid var(--dsw-alias-border-l1);border-radius:10px}
`;
@@ -141,8 +144,10 @@ window.__ModuleLoader__.load({
return () => el.remove();
}
/** Columns that fit `width` while each keeps at least minWidth (never more than n). */
const columnsFor = (width, n, s) => Math.max(1, Math.min(n || 1, Math.floor((width + s.gap) / (s.minWidth + s.gap))));
/** Narrowest a window may get: the readable conversation width plus its chat list when that is open by default. */
const windowMinWidth = (s) => s.minWidth + (s.sidebarOpen ? s.sidebarWidth : 0);
/** Columns that fit `width` while every window keeps windowMinWidth (never more than n). */
const columnsFor = (width, n, s) => Math.max(1, Math.min(n || 1, Math.floor((width + s.gap) / (windowMinWidth(s) + s.gap))));
// ------------------------------------------------------------------ embedded conversation
function FixedChatView(props) { return h(React.Fragment, null, props.renderSlot('conversation.session', { view: 'chat' })); }
@@ -401,7 +406,7 @@ window.__ModuleLoader__.load({
h('p', null, 'Open several chats at once from "Split view" in the sidebar. Chats sit side by side while each keeps the readability width; otherwise they wrap into a grid.'),
h('div', { className: 'dcs-fields' },
h(Slider, { label: 'Minimum window height', value: s.minHeight, min: 240, max: 900, step: 4, hint: 'Default 396px. Rows never get shorter; the grid scrolls instead.', onChange: (v) => store.setSettings({ minHeight: v }) }),
h(Slider, { label: 'Readability width', value: s.minWidth, min: 300, max: 900, step: 10, hint: 'Narrowest a chat may get before windows wrap to the next row.', onChange: (v) => store.setSettings({ minWidth: v }) }),
h(Slider, { label: 'Readability width', value: s.minWidth, min: 300, max: 900, step: 10, hint: 'Narrowest the conversation itself may get (the window\'s chat list comes on top of it) before windows wrap to the next row.', onChange: (v) => store.setSettings({ minWidth: v }) }),
h(Slider, { label: 'Gap between windows', value: s.gap, min: 0, max: 24, onChange: (v) => store.setSettings({ gap: v }) }),
h(Slider, { label: 'Window chat-list width', value: s.sidebarWidth, min: 120, max: 320, step: 4, onChange: (v) => store.setSettings({ sidebarWidth: v }) }),
h('div', { className: 'dcs-f' },
+12 -3
View File
@@ -105,13 +105,22 @@ test('layout: side by side while each keeps the readability width, then wraps',
assert.match(html, /396px/)
assert.match(html, /Readability width/)
assert.match(html, /Preview/)
// window.innerWidth 1600 → preview width 1300; 3 chats at 420+8 → 3 columns side by side.
assert.match(html, /3 columns × 1 row/)
assert.match(html, /all chats side by side/)
// window.innerWidth 1600 → preview width 1300. A window needs 420 (conversation) + 180 (its
// chat list) = 600 px, so 3 chats do not fit side by side: 2 columns, wrapping to a 2nd row.
assert.match(html, /2 columns × 2 rows/)
assert.match(html, /too narrow for all chats side by side/)
// Real chat titles appear in the preview windows.
assert.match(html, /Alpha chat/)
})
test('layout: a wide screen keeps all chats in one row', { skip }, () => {
const { React, ReactDOMServer, regs } = load()
window.innerWidth = 2400 // preview 2100 px → 3 × 600 fits
const html = ReactDOMServer.renderToString(React.createElement(regs['settings.section'].Comp, { close() {} }))
assert.match(html, /3 columns × 1 row/)
assert.match(html, /all chats side by side/)
})
test('choosing an open chat in the main sidebar keeps split view and glows it', { skip }, async () => {
const { React, ReactDOMServer, regs, list, panel, layout } = load()
const h = React.createElement