|
1079 | 1079 | .sesspanel .sessbar { display: flex; align-items: center; gap: 9px; padding: 12px 14px 10px; border-bottom: 1px solid var(--cc-line); } |
1080 | 1080 | .sesspanel .sesstitle { font-weight: 600; font-size: 14px; } |
1081 | 1081 | .sesspanel .sesslist { flex: 1 1 auto; overflow-y: auto; padding: 2px 12px 14px; } |
| 1082 | + /* Undo toast pinned at the panel foot after Done/Delete (an accidental click is recoverable). */ |
| 1083 | + .sesspanel .sessundo { flex: 0 0 auto; display: flex; align-items: center; justify-content: space-between; gap: 10px; margin: 0 12px 12px; padding: 8px 12px; background: var(--cc-surface); border: 1px solid var(--cc-line); border-radius: 8px; font-size: 12.5px; color: var(--cc-text2); } |
| 1084 | + .sesspanel .sessundo[hidden] { display: none; } |
| 1085 | + .sesspanel .sessundo .ut { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } |
| 1086 | + .sesspanel .sessundo .ub { flex: 0 0 auto; background: transparent; border: none; color: var(--cc-accent); font: inherit; font-size: 12.5px; font-weight: 600; cursor: pointer; padding: 2px 4px; border-radius: 4px; } |
| 1087 | + .sesspanel .sessundo .ub:hover { text-decoration: underline; } |
1082 | 1088 | .sesspanel .sessbucket { font-family: var(--vscode-editor-font-family, ui-monospace, monospace); font-size: 10px; letter-spacing: .1em; text-transform: uppercase; color: var(--cc-text3); margin: 12px 4px 7px; } |
1083 | 1089 | .sesspanel .sessempty { padding: 44px 18px; text-align: center; color: var(--cc-text3); font-size: 13px; line-height: 1.6; } |
1084 | 1090 | .sesscard { position: relative; background: var(--cc-bg); border: 1px solid var(--cc-line); border-radius: 7px; padding: 9px 11px; margin-bottom: 7px; cursor: pointer; transition: border-color .12s, transform .12s, box-shadow .12s; } |
|
1231 | 1237 | <button class="ovclose" id="sessClose" title="Close" aria-label="Close">✕</button> |
1232 | 1238 | <div class="sessbar"><span class="sesstitle">Sessions</span></div> |
1233 | 1239 | <div class="sesslist" id="sessList"></div> |
| 1240 | + <div class="sessundo" id="sessUndo" hidden></div> |
1234 | 1241 | </div> |
1235 | 1242 | </div> |
1236 | 1243 |
|
|
3372 | 3379 | renderSessions(); ov.style.display = 'flex'; |
3373 | 3380 | } |
3374 | 3381 | function closeSessions(){ const ov = document.getElementById('sessOverlay'); if (ov) { ov.style.display = 'none'; } } |
| 3382 | + // The Undo toast for Done/Delete — a quick, recoverable safety net. Auto-hides after a few seconds. |
| 3383 | + let sessUndoTimer = null; |
| 3384 | + function showUndo(m){ |
| 3385 | + const el = document.getElementById('sessUndo'); if (!el) { return; } |
| 3386 | + const verb = m.action === 'delete' ? 'Deleted' : 'Archived'; |
| 3387 | + el.innerHTML = '<span class="ut">' + verb + ' “' + esc(m.title || 'session') + '”</span><button class="ub" data-id="' + escAttr(m.id || '') + '">Undo</button>'; |
| 3388 | + el.hidden = false; |
| 3389 | + clearTimeout(sessUndoTimer); sessUndoTimer = setTimeout(function(){ el.hidden = true; }, 7000); |
| 3390 | + } |
3375 | 3391 | // Replay a resumed session into the chat: a compact "Resumed" banner (+ the honest summary note, if the |
3376 | 3392 | // transcript was too big to carry verbatim) followed by the readable conversation — user prompts and the |
3377 | 3393 | // assistant's prose, tool plumbing dropped. The host has already reset the log and restored the model's |
|
3402 | 3418 | vscode.postMessage({ type: 'sessionAction', action: action, id: id }); |
3403 | 3419 | if (action === 'resume') { closeSessions(); } |
3404 | 3420 | }); } |
| 3421 | + const undo = document.getElementById('sessUndo'); |
| 3422 | + if (undo) { undo.addEventListener('click', (e) => { |
| 3423 | + const b = e.target.closest && e.target.closest('.ub'); if (!b) { return; } |
| 3424 | + vscode.postMessage({ type: 'sessionAction', action: 'restore', id: b.getAttribute('data-id') }); |
| 3425 | + undo.hidden = true; clearTimeout(sessUndoTimer); |
| 3426 | + }); } |
3405 | 3427 | document.addEventListener('keydown', (e) => { const o = document.getElementById('sessOverlay'); if (e.key === 'Escape' && o && o.style.display !== 'none'){ e.preventDefault(); closeSessions(); } }); |
3406 | 3428 | })(); |
3407 | 3429 |
|
|
3460 | 3482 | else if (m.type === 'mcpList'){ renderMcpList(m.mcp || {}); } |
3461 | 3483 | else if (m.type === 'sessions'){ sessData = Array.isArray(m.entries) ? m.entries : []; if (m.open === false) { renderSessions(); } else { openSessions(); } } |
3462 | 3484 | else if (m.type === 'sessionResumed'){ resumeTranscript(m); } |
| 3485 | + else if (m.type === 'sessionUndo'){ showUndo(m); } |
3463 | 3486 | else if (m.type === 'verifyRun'){ addVerifyRun(m); } |
3464 | 3487 | else if (m.type === 'verifyOutput'){ verifyOutputAppend(m); } |
3465 | 3488 | else if (m.type === 'verifyDone'){ verifyDoneFinish(m); } |
|
0 commit comments