Ryker_Feng 98b8e4657e
feat(chats): add archive and restore (#5236)
* feat(chats): add archive and restore

* test(chats): observe archive search requests in pagination e2e

* docs(gateway): move thread lifecycle details out of inherited guidance

* docs(chats): add concise archive and restore RFC

* docs(chats): move archive RFC discussion to issue 5237
2026-09-06 22:30:26 +08:00

62 lines
1.4 KiB
TypeScript

import type { BaseStream } from "@langchain/langgraph-sdk";
import { useEffect } from "react";
import { useI18n } from "@/core/i18n/hooks";
import type { AgentThreadState } from "@/core/threads";
import { cn } from "@/lib/utils";
import { useThreadChat } from "./chats";
import { FlipDisplay } from "./flip-display";
export type ThreadTitleProps = {
className?: string;
threadId: string;
thread: BaseStream<AgentThreadState>;
canonicalTitle?: string;
};
export function ThreadTitle({
className,
threadId,
thread,
canonicalTitle,
}: ThreadTitleProps) {
const { t } = useI18n();
const { isNewThread } = useThreadChat();
const title = canonicalTitle?.length ? canonicalTitle : thread.values?.title;
useEffect(() => {
let _title = t.pages.untitled;
if (title) {
_title = title;
} else if (isNewThread) {
_title = t.pages.newChat;
}
if (thread.isThreadLoading) {
document.title = `Loading... - ${t.pages.appName}`;
} else {
document.title = `${_title} - ${t.pages.appName}`;
}
}, [
isNewThread,
t.pages.newChat,
t.pages.untitled,
t.pages.appName,
thread.isThreadLoading,
title,
]);
if (!title) {
return null;
}
return (
<FlipDisplay
uniqueKey={threadId}
className={cn("min-w-0 [&>div]:truncate", className)}
>
{title}
</FlipDisplay>
);
}