Skip to content

Commit 774d5ff

Browse files
authored
Merge pull request #67 from aakhter/feat/tab-badges
feat: improve active tab visibility and add Alt+N number badges
2 parents 98ceb5d + 829c797 commit 774d5ff

2 files changed

Lines changed: 50 additions & 12 deletions

File tree

src/web/public/app.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1759,6 +1759,17 @@ class CodemanApp {
17591759
else if (wantIdle && !hasIdle) { tab.classList.add('tab-alert-idle'); tab.classList.remove('tab-alert-action'); }
17601760
else if (!alertType && (hasAction || hasIdle)) { tab.classList.remove('tab-alert-action', 'tab-alert-idle'); }
17611761

1762+
// Inject tab-number badge if missing (added after initial render)
1763+
if (!tab.querySelector('.tab-number')) {
1764+
const idx = this.sessionOrder.indexOf(id);
1765+
if (idx >= 0 && idx < 9) {
1766+
const numSpan = document.createElement('span');
1767+
numSpan.className = 'tab-number';
1768+
numSpan.textContent = String(idx + 1);
1769+
tab.insertBefore(numSpan, tab.firstChild);
1770+
}
1771+
}
1772+
17621773
// Update status indicator
17631774
const statusEl = tab.querySelector('.tab-status');
17641775
if (statusEl && !statusEl.classList.contains(status)) {
@@ -1851,6 +1862,7 @@ class CodemanApp {
18511862
// Reorder to put active tab first
18521863
tabOrder = [this.activeSessionId, ...this.sessionOrder.filter(id => id !== this.activeSessionId)];
18531864
}
1865+
let _tabIdx = 0;
18541866
for (const id of tabOrder) {
18551867
const session = this.sessions.get(id);
18561868
if (!session) continue; // Skip if session was removed
@@ -1877,6 +1889,7 @@ class CodemanApp {
18771889

18781890
const endedAttr = session._ended ? ' data-ended="1"' : '';
18791891
parts.push(`<div class="session-tab ${isActive ? 'active' : ''}${alertClass}" data-id="${id}" data-color="${color}"${endedAttr} onclick="app.selectSession('${escapeHtml(id)}')" oncontextmenu="event.preventDefault(); app.startInlineRename('${escapeHtml(id)}')" tabindex="0" role="tab" aria-selected="${isActive ? 'true' : 'false'}" aria-label="${escapeHtml(name)} session" ${session.workingDir ? `title="${escapeHtml(session.workingDir)}"` : ''}>
1892+
${_tabIdx < 9 ? '<span class="tab-number">' + (_tabIdx + 1) + '</span>' : ''}
18801893
<span class="tab-status ${status}" aria-hidden="true"></span>
18811894
<span class="tab-info">
18821895
<span class="tab-name-row">
@@ -1890,6 +1903,7 @@ class CodemanApp {
18901903
<span class="tab-gear" onclick="event.stopPropagation(); app.openSessionOptions('${escapeHtml(id)}')" title="Session options" aria-label="Session options" tabindex="0">&#x2699;</span>
18911904
<span class="tab-close" onclick="event.stopPropagation(); app.requestCloseSession('${escapeHtml(id)}')" title="Close session" aria-label="Close session" tabindex="0">&times;</span>
18921905
</div>`);
1906+
_tabIdx++;
18931907
}
18941908

18951909
container.innerHTML = parts.join('');

src/web/public/styles.css

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -258,15 +258,16 @@ body {
258258
}
259259

260260
.session-tab.active {
261-
background: rgba(255, 255, 255, 0.04);
262-
border-color: var(--glass-border);
263-
color: var(--text);
264-
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04);
261+
background: rgba(34, 197, 94, 0.15) !important;
262+
border: 2px solid #00FF66 !important;
263+
color: #fff !important;
264+
box-shadow: none !important;
265+
outline: none !important;
265266
}
266267

267268
/* Tab switch feedback: bright green glow on the newly-active tab */
268269
.session-tab.tab-glow {
269-
animation: tab-glow 0.35s ease-out forwards;
270+
animation: tab-glow 0.35s ease-out;
270271
}
271272

272273
@keyframes tab-glow {
@@ -304,13 +305,36 @@ body {
304305
.session-tab[data-color="pink"] { border-left: 3px solid var(--session-pink); }
305306

306307
/* Active tabs with color get subtle background tint */
307-
.session-tab.active[data-color="red"] { background: rgba(239, 68, 68, 0.1); }
308-
.session-tab.active[data-color="orange"] { background: rgba(249, 115, 22, 0.1); }
309-
.session-tab.active[data-color="yellow"] { background: rgba(234, 179, 8, 0.1); }
310-
.session-tab.active[data-color="green"] { background: rgba(34, 197, 94, 0.1); }
311-
.session-tab.active[data-color="blue"] { background: rgba(59, 130, 246, 0.1); }
312-
.session-tab.active[data-color="purple"] { background: rgba(168, 85, 247, 0.1); }
313-
.session-tab.active[data-color="pink"] { background: rgba(236, 72, 153, 0.1); }
308+
.session-tab.active[data-color="red"] { background: rgba(239, 68, 68, 0.15); border-color: rgba(239, 68, 68, 0.5); box-shadow: 0 0 10px rgba(239, 68, 68, 0.3); }
309+
.session-tab.active[data-color="orange"] { background: rgba(249, 115, 22, 0.15); border-color: rgba(249, 115, 22, 0.5); box-shadow: 0 0 10px rgba(249, 115, 22, 0.3); }
310+
.session-tab.active[data-color="yellow"] { background: rgba(234, 179, 8, 0.15); border-color: rgba(234, 179, 8, 0.5); box-shadow: 0 0 10px rgba(234, 179, 8, 0.3); }
311+
.session-tab.active[data-color="green"] { background: rgba(34, 197, 94, 0.15); border-color: rgba(34, 197, 94, 0.5); box-shadow: 0 0 10px rgba(34, 197, 94, 0.3); }
312+
.session-tab.active[data-color="blue"] { background: rgba(59, 130, 246, 0.15); border-color: rgba(59, 130, 246, 0.5); box-shadow: 0 0 10px rgba(59, 130, 246, 0.3); }
313+
.session-tab.active[data-color="purple"] { background: rgba(168, 85, 247, 0.15); border-color: rgba(168, 85, 247, 0.5); box-shadow: 0 0 10px rgba(168, 85, 247, 0.3); }
314+
.session-tab.active[data-color="pink"] { background: rgba(236, 72, 153, 0.15); border-color: rgba(236, 72, 153, 0.5); box-shadow: 0 0 10px rgba(236, 72, 153, 0.3); }
315+
316+
/* Tab number indicator (Alt+N shortcut hint) */
317+
.session-tab .tab-number {
318+
display: inline-flex;
319+
align-items: center;
320+
justify-content: center;
321+
width: 16px;
322+
height: 16px;
323+
border-radius: 3px;
324+
background: rgba(255, 255, 255, 0.15);
325+
border: 1px solid rgba(255, 255, 255, 0.35);
326+
color: rgba(255, 255, 255, 0.75);
327+
font-size: 0.6rem;
328+
font-weight: 700;
329+
flex-shrink: 0;
330+
font-family: monospace;
331+
}
332+
333+
.session-tab.active .tab-number {
334+
background: rgba(0, 255, 102, 0.2) !important;
335+
border-color: rgba(0, 255, 102, 0.5) !important;
336+
color: #00FF66 !important;
337+
}
314338

315339
.session-tab .tab-info {
316340
display: flex;

0 commit comments

Comments
 (0)