Mark the session on screen as Current in the session lists

- The conversation page tells the rail and the sessions modal which
  session it shows (announceShownSession, useShownSession); they reload,
  so a session reopened by ?session_id= shows at once.
- Only that session is Current and greyed out (the active one without
  ?session_id=); the active row then leads back to it.
- The rail lists the session on screen even when it's older than its
  latest sessions.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
2026-10-26 05:56:13 +01:00
co-authored by Claude Opus 5.5
parent cc109bc361
commit 657a76d868
10 changed files with 153 additions and 31 deletions
+21 -10
View File
@@ -12,31 +12,42 @@ type Props = {
loading?: boolean;
disabled?: boolean;
onOpen: () => void;
/**
* The session the page shows (`?session_id=`, else the active one):
* marked Current and greyed out.
*/
current: boolean;
};
/**
* One session in the sessions modal: its title, the summary or last
* message, how long and how recent. The active one says so; any other
* reopens on click.
* message, how long and how recent. The one on screen is
* Current (greyed out); any other opens on click (reopening a closed one,
* going back to the active one).
*/
export default function BotSessionRow({ session, loading, disabled, onOpen }: Props) {
const active = session.status == "active";
export default function BotSessionRow({ session, loading, disabled, onOpen, current }: Props) {
const preview = session.summary || session.last_message_text || "";
const at = session.last_activity_at || session.created_at;
return (
<Button
title={active ? "This is the current session" : `Reopen "${session.title || "Untitled"}"`}
title={
current
? "This is the session on screen"
: session.status == "active"
? "Go back to the active session"
: `Reopen "${session.title || "Untitled"}"`
}
type="button"
variant="ghost"
color="text"
loading={loading}
disabled={active || disabled}
disabled={current || disabled}
onClick={onOpen}
buttonContentProps={{ className: "w-full min-w-0 flex-nowrap" }}
className={twMerge(
"w-full justify-start! items-start! gap-0! px-3! py-2.5! rounded-default text-left text-ink dark:text-ink hover:bg-ink/5 hover:dark:bg-ink/5 focus-visible:ring-2 focus-visible:ring-ink",
active && "bg-sunken hover:bg-sunken hover:dark:bg-sunken opacity-100!",
current && "bg-sunken hover:bg-sunken hover:dark:bg-sunken opacity-100!",
)}
>
<Stack className="w-full min-w-0 gap-0.5! items-stretch">
@@ -44,16 +55,16 @@ export default function BotSessionRow({ session, loading, disabled, onOpen }: Pr
<Span
className={twMerge(
"grow min-w-0 truncate text-sm font-bold leading-5",
active ? "text-ink-secondary" : "text-ink",
current ? "text-ink-secondary" : "text-ink",
)}
>
{session.title || "Untitled session"}
</Span>
{session.unread && !active ? (
{session.unread && !current ? (
<Span className="shrink-0 text-[11px] font-bold leading-4 text-ink">New</Span>
) : null}
<Span className="shrink-0 text-[11px] leading-4 text-ink-secondary">
{active ? "Current" : at ? relativeTime({ at: Number(at) }) : ""}
{current ? "Current" : at ? relativeTime({ at: Number(at) }) : ""}
</Span>
</Row>
<Span className="w-full truncate text-xs leading-4 text-ink-secondary">