fix: space after pane status icons, prevent repeated idle notification sounds
- Add space between status icon and project name in pane list for readability - Add notifiedIdle set to checkTransitions to prevent re-triggering sound after busySessions fluctuations during the same idle period Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -753,9 +753,9 @@ export class DirectGridRenderer {
|
|||||||
|
|
||||||
// Status icon: ● green=running, ◉ yellow=idle, ○ dim=unknown
|
// Status icon: ● green=running, ◉ yellow=idle, ○ dim=unknown
|
||||||
let statusIcon: string
|
let statusIcon: string
|
||||||
if (pane.status === "busy") statusIcon = `${hexFg("#9ece6a")}●${RESET}`
|
if (pane.status === "busy") statusIcon = `${hexFg("#9ece6a")}● ${RESET}`
|
||||||
else if (pane.status === "idle") statusIcon = `${hexFg("#e0af68")}◉${RESET}`
|
else if (pane.status === "idle") statusIcon = `${hexFg("#e0af68")}◉ ${RESET}`
|
||||||
else statusIcon = `${DIM}○${RESET}`
|
else statusIcon = `${DIM}○ ${RESET}`
|
||||||
|
|
||||||
const startCol = col
|
const startCol = col
|
||||||
if (isFocused) {
|
if (isFocused) {
|
||||||
@@ -763,7 +763,7 @@ export class DirectGridRenderer {
|
|||||||
} else {
|
} else {
|
||||||
out += `${statusIcon}${DIM}${short}${RESET}`
|
out += `${statusIcon}${DIM}${short}${RESET}`
|
||||||
}
|
}
|
||||||
col += 1 + short.length // icon + name
|
col += 2 + short.length // icon + space + name
|
||||||
this.paneListHitRegions.push({ tabId: tab.id, paneIndex: pi, startCol, endCol: col - 1 })
|
this.paneListHitRegions.push({ tabId: tab.id, paneIndex: pi, startCol, endCol: col - 1 })
|
||||||
|
|
||||||
if (pi < tabPanes.length - 1) {
|
if (pi < tabPanes.length - 1) {
|
||||||
|
|||||||
@@ -314,6 +314,7 @@ export function updateProjectSessions(projects: Project[], sessions: Map<string,
|
|||||||
|
|
||||||
const IDLE_SOUND_DELAY_MS = 10_000
|
const IDLE_SOUND_DELAY_MS = 10_000
|
||||||
const pendingIdle = new Map<string, number>() // path → timestamp when first went idle
|
const pendingIdle = new Map<string, number>() // path → timestamp when first went idle
|
||||||
|
const notifiedIdle = new Set<string>() // paths already notified — prevents re-trigger
|
||||||
|
|
||||||
export function checkTransitions(
|
export function checkTransitions(
|
||||||
projects: Project[],
|
projects: Project[],
|
||||||
@@ -325,20 +326,26 @@ export function checkTransitions(
|
|||||||
const prev = prevBusy.get(project.path) || 0
|
const prev = prevBusy.get(project.path) || 0
|
||||||
const isIdle = project.busySessions === 0 && project.activeSessions > 0
|
const isIdle = project.busySessions === 0 && project.activeSessions > 0
|
||||||
|
|
||||||
if (prev > 0 && isIdle && !pendingIdle.has(project.path)) {
|
if (!isIdle) {
|
||||||
|
// Not idle — clear notification state so next idle transition can fire
|
||||||
|
notifiedIdle.delete(project.path)
|
||||||
|
pendingIdle.delete(project.path)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Already notified for this idle period — skip
|
||||||
|
if (notifiedIdle.has(project.path)) continue
|
||||||
|
|
||||||
|
if (prev > 0 && !pendingIdle.has(project.path)) {
|
||||||
// Just transitioned busy→idle — start the delay timer
|
// Just transitioned busy→idle — start the delay timer
|
||||||
pendingIdle.set(project.path, now)
|
pendingIdle.set(project.path, now)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pendingIdle.has(project.path)) {
|
if (pendingIdle.has(project.path) && now - pendingIdle.get(project.path)! >= IDLE_SOUND_DELAY_MS) {
|
||||||
if (!isIdle) {
|
// Confirmed idle for 10+ seconds — notify once
|
||||||
// Went busy again — false alarm, cancel
|
transitioned.push(project.name)
|
||||||
pendingIdle.delete(project.path)
|
pendingIdle.delete(project.path)
|
||||||
} else if (now - pendingIdle.get(project.path)! >= IDLE_SOUND_DELAY_MS) {
|
notifiedIdle.add(project.path)
|
||||||
// Confirmed idle for 10+ seconds
|
|
||||||
transitioned.push(project.name)
|
|
||||||
pendingIdle.delete(project.path)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return transitioned
|
return transitioned
|
||||||
|
|||||||
@@ -96,9 +96,9 @@ export function updatePaneList() {
|
|||||||
const isFocused = app.directGrid!.activeTabId === tab.id && app.directGrid!.focusIndex === pi
|
const isFocused = app.directGrid!.activeTabId === tab.id && app.directGrid!.focusIndex === pi
|
||||||
|
|
||||||
// Status icon: ● green=running, ◉ yellow=idle, ○ dim=unknown
|
// Status icon: ● green=running, ◉ yellow=idle, ○ dim=unknown
|
||||||
const statusIcon = pane.status === "busy" ? green("●")
|
const statusIcon = pane.status === "busy" ? green("● ")
|
||||||
: pane.status === "idle" ? yellow("◉")
|
: pane.status === "idle" ? yellow("◉ ")
|
||||||
: dim("○")
|
: dim("○ ")
|
||||||
|
|
||||||
if (!first) parts.push(dim(" · "))
|
if (!first) parts.push(dim(" · "))
|
||||||
parts.push(statusIcon)
|
parts.push(statusIcon)
|
||||||
|
|||||||
Reference in New Issue
Block a user