mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-08 08:29:42 +02:00
Merge pull request #67 from aakhter/feat/tab-badges
feat: improve active tab visibility and add Alt+N number badges
This commit is contained in:
@@ -1759,6 +1759,17 @@ class CodemanApp {
|
|||||||
else if (wantIdle && !hasIdle) { tab.classList.add('tab-alert-idle'); tab.classList.remove('tab-alert-action'); }
|
else if (wantIdle && !hasIdle) { tab.classList.add('tab-alert-idle'); tab.classList.remove('tab-alert-action'); }
|
||||||
else if (!alertType && (hasAction || hasIdle)) { tab.classList.remove('tab-alert-action', 'tab-alert-idle'); }
|
else if (!alertType && (hasAction || hasIdle)) { tab.classList.remove('tab-alert-action', 'tab-alert-idle'); }
|
||||||
|
|
||||||
|
// Inject tab-number badge if missing (added after initial render)
|
||||||
|
if (!tab.querySelector('.tab-number')) {
|
||||||
|
const idx = this.sessionOrder.indexOf(id);
|
||||||
|
if (idx >= 0 && idx < 9) {
|
||||||
|
const numSpan = document.createElement('span');
|
||||||
|
numSpan.className = 'tab-number';
|
||||||
|
numSpan.textContent = String(idx + 1);
|
||||||
|
tab.insertBefore(numSpan, tab.firstChild);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Update status indicator
|
// Update status indicator
|
||||||
const statusEl = tab.querySelector('.tab-status');
|
const statusEl = tab.querySelector('.tab-status');
|
||||||
if (statusEl && !statusEl.classList.contains(status)) {
|
if (statusEl && !statusEl.classList.contains(status)) {
|
||||||
@@ -1851,6 +1862,7 @@ class CodemanApp {
|
|||||||
// Reorder to put active tab first
|
// Reorder to put active tab first
|
||||||
tabOrder = [this.activeSessionId, ...this.sessionOrder.filter(id => id !== this.activeSessionId)];
|
tabOrder = [this.activeSessionId, ...this.sessionOrder.filter(id => id !== this.activeSessionId)];
|
||||||
}
|
}
|
||||||
|
let _tabIdx = 0;
|
||||||
for (const id of tabOrder) {
|
for (const id of tabOrder) {
|
||||||
const session = this.sessions.get(id);
|
const session = this.sessions.get(id);
|
||||||
if (!session) continue; // Skip if session was removed
|
if (!session) continue; // Skip if session was removed
|
||||||
@@ -1877,6 +1889,7 @@ class CodemanApp {
|
|||||||
|
|
||||||
const endedAttr = session._ended ? ' data-ended="1"' : '';
|
const endedAttr = session._ended ? ' data-ended="1"' : '';
|
||||||
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)}"` : ''}>
|
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)}"` : ''}>
|
||||||
|
${_tabIdx < 9 ? '<span class="tab-number">' + (_tabIdx + 1) + '</span>' : ''}
|
||||||
<span class="tab-status ${status}" aria-hidden="true"></span>
|
<span class="tab-status ${status}" aria-hidden="true"></span>
|
||||||
<span class="tab-info">
|
<span class="tab-info">
|
||||||
<span class="tab-name-row">
|
<span class="tab-name-row">
|
||||||
@@ -1890,6 +1903,7 @@ class CodemanApp {
|
|||||||
<span class="tab-gear" onclick="event.stopPropagation(); app.openSessionOptions('${escapeHtml(id)}')" title="Session options" aria-label="Session options" tabindex="0">⚙</span>
|
<span class="tab-gear" onclick="event.stopPropagation(); app.openSessionOptions('${escapeHtml(id)}')" title="Session options" aria-label="Session options" tabindex="0">⚙</span>
|
||||||
<span class="tab-close" onclick="event.stopPropagation(); app.requestCloseSession('${escapeHtml(id)}')" title="Close session" aria-label="Close session" tabindex="0">×</span>
|
<span class="tab-close" onclick="event.stopPropagation(); app.requestCloseSession('${escapeHtml(id)}')" title="Close session" aria-label="Close session" tabindex="0">×</span>
|
||||||
</div>`);
|
</div>`);
|
||||||
|
_tabIdx++;
|
||||||
}
|
}
|
||||||
|
|
||||||
container.innerHTML = parts.join('');
|
container.innerHTML = parts.join('');
|
||||||
|
|||||||
+36
-12
@@ -258,15 +258,16 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.session-tab.active {
|
.session-tab.active {
|
||||||
background: rgba(255, 255, 255, 0.04);
|
background: rgba(34, 197, 94, 0.15) !important;
|
||||||
border-color: var(--glass-border);
|
border: 2px solid #00FF66 !important;
|
||||||
color: var(--text);
|
color: #fff !important;
|
||||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04);
|
box-shadow: none !important;
|
||||||
|
outline: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Tab switch feedback: bright green glow on the newly-active tab */
|
/* Tab switch feedback: bright green glow on the newly-active tab */
|
||||||
.session-tab.tab-glow {
|
.session-tab.tab-glow {
|
||||||
animation: tab-glow 0.35s ease-out forwards;
|
animation: tab-glow 0.35s ease-out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes tab-glow {
|
@keyframes tab-glow {
|
||||||
@@ -304,13 +305,36 @@ body {
|
|||||||
.session-tab[data-color="pink"] { border-left: 3px solid var(--session-pink); }
|
.session-tab[data-color="pink"] { border-left: 3px solid var(--session-pink); }
|
||||||
|
|
||||||
/* Active tabs with color get subtle background tint */
|
/* Active tabs with color get subtle background tint */
|
||||||
.session-tab.active[data-color="red"] { background: rgba(239, 68, 68, 0.1); }
|
.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); }
|
||||||
.session-tab.active[data-color="orange"] { background: rgba(249, 115, 22, 0.1); }
|
.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); }
|
||||||
.session-tab.active[data-color="yellow"] { background: rgba(234, 179, 8, 0.1); }
|
.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); }
|
||||||
.session-tab.active[data-color="green"] { background: rgba(34, 197, 94, 0.1); }
|
.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); }
|
||||||
.session-tab.active[data-color="blue"] { background: rgba(59, 130, 246, 0.1); }
|
.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); }
|
||||||
.session-tab.active[data-color="purple"] { background: rgba(168, 85, 247, 0.1); }
|
.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); }
|
||||||
.session-tab.active[data-color="pink"] { background: rgba(236, 72, 153, 0.1); }
|
.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); }
|
||||||
|
|
||||||
|
/* Tab number indicator (Alt+N shortcut hint) */
|
||||||
|
.session-tab .tab-number {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
border-radius: 3px;
|
||||||
|
background: rgba(255, 255, 255, 0.15);
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.35);
|
||||||
|
color: rgba(255, 255, 255, 0.75);
|
||||||
|
font-size: 0.6rem;
|
||||||
|
font-weight: 700;
|
||||||
|
flex-shrink: 0;
|
||||||
|
font-family: monospace;
|
||||||
|
}
|
||||||
|
|
||||||
|
.session-tab.active .tab-number {
|
||||||
|
background: rgba(0, 255, 102, 0.2) !important;
|
||||||
|
border-color: rgba(0, 255, 102, 0.5) !important;
|
||||||
|
color: #00FF66 !important;
|
||||||
|
}
|
||||||
|
|
||||||
.session-tab .tab-info {
|
.session-tab .tab-info {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
Reference in New Issue
Block a user