unread indicator
This commit is contained in:
parent
d01e715e68
commit
230814bee4
45
renderer.ts
45
renderer.ts
|
|
@ -27,6 +27,7 @@ interface Session {
|
||||||
config: SessionConfig;
|
config: SessionConfig;
|
||||||
worktreePath: string;
|
worktreePath: string;
|
||||||
hasActivePty: boolean;
|
hasActivePty: boolean;
|
||||||
|
hasUnreadActivity: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface McpServer {
|
interface McpServer {
|
||||||
|
|
@ -73,6 +74,15 @@ function createTerminalUI(sessionId: string) {
|
||||||
ipcRenderer.send("session-input", sessionId, data);
|
ipcRenderer.send("session-input", sessionId, data);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Listen for bell character to mark unread activity
|
||||||
|
term.onBell(() => {
|
||||||
|
console.log(`Bell received for session ${sessionId}, activeSessionId: ${activeSessionId}`);
|
||||||
|
if (activeSessionId !== sessionId) {
|
||||||
|
console.log(`Marking session ${sessionId} as unread`);
|
||||||
|
markSessionAsUnread(sessionId);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Handle resize
|
// Handle resize
|
||||||
const resizeHandler = () => {
|
const resizeHandler = () => {
|
||||||
if (activeSessionId === sessionId) {
|
if (activeSessionId === sessionId) {
|
||||||
|
|
@ -95,6 +105,7 @@ function addSession(persistedSession: PersistedSession, hasActivePty: boolean) {
|
||||||
config: persistedSession.config,
|
config: persistedSession.config,
|
||||||
worktreePath: persistedSession.worktreePath,
|
worktreePath: persistedSession.worktreePath,
|
||||||
hasActivePty,
|
hasActivePty,
|
||||||
|
hasUnreadActivity: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
sessions.set(persistedSession.id, session);
|
sessions.set(persistedSession.id, session);
|
||||||
|
|
@ -299,6 +310,32 @@ function addTab(sessionId: string, name: string) {
|
||||||
tabsContainer.appendChild(tab);
|
tabsContainer.appendChild(tab);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function markSessionAsUnread(sessionId: string) {
|
||||||
|
const session = sessions.get(sessionId);
|
||||||
|
if (!session) return;
|
||||||
|
|
||||||
|
session.hasUnreadActivity = true;
|
||||||
|
|
||||||
|
// Add unread indicator to tab
|
||||||
|
const tab = document.getElementById(`tab-${sessionId}`);
|
||||||
|
if (tab && !tab.classList.contains("unread")) {
|
||||||
|
tab.classList.add("unread");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearUnreadStatus(sessionId: string) {
|
||||||
|
const session = sessions.get(sessionId);
|
||||||
|
if (!session) return;
|
||||||
|
|
||||||
|
session.hasUnreadActivity = false;
|
||||||
|
|
||||||
|
// Remove unread indicator from tab
|
||||||
|
const tab = document.getElementById(`tab-${sessionId}`);
|
||||||
|
if (tab) {
|
||||||
|
tab.classList.remove("unread");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function switchToSession(sessionId: string) {
|
function switchToSession(sessionId: string) {
|
||||||
// Hide all sessions
|
// Hide all sessions
|
||||||
sessions.forEach((session, id) => {
|
sessions.forEach((session, id) => {
|
||||||
|
|
@ -317,6 +354,9 @@ function switchToSession(sessionId: string) {
|
||||||
document.getElementById(`sidebar-${sessionId}`)?.classList.add("active");
|
document.getElementById(`sidebar-${sessionId}`)?.classList.add("active");
|
||||||
activeSessionId = sessionId;
|
activeSessionId = sessionId;
|
||||||
|
|
||||||
|
// Clear unread status when switching to this session
|
||||||
|
clearUnreadStatus(sessionId);
|
||||||
|
|
||||||
// Focus and resize
|
// Focus and resize
|
||||||
session.terminal.focus();
|
session.terminal.focus();
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
|
@ -407,6 +447,11 @@ ipcRenderer.on("session-output", (_event, sessionId: string, data: string) => {
|
||||||
const session = sessions.get(sessionId);
|
const session = sessions.get(sessionId);
|
||||||
if (session && session.terminal) {
|
if (session && session.terminal) {
|
||||||
session.terminal.write(data);
|
session.terminal.write(data);
|
||||||
|
|
||||||
|
// Mark as unread if this is not the active session and there's output
|
||||||
|
if (activeSessionId !== sessionId && session.hasActivePty) {
|
||||||
|
markSessionAsUnread(sessionId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
11
styles.css
11
styles.css
|
|
@ -105,6 +105,17 @@
|
||||||
@apply bg-gray-800 border-b-2 border-blue-500;
|
@apply bg-gray-800 border-b-2 border-blue-500;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tab.unread .tab-name::after {
|
||||||
|
content: '';
|
||||||
|
display: inline-block;
|
||||||
|
width: 6px;
|
||||||
|
height: 6px;
|
||||||
|
background-color: #3b82f6;
|
||||||
|
border-radius: 50%;
|
||||||
|
margin-left: 6px;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
.tab-name {
|
.tab-name {
|
||||||
@apply text-sm text-gray-300;
|
@apply text-sm text-gray-300;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue