chore(desktop): dedupe session-color precedence, tighten tileStoredRow

- Extract resolveSessionColor(): the sessionColorFor fallback no longer
  re-implements the override -> project-color precedence that the
  $sessionColorById computed already owns.
- tileStoredRow: collapse the nested project-tree walk into a flatMap +
  find, matching the local style.
This commit is contained in:
Brooklyn Nicholson 2026-07-22 22:11:49 -05:00
parent 30f6fc81e2
commit f91d5b2d13
2 changed files with 23 additions and 34 deletions

View file

@ -286,31 +286,15 @@ export function SessionTilePane({ storedSessionId }: { storedSessionId: string }
* activity lands it there resolving through the tree keeps its tab titled
* and tinted instead of a grey "Session" placeholder. */
export function tileStoredRow(storedSessionId: string): SessionInfo | undefined {
const fromList = $sessions.get().find(s => sessionMatchesStoredId(s, storedSessionId))
const match = (s: SessionInfo) => sessionMatchesStoredId(s, storedSessionId)
if (fromList) {
return fromList
}
for (const project of $projectTree.get()) {
for (const repo of project.repos) {
for (const group of repo.groups) {
const row = group.sessions.find(s => sessionMatchesStoredId(s, storedSessionId))
if (row) {
return row
}
}
}
const preview = project.previewSessions?.find(s => sessionMatchesStoredId(s, storedSessionId))
if (preview) {
return preview
}
}
return undefined
return (
$sessions.get().find(match) ??
$projectTree
.get()
.flatMap(p => [...p.repos.flatMap(r => r.groups.flatMap(g => g.sessions)), ...(p.previewSessions ?? [])])
.find(match)
)
}
function tileTitle(storedSessionId: string): string {
@ -416,6 +400,8 @@ export function SessionTabMenu({
/** Layout-tree pane id — powers the Close-others/right/all verbs. */
tabPaneId: string
}) {
// Subscribe for reactivity; the row is read imperatively via tileStoredRow
// (which spans both sources), so the values themselves are unused here.
useStore($sessions)
useStore($projectTree)
const pinnedSessionIds = useStore($pinnedSessionIds)

View file

@ -4,7 +4,7 @@ import { sessionProjectColor } from '@/app/chat/sidebar/projects/workspace-group
import { Codecs, persistentAtom } from '@/lib/persisted'
import { $projects } from '@/store/projects'
import { $sessions, sessionPinId } from '@/store/session'
import type { SessionInfo } from '@/types/hermes'
import type { ProjectInfo, SessionInfo } from '@/types/hermes'
// Per-session color OVERRIDES — a user-picked color that wins over the inherited
// project color (#66565 layer 2). Desktop-local like pins, keyed by the DURABLE
@ -39,13 +39,21 @@ export function setSessionColorOverride(durableId: string, color: null | string)
//
// Precedence in one place: an explicit per-session override wins over the
// inherited project color. Agent-set color (#66565 layer 3) slots in here too.
function resolveSessionColor(
session: SessionInfo,
projects: ProjectInfo[],
overrides: Record<string, string>
): string | undefined {
return overrides[sessionPinId(session)] ?? sessionProjectColor(session, projects) ?? undefined
}
export const $sessionColorById = computed(
[$sessions, $projects, $sessionColorOverrides],
(sessions, projects, overrides) => {
const map: Record<string, string> = {}
for (const session of sessions) {
const color = overrides[sessionPinId(session)] ?? sessionProjectColor(session, projects)
const color = resolveSessionColor(session, projects, overrides)
if (color) {
map[session.id] = color
@ -59,17 +67,12 @@ export const $sessionColorById = computed(
// The color for a single session object (the tabs already hold the SessionInfo
// they render, so they resolve through the same map the sidebar reads). A row
// that isn't in `$sessions` — e.g. a project-tree session older than the
// paginated recents page, opened as a tab — misses the map, so fall back to
// resolving it directly through the same precedence the map uses.
// paginated recents page, opened as a tab — misses the map, so fall back to the
// same resolver the map is built from.
export function sessionColorFor(session: null | SessionInfo | undefined): string | undefined {
if (!session) {
return undefined
}
return (
$sessionColorById.get()[session.id] ??
$sessionColorOverrides.get()[sessionPinId(session)] ??
sessionProjectColor(session, $projects.get()) ??
undefined
)
return $sessionColorById.get()[session.id] ?? resolveSessionColor(session, $projects.get(), $sessionColorOverrides.get())
}