mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-25 14:28:51 +08:00
feat(core): restore pinned chat for independent chat (#13154)
<!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Improved chat session management by automatically restoring a pinned chat session when opening the workspace chat. * **Enhancements** * Added support for cancelling certain requests, improving responsiveness and user experience. * **Style** * Updated the label "AFFiNE Intelligence" to "Intelligence" in relevant UI components for a more concise display. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
@@ -82,6 +82,10 @@ export type RequestOptions<Q extends GraphQLQuery> = QueryVariablesOption<Q> & {
|
|||||||
* @default 15000
|
* @default 15000
|
||||||
*/
|
*/
|
||||||
timeout?: number;
|
timeout?: number;
|
||||||
|
/**
|
||||||
|
* Abort signal
|
||||||
|
*/
|
||||||
|
signal?: AbortSignal;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type QueryOptions<Q extends GraphQLQuery> = RequestOptions<Q> & {
|
export type QueryOptions<Q extends GraphQLQuery> = RequestOptions<Q> & {
|
||||||
@@ -207,6 +211,7 @@ export const gqlFetcherFactory = (
|
|||||||
headers,
|
headers,
|
||||||
body: isFormData ? body : JSON.stringify(body),
|
body: isFormData ? body : JSON.stringify(body),
|
||||||
timeout: options.timeout,
|
timeout: options.timeout,
|
||||||
|
signal: options.signal,
|
||||||
})
|
})
|
||||||
).then(async res => {
|
).then(async res => {
|
||||||
if (res.headers.get('content-type')?.startsWith('application/json')) {
|
if (res.headers.get('content-type')?.startsWith('application/json')) {
|
||||||
|
|||||||
@@ -165,7 +165,8 @@ export class CopilotClient {
|
|||||||
docId?: string,
|
docId?: string,
|
||||||
options?: RequestOptions<
|
options?: RequestOptions<
|
||||||
typeof getCopilotSessionsQuery
|
typeof getCopilotSessionsQuery
|
||||||
>['variables']['options']
|
>['variables']['options'],
|
||||||
|
signal?: AbortSignal
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
const res = await this.gql({
|
const res = await this.gql({
|
||||||
@@ -176,6 +177,7 @@ export class CopilotClient {
|
|||||||
docId,
|
docId,
|
||||||
options,
|
options,
|
||||||
},
|
},
|
||||||
|
signal,
|
||||||
});
|
});
|
||||||
return res.currentUser?.copilot?.chats.edges.map(e => e.node);
|
return res.currentUser?.copilot?.chats.edges.map(e => e.node);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ const AIChatButton = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<MenuLinkItem icon={<AiOutlineIcon />} active={aiChatActive} to={'/chat'}>
|
<MenuLinkItem icon={<AiOutlineIcon />} active={aiChatActive} to={'/chat'}>
|
||||||
<span data-testid="ai-chat">AFFiNE Intelligence</span>
|
<span data-testid="ai-chat">Intelligence</span>
|
||||||
</MenuLinkItem>
|
</MenuLinkItem>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -260,6 +260,38 @@ export const Component = () => {
|
|||||||
status,
|
status,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
// restore pinned session
|
||||||
|
useEffect(() => {
|
||||||
|
if (!chatContent) return;
|
||||||
|
|
||||||
|
const controller = new AbortController();
|
||||||
|
const signal = controller.signal;
|
||||||
|
client
|
||||||
|
.getSessions(
|
||||||
|
workspaceId,
|
||||||
|
{},
|
||||||
|
undefined,
|
||||||
|
{ pinned: true, limit: 1 },
|
||||||
|
signal
|
||||||
|
)
|
||||||
|
.then(sessions => {
|
||||||
|
if (!Array.isArray(sessions)) return;
|
||||||
|
const session = sessions[0];
|
||||||
|
if (!session) return;
|
||||||
|
setCurrentSession(session);
|
||||||
|
if (chatContent) {
|
||||||
|
chatContent.session = session;
|
||||||
|
chatContent.reloadSession();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(console.error);
|
||||||
|
|
||||||
|
// abort the request
|
||||||
|
return () => {
|
||||||
|
controller.abort();
|
||||||
|
};
|
||||||
|
}, [chatContent, client, workspaceId]);
|
||||||
|
|
||||||
const onChatContainerRef = useCallback((node: HTMLDivElement) => {
|
const onChatContainerRef = useCallback((node: HTMLDivElement) => {
|
||||||
if (node) {
|
if (node) {
|
||||||
setIsBodyProvided(true);
|
setIsBodyProvided(true);
|
||||||
@@ -285,7 +317,7 @@ export const Component = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<ViewTitle title="AFFiNE Intelligence" />
|
<ViewTitle title="Intelligence" />
|
||||||
<ViewIcon icon="ai" />
|
<ViewIcon icon="ai" />
|
||||||
<ViewHeader>
|
<ViewHeader>
|
||||||
<div className={styles.chatHeader}>
|
<div className={styles.chatHeader}>
|
||||||
|
|||||||
Reference in New Issue
Block a user