mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-05-17 18:35:19 +02:00
Integrate ChatSessionStatus and blocking logic into Composer
This commit is contained in:
parent
b56c70c401
commit
22ead877fa
2 changed files with 28 additions and 6 deletions
|
|
@ -10,8 +10,8 @@ interface ChatSessionStatusProps {
|
||||||
currentUserId: string | null;
|
currentUserId: string | null;
|
||||||
members: Array<{
|
members: Array<{
|
||||||
user_id: string;
|
user_id: string;
|
||||||
user_display_name: string | null;
|
user_display_name?: string | null;
|
||||||
user_email: string;
|
user_email?: string | null;
|
||||||
}>;
|
}>;
|
||||||
className?: string;
|
className?: string;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ import {
|
||||||
mentionedDocumentIdsAtom,
|
mentionedDocumentIdsAtom,
|
||||||
mentionedDocumentsAtom,
|
mentionedDocumentsAtom,
|
||||||
} from "@/atoms/chat/mentioned-documents.atom";
|
} from "@/atoms/chat/mentioned-documents.atom";
|
||||||
|
import { membersAtom } from "@/atoms/members/members-query.atoms";
|
||||||
import {
|
import {
|
||||||
globalNewLLMConfigsAtom,
|
globalNewLLMConfigsAtom,
|
||||||
llmPreferencesAtom,
|
llmPreferencesAtom,
|
||||||
|
|
@ -39,6 +40,7 @@ import {
|
||||||
import { currentUserAtom } from "@/atoms/user/user-query.atoms";
|
import { currentUserAtom } from "@/atoms/user/user-query.atoms";
|
||||||
import { AssistantMessage } from "@/components/assistant-ui/assistant-message";
|
import { AssistantMessage } from "@/components/assistant-ui/assistant-message";
|
||||||
import { ComposerAddAttachment, ComposerAttachments } from "@/components/assistant-ui/attachment";
|
import { ComposerAddAttachment, ComposerAttachments } from "@/components/assistant-ui/attachment";
|
||||||
|
import { ChatSessionStatus } from "@/components/assistant-ui/chat-session-status";
|
||||||
import { ConnectorIndicator } from "@/components/assistant-ui/connector-popup";
|
import { ConnectorIndicator } from "@/components/assistant-ui/connector-popup";
|
||||||
import {
|
import {
|
||||||
InlineMentionEditor,
|
InlineMentionEditor,
|
||||||
|
|
@ -59,6 +61,7 @@ import {
|
||||||
import type { ThinkingStep } from "@/components/tool-ui/deepagent-thinking";
|
import type { ThinkingStep } from "@/components/tool-ui/deepagent-thinking";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import type { Document } from "@/contracts/types/document.types";
|
import type { Document } from "@/contracts/types/document.types";
|
||||||
|
import { useChatSessionState } from "@/hooks/use-chat-session-state";
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
|
|
||||||
interface ThreadProps {
|
interface ThreadProps {
|
||||||
|
|
@ -215,7 +218,7 @@ const Composer: FC = () => {
|
||||||
const editorRef = useRef<InlineMentionEditorRef>(null);
|
const editorRef = useRef<InlineMentionEditorRef>(null);
|
||||||
const editorContainerRef = useRef<HTMLDivElement>(null);
|
const editorContainerRef = useRef<HTMLDivElement>(null);
|
||||||
const documentPickerRef = useRef<DocumentMentionPickerRef>(null);
|
const documentPickerRef = useRef<DocumentMentionPickerRef>(null);
|
||||||
const { search_space_id } = useParams();
|
const { search_space_id, chat_id } = useParams();
|
||||||
const setMentionedDocumentIds = useSetAtom(mentionedDocumentIdsAtom);
|
const setMentionedDocumentIds = useSetAtom(mentionedDocumentIdsAtom);
|
||||||
const composerRuntime = useComposerRuntime();
|
const composerRuntime = useComposerRuntime();
|
||||||
const hasAutoFocusedRef = useRef(false);
|
const hasAutoFocusedRef = useRef(false);
|
||||||
|
|
@ -223,6 +226,18 @@ const Composer: FC = () => {
|
||||||
const isThreadEmpty = useAssistantState(({ thread }) => thread.isEmpty);
|
const isThreadEmpty = useAssistantState(({ thread }) => thread.isEmpty);
|
||||||
const isThreadRunning = useAssistantState(({ thread }) => thread.isRunning);
|
const isThreadRunning = useAssistantState(({ thread }) => thread.isRunning);
|
||||||
|
|
||||||
|
// Live collaboration: track AI responding state
|
||||||
|
const { data: currentUser } = useAtomValue(currentUserAtom);
|
||||||
|
const { data: members } = useAtomValue(membersAtom);
|
||||||
|
const threadId = useMemo(() => {
|
||||||
|
if (Array.isArray(chat_id) && chat_id.length > 0) {
|
||||||
|
return Number.parseInt(chat_id[0], 10) || null;
|
||||||
|
}
|
||||||
|
return typeof chat_id === "string" ? Number.parseInt(chat_id, 10) || null : null;
|
||||||
|
}, [chat_id]);
|
||||||
|
const { isAiResponding, respondingToUserId } = useChatSessionState(threadId);
|
||||||
|
const isBlockedByOtherUser = isAiResponding && respondingToUserId !== currentUser?.id;
|
||||||
|
|
||||||
// Auto-focus editor on new chat page after mount
|
// Auto-focus editor on new chat page after mount
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isThreadEmpty && !hasAutoFocusedRef.current && editorRef.current) {
|
if (isThreadEmpty && !hasAutoFocusedRef.current && editorRef.current) {
|
||||||
|
|
@ -298,9 +313,9 @@ const Composer: FC = () => {
|
||||||
[showDocumentPopover]
|
[showDocumentPopover]
|
||||||
);
|
);
|
||||||
|
|
||||||
// Submit message (blocked during streaming or when document picker is open)
|
// Submit message (blocked during streaming, document picker open, or AI responding to another user)
|
||||||
const handleSubmit = useCallback(() => {
|
const handleSubmit = useCallback(() => {
|
||||||
if (isThreadRunning) {
|
if (isThreadRunning || isBlockedByOtherUser) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!showDocumentPopover) {
|
if (!showDocumentPopover) {
|
||||||
|
|
@ -315,6 +330,7 @@ const Composer: FC = () => {
|
||||||
}, [
|
}, [
|
||||||
showDocumentPopover,
|
showDocumentPopover,
|
||||||
isThreadRunning,
|
isThreadRunning,
|
||||||
|
isBlockedByOtherUser,
|
||||||
composerRuntime,
|
composerRuntime,
|
||||||
setMentionedDocuments,
|
setMentionedDocuments,
|
||||||
setMentionedDocumentIds,
|
setMentionedDocumentIds,
|
||||||
|
|
@ -374,7 +390,13 @@ const Composer: FC = () => {
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ComposerPrimitive.Root className="aui-composer-root relative flex w-full flex-col">
|
<ComposerPrimitive.Root className="aui-composer-root relative flex w-full flex-col gap-2">
|
||||||
|
<ChatSessionStatus
|
||||||
|
isAiResponding={isAiResponding}
|
||||||
|
respondingToUserId={respondingToUserId}
|
||||||
|
currentUserId={currentUser?.id ?? null}
|
||||||
|
members={members ?? []}
|
||||||
|
/>
|
||||||
<ComposerPrimitive.AttachmentDropzone className="aui-composer-attachment-dropzone flex w-full flex-col rounded-2xl border-input bg-muted px-1 pt-2 outline-none transition-shadow data-[dragging=true]:border-ring data-[dragging=true]:border-dashed data-[dragging=true]:bg-accent/50">
|
<ComposerPrimitive.AttachmentDropzone className="aui-composer-attachment-dropzone flex w-full flex-col rounded-2xl border-input bg-muted px-1 pt-2 outline-none transition-shadow data-[dragging=true]:border-ring data-[dragging=true]:border-dashed data-[dragging=true]:bg-accent/50">
|
||||||
<ComposerAttachments />
|
<ComposerAttachments />
|
||||||
{/* Inline editor with @mention support */}
|
{/* Inline editor with @mention support */}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue