This commit is contained in:
Rhys Sullivan 2025-12-23 15:42:30 +08:00 committed by GitHub
commit cd68d7f046
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 40 additions and 2 deletions

View file

@ -182,6 +182,15 @@ function App() {
console.log(JSON.stringify(route.data))
})
// Track current session for unread indicator
createEffect(() => {
if (route.data.type === "session") {
sync.session.setCurrentSession(route.data.sessionID)
} else {
sync.session.setCurrentSession(undefined)
}
})
// Update terminal window title based on current route and session
createEffect(() => {
if (!terminalTitleEnabled() || Flag.OPENCODE_DISABLE_TERMINAL_TITLE) return

View file

@ -39,13 +39,19 @@ export function DialogSessionList() {
const isDeleting = toDelete() === x.id
const status = sync.data.session_status?.[x.id]
const isWorking = status?.type === "busy"
const isUnread = sync.data.session_unread[x.id]
const gutter = isWorking ? (
<spinner frames={spinnerFrames} interval={80} color={theme.primary} />
) : isUnread ? (
<text fg={theme.primary}></text>
) : undefined
return {
title: isDeleting ? `Press ${deleteKeybind} again to confirm` : x.title,
bg: isDeleting ? theme.error : undefined,
value: x.id,
category,
footer: Locale.time(x.time.updated),
gutter: isWorking ? <spinner frames={spinnerFrames} interval={80} color={theme.primary} /> : undefined,
gutter,
}
})
.slice(0, 150)

View file

@ -46,6 +46,9 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({
session_status: {
[sessionID: string]: SessionStatus
}
session_unread: {
[sessionID: string]: boolean
}
session_diff: {
[sessionID: string]: Snapshot.FileDiff[]
}
@ -81,6 +84,7 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({
provider_default: {},
session: [],
session_status: {},
session_unread: {},
session_diff: {},
todo: {},
message: {},
@ -93,6 +97,7 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({
})
const sdk = useSDK()
let currentSessionID: string | undefined = undefined
sdk.event.listen((e) => {
const event = e.details
@ -168,7 +173,13 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({
}
case "session.status": {
setStore("session_status", event.properties.sessionID, event.properties.status)
const prev = store.session_status[event.properties.sessionID]
const next = event.properties.status
// Track if session transitioned from busy to idle while user is not viewing it
if (prev?.type === "busy" && next.type === "idle" && currentSessionID !== event.properties.sessionID) {
setStore("session_unread", event.properties.sessionID, true)
}
setStore("session_status", event.properties.sessionID, next)
break
}
@ -341,6 +352,18 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({
if (last.role === "user") return "working"
return last.time.completed ? "idle" : "working"
},
setCurrentSession(sessionID: string | undefined) {
currentSessionID = sessionID
if (sessionID) {
setStore("session_unread", sessionID, false)
}
},
getCurrentSession() {
return currentSessionID
},
markRead(sessionID: string) {
setStore("session_unread", sessionID, false)
},
async sync(sessionID: string) {
if (fullSyncedSessions.has(sessionID)) return
const [session, messages, todo, diff] = await Promise.all([