Skip to content

Commit 8098389

Browse files
ndemiancclaude
andcommitted
refine(levelcode): drop the Resume icon — 4 row actions, card-click resumes
Clicking the card body already resumes, so the Resume icon was redundant. The hover row now carries four icons — Rename · Archive · Delete · Pin — and the play glyph is removed. Fewer, calmer affordances; resume stays a single click on the row. - media/chat.html + media/sessionsView.html (shared block, byte-identical): drop sessActBtn('resume', …) and SESS_IC.play; note in the comment that the card body resumes. - test/sessionsUi.test.js: CARD (actions) now asserts the four icons, no data-act="resume", and the Rename a11y label. 30 files green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent be7b028 commit 8098389

3 files changed

Lines changed: 10 additions & 11 deletions

File tree

‎extensions/levelcode-ai/media/chat.html‎

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3307,7 +3307,6 @@
33073307
// Inline codicons (self-contained — the shared block can't reach the chat's codicon() helper). play is a
33083308
// plain triangle; edit/check/trash are the editor's own glyphs; star doubles as the pin toggle.
33093309
var SESS_IC = {
3310-
play: '<svg class="ci" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true"><path d="M5 3.3 L12.6 8 L5 12.7 Z"/></svg>',
33113310
edit: '<svg class="ci" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true"><path d="M14.236 1.76386C13.2123 0.740172 11.5525 0.740171 10.5289 1.76386L2.65722 9.63549C2.28304 10.0097 2.01623 10.4775 1.88467 10.99L1.01571 14.3755C0.971767 14.5467 1.02148 14.7284 1.14646 14.8534C1.27144 14.9783 1.45312 15.028 1.62432 14.9841L5.00978 14.1151C5.52234 13.9836 5.99015 13.7168 6.36433 13.3426L14.236 5.47097C15.2596 4.44728 15.2596 2.78755 14.236 1.76386ZM11.236 2.47097C11.8691 1.8378 12.8957 1.8378 13.5288 2.47097C14.162 3.10413 14.162 4.1307 13.5288 4.76386L12.75 5.54269L10.4571 3.24979L11.236 2.47097ZM9.75002 3.9569L12.0429 6.24979L5.65722 12.6355C5.40969 12.883 5.10023 13.0595 4.76117 13.1465L2.19447 13.8053L2.85327 11.2386C2.9403 10.8996 3.1168 10.5901 3.36433 10.3426L9.75002 3.9569Z"/></svg>',
33123311
check: '<svg class="ci" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true"><path d="M13.6572 3.13573C13.8583 2.9465 14.175 2.95614 14.3643 3.15722C14.5535 3.35831 14.5438 3.675 14.3428 3.86425L5.84277 11.8642C5.64597 12.0494 5.33756 12.0446 5.14648 11.8535L1.64648 8.35351C1.45121 8.15824 1.45121 7.84174 1.64648 7.64647C1.84174 7.45121 2.15825 7.45121 2.35351 7.64647L5.50976 10.8027L13.6572 3.13573Z"/></svg>',
33133312
trash: '<svg class="ci" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true"><path d="M10 3h3v1h-1v9l-1 1H4l-1-1V4H2V3h3V2a1 1 0 0 1 1-1h3a1 1 0 0 1 1 1v1zM9 2H6v1h3V2zM4 13h7V4H4v9zm2-8H5v7h1V5zm1 0h1v7H7V5zm2 0h1v7H9V5z"/></svg>',
@@ -3324,8 +3323,9 @@
33243323
}
33253324
// esc/escAttr are INJECTED so this whole block stays pure (unit-testable without the webview globals).
33263325
// The card is two fixed-height lines: title + (primary file · time). Actions are compact icon buttons on
3327-
// the RIGHT of the title row — hidden at rest, revealed on hover — so nothing reflows or floats. The pin
3328-
// stays visible at rest when pinned. Secondary detail (model · turns · files) rides the native tooltip.
3326+
// the RIGHT of the title row — hidden at rest, revealed on hover — so nothing reflows or floats. Clicking
3327+
// the card body resumes (so there is no Resume icon); the pin stays visible at rest when pinned. Secondary
3328+
// detail (model · turns · files) rides the native tooltip.
33293329
function sessCardHtml(e, nowMs, escFn, escAttrFn){
33303330
const st = e.state === 'interrupted' ? ' warn' : e.state === 'error' ? ' err' : e.state === 'resumed' ? ' res' : '';
33313331
const files = e.filesEdited || [];
@@ -3334,7 +3334,6 @@
33343334
const detail = (e.title || 'Untitled') + ' — ' + turns + ' turn' + (turns === 1 ? '' : 's')
33353335
+ (e.model ? ' · ' + sessModelShort(e.model) : '') + (files.length ? ' · ' + files.join(', ') : '');
33363336
const acts = '<span class="sessacts">'
3337-
+ sessActBtn('resume', 'Resume', SESS_IC.play)
33383337
+ sessActBtn('rename', 'Rename', SESS_IC.edit)
33393338
+ sessActBtn('done', 'Archive', SESS_IC.check)
33403339
+ sessActBtn('delete', 'Delete', SESS_IC.trash)

‎extensions/levelcode-ai/media/sessionsView.html‎

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,6 @@
8080
// Inline codicons (self-contained — the shared block can't reach the chat's codicon() helper). play is a
8181
// plain triangle; edit/check/trash are the editor's own glyphs; star doubles as the pin toggle.
8282
var SESS_IC = {
83-
play: '<svg class="ci" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true"><path d="M5 3.3 L12.6 8 L5 12.7 Z"/></svg>',
8483
edit: '<svg class="ci" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true"><path d="M14.236 1.76386C13.2123 0.740172 11.5525 0.740171 10.5289 1.76386L2.65722 9.63549C2.28304 10.0097 2.01623 10.4775 1.88467 10.99L1.01571 14.3755C0.971767 14.5467 1.02148 14.7284 1.14646 14.8534C1.27144 14.9783 1.45312 15.028 1.62432 14.9841L5.00978 14.1151C5.52234 13.9836 5.99015 13.7168 6.36433 13.3426L14.236 5.47097C15.2596 4.44728 15.2596 2.78755 14.236 1.76386ZM11.236 2.47097C11.8691 1.8378 12.8957 1.8378 13.5288 2.47097C14.162 3.10413 14.162 4.1307 13.5288 4.76386L12.75 5.54269L10.4571 3.24979L11.236 2.47097ZM9.75002 3.9569L12.0429 6.24979L5.65722 12.6355C5.40969 12.883 5.10023 13.0595 4.76117 13.1465L2.19447 13.8053L2.85327 11.2386C2.9403 10.8996 3.1168 10.5901 3.36433 10.3426L9.75002 3.9569Z"/></svg>',
8584
check: '<svg class="ci" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true"><path d="M13.6572 3.13573C13.8583 2.9465 14.175 2.95614 14.3643 3.15722C14.5535 3.35831 14.5438 3.675 14.3428 3.86425L5.84277 11.8642C5.64597 12.0494 5.33756 12.0446 5.14648 11.8535L1.64648 8.35351C1.45121 8.15824 1.45121 7.84174 1.64648 7.64647C1.84174 7.45121 2.15825 7.45121 2.35351 7.64647L5.50976 10.8027L13.6572 3.13573Z"/></svg>',
8685
trash: '<svg class="ci" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true"><path d="M10 3h3v1h-1v9l-1 1H4l-1-1V4H2V3h3V2a1 1 0 0 1 1-1h3a1 1 0 0 1 1 1v1zM9 2H6v1h3V2zM4 13h7V4H4v9zm2-8H5v7h1V5zm1 0h1v7H7V5zm2 0h1v7H9V5z"/></svg>',
@@ -97,8 +96,9 @@
9796
}
9897
// esc/escAttr are INJECTED so this whole block stays pure (unit-testable without the webview globals).
9998
// The card is two fixed-height lines: title + (primary file · time). Actions are compact icon buttons on
100-
// the RIGHT of the title row — hidden at rest, revealed on hover — so nothing reflows or floats. The pin
101-
// stays visible at rest when pinned. Secondary detail (model · turns · files) rides the native tooltip.
99+
// the RIGHT of the title row — hidden at rest, revealed on hover — so nothing reflows or floats. Clicking
100+
// the card body resumes (so there is no Resume icon); the pin stays visible at rest when pinned. Secondary
101+
// detail (model · turns · files) rides the native tooltip.
102102
function sessCardHtml(e, nowMs, escFn, escAttrFn){
103103
const st = e.state === 'interrupted' ? ' warn' : e.state === 'error' ? ' err' : e.state === 'resumed' ? ' res' : '';
104104
const files = e.filesEdited || [];
@@ -107,7 +107,6 @@
107107
const detail = (e.title || 'Untitled') + ' — ' + turns + ' turn' + (turns === 1 ? '' : 's')
108108
+ (e.model ? ' · ' + sessModelShort(e.model) : '') + (files.length ? ' · ' + files.join(', ') : '');
109109
const acts = '<span class="sessacts">'
110-
+ sessActBtn('resume', 'Resume', SESS_IC.play)
111110
+ sessActBtn('rename', 'Rename', SESS_IC.edit)
112111
+ sessActBtn('done', 'Archive', SESS_IC.check)
113112
+ sessActBtn('delete', 'Delete', SESS_IC.trash)

‎extensions/levelcode-ai/test/sessionsUi.test.js‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,15 +74,16 @@ test('CARD (state): interrupted gets the warn class; an unpinned card has no pin
7474
assert.match(h, /data-act="pin"[^>]*aria-label="Pin"/, 'and the toggle offers Pin');
7575
});
7676

77-
test('CARD (actions): resume/rename/done/delete/pin as icon buttons on the row — no drawer, no text labels', () => {
77+
test('CARD (actions): four row icon buttons (rename/done/delete/pin); clicking the card body resumes', () => {
7878
const e = { id: 's3', title: 't', updatedAt: msAgo(3600), turns: 41, model: 'anthropic/claude-opus-5',
7979
state: 'done', filesEdited: ['refund.rb', 'lock.rb'] };
8080
const h = P.sessCardHtml(e, NOW, esc, escAttr);
81-
for (const a of ['resume', 'rename', 'done', 'delete', 'pin']) { assert.match(h, new RegExp('data-act="' + a + '"'), a + ' action present'); }
81+
for (const a of ['rename', 'done', 'delete', 'pin']) { assert.match(h, new RegExp('data-act="' + a + '"'), a + ' action present'); }
82+
assert.ok(!/data-act="resume"/.test(h), 'no Resume icon — clicking the card body resumes (default action)');
8283
assert.match(h, /class="sessacts">/, 'actions live in the row…');
8384
assert.ok(!/sessrich|sessbtn|sesschip|sessmeta/.test(h), '…not the old drawer/chip/meta markup');
8485
assert.match(h, /<svg class="ci"/, 'actions are icon buttons');
85-
assert.match(h, /aria-label="Resume"/, 'labelled for a11y (icon-only)');
86+
assert.match(h, /aria-label="Rename"/, 'labelled for a11y (icon-only)');
8687
assert.match(h, /title="t — 41 turns · claude-opus-5 · refund\.rb, lock\.rb"/, 'model · turns · files fold into the tooltip');
8788
});
8889

0 commit comments

Comments
 (0)