@chat-lab/ui 0.1.0-beta.39 → 0.1.0-beta.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adk/components/Debug/Events/EventDetail.cjs +1 -4
- package/dist/adk/components/Debug/Events/EventDetail.cjs.map +1 -1
- package/dist/adk/components/Debug/Events/EventDetail.d.ts.map +1 -1
- package/dist/adk/components/Debug/Events/EventDetail.js +1 -4
- package/dist/adk/components/Debug/Events/EventDetail.js.map +1 -1
- package/dist/adk/components/Debug/Events/EventTab.d.ts.map +1 -1
- package/dist/adk/components/Debug/Events/index.cjs +3 -2
- package/dist/adk/components/Debug/Events/index.cjs.map +1 -1
- package/dist/adk/components/Debug/Events/index.d.ts.map +1 -1
- package/dist/adk/components/Debug/Events/index.js +3 -2
- package/dist/adk/components/Debug/Events/index.js.map +1 -1
- package/dist/adk/components/Debug/Trace/TraceDetail.cjs +6 -6
- package/dist/adk/components/Debug/Trace/TraceDetail.cjs.map +1 -1
- package/dist/adk/components/Debug/Trace/TraceDetail.d.ts.map +1 -1
- package/dist/adk/components/Debug/Trace/TraceDetail.js +6 -6
- package/dist/adk/components/Debug/Trace/TraceDetail.js.map +1 -1
- package/dist/adk/components/Debug/Trace/TraceMessageGroup.cjs +12 -5
- package/dist/adk/components/Debug/Trace/TraceMessageGroup.cjs.map +1 -1
- package/dist/adk/components/Debug/Trace/TraceMessageGroup.d.ts +1 -0
- package/dist/adk/components/Debug/Trace/TraceMessageGroup.d.ts.map +1 -1
- package/dist/adk/components/Debug/Trace/TraceMessageGroup.js +13 -6
- package/dist/adk/components/Debug/Trace/TraceMessageGroup.js.map +1 -1
- package/dist/adk/components/Debug/Trace/index.cjs +7 -3
- package/dist/adk/components/Debug/Trace/index.cjs.map +1 -1
- package/dist/adk/components/Debug/Trace/index.d.ts.map +1 -1
- package/dist/adk/components/Debug/Trace/index.js +7 -3
- package/dist/adk/components/Debug/Trace/index.js.map +1 -1
- package/dist/adk/components/Debug/Trace/utils.cjs +1 -0
- package/dist/adk/components/Debug/Trace/utils.cjs.map +1 -1
- package/dist/adk/components/Debug/Trace/utils.d.ts.map +1 -1
- package/dist/adk/components/Debug/Trace/utils.js +1 -0
- package/dist/adk/components/Debug/Trace/utils.js.map +1 -1
- package/dist/adk/components/Debug/index.cjs +1 -1
- package/dist/adk/components/Debug/index.cjs.map +1 -1
- package/dist/adk/components/Debug/index.js +1 -1
- package/dist/adk/components/Debug/index.js.map +1 -1
- package/dist/adk/hooks/useEvents.cjs +13 -5
- package/dist/adk/hooks/useEvents.cjs.map +1 -1
- package/dist/adk/hooks/useEvents.d.ts +10 -5
- package/dist/adk/hooks/useEvents.d.ts.map +1 -1
- package/dist/adk/hooks/useEvents.js +13 -5
- package/dist/adk/hooks/useEvents.js.map +1 -1
- package/dist/assets/Empty.cjs +8 -0
- package/dist/assets/Empty.cjs.map +1 -0
- package/dist/assets/Empty.d.ts +3 -0
- package/dist/assets/Empty.d.ts.map +1 -0
- package/dist/assets/Empty.js +6 -0
- package/dist/assets/Empty.js.map +1 -0
- package/dist/components/Chatkit/index.cjs +2 -2
- package/dist/components/Chatkit/index.cjs.map +1 -1
- package/dist/components/Chatkit/index.d.ts.map +1 -1
- package/dist/components/Chatkit/index.js +2 -2
- package/dist/components/Chatkit/index.js.map +1 -1
- package/dist/components/ThreadOptionsMenu.cjs +8 -1
- package/dist/components/ThreadOptionsMenu.cjs.map +1 -1
- package/dist/components/ThreadOptionsMenu.d.ts.map +1 -1
- package/dist/components/ThreadOptionsMenu.js +8 -1
- package/dist/components/ThreadOptionsMenu.js.map +1 -1
- package/dist/components/assistant-ui/WarningModal.cjs +13 -0
- package/dist/components/assistant-ui/WarningModal.cjs.map +1 -0
- package/dist/components/assistant-ui/WarningModal.d.ts +12 -0
- package/dist/components/assistant-ui/WarningModal.d.ts.map +1 -0
- package/dist/components/assistant-ui/WarningModal.js +11 -0
- package/dist/components/assistant-ui/WarningModal.js.map +1 -0
- package/dist/components/thread-list.cjs +1 -1
- package/dist/components/thread-list.cjs.map +1 -1
- package/dist/components/thread-list.js +1 -1
- package/dist/components/thread-list.js.map +1 -1
- package/dist/index.css +1 -1
- package/dist/node_modules/.pnpm/lucide-react@0.552.0_react@17.0.2/node_modules/lucide-react/dist/esm/icons/loader.cjs +29 -0
- package/dist/node_modules/.pnpm/lucide-react@0.552.0_react@17.0.2/node_modules/lucide-react/dist/esm/icons/loader.cjs.map +1 -0
- package/dist/node_modules/.pnpm/lucide-react@0.552.0_react@17.0.2/node_modules/lucide-react/dist/esm/icons/loader.js +24 -0
- package/dist/node_modules/.pnpm/lucide-react@0.552.0_react@17.0.2/node_modules/lucide-react/dist/esm/icons/loader.js.map +1 -0
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../src/components/Chatkit/index.tsx"],"sourcesContent":["import {\n ForwardedRef,\n forwardRef,\n MutableRefObject,\n Ref,\n useMemo,\n useRef,\n useEffect,\n useState,\n} from 'react';\nimport { v4 as uuid } from 'uuid';\nimport { ChatkitProps, ChatkitRef } from './types';\nimport { cloneDeep, compact, findLastIndex, isString, values } from 'lodash-es';\nimport { ChatkitProvider } from '@/contexts/ChatkitContext';\n\nimport { Thread } from '../assistant-ui/thread';\nimport {\n AssistantRuntimeProvider,\n useExternalStoreRuntime,\n} from '@assistant-ui/react';\nimport { ChatMessage, ChatController } from '@chat-lab/core';\nimport { Group, Panel } from 'react-resizable-panels';\nimport convertToAssistantMessage from '@/utils/convertToAssistantMessage';\nimport ThreadList from '../thread-list';\nimport { Thread as ThreadType, useSnapshot } from '@chat-lab/core';\nimport { Toaster } from '../ui/toaster';\nimport { toast } from '@/hooks/use-toast';\nimport ExecutionCard from '../assistant-ui-tools/execution-card';\nimport { convertToBase64 } from '@/utils/convertToBase64';\nimport checkMedia from '@/utils/checkMedia';\nimport { TextMessage } from '@chat-lab/core';\nimport './style.less';\nimport TraceDetail from '@/adk/components/Debug/Trace/TraceDetail';\nimport { useTraceStore } from '@/adk/components/Debug/Trace/store';\nimport Debug from '@/adk/components/Debug';\nconst ChatkitImpl = forwardRef(\n (\n props: {\n initialConfig: ChatkitProps['initialConfig'];\n welcome?: React.ReactNode;\n recommends?: string[];\n plugins?: React.ReactNode[];\n tools?: React.ReactNode[];\n placeholder?: string;\n threadList?:\n | React.ReactNode\n | boolean\n | ((props: { threadList: Readonly<ThreadType>[] }) => React.ReactNode);\n showHeader?: boolean;\n expandToolGroup?: boolean;\n expandToolDetail?: boolean;\n toolDisplay?: 'group' | 'none' | 'step';\n expandReasoning?: boolean;\n controller: ChatController;\n region?: string;\n },\n ref: ForwardedRef<ChatkitRef>,\n ) => {\n const {\n initialConfig,\n tools,\n toolDisplay = 'group',\n welcome,\n recommends,\n plugins,\n threadList,\n showHeader = true,\n placeholder,\n expandToolGroup = false,\n expandReasoning = false,\n expandToolDetail = false,\n region,\n } = props;\n const controller = props.controller;\n const { threadMap, currentThreadId } = useSnapshot(controller.store.state);\n // useImperativeHandleChatkitRef(ref, controller, onError);\n\n const currentThread = currentThreadId ? threadMap[currentThreadId] : null;\n const messages = useMemo(\n () => cloneDeep(threadMap[currentThread?.id || '']?.messages || []) || [],\n [currentThread?.id, threadMap],\n );\n\n const uiMessages = useMemo(\n () =>\n convertToAssistantMessage(messages as Readonly<ChatMessage>[], {\n toolDisplay: toolDisplay || 'group',\n }),\n [messages],\n );\n\n const runtime = useExternalStoreRuntime({\n messages: uiMessages,\n isLoading: currentThread?.sending,\n isDisabled: !!currentThread?.metadata['isInitingSession'],\n convertMessage: message => message,\n onNew: async message => {\n const attachments = await Promise.all(\n message.attachments?.map(async item => {\n return {\n ...item,\n base64: await convertToBase64(item.file as File),\n };\n }) || [],\n );\n\n controller?.sendMessage({\n attaches: attachments.map(item => ({\n id: item.id,\n attachId: item.id,\n url: item.base64,\n status: 'success',\n type: checkMedia(item.contentType),\n mimeType: item.contentType,\n })),\n content: compact([\n ...message.content.map(item => {\n if (item.type === 'text') {\n return {\n type: 'text',\n text: item.text,\n } as TextMessage;\n }\n }),\n ]),\n });\n },\n onReload: async (parentId, config) => {\n if (currentThread?.id && parentId)\n controller?.reloadMessage({\n threadId: currentThread?.id,\n messageId: parentId,\n });\n else {\n controller.onError?.(new Error('未找到对应的对话'));\n }\n },\n onCancel: async () => {\n controller?.abortMessage();\n },\n adapters: {\n attachments: {\n remove: async ({ id }) => {\n console.log(id);\n },\n send: async ({ id, file }) => {\n return {\n id,\n type: 'image',\n name: file.name,\n contentType: file.type,\n content: [\n {\n type: 'image',\n image: file.name,\n },\n ],\n status: {\n type: 'complete',\n },\n file,\n };\n },\n accept: 'image/*',\n add: async ({ file }) => {\n return {\n file,\n id: uuid(),\n type: 'image',\n name: file.name,\n contentType: file.type,\n status: {\n type: 'running',\n reason: 'uploading',\n progress: 0,\n },\n };\n },\n },\n },\n });\n\n const selectedSpan = useTraceStore(state => state.selectedSpan);\n const setSelectedSpan = useTraceStore(state => state.setSelectedSpan);\n useEffect(() => () => setSelectedSpan(null), [setSelectedSpan]);\n // const events = useEvent(currentThreadId);\n // useEvent(currentThreadId);\n return (\n <AssistantRuntimeProvider key={currentThreadId} runtime={runtime}>\n <Toaster />\n <ExecutionCard />\n <ChatkitProvider\n value={{\n ref: ref as MutableRefObject<ChatkitRef | null>,\n plugins: plugins || [],\n showThreadList: threadList !== false,\n placeholder: placeholder || '请输入内容',\n showHeader,\n expandToolGroup,\n expandToolDetail,\n expandReasoning,\n controller,\n }}\n >\n <div className=\"flex h-full w-full\">\n {threadList !== false &&\n (typeof threadList === 'function' ? (\n threadList({\n threadList: cloneDeep(values(threadMap)) as ThreadType[],\n })\n ) : (\n <ThreadList />\n ))}\n <div className=\"flex-1 h-full\">\n <Group orientation=\"vertical\" style={{ height: '100%' }}>\n <Panel>\n <Thread welcome={welcome} recommends={recommends} />\n </Panel>\n {selectedSpan && (\n <Panel defaultSize={'30%'}>\n <TraceDetail\n selectedSpan={selectedSpan || undefined}\n onCancel={() => setSelectedSpan(null)}\n />\n </Panel>\n )}\n </Group>\n </div>\n </div>\n </ChatkitProvider>\n {(tools || []).map((tool, index) => tool)}\n </AssistantRuntimeProvider>\n );\n },\n);\n\nconst Chatkit = (\n props: ChatkitProps,\n refFromProps: ForwardedRef<ChatkitRef>,\n) => {\n const {\n initialConfig,\n welcome,\n recommends,\n onError,\n toolDisplay,\n plugins,\n chatController: chatControllerFromProps = null,\n chatControllerPlugins,\n threadList,\n showHeader = true,\n placeholder,\n expandToolGroup,\n expandToolDetail,\n region,\n } = props;\n\n const controllerRef = useRef<ChatController | null>(chatControllerFromProps);\n\n const controller = controllerRef.current;\n\n const { currentThreadId, threadMap } = useSnapshot(controller!.store.state);\n\n const currentThread = currentThreadId ? threadMap[currentThreadId] : null;\n\n const messages = useMemo(\n () => cloneDeep(threadMap[currentThread?.id || '']?.messages || []) || [],\n [currentThread?.id, threadMap],\n );\n return (\n <div className={'chatkit-wrapper'} style={{ height: '100%' }} data-chatkit>\n <Group style={{ height: '100%' }}>\n <Panel minSize={600}>\n <ChatkitImpl\n key={currentThreadId}\n tools={[<Toaster />, <ExecutionCard />]}\n showHeader={showHeader}\n recommends={recommends}\n initialConfig={initialConfig}\n expandToolGroup={expandToolGroup}\n expandToolDetail={expandToolDetail}\n placeholder={placeholder}\n welcome={welcome}\n plugins={plugins}\n threadList={threadList}\n controller={controller!}\n />\n </Panel>\n {region && (\n <Panel defaultSize={'25%'} className=\"border-l\">\n <Debug\n region={region}\n controller={controller!}\n messages={\n (messages.filter(msg => msg.role !== 'user') || []) as any[]\n }\n />\n </Panel>\n )}\n </Group>\n </div>\n );\n};\n\nexport default forwardRef(Chatkit);\n"],"names":["uuid","_jsxs","_jsx","Group","Panel","Debug"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../src/components/Chatkit/index.tsx"],"sourcesContent":["import {\n ForwardedRef,\n forwardRef,\n MutableRefObject,\n Ref,\n useMemo,\n useRef,\n useEffect,\n useState,\n} from 'react';\nimport { v4 as uuid } from 'uuid';\nimport { ChatkitProps, ChatkitRef } from './types';\nimport { cloneDeep, compact, findLastIndex, isString, values } from 'lodash-es';\nimport { ChatkitProvider } from '@/contexts/ChatkitContext';\n\nimport { Thread } from '../assistant-ui/thread';\nimport {\n AssistantRuntimeProvider,\n useExternalStoreRuntime,\n} from '@assistant-ui/react';\nimport { ChatMessage, ChatController } from '@chat-lab/core';\nimport { Group, Panel } from 'react-resizable-panels';\nimport convertToAssistantMessage from '@/utils/convertToAssistantMessage';\nimport ThreadList from '../thread-list';\nimport { Thread as ThreadType, useSnapshot } from '@chat-lab/core';\nimport { Toaster } from '../ui/toaster';\nimport { toast } from '@/hooks/use-toast';\nimport ExecutionCard from '../assistant-ui-tools/execution-card';\nimport { convertToBase64 } from '@/utils/convertToBase64';\nimport checkMedia from '@/utils/checkMedia';\nimport { TextMessage } from '@chat-lab/core';\nimport './style.less';\nimport TraceDetail from '@/adk/components/Debug/Trace/TraceDetail';\nimport { useTraceStore } from '@/adk/components/Debug/Trace/store';\nimport Debug from '@/adk/components/Debug';\nconst ChatkitImpl = forwardRef(\n (\n props: {\n initialConfig: ChatkitProps['initialConfig'];\n welcome?: React.ReactNode;\n recommends?: string[];\n plugins?: React.ReactNode[];\n tools?: React.ReactNode[];\n placeholder?: string;\n threadList?:\n | React.ReactNode\n | boolean\n | ((props: { threadList: Readonly<ThreadType>[] }) => React.ReactNode);\n showHeader?: boolean;\n expandToolGroup?: boolean;\n expandToolDetail?: boolean;\n toolDisplay?: 'group' | 'none' | 'step';\n expandReasoning?: boolean;\n controller: ChatController;\n region?: string;\n },\n ref: ForwardedRef<ChatkitRef>,\n ) => {\n const {\n initialConfig,\n tools,\n toolDisplay = 'group',\n welcome,\n recommends,\n plugins,\n threadList,\n showHeader = true,\n placeholder,\n expandToolGroup = false,\n expandReasoning = false,\n expandToolDetail = false,\n region,\n } = props;\n const controller = props.controller;\n const { threadMap, currentThreadId } = useSnapshot(controller.store.state);\n // useImperativeHandleChatkitRef(ref, controller, onError);\n\n const currentThread = currentThreadId ? threadMap[currentThreadId] : null;\n const messages = useMemo(\n () => cloneDeep(threadMap[currentThread?.id || '']?.messages || []) || [],\n [currentThread?.id, threadMap],\n );\n\n const uiMessages = useMemo(\n () =>\n convertToAssistantMessage(messages as Readonly<ChatMessage>[], {\n toolDisplay: toolDisplay || 'group',\n }),\n [messages],\n );\n\n const runtime = useExternalStoreRuntime({\n messages: uiMessages,\n isLoading: currentThread?.sending,\n isDisabled: !!currentThread?.metadata['isInitingSession'],\n convertMessage: message => message,\n onNew: async message => {\n const attachments = await Promise.all(\n message.attachments?.map(async item => {\n return {\n ...item,\n base64: await convertToBase64(item.file as File),\n };\n }) || [],\n );\n\n controller?.sendMessage({\n attaches: attachments.map(item => ({\n id: item.id,\n attachId: item.id,\n url: item.base64,\n status: 'success',\n type: checkMedia(item.contentType),\n mimeType: item.contentType,\n })),\n content: compact([\n ...message.content.map(item => {\n if (item.type === 'text') {\n return {\n type: 'text',\n text: item.text,\n } as TextMessage;\n }\n }),\n ]),\n });\n },\n onReload: async (parentId, config) => {\n if (currentThread?.id && parentId)\n controller?.reloadMessage({\n threadId: currentThread?.id,\n messageId: parentId,\n });\n else {\n controller.onError?.(new Error('未找到对应的对话'));\n }\n },\n onCancel: async () => {\n controller?.abortMessage();\n },\n adapters: {\n attachments: {\n remove: async ({ id }) => {\n console.log(id);\n },\n send: async ({ id, file }) => {\n return {\n id,\n type: 'image',\n name: file.name,\n contentType: file.type,\n content: [\n {\n type: 'image',\n image: file.name,\n },\n ],\n status: {\n type: 'complete',\n },\n file,\n };\n },\n accept: 'image/*',\n add: async ({ file }) => {\n return {\n file,\n id: uuid(),\n type: 'image',\n name: file.name,\n contentType: file.type,\n status: {\n type: 'running',\n reason: 'uploading',\n progress: 0,\n },\n };\n },\n },\n },\n });\n\n const selectedSpan = useTraceStore(state => state.selectedSpan);\n const setSelectedSpan = useTraceStore(state => state.setSelectedSpan);\n useEffect(() => () => setSelectedSpan(null), [setSelectedSpan]);\n // const events = useEvent(currentThreadId);\n // useEvent(currentThreadId);\n return (\n <AssistantRuntimeProvider key={currentThreadId} runtime={runtime}>\n <Toaster />\n <ExecutionCard />\n <ChatkitProvider\n value={{\n ref: ref as MutableRefObject<ChatkitRef | null>,\n plugins: plugins || [],\n showThreadList: threadList !== false,\n placeholder: placeholder || '请输入内容',\n showHeader,\n expandToolGroup,\n expandToolDetail,\n expandReasoning,\n controller,\n }}\n >\n <div className=\"flex h-full w-full\">\n {threadList !== false &&\n (typeof threadList === 'function' ? (\n threadList({\n threadList: cloneDeep(values(threadMap)) as ThreadType[],\n })\n ) : (\n <ThreadList />\n ))}\n <div className=\"flex-1 h-full w-[calc(100%-200px)]\">\n <Group\n orientation=\"vertical\"\n style={{ height: '100%', width: '100%' }}\n >\n <Panel>\n <Thread welcome={welcome} recommends={recommends} />\n </Panel>\n {selectedSpan && (\n <Panel defaultSize={'30%'}>\n <TraceDetail\n selectedSpan={selectedSpan || undefined}\n onCancel={() => setSelectedSpan(null)}\n />\n </Panel>\n )}\n </Group>\n </div>\n </div>\n </ChatkitProvider>\n {(tools || []).map((tool, index) => tool)}\n </AssistantRuntimeProvider>\n );\n },\n);\n\nconst Chatkit = (\n props: ChatkitProps,\n refFromProps: ForwardedRef<ChatkitRef>,\n) => {\n const {\n initialConfig,\n welcome,\n recommends,\n onError,\n toolDisplay,\n plugins,\n chatController: chatControllerFromProps = null,\n chatControllerPlugins,\n threadList,\n showHeader = true,\n placeholder,\n expandToolGroup,\n expandToolDetail,\n region,\n } = props;\n\n const controllerRef = useRef<ChatController | null>(chatControllerFromProps);\n\n const controller = controllerRef.current;\n\n const { currentThreadId, threadMap } = useSnapshot(controller!.store.state);\n\n const currentThread = currentThreadId ? threadMap[currentThreadId] : null;\n\n const messages = useMemo(\n () => cloneDeep(threadMap[currentThread?.id || '']?.messages || []) || [],\n [currentThread?.id, threadMap],\n );\n return (\n <div className={'chatkit-wrapper'} style={{ height: '100%' }} data-chatkit>\n <Group style={{ height: '100%' }}>\n <Panel minSize={750} maxSize={900}>\n <ChatkitImpl\n key={currentThreadId}\n tools={[<Toaster />, <ExecutionCard />]}\n showHeader={showHeader}\n recommends={recommends}\n initialConfig={initialConfig}\n expandToolGroup={expandToolGroup}\n expandToolDetail={expandToolDetail}\n placeholder={placeholder}\n welcome={welcome}\n plugins={plugins}\n threadList={threadList}\n controller={controller!}\n />\n </Panel>\n {region && (\n <Panel defaultSize={'25%'} className=\"border-l\">\n <Debug\n region={region}\n controller={controller!}\n messages={\n (messages.filter(msg => msg.role !== 'user') || []) as any[]\n }\n />\n </Panel>\n )}\n </Group>\n </div>\n );\n};\n\nexport default forwardRef(Chatkit);\n"],"names":["uuid","_jsxs","_jsx","Group","Panel","Debug"],"mappings":"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"}
|
|
@@ -9,12 +9,14 @@ var input = require('./ui/input.cjs');
|
|
|
9
9
|
var button = require('./ui/button.cjs');
|
|
10
10
|
var useThread = require('../hooks/useThread.cjs');
|
|
11
11
|
var ChatkitContext = require('../contexts/ChatkitContext.cjs');
|
|
12
|
+
var WarningModal = require('./assistant-ui/WarningModal.cjs');
|
|
12
13
|
var ellipsis = require('../node_modules/.pnpm/lucide-react@0.552.0_react@17.0.2/node_modules/lucide-react/dist/esm/icons/ellipsis.cjs');
|
|
13
14
|
var trash2 = require('../node_modules/.pnpm/lucide-react@0.552.0_react@17.0.2/node_modules/lucide-react/dist/esm/icons/trash-2.cjs');
|
|
14
15
|
|
|
15
16
|
// 在组件中添加状态管理
|
|
16
17
|
const ThreadOptionsMenu = ({ threadId, onEditName, onDelete, className = '', }) => {
|
|
17
18
|
React.useState(false);
|
|
19
|
+
const [showWarningModal, setShowWarningModal] = React.useState(false);
|
|
18
20
|
const [newThreadName, setNewThreadName] = React.useState('');
|
|
19
21
|
const { currentThread, threadList } = useThread();
|
|
20
22
|
const ref = ChatkitContext.useChatkitRef();
|
|
@@ -25,17 +27,22 @@ const ThreadOptionsMenu = ({ threadId, onEditName, onDelete, className = '', })
|
|
|
25
27
|
}
|
|
26
28
|
};
|
|
27
29
|
const handleDelete = () => {
|
|
30
|
+
setShowWarningModal(true);
|
|
31
|
+
};
|
|
32
|
+
const handleConfirmDelete = () => {
|
|
28
33
|
const selectableThreadList = threadList.filter(thread => thread.id !== threadId);
|
|
29
34
|
if (selectableThreadList.length === 0) {
|
|
30
35
|
console.warn('[warning]: cannot delete the last thread');
|
|
36
|
+
setShowWarningModal(false);
|
|
31
37
|
return;
|
|
32
38
|
}
|
|
33
39
|
ref?.setCurrentThread(selectableThreadList[0]?.id);
|
|
34
40
|
ref?.abortMessage(threadId);
|
|
35
41
|
ref?.deleteThread(threadId);
|
|
42
|
+
setShowWarningModal(false);
|
|
36
43
|
};
|
|
37
44
|
const [showEditDialog, setShowEditDialog] = React.useState(false);
|
|
38
|
-
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(dialog.Dialog, { open: showEditDialog, onOpenChange: setShowEditDialog, children: jsxRuntime.jsxs(dialog.DialogContent, { className: "sm:max-w-[480px] border-none shadow-2xl rounded-2xl overflow-hidden", children: [jsxRuntime.jsx(dialog.DialogHeader, { className: "space-y-3 pb-6", children: jsxRuntime.jsx(dialog.DialogTitle, { className: "text-2xl font-semibold text-gray-900 tracking-tight", children: "\u7F16\u8F91\u5BF9\u8BDD\u540D\u79F0" }) }), jsxRuntime.jsx("div", { className: "space-y-6 py-2", children: jsxRuntime.jsx("div", { className: "space-y-3", children: jsxRuntime.jsx(input.Input, { id: "thread-name", value: newThreadName, onChange: (e) => setNewThreadName(e.target.value), placeholder: "\u8BF7\u8F93\u5165\u5BF9\u8BDD\u540D\u79F0...", maxLength: 100, className: "w-full h-11 px-4 border-2 border-gray-200 rounded-xl transition-all duration-200 focus:border-blue-400 focus:ring-4 focus:ring-blue-50 focus-visible:ring-offset-0", autoFocus: true, onKeyDown: (e) => {
|
|
45
|
+
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(WarningModal.WarningModal, { open: showWarningModal, onOpenChange: setShowWarningModal, onConfirm: handleConfirmDelete }), jsxRuntime.jsx(dialog.Dialog, { open: showEditDialog, onOpenChange: setShowEditDialog, children: jsxRuntime.jsxs(dialog.DialogContent, { className: "sm:max-w-[480px] border-none shadow-2xl rounded-2xl overflow-hidden", children: [jsxRuntime.jsx(dialog.DialogHeader, { className: "space-y-3 pb-6", children: jsxRuntime.jsx(dialog.DialogTitle, { className: "text-2xl font-semibold text-gray-900 tracking-tight", children: "\u7F16\u8F91\u5BF9\u8BDD\u540D\u79F0" }) }), jsxRuntime.jsx("div", { className: "space-y-6 py-2", children: jsxRuntime.jsx("div", { className: "space-y-3", children: jsxRuntime.jsx(input.Input, { id: "thread-name", value: newThreadName, onChange: (e) => setNewThreadName(e.target.value), placeholder: "\u8BF7\u8F93\u5165\u5BF9\u8BDD\u540D\u79F0...", maxLength: 100, className: "w-full h-11 px-4 border-2 border-gray-200 rounded-xl transition-all duration-200 focus:border-blue-400 focus:ring-4 focus:ring-blue-50 focus-visible:ring-offset-0", autoFocus: true, onKeyDown: (e) => {
|
|
39
46
|
if (e.key === 'Enter' && newThreadName.trim()) {
|
|
40
47
|
handleSaveName();
|
|
41
48
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ThreadOptionsMenu.cjs","sources":["../../src/components/ThreadOptionsMenu.tsx"],"sourcesContent":["import React from 'react';\nimport { Ellipsis } from 'lucide-react';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '@radix-ui/react-dropdown-menu';\nimport { Trash2 } from 'lucide-react';\nimport { cn } from '@/lib/utils';\nimport Edit from '@/assets/Edit';\n\ninterface ThreadOptionsMenuProps {\n threadId: string;\n onEditName?: () => void;\n onDelete?: () => void;\n className?: string;\n}\n\n// 首先添加必要的导入\nimport { useState } from 'react';\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n DialogTrigger,\n} from '@/components/ui/dialog';\nimport { Input } from '@/components/ui/input';\nimport { Button } from '@/components/ui/button';\nimport { createDialogScope } from '@radix-ui/react-dialog';\nimport useThread from '@/hooks/useThread';\nimport { useChatkitRef } from '@/contexts/ChatkitContext';\nimport { toast } from '@/hooks/use-toast';\n\n// 在组件中添加状态管理\nconst ThreadOptionsMenu: React.FC<ThreadOptionsMenuProps> = ({\n threadId,\n onEditName,\n onDelete,\n className = '',\n}) => {\n const [isDialogOpen, setIsDialogOpen] = useState(false);\n const [newThreadName, setNewThreadName] = useState('');\n\n const handleEditName = () => {\n // 设置默认名称(这里可以从props中获取)\n setNewThreadName(currentThread?.name || ``);\n setShowEditDialog(true);\n };\n\n const { currentThread, threadList } = useThread();\n\n const ref = useChatkitRef();\n const handleSaveName = () => {\n if (newThreadName.trim()) {\n ref?.setThreadName(threadId, newThreadName.trim());\n setShowEditDialog(false);\n }\n };\n\n const handleDelete = () => {\n const selectableThreadList = threadList.filter(\n thread => thread.id !== threadId,\n );\n if (selectableThreadList.length === 0) {\n console.warn('[warning]: cannot delete the last thread');\n return;\n }\n ref?.setCurrentThread(selectableThreadList[0]?.id);\n ref?.abortMessage(threadId);\n ref?.deleteThread(threadId);\n };\n\n const [showEditDialog, setShowEditDialog] = useState(false);\n return (\n <>\n <Dialog open={showEditDialog} onOpenChange={setShowEditDialog}>\n <DialogContent className=\"sm:max-w-[480px] border-none shadow-2xl rounded-2xl overflow-hidden\">\n <DialogHeader className=\"space-y-3 pb-6\">\n <DialogTitle className=\"text-2xl font-semibold text-gray-900 tracking-tight\">\n 编辑对话名称\n </DialogTitle>\n </DialogHeader>\n\n <div className=\"space-y-6 py-2\">\n <div className=\"space-y-3\">\n <Input\n id=\"thread-name\"\n value={newThreadName}\n onChange={(e: React.ChangeEvent<HTMLInputElement>) =>\n setNewThreadName(e.target.value)\n }\n placeholder=\"请输入对话名称...\"\n maxLength={100}\n className=\"w-full h-11 px-4 border-2 border-gray-200 rounded-xl transition-all duration-200 focus:border-blue-400 focus:ring-4 focus:ring-blue-50 focus-visible:ring-offset-0\"\n autoFocus\n onKeyDown={(e: React.KeyboardEvent<HTMLInputElement>) => {\n if (e.key === 'Enter' && newThreadName.trim()) {\n handleSaveName();\n }\n }}\n />\n </div>\n </div>\n\n <DialogFooter className=\"flex gap-3 pt-6 border-t border-gray-100\">\n <Button\n variant=\"ghost\"\n onClick={() => setShowEditDialog(false)}\n className=\"flex-1 h-11 rounded-xl hover:bg-gray-100 transition-all duration-200 font-medium\"\n >\n 取消\n </Button>\n <Button\n onClick={handleSaveName}\n disabled={!newThreadName.trim()}\n className=\"flex-1 h-11 rounded-xl disabled:from-gray-300 disabled:to-gray-300 disabled:cursor-not-allowed shadow-md hover:shadow-lg transition-all duration-200 font-medium\"\n >\n 保存更改\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <button\n className={cn(\n 'flex items-center justify-center h-8 w-8 rounded-full hover:bg-gray-100 transition-colors',\n className,\n )}\n aria-label={`线程 ${threadId} 选项`}\n type=\"button\"\n >\n <Ellipsis className=\"h-4 w-4 text-[#808388]\" />\n </button>\n </DropdownMenuTrigger>\n <DropdownMenuContent\n align=\"end\"\n className=\"bg-white py-[8px] px-[6px] rounded-[8px]\"\n >\n <DropdownMenuItem\n disabled={threadList.length === 1}\n className={cn(\n 'cursor-pointer flex items-center hover:bg-[rgba(46,50,56,0.05)] px-2 py-1 rounded-[4px]',\n {\n 'cursor-not-allowed text-[#808388] opacity-50':\n threadList.length === 1,\n },\n )}\n onClick={(e: React.MouseEvent<HTMLDivElement>) => {\n e.stopPropagation();\n if (threadList.length === 1) {\n return;\n }\n handleDelete();\n }}\n >\n <Trash2 className=\"mr-2 h-4 w-4\" />\n <span className=\"mr-4\">删除会话</span>\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </>\n );\n};\n\nexport default ThreadOptionsMenu;\n"],"names":["useState","useChatkitRef","_jsxs","_jsx","Dialog","DialogContent","DialogHeader","DialogTitle","Input","DialogFooter","Button","DropdownMenu","DropdownMenuTrigger","cn","Ellipsis","DropdownMenuContent","DropdownMenuItem","Trash2"],"mappings":"
|
|
1
|
+
{"version":3,"file":"ThreadOptionsMenu.cjs","sources":["../../src/components/ThreadOptionsMenu.tsx"],"sourcesContent":["import React from 'react';\nimport { Ellipsis } from 'lucide-react';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '@radix-ui/react-dropdown-menu';\nimport { Trash2 } from 'lucide-react';\nimport { cn } from '@/lib/utils';\nimport Edit from '@/assets/Edit';\n\ninterface ThreadOptionsMenuProps {\n threadId: string;\n onEditName?: () => void;\n onDelete?: () => void;\n className?: string;\n}\n\n// 首先添加必要的导入\nimport { useState } from 'react';\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n DialogTrigger,\n} from '@/components/ui/dialog';\nimport { Input } from '@/components/ui/input';\nimport { Button } from '@/components/ui/button';\nimport { createDialogScope } from '@radix-ui/react-dialog';\nimport useThread from '@/hooks/useThread';\nimport { useChatkitRef } from '@/contexts/ChatkitContext';\nimport { toast } from '@/hooks/use-toast';\nimport { WarningModal } from '@/components/assistant-ui/WarningModal';\n\n// 在组件中添加状态管理\nconst ThreadOptionsMenu: React.FC<ThreadOptionsMenuProps> = ({\n threadId,\n onEditName,\n onDelete,\n className = '',\n}) => {\n const [isDialogOpen, setIsDialogOpen] = useState(false);\n const [showWarningModal, setShowWarningModal] = useState(false);\n const [newThreadName, setNewThreadName] = useState('');\n\n const handleEditName = () => {\n // 设置默认名称(这里可以从props中获取)\n setNewThreadName(currentThread?.name || ``);\n setShowEditDialog(true);\n };\n\n const { currentThread, threadList } = useThread();\n\n const ref = useChatkitRef();\n const handleSaveName = () => {\n if (newThreadName.trim()) {\n ref?.setThreadName(threadId, newThreadName.trim());\n setShowEditDialog(false);\n }\n };\n\n const handleDelete = () => {\n setShowWarningModal(true);\n };\n\n const handleConfirmDelete = () => {\n const selectableThreadList = threadList.filter(\n thread => thread.id !== threadId,\n );\n if (selectableThreadList.length === 0) {\n console.warn('[warning]: cannot delete the last thread');\n setShowWarningModal(false);\n return;\n }\n ref?.setCurrentThread(selectableThreadList[0]?.id);\n ref?.abortMessage(threadId);\n ref?.deleteThread(threadId);\n setShowWarningModal(false);\n };\n\n const [showEditDialog, setShowEditDialog] = useState(false);\n return (\n <>\n <WarningModal\n open={showWarningModal}\n onOpenChange={setShowWarningModal}\n onConfirm={handleConfirmDelete}\n />\n <Dialog open={showEditDialog} onOpenChange={setShowEditDialog}>\n <DialogContent className=\"sm:max-w-[480px] border-none shadow-2xl rounded-2xl overflow-hidden\">\n <DialogHeader className=\"space-y-3 pb-6\">\n <DialogTitle className=\"text-2xl font-semibold text-gray-900 tracking-tight\">\n 编辑对话名称\n </DialogTitle>\n </DialogHeader>\n\n <div className=\"space-y-6 py-2\">\n <div className=\"space-y-3\">\n <Input\n id=\"thread-name\"\n value={newThreadName}\n onChange={(e: React.ChangeEvent<HTMLInputElement>) =>\n setNewThreadName(e.target.value)\n }\n placeholder=\"请输入对话名称...\"\n maxLength={100}\n className=\"w-full h-11 px-4 border-2 border-gray-200 rounded-xl transition-all duration-200 focus:border-blue-400 focus:ring-4 focus:ring-blue-50 focus-visible:ring-offset-0\"\n autoFocus\n onKeyDown={(e: React.KeyboardEvent<HTMLInputElement>) => {\n if (e.key === 'Enter' && newThreadName.trim()) {\n handleSaveName();\n }\n }}\n />\n </div>\n </div>\n\n <DialogFooter className=\"flex gap-3 pt-6 border-t border-gray-100\">\n <Button\n variant=\"ghost\"\n onClick={() => setShowEditDialog(false)}\n className=\"flex-1 h-11 rounded-xl hover:bg-gray-100 transition-all duration-200 font-medium\"\n >\n 取消\n </Button>\n <Button\n onClick={handleSaveName}\n disabled={!newThreadName.trim()}\n className=\"flex-1 h-11 rounded-xl disabled:from-gray-300 disabled:to-gray-300 disabled:cursor-not-allowed shadow-md hover:shadow-lg transition-all duration-200 font-medium\"\n >\n 保存更改\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <button\n className={cn(\n 'flex items-center justify-center h-8 w-8 rounded-full hover:bg-gray-100 transition-colors',\n className,\n )}\n aria-label={`线程 ${threadId} 选项`}\n type=\"button\"\n >\n <Ellipsis className=\"h-4 w-4 text-[#808388]\" />\n </button>\n </DropdownMenuTrigger>\n <DropdownMenuContent\n align=\"end\"\n className=\"bg-white py-[8px] px-[6px] rounded-[8px]\"\n >\n <DropdownMenuItem\n disabled={threadList.length === 1}\n className={cn(\n 'cursor-pointer flex items-center hover:bg-[rgba(46,50,56,0.05)] px-2 py-1 rounded-[4px]',\n {\n 'cursor-not-allowed text-[#808388] opacity-50':\n threadList.length === 1,\n },\n )}\n onClick={(e: React.MouseEvent<HTMLDivElement>) => {\n e.stopPropagation();\n if (threadList.length === 1) {\n return;\n }\n handleDelete();\n }}\n >\n <Trash2 className=\"mr-2 h-4 w-4\" />\n <span className=\"mr-4\">删除会话</span>\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </>\n );\n};\n\nexport default ThreadOptionsMenu;\n"],"names":["useState","useChatkitRef","_jsxs","_Fragment","_jsx","WarningModal","Dialog","DialogContent","DialogHeader","DialogTitle","Input","DialogFooter","Button","DropdownMenu","DropdownMenuTrigger","cn","Ellipsis","DropdownMenuContent","DropdownMenuItem","Trash2"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ThreadOptionsMenu.d.ts","sourceRoot":"","sources":["../../src/components/ThreadOptionsMenu.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAY1B,UAAU,sBAAsB;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;
|
|
1
|
+
{"version":3,"file":"ThreadOptionsMenu.d.ts","sourceRoot":"","sources":["../../src/components/ThreadOptionsMenu.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAY1B,UAAU,sBAAsB;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAsBD,QAAA,MAAM,iBAAiB,EAAE,KAAK,CAAC,EAAE,CAAC,sBAAsB,CA6IvD,CAAC;AAEF,eAAe,iBAAiB,CAAC"}
|
|
@@ -7,12 +7,14 @@ import { Input } from './ui/input.js';
|
|
|
7
7
|
import { Button } from './ui/button.js';
|
|
8
8
|
import useThread from '../hooks/useThread.js';
|
|
9
9
|
import { useChatkitRef } from '../contexts/ChatkitContext.js';
|
|
10
|
+
import { WarningModal } from './assistant-ui/WarningModal.js';
|
|
10
11
|
import Ellipsis from '../node_modules/.pnpm/lucide-react@0.552.0_react@17.0.2/node_modules/lucide-react/dist/esm/icons/ellipsis.js';
|
|
11
12
|
import Trash2 from '../node_modules/.pnpm/lucide-react@0.552.0_react@17.0.2/node_modules/lucide-react/dist/esm/icons/trash-2.js';
|
|
12
13
|
|
|
13
14
|
// 在组件中添加状态管理
|
|
14
15
|
const ThreadOptionsMenu = ({ threadId, onEditName, onDelete, className = '', }) => {
|
|
15
16
|
useState(false);
|
|
17
|
+
const [showWarningModal, setShowWarningModal] = useState(false);
|
|
16
18
|
const [newThreadName, setNewThreadName] = useState('');
|
|
17
19
|
const { currentThread, threadList } = useThread();
|
|
18
20
|
const ref = useChatkitRef();
|
|
@@ -23,17 +25,22 @@ const ThreadOptionsMenu = ({ threadId, onEditName, onDelete, className = '', })
|
|
|
23
25
|
}
|
|
24
26
|
};
|
|
25
27
|
const handleDelete = () => {
|
|
28
|
+
setShowWarningModal(true);
|
|
29
|
+
};
|
|
30
|
+
const handleConfirmDelete = () => {
|
|
26
31
|
const selectableThreadList = threadList.filter(thread => thread.id !== threadId);
|
|
27
32
|
if (selectableThreadList.length === 0) {
|
|
28
33
|
console.warn('[warning]: cannot delete the last thread');
|
|
34
|
+
setShowWarningModal(false);
|
|
29
35
|
return;
|
|
30
36
|
}
|
|
31
37
|
ref?.setCurrentThread(selectableThreadList[0]?.id);
|
|
32
38
|
ref?.abortMessage(threadId);
|
|
33
39
|
ref?.deleteThread(threadId);
|
|
40
|
+
setShowWarningModal(false);
|
|
34
41
|
};
|
|
35
42
|
const [showEditDialog, setShowEditDialog] = useState(false);
|
|
36
|
-
return (jsxs(Fragment, { children: [jsx(Dialog, { open: showEditDialog, onOpenChange: setShowEditDialog, children: jsxs(DialogContent, { className: "sm:max-w-[480px] border-none shadow-2xl rounded-2xl overflow-hidden", children: [jsx(DialogHeader, { className: "space-y-3 pb-6", children: jsx(DialogTitle, { className: "text-2xl font-semibold text-gray-900 tracking-tight", children: "\u7F16\u8F91\u5BF9\u8BDD\u540D\u79F0" }) }), jsx("div", { className: "space-y-6 py-2", children: jsx("div", { className: "space-y-3", children: jsx(Input, { id: "thread-name", value: newThreadName, onChange: (e) => setNewThreadName(e.target.value), placeholder: "\u8BF7\u8F93\u5165\u5BF9\u8BDD\u540D\u79F0...", maxLength: 100, className: "w-full h-11 px-4 border-2 border-gray-200 rounded-xl transition-all duration-200 focus:border-blue-400 focus:ring-4 focus:ring-blue-50 focus-visible:ring-offset-0", autoFocus: true, onKeyDown: (e) => {
|
|
43
|
+
return (jsxs(Fragment, { children: [jsx(WarningModal, { open: showWarningModal, onOpenChange: setShowWarningModal, onConfirm: handleConfirmDelete }), jsx(Dialog, { open: showEditDialog, onOpenChange: setShowEditDialog, children: jsxs(DialogContent, { className: "sm:max-w-[480px] border-none shadow-2xl rounded-2xl overflow-hidden", children: [jsx(DialogHeader, { className: "space-y-3 pb-6", children: jsx(DialogTitle, { className: "text-2xl font-semibold text-gray-900 tracking-tight", children: "\u7F16\u8F91\u5BF9\u8BDD\u540D\u79F0" }) }), jsx("div", { className: "space-y-6 py-2", children: jsx("div", { className: "space-y-3", children: jsx(Input, { id: "thread-name", value: newThreadName, onChange: (e) => setNewThreadName(e.target.value), placeholder: "\u8BF7\u8F93\u5165\u5BF9\u8BDD\u540D\u79F0...", maxLength: 100, className: "w-full h-11 px-4 border-2 border-gray-200 rounded-xl transition-all duration-200 focus:border-blue-400 focus:ring-4 focus:ring-blue-50 focus-visible:ring-offset-0", autoFocus: true, onKeyDown: (e) => {
|
|
37
44
|
if (e.key === 'Enter' && newThreadName.trim()) {
|
|
38
45
|
handleSaveName();
|
|
39
46
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ThreadOptionsMenu.js","sources":["../../src/components/ThreadOptionsMenu.tsx"],"sourcesContent":["import React from 'react';\nimport { Ellipsis } from 'lucide-react';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '@radix-ui/react-dropdown-menu';\nimport { Trash2 } from 'lucide-react';\nimport { cn } from '@/lib/utils';\nimport Edit from '@/assets/Edit';\n\ninterface ThreadOptionsMenuProps {\n threadId: string;\n onEditName?: () => void;\n onDelete?: () => void;\n className?: string;\n}\n\n// 首先添加必要的导入\nimport { useState } from 'react';\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n DialogTrigger,\n} from '@/components/ui/dialog';\nimport { Input } from '@/components/ui/input';\nimport { Button } from '@/components/ui/button';\nimport { createDialogScope } from '@radix-ui/react-dialog';\nimport useThread from '@/hooks/useThread';\nimport { useChatkitRef } from '@/contexts/ChatkitContext';\nimport { toast } from '@/hooks/use-toast';\n\n// 在组件中添加状态管理\nconst ThreadOptionsMenu: React.FC<ThreadOptionsMenuProps> = ({\n threadId,\n onEditName,\n onDelete,\n className = '',\n}) => {\n const [isDialogOpen, setIsDialogOpen] = useState(false);\n const [newThreadName, setNewThreadName] = useState('');\n\n const handleEditName = () => {\n // 设置默认名称(这里可以从props中获取)\n setNewThreadName(currentThread?.name || ``);\n setShowEditDialog(true);\n };\n\n const { currentThread, threadList } = useThread();\n\n const ref = useChatkitRef();\n const handleSaveName = () => {\n if (newThreadName.trim()) {\n ref?.setThreadName(threadId, newThreadName.trim());\n setShowEditDialog(false);\n }\n };\n\n const handleDelete = () => {\n const selectableThreadList = threadList.filter(\n thread => thread.id !== threadId,\n );\n if (selectableThreadList.length === 0) {\n console.warn('[warning]: cannot delete the last thread');\n return;\n }\n ref?.setCurrentThread(selectableThreadList[0]?.id);\n ref?.abortMessage(threadId);\n ref?.deleteThread(threadId);\n };\n\n const [showEditDialog, setShowEditDialog] = useState(false);\n return (\n <>\n <Dialog open={showEditDialog} onOpenChange={setShowEditDialog}>\n <DialogContent className=\"sm:max-w-[480px] border-none shadow-2xl rounded-2xl overflow-hidden\">\n <DialogHeader className=\"space-y-3 pb-6\">\n <DialogTitle className=\"text-2xl font-semibold text-gray-900 tracking-tight\">\n 编辑对话名称\n </DialogTitle>\n </DialogHeader>\n\n <div className=\"space-y-6 py-2\">\n <div className=\"space-y-3\">\n <Input\n id=\"thread-name\"\n value={newThreadName}\n onChange={(e: React.ChangeEvent<HTMLInputElement>) =>\n setNewThreadName(e.target.value)\n }\n placeholder=\"请输入对话名称...\"\n maxLength={100}\n className=\"w-full h-11 px-4 border-2 border-gray-200 rounded-xl transition-all duration-200 focus:border-blue-400 focus:ring-4 focus:ring-blue-50 focus-visible:ring-offset-0\"\n autoFocus\n onKeyDown={(e: React.KeyboardEvent<HTMLInputElement>) => {\n if (e.key === 'Enter' && newThreadName.trim()) {\n handleSaveName();\n }\n }}\n />\n </div>\n </div>\n\n <DialogFooter className=\"flex gap-3 pt-6 border-t border-gray-100\">\n <Button\n variant=\"ghost\"\n onClick={() => setShowEditDialog(false)}\n className=\"flex-1 h-11 rounded-xl hover:bg-gray-100 transition-all duration-200 font-medium\"\n >\n 取消\n </Button>\n <Button\n onClick={handleSaveName}\n disabled={!newThreadName.trim()}\n className=\"flex-1 h-11 rounded-xl disabled:from-gray-300 disabled:to-gray-300 disabled:cursor-not-allowed shadow-md hover:shadow-lg transition-all duration-200 font-medium\"\n >\n 保存更改\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <button\n className={cn(\n 'flex items-center justify-center h-8 w-8 rounded-full hover:bg-gray-100 transition-colors',\n className,\n )}\n aria-label={`线程 ${threadId} 选项`}\n type=\"button\"\n >\n <Ellipsis className=\"h-4 w-4 text-[#808388]\" />\n </button>\n </DropdownMenuTrigger>\n <DropdownMenuContent\n align=\"end\"\n className=\"bg-white py-[8px] px-[6px] rounded-[8px]\"\n >\n <DropdownMenuItem\n disabled={threadList.length === 1}\n className={cn(\n 'cursor-pointer flex items-center hover:bg-[rgba(46,50,56,0.05)] px-2 py-1 rounded-[4px]',\n {\n 'cursor-not-allowed text-[#808388] opacity-50':\n threadList.length === 1,\n },\n )}\n onClick={(e: React.MouseEvent<HTMLDivElement>) => {\n e.stopPropagation();\n if (threadList.length === 1) {\n return;\n }\n handleDelete();\n }}\n >\n <Trash2 className=\"mr-2 h-4 w-4\" />\n <span className=\"mr-4\">删除会话</span>\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </>\n );\n};\n\nexport default ThreadOptionsMenu;\n"],"names":["_jsxs","_jsx"],"mappings":"
|
|
1
|
+
{"version":3,"file":"ThreadOptionsMenu.js","sources":["../../src/components/ThreadOptionsMenu.tsx"],"sourcesContent":["import React from 'react';\nimport { Ellipsis } from 'lucide-react';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '@radix-ui/react-dropdown-menu';\nimport { Trash2 } from 'lucide-react';\nimport { cn } from '@/lib/utils';\nimport Edit from '@/assets/Edit';\n\ninterface ThreadOptionsMenuProps {\n threadId: string;\n onEditName?: () => void;\n onDelete?: () => void;\n className?: string;\n}\n\n// 首先添加必要的导入\nimport { useState } from 'react';\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n DialogTrigger,\n} from '@/components/ui/dialog';\nimport { Input } from '@/components/ui/input';\nimport { Button } from '@/components/ui/button';\nimport { createDialogScope } from '@radix-ui/react-dialog';\nimport useThread from '@/hooks/useThread';\nimport { useChatkitRef } from '@/contexts/ChatkitContext';\nimport { toast } from '@/hooks/use-toast';\nimport { WarningModal } from '@/components/assistant-ui/WarningModal';\n\n// 在组件中添加状态管理\nconst ThreadOptionsMenu: React.FC<ThreadOptionsMenuProps> = ({\n threadId,\n onEditName,\n onDelete,\n className = '',\n}) => {\n const [isDialogOpen, setIsDialogOpen] = useState(false);\n const [showWarningModal, setShowWarningModal] = useState(false);\n const [newThreadName, setNewThreadName] = useState('');\n\n const handleEditName = () => {\n // 设置默认名称(这里可以从props中获取)\n setNewThreadName(currentThread?.name || ``);\n setShowEditDialog(true);\n };\n\n const { currentThread, threadList } = useThread();\n\n const ref = useChatkitRef();\n const handleSaveName = () => {\n if (newThreadName.trim()) {\n ref?.setThreadName(threadId, newThreadName.trim());\n setShowEditDialog(false);\n }\n };\n\n const handleDelete = () => {\n setShowWarningModal(true);\n };\n\n const handleConfirmDelete = () => {\n const selectableThreadList = threadList.filter(\n thread => thread.id !== threadId,\n );\n if (selectableThreadList.length === 0) {\n console.warn('[warning]: cannot delete the last thread');\n setShowWarningModal(false);\n return;\n }\n ref?.setCurrentThread(selectableThreadList[0]?.id);\n ref?.abortMessage(threadId);\n ref?.deleteThread(threadId);\n setShowWarningModal(false);\n };\n\n const [showEditDialog, setShowEditDialog] = useState(false);\n return (\n <>\n <WarningModal\n open={showWarningModal}\n onOpenChange={setShowWarningModal}\n onConfirm={handleConfirmDelete}\n />\n <Dialog open={showEditDialog} onOpenChange={setShowEditDialog}>\n <DialogContent className=\"sm:max-w-[480px] border-none shadow-2xl rounded-2xl overflow-hidden\">\n <DialogHeader className=\"space-y-3 pb-6\">\n <DialogTitle className=\"text-2xl font-semibold text-gray-900 tracking-tight\">\n 编辑对话名称\n </DialogTitle>\n </DialogHeader>\n\n <div className=\"space-y-6 py-2\">\n <div className=\"space-y-3\">\n <Input\n id=\"thread-name\"\n value={newThreadName}\n onChange={(e: React.ChangeEvent<HTMLInputElement>) =>\n setNewThreadName(e.target.value)\n }\n placeholder=\"请输入对话名称...\"\n maxLength={100}\n className=\"w-full h-11 px-4 border-2 border-gray-200 rounded-xl transition-all duration-200 focus:border-blue-400 focus:ring-4 focus:ring-blue-50 focus-visible:ring-offset-0\"\n autoFocus\n onKeyDown={(e: React.KeyboardEvent<HTMLInputElement>) => {\n if (e.key === 'Enter' && newThreadName.trim()) {\n handleSaveName();\n }\n }}\n />\n </div>\n </div>\n\n <DialogFooter className=\"flex gap-3 pt-6 border-t border-gray-100\">\n <Button\n variant=\"ghost\"\n onClick={() => setShowEditDialog(false)}\n className=\"flex-1 h-11 rounded-xl hover:bg-gray-100 transition-all duration-200 font-medium\"\n >\n 取消\n </Button>\n <Button\n onClick={handleSaveName}\n disabled={!newThreadName.trim()}\n className=\"flex-1 h-11 rounded-xl disabled:from-gray-300 disabled:to-gray-300 disabled:cursor-not-allowed shadow-md hover:shadow-lg transition-all duration-200 font-medium\"\n >\n 保存更改\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <button\n className={cn(\n 'flex items-center justify-center h-8 w-8 rounded-full hover:bg-gray-100 transition-colors',\n className,\n )}\n aria-label={`线程 ${threadId} 选项`}\n type=\"button\"\n >\n <Ellipsis className=\"h-4 w-4 text-[#808388]\" />\n </button>\n </DropdownMenuTrigger>\n <DropdownMenuContent\n align=\"end\"\n className=\"bg-white py-[8px] px-[6px] rounded-[8px]\"\n >\n <DropdownMenuItem\n disabled={threadList.length === 1}\n className={cn(\n 'cursor-pointer flex items-center hover:bg-[rgba(46,50,56,0.05)] px-2 py-1 rounded-[4px]',\n {\n 'cursor-not-allowed text-[#808388] opacity-50':\n threadList.length === 1,\n },\n )}\n onClick={(e: React.MouseEvent<HTMLDivElement>) => {\n e.stopPropagation();\n if (threadList.length === 1) {\n return;\n }\n handleDelete();\n }}\n >\n <Trash2 className=\"mr-2 h-4 w-4\" />\n <span className=\"mr-4\">删除会话</span>\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </>\n );\n};\n\nexport default ThreadOptionsMenu;\n"],"names":["_jsxs","_Fragment","_jsx"],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
+
var dialog = require('../ui/dialog.cjs');
|
|
5
|
+
var button = require('../ui/button.cjs');
|
|
6
|
+
var circleAlert = require('../../node_modules/.pnpm/lucide-react@0.552.0_react@17.0.2/node_modules/lucide-react/dist/esm/icons/circle-alert.cjs');
|
|
7
|
+
|
|
8
|
+
const WarningModal = ({ open, onOpenChange, title = '确认删除会话吗?', content = '此操作无法撤销,删除后将不可恢复。', onConfirm, confirmText = '删除', cancelText = '取消', }) => {
|
|
9
|
+
return (jsxRuntime.jsx(dialog.Dialog, { open: open, onOpenChange: onOpenChange, children: jsxRuntime.jsxs(dialog.DialogContent, { className: "sm:max-w-[425px]", children: [jsxRuntime.jsx(dialog.DialogHeader, { children: jsxRuntime.jsxs(dialog.DialogTitle, { className: "flex items-center gap-2 text-xl", children: [jsxRuntime.jsx(circleAlert.default, { className: "size-8 text-white fill-amber-500" }), jsxRuntime.jsx("span", { children: title })] }) }), jsxRuntime.jsx("div", { className: "py-3", children: jsxRuntime.jsx("p", { className: "text-muted-foreground", children: content }) }), jsxRuntime.jsxs(dialog.DialogFooter, { children: [jsxRuntime.jsx(button.Button, { variant: "outline", onClick: () => onOpenChange(false), children: cancelText }), jsxRuntime.jsx(button.Button, { variant: "outline", className: "bg-[#D7312A] text-white", onClick: onConfirm, children: confirmText })] })] }) }));
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
exports.WarningModal = WarningModal;
|
|
13
|
+
//# sourceMappingURL=WarningModal.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WarningModal.cjs","sources":["../../../src/components/assistant-ui/WarningModal.tsx"],"sourcesContent":["import React from 'react';\nimport {\n Dialog,\n DialogContent,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n} from '@/components/ui/dialog';\nimport { Button } from '@/components/ui/button';\nimport { AlertCircle } from 'lucide-react';\n\ninterface WarningModalProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n title?: string;\n content?: string;\n onConfirm: () => void;\n confirmText?: string;\n cancelText?: string;\n}\n\nexport const WarningModal = ({\n open,\n onOpenChange,\n title = '确认删除会话吗?',\n content = '此操作无法撤销,删除后将不可恢复。',\n onConfirm,\n confirmText = '删除',\n cancelText = '取消',\n}: WarningModalProps) => {\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent className=\"sm:max-w-[425px]\">\n <DialogHeader>\n <DialogTitle className=\"flex items-center gap-2 text-xl\">\n <AlertCircle className=\"size-8 text-white fill-amber-500\" />\n <span>{title}</span>\n </DialogTitle>\n </DialogHeader>\n <div className=\"py-3\">\n <p className=\"text-muted-foreground\">{content}</p>\n </div>\n <DialogFooter>\n <Button variant=\"outline\" onClick={() => onOpenChange(false)}>\n {cancelText}\n </Button>\n <Button\n variant=\"outline\"\n className=\"bg-[#D7312A] text-white\"\n onClick={onConfirm}\n >\n {confirmText}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n );\n};\n"],"names":["_jsx","Dialog","_jsxs","DialogContent","DialogHeader","DialogTitle","AlertCircle","DialogFooter","Button"],"mappings":";;;;;;;AAqBO,MAAM,YAAY,GAAG,CAAC,EAC3B,IAAI,EACJ,YAAY,EACZ,KAAK,GAAG,UAAU,EAClB,OAAO,GAAG,mBAAmB,EAC7B,SAAS,EACT,WAAW,GAAG,IAAI,EAClB,UAAU,GAAG,IAAI,GACC,KAAI;IACtB,QACEA,eAACC,aAAM,EAAA,EAAC,IAAI,EAAE,IAAI,EAAE,YAAY,EAAE,YAAY,YAC5CC,eAAC,CAAAC,oBAAa,IAAC,SAAS,EAAC,kBAAkB,EACzC,QAAA,EAAA,CAAAH,cAAA,CAACI,mBAAY,EAAA,EAAA,QAAA,EACXF,eAAC,CAAAG,kBAAW,IAAC,SAAS,EAAC,iCAAiC,EACtD,QAAA,EAAA,CAAAL,cAAA,CAACM,mBAAW,EAAC,EAAA,SAAS,EAAC,kCAAkC,EAAG,CAAA,EAC5DN,mCAAO,KAAK,EAAA,CAAQ,IACR,EACD,CAAA,EACfA,wBAAK,SAAS,EAAC,MAAM,EAAA,QAAA,EACnBA,cAAG,CAAA,GAAA,EAAA,EAAA,SAAS,EAAC,uBAAuB,EAAA,QAAA,EAAE,OAAO,EAAK,CAAA,EAAA,CAC9C,EACNE,eAAC,CAAAK,mBAAY,EACX,EAAA,QAAA,EAAA,CAAAP,cAAA,CAACQ,aAAM,EAAA,EAAC,OAAO,EAAC,SAAS,EAAC,OAAO,EAAE,MAAM,YAAY,CAAC,KAAK,CAAC,YACzD,UAAU,EAAA,CACJ,EACTR,cAAC,CAAAQ,aAAM,IACL,OAAO,EAAC,SAAS,EACjB,SAAS,EAAC,yBAAyB,EACnC,OAAO,EAAE,SAAS,EAEjB,QAAA,EAAA,WAAW,GACL,CACI,EAAA,CAAA,CAAA,EAAA,CACD,EACT,CAAA,EACT;AACJ;;;;"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
interface WarningModalProps {
|
|
2
|
+
open: boolean;
|
|
3
|
+
onOpenChange: (open: boolean) => void;
|
|
4
|
+
title?: string;
|
|
5
|
+
content?: string;
|
|
6
|
+
onConfirm: () => void;
|
|
7
|
+
confirmText?: string;
|
|
8
|
+
cancelText?: string;
|
|
9
|
+
}
|
|
10
|
+
export declare const WarningModal: ({ open, onOpenChange, title, content, onConfirm, confirmText, cancelText, }: WarningModalProps) => JSX.Element;
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=WarningModal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WarningModal.d.ts","sourceRoot":"","sources":["../../../src/components/assistant-ui/WarningModal.tsx"],"names":[],"mappings":"AAWA,UAAU,iBAAiB;IACzB,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACtC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,eAAO,MAAM,YAAY,GAAI,6EAQ1B,iBAAiB,gBA4BnB,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
|
+
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from '../ui/dialog.js';
|
|
3
|
+
import { Button } from '../ui/button.js';
|
|
4
|
+
import CircleAlert from '../../node_modules/.pnpm/lucide-react@0.552.0_react@17.0.2/node_modules/lucide-react/dist/esm/icons/circle-alert.js';
|
|
5
|
+
|
|
6
|
+
const WarningModal = ({ open, onOpenChange, title = '确认删除会话吗?', content = '此操作无法撤销,删除后将不可恢复。', onConfirm, confirmText = '删除', cancelText = '取消', }) => {
|
|
7
|
+
return (jsx(Dialog, { open: open, onOpenChange: onOpenChange, children: jsxs(DialogContent, { className: "sm:max-w-[425px]", children: [jsx(DialogHeader, { children: jsxs(DialogTitle, { className: "flex items-center gap-2 text-xl", children: [jsx(CircleAlert, { className: "size-8 text-white fill-amber-500" }), jsx("span", { children: title })] }) }), jsx("div", { className: "py-3", children: jsx("p", { className: "text-muted-foreground", children: content }) }), jsxs(DialogFooter, { children: [jsx(Button, { variant: "outline", onClick: () => onOpenChange(false), children: cancelText }), jsx(Button, { variant: "outline", className: "bg-[#D7312A] text-white", onClick: onConfirm, children: confirmText })] })] }) }));
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export { WarningModal };
|
|
11
|
+
//# sourceMappingURL=WarningModal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WarningModal.js","sources":["../../../src/components/assistant-ui/WarningModal.tsx"],"sourcesContent":["import React from 'react';\nimport {\n Dialog,\n DialogContent,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n} from '@/components/ui/dialog';\nimport { Button } from '@/components/ui/button';\nimport { AlertCircle } from 'lucide-react';\n\ninterface WarningModalProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n title?: string;\n content?: string;\n onConfirm: () => void;\n confirmText?: string;\n cancelText?: string;\n}\n\nexport const WarningModal = ({\n open,\n onOpenChange,\n title = '确认删除会话吗?',\n content = '此操作无法撤销,删除后将不可恢复。',\n onConfirm,\n confirmText = '删除',\n cancelText = '取消',\n}: WarningModalProps) => {\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent className=\"sm:max-w-[425px]\">\n <DialogHeader>\n <DialogTitle className=\"flex items-center gap-2 text-xl\">\n <AlertCircle className=\"size-8 text-white fill-amber-500\" />\n <span>{title}</span>\n </DialogTitle>\n </DialogHeader>\n <div className=\"py-3\">\n <p className=\"text-muted-foreground\">{content}</p>\n </div>\n <DialogFooter>\n <Button variant=\"outline\" onClick={() => onOpenChange(false)}>\n {cancelText}\n </Button>\n <Button\n variant=\"outline\"\n className=\"bg-[#D7312A] text-white\"\n onClick={onConfirm}\n >\n {confirmText}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n );\n};\n"],"names":["_jsx","_jsxs","AlertCircle"],"mappings":";;;;;AAqBO,MAAM,YAAY,GAAG,CAAC,EAC3B,IAAI,EACJ,YAAY,EACZ,KAAK,GAAG,UAAU,EAClB,OAAO,GAAG,mBAAmB,EAC7B,SAAS,EACT,WAAW,GAAG,IAAI,EAClB,UAAU,GAAG,IAAI,GACC,KAAI;IACtB,QACEA,IAAC,MAAM,EAAA,EAAC,IAAI,EAAE,IAAI,EAAE,YAAY,EAAE,YAAY,YAC5CC,IAAC,CAAA,aAAa,IAAC,SAAS,EAAC,kBAAkB,EACzC,QAAA,EAAA,CAAAD,GAAA,CAAC,YAAY,EAAA,EAAA,QAAA,EACXC,IAAC,CAAA,WAAW,IAAC,SAAS,EAAC,iCAAiC,EACtD,QAAA,EAAA,CAAAD,GAAA,CAACE,WAAW,EAAC,EAAA,SAAS,EAAC,kCAAkC,EAAG,CAAA,EAC5DF,wBAAO,KAAK,EAAA,CAAQ,IACR,EACD,CAAA,EACfA,aAAK,SAAS,EAAC,MAAM,EAAA,QAAA,EACnBA,GAAG,CAAA,GAAA,EAAA,EAAA,SAAS,EAAC,uBAAuB,EAAA,QAAA,EAAE,OAAO,EAAK,CAAA,EAAA,CAC9C,EACNC,IAAC,CAAA,YAAY,EACX,EAAA,QAAA,EAAA,CAAAD,GAAA,CAAC,MAAM,EAAA,EAAC,OAAO,EAAC,SAAS,EAAC,OAAO,EAAE,MAAM,YAAY,CAAC,KAAK,CAAC,YACzD,UAAU,EAAA,CACJ,EACTA,GAAC,CAAA,MAAM,IACL,OAAO,EAAC,SAAS,EACjB,SAAS,EAAC,yBAAyB,EACnC,OAAO,EAAE,SAAS,EAEjB,QAAA,EAAA,WAAW,GACL,CACI,EAAA,CAAA,CAAA,EAAA,CACD,EACT,CAAA,EACT;AACJ;;;;"}
|
|
@@ -89,7 +89,7 @@ const ThreadList = () => {
|
|
|
89
89
|
ref?.setCurrentThread(threadId);
|
|
90
90
|
// 这里可以添加线程切换的逻辑
|
|
91
91
|
};
|
|
92
|
-
return (jsxRuntime.jsx("div", { className: "bg-[#F6F8FA]", children: jsxRuntime.jsxs("div", { className: "flex flex-col h-full w-[
|
|
92
|
+
return (jsxRuntime.jsx("div", { className: "bg-[#F6F8FA]", children: jsxRuntime.jsxs("div", { className: "flex flex-col h-full w-[200px]", children: [jsxRuntime.jsx("div", { className: "flex items-center justify-between py-[12px] px-[15px]", children: jsxRuntime.jsx("div", { className: "flex items-center gap-2", children: jsxRuntime.jsx("h2", { className: "text-[16px] font-semibold", children: "Session" }) }) }), jsxRuntime.jsx("div", { className: "flex-1 overflow-y-auto scrollbar-thin", children: threadGroups.map(group => (jsxRuntime.jsxs("div", { className: "mb-3", children: [jsxRuntime.jsx("div", { className: "pl-[16px] h-[24px] text-[#808388] leading-[22px] mb-[4px]", children: group.title }), group.threads.map(thread => (jsxRuntime.jsx("div", { onClick: () => handleThreadClick(thread.id), className: utils.cn('flex items-center justify-between p-3 cursor-pointer transition-colors m-[4px]', currentThread?.id === thread.id
|
|
93
93
|
? 'rounded-[10px] border bg-[#EBF1FF] border-[#1664FF1A]'
|
|
94
94
|
: 'hover:bg-gray-50 border border-transparent'), children: jsxRuntime.jsxs("div", { className: "flex-1 min-w-0", children: [jsxRuntime.jsxs("div", { className: "flex justify-between items-center mb-1", children: [jsxRuntime.jsx("h3", { className: utils.cn('font-medium truncate leading-[22px]', currentThread?.id === thread.id
|
|
95
95
|
? 'text-[#1664FF]'
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"thread-list.cjs","sources":["../../src/components/thread-list.tsx"],"sourcesContent":["import React, { useMemo, useState } from 'react';\nimport dayjs from 'dayjs';\nimport { MoreHorizontal } from 'lucide-react';\nimport { cn } from '@/lib/utils';\nimport ThreadOptionsMenu from './ThreadOptionsMenu';\nimport { useChatkitRef } from '@/contexts/ChatkitContext';\nimport useThread from '@/hooks/useThread';\nimport { Thread } from '@chat-lab/core';\n\n// 定义线程组类型\ninterface ThreadGroup {\n id: string;\n title: string;\n threads: Thread[];\n}\n\nconst ThreadList = () => {\n // 状态管理\n const ref = useChatkitRef();\n const { currentThread, threadList } = useThread();\n\n const threadGroups: ThreadGroup[] = useMemo(() => {\n if (!threadList || threadList.length === 0) {\n return [];\n }\n\n const sortedThreads = [...(threadList as Thread[])].sort((a, b) => {\n const timeA = a.updatedAt || a.createdAt || 0;\n const timeB = b.updatedAt || b.createdAt || 0;\n return timeB - timeA;\n });\n\n const groups: { [key: string]: Thread[] } = {};\n const groupOrder: string[] = [];\n\n sortedThreads.forEach(thread => {\n const timestamp = thread.updatedAt || thread.createdAt || 0;\n const threadDate = dayjs.unix(timestamp);\n const today = dayjs().startOf('day');\n const yesterday = dayjs().subtract(1, 'day').startOf('day');\n\n let groupTitle: string;\n\n if (threadDate.isSame(today, 'day')) {\n groupTitle = '今天';\n } else if (threadDate.isSame(yesterday, 'day')) {\n groupTitle = '昨天';\n } else if (threadDate.isAfter(today.subtract(7, 'day'))) {\n groupTitle = '最近7天';\n } else {\n groupTitle = threadDate.format('YYYY年MM月');\n }\n\n if (!groups[groupTitle]) {\n groups[groupTitle] = [];\n groupOrder.push(groupTitle);\n }\n groups[groupTitle].push(thread);\n });\n\n // 确保分组顺序\n const groupTitleOrder = ['今天', '昨天', '最近7天'];\n const sortedGroupOrder = groupOrder.sort((a, b) => {\n const indexA = groupTitleOrder.indexOf(a);\n const indexB = groupTitleOrder.indexOf(b);\n if (indexA !== -1 && indexB !== -1) return indexA - indexB;\n if (indexA !== -1) return -1;\n if (indexB !== -1) return 1;\n return b.localeCompare(a);\n });\n\n return sortedGroupOrder.map(groupTitle => ({\n id: groupTitle,\n title: groupTitle,\n threads: groups[groupTitle],\n }));\n }, [threadList]);\n\n const formatTime = (timestamp?: number) => {\n if (!timestamp) return '';\n\n const date = dayjs.unix(timestamp);\n const now = dayjs();\n\n if (date.isSame(now, 'day')) {\n return date.format('HH:mm');\n } else if (date.isSame(now.subtract(1, 'day'), 'day')) {\n return `昨天`;\n } else if (date.isSame(now, 'year')) {\n return date.format('MM-DD');\n } else {\n return date.format('YYYY-MM-DD');\n }\n };\n\n // 处理线程点击\n const handleThreadClick = (threadId: string) => {\n ref?.setCurrentThread(threadId);\n // 这里可以添加线程切换的逻辑\n };\n\n // 处理新建线程\n const handleNewThread = () => {\n // 这里可以添加新建线程的逻辑\n ref?.addThread({\n id: `thread-${Date.now()}`,\n name: '新对话',\n sending: false,\n metadata: {},\n messages: [],\n createdAt: dayjs().unix(),\n });\n };\n\n return (\n <div className=\"bg-[#F6F8FA]\">\n <div className=\"flex flex-col h-full w-[240px]\">\n {/* 头部 */}\n <div className=\"flex items-center justify-between py-[12px] px-[15px]\">\n <div className=\"flex items-center gap-2\">\n <h2 className=\"text-lg font-semibold\">ChatKit</h2>\n </div>\n </div>\n\n {/* 线程列表 */}\n <div className=\"flex-1 overflow-y-auto scrollbar-thin\">\n {threadGroups.map(group => (\n <div key={group.id} className=\"mb-3\">\n <div className=\"pl-[16px] h-[24px] text-[#808388] leading-[22px] mb-[4px]\">\n {group.title}\n </div>\n {group.threads.map(thread => (\n <div\n key={thread.id}\n onClick={() => handleThreadClick(thread.id)}\n className={cn(\n 'flex items-center justify-between p-3 cursor-pointer transition-colors m-[4px]',\n currentThread?.id === thread.id\n ? 'rounded-[10px] border bg-[#EBF1FF] border-[#1664FF1A]'\n : 'hover:bg-gray-50 border border-transparent',\n )}\n >\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex justify-between items-center mb-1\">\n <h3\n className={cn(\n 'font-medium truncate leading-[22px]',\n currentThread?.id === thread.id\n ? 'text-[#1664FF]'\n : 'text-gray-900',\n )}\n >\n {thread.name || '新对话'}\n </h3>\n <ThreadOptionsMenu\n className=\"flex-shrink-0\"\n threadId={thread.id}\n />\n </div>\n <p className=\"text-xs text-[#808388]\">\n {formatTime(thread.updatedAt || thread.createdAt)}\n </p>\n </div>\n </div>\n ))}\n </div>\n ))}\n </div>\n </div>\n </div>\n );\n};\n\nexport default ThreadList;\n"],"names":["useChatkitRef","useMemo","dayjs","_jsx","_jsxs","cn"],"mappings":";;;;;;;;;;AAgBM,MAAA,UAAU,GAAG,MAAK;;AAEtB,IAAA,MAAM,GAAG,GAAGA,4BAAa,EAAE,CAAC;IAC5B,MAAM,EAAE,aAAa,EAAE,UAAU,EAAE,GAAG,SAAS,EAAE,CAAC;AAElD,IAAA,MAAM,YAAY,GAAkBC,aAAO,CAAC,MAAK;QAC/C,IAAI,CAAC,UAAU,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE;AAC1C,YAAA,OAAO,EAAE,CAAC;SACX;AAED,QAAA,MAAM,aAAa,GAAG,CAAC,GAAI,UAAuB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,KAAI;YAChE,MAAM,KAAK,GAAG,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC;YAC9C,MAAM,KAAK,GAAG,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC;YAC9C,OAAO,KAAK,GAAG,KAAK,CAAC;AACvB,SAAC,CAAC,CAAC;QAEH,MAAM,MAAM,GAAgC,EAAE,CAAC;QAC/C,MAAM,UAAU,GAAa,EAAE,CAAC;AAEhC,QAAA,aAAa,CAAC,OAAO,CAAC,MAAM,IAAG;YAC7B,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,IAAI,MAAM,CAAC,SAAS,IAAI,CAAC,CAAC;YAC5D,MAAM,UAAU,GAAGC,SAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACzC,MAAM,KAAK,GAAGA,SAAK,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AACrC,YAAA,MAAM,SAAS,GAAGA,SAAK,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAE5D,YAAA,IAAI,UAAkB,CAAC;YAEvB,IAAI,UAAU,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE;gBACnC,UAAU,GAAG,IAAI,CAAC;aACnB;iBAAM,IAAI,UAAU,CAAC,MAAM,CAAC,SAAS,EAAE,KAAK,CAAC,EAAE;gBAC9C,UAAU,GAAG,IAAI,CAAC;aACnB;AAAM,iBAAA,IAAI,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE;gBACvD,UAAU,GAAG,MAAM,CAAC;aACrB;iBAAM;AACL,gBAAA,UAAU,GAAG,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;aAC5C;AAED,YAAA,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE;AACvB,gBAAA,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC;AACxB,gBAAA,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;aAC7B;YACD,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AAClC,SAAC,CAAC,CAAC;;QAGH,MAAM,eAAe,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;QAC7C,MAAM,gBAAgB,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,KAAI;YAChD,MAAM,MAAM,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;YAC1C,MAAM,MAAM,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;YAC1C,IAAI,MAAM,KAAK,CAAC,CAAC,IAAI,MAAM,KAAK,CAAC,CAAC;gBAAE,OAAO,MAAM,GAAG,MAAM,CAAC;YAC3D,IAAI,MAAM,KAAK,CAAC,CAAC;gBAAE,OAAO,CAAC,CAAC,CAAC;YAC7B,IAAI,MAAM,KAAK,CAAC,CAAC;AAAE,gBAAA,OAAO,CAAC,CAAC;AAC5B,YAAA,OAAO,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;AAC5B,SAAC,CAAC,CAAC;QAEH,OAAO,gBAAgB,CAAC,GAAG,CAAC,UAAU,KAAK;AACzC,YAAA,EAAE,EAAE,UAAU;AACd,YAAA,KAAK,EAAE,UAAU;AACjB,YAAA,OAAO,EAAE,MAAM,CAAC,UAAU,CAAC;AAC5B,SAAA,CAAC,CAAC,CAAC;AACN,KAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;AAEjB,IAAA,MAAM,UAAU,GAAG,CAAC,SAAkB,KAAI;AACxC,QAAA,IAAI,CAAC,SAAS;AAAE,YAAA,OAAO,EAAE,CAAC;QAE1B,MAAM,IAAI,GAAGA,SAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;AACnC,QAAA,MAAM,GAAG,GAAGA,SAAK,EAAE,CAAC;QAEpB,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE;AAC3B,YAAA,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;SAC7B;AAAM,aAAA,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,KAAK,CAAC,EAAE;AACrD,YAAA,OAAO,IAAI,CAAC;SACb;aAAM,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE;AACnC,YAAA,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;SAC7B;aAAM;AACL,YAAA,OAAO,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;SAClC;AACH,KAAC,CAAC;;AAGF,IAAA,MAAM,iBAAiB,GAAG,CAAC,QAAgB,KAAI;AAC7C,QAAA,GAAG,EAAE,gBAAgB,CAAC,QAAQ,CAAC,CAAC;;AAElC,KAAC,CAAC;IAeF,QACEC,wBAAK,SAAS,EAAC,cAAc,EAC3B,QAAA,EAAAC,eAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,gCAAgC,aAE7CD,cAAK,CAAA,KAAA,EAAA,EAAA,SAAS,EAAC,uDAAuD,EAAA,QAAA,EACpEA,wBAAK,SAAS,EAAC,yBAAyB,EACtC,QAAA,EAAAA,cAAA,CAAA,IAAA,EAAA,EAAI,SAAS,EAAC,uBAAuB,wBAAa,EAC9C,CAAA,EAAA,CACF,EAGNA,cAAK,CAAA,KAAA,EAAA,EAAA,SAAS,EAAC,uCAAuC,EAAA,QAAA,EACnD,YAAY,CAAC,GAAG,CAAC,KAAK,KACrBC,eAAoB,CAAA,KAAA,EAAA,EAAA,SAAS,EAAC,MAAM,aAClCD,cAAK,CAAA,KAAA,EAAA,EAAA,SAAS,EAAC,2DAA2D,EAAA,QAAA,EACvE,KAAK,CAAC,KAAK,GACR,EACL,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,KACvBA,cAEE,CAAA,KAAA,EAAA,EAAA,OAAO,EAAE,MAAM,iBAAiB,CAAC,MAAM,CAAC,EAAE,CAAC,EAC3C,SAAS,EAAEE,QAAE,CACX,gFAAgF,EAChF,aAAa,EAAE,EAAE,KAAK,MAAM,CAAC,EAAE;AAC7B,sCAAE,uDAAuD;sCACvD,4CAA4C,CACjD,EAED,QAAA,EAAAD,eAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,gBAAgB,EAAA,QAAA,EAAA,CAC7BA,eAAK,CAAA,KAAA,EAAA,EAAA,SAAS,EAAC,wCAAwC,EACrD,QAAA,EAAA,CAAAD,cAAA,CAAA,IAAA,EAAA,EACE,SAAS,EAAEE,QAAE,CACX,qCAAqC,EACrC,aAAa,EAAE,EAAE,KAAK,MAAM,CAAC,EAAE;AAC7B,0DAAE,gBAAgB;AAClB,0DAAE,eAAe,CACpB,EAAA,QAAA,EAEA,MAAM,CAAC,IAAI,IAAI,KAAK,EAAA,CAClB,EACLF,cAAA,CAAC,iBAAiB,EAAA,EAChB,SAAS,EAAC,eAAe,EACzB,QAAQ,EAAE,MAAM,CAAC,EAAE,EAAA,CACnB,CACE,EAAA,CAAA,EACNA,cAAG,CAAA,GAAA,EAAA,EAAA,SAAS,EAAC,wBAAwB,EAClC,QAAA,EAAA,UAAU,CAAC,MAAM,CAAC,SAAS,IAAI,MAAM,CAAC,SAAS,CAAC,EAAA,CAC/C,CACA,EAAA,CAAA,EAAA,EA7BD,MAAM,CAAC,EAAE,CA8BV,CACP,CAAC,CArCM,EAAA,EAAA,KAAK,CAAC,EAAE,CAsCZ,CACP,CAAC,EAAA,CACE,CACF,EAAA,CAAA,EAAA,CACF,EACN;AACJ;;;;"}
|
|
1
|
+
{"version":3,"file":"thread-list.cjs","sources":["../../src/components/thread-list.tsx"],"sourcesContent":["import React, { useMemo, useState } from 'react';\nimport dayjs from 'dayjs';\nimport { MoreHorizontal } from 'lucide-react';\nimport { cn } from '@/lib/utils';\nimport ThreadOptionsMenu from './ThreadOptionsMenu';\nimport { useChatkitRef } from '@/contexts/ChatkitContext';\nimport useThread from '@/hooks/useThread';\nimport { Thread } from '@chat-lab/core';\n\n// 定义线程组类型\ninterface ThreadGroup {\n id: string;\n title: string;\n threads: Thread[];\n}\n\nconst ThreadList = () => {\n // 状态管理\n const ref = useChatkitRef();\n const { currentThread, threadList } = useThread();\n\n const threadGroups: ThreadGroup[] = useMemo(() => {\n if (!threadList || threadList.length === 0) {\n return [];\n }\n\n const sortedThreads = [...(threadList as Thread[])].sort((a, b) => {\n const timeA = a.updatedAt || a.createdAt || 0;\n const timeB = b.updatedAt || b.createdAt || 0;\n return timeB - timeA;\n });\n\n const groups: { [key: string]: Thread[] } = {};\n const groupOrder: string[] = [];\n\n sortedThreads.forEach(thread => {\n const timestamp = thread.updatedAt || thread.createdAt || 0;\n const threadDate = dayjs.unix(timestamp);\n const today = dayjs().startOf('day');\n const yesterday = dayjs().subtract(1, 'day').startOf('day');\n\n let groupTitle: string;\n\n if (threadDate.isSame(today, 'day')) {\n groupTitle = '今天';\n } else if (threadDate.isSame(yesterday, 'day')) {\n groupTitle = '昨天';\n } else if (threadDate.isAfter(today.subtract(7, 'day'))) {\n groupTitle = '最近7天';\n } else {\n groupTitle = threadDate.format('YYYY年MM月');\n }\n\n if (!groups[groupTitle]) {\n groups[groupTitle] = [];\n groupOrder.push(groupTitle);\n }\n groups[groupTitle].push(thread);\n });\n\n // 确保分组顺序\n const groupTitleOrder = ['今天', '昨天', '最近7天'];\n const sortedGroupOrder = groupOrder.sort((a, b) => {\n const indexA = groupTitleOrder.indexOf(a);\n const indexB = groupTitleOrder.indexOf(b);\n if (indexA !== -1 && indexB !== -1) return indexA - indexB;\n if (indexA !== -1) return -1;\n if (indexB !== -1) return 1;\n return b.localeCompare(a);\n });\n\n return sortedGroupOrder.map(groupTitle => ({\n id: groupTitle,\n title: groupTitle,\n threads: groups[groupTitle],\n }));\n }, [threadList]);\n\n const formatTime = (timestamp?: number) => {\n if (!timestamp) return '';\n\n const date = dayjs.unix(timestamp);\n const now = dayjs();\n\n if (date.isSame(now, 'day')) {\n return date.format('HH:mm');\n } else if (date.isSame(now.subtract(1, 'day'), 'day')) {\n return `昨天`;\n } else if (date.isSame(now, 'year')) {\n return date.format('MM-DD');\n } else {\n return date.format('YYYY-MM-DD');\n }\n };\n\n // 处理线程点击\n const handleThreadClick = (threadId: string) => {\n ref?.setCurrentThread(threadId);\n // 这里可以添加线程切换的逻辑\n };\n\n // 处理新建线程\n const handleNewThread = () => {\n // 这里可以添加新建线程的逻辑\n ref?.addThread({\n id: `thread-${Date.now()}`,\n name: '新对话',\n sending: false,\n metadata: {},\n messages: [],\n createdAt: dayjs().unix(),\n });\n };\n\n return (\n <div className=\"bg-[#F6F8FA]\">\n <div className=\"flex flex-col h-full w-[200px]\">\n {/* 头部 */}\n <div className=\"flex items-center justify-between py-[12px] px-[15px]\">\n <div className=\"flex items-center gap-2\">\n <h2 className=\"text-[16px] font-semibold\">Session</h2>\n </div>\n </div>\n\n {/* 线程列表 */}\n <div className=\"flex-1 overflow-y-auto scrollbar-thin\">\n {threadGroups.map(group => (\n <div key={group.id} className=\"mb-3\">\n <div className=\"pl-[16px] h-[24px] text-[#808388] leading-[22px] mb-[4px]\">\n {group.title}\n </div>\n {group.threads.map(thread => (\n <div\n key={thread.id}\n onClick={() => handleThreadClick(thread.id)}\n className={cn(\n 'flex items-center justify-between p-3 cursor-pointer transition-colors m-[4px]',\n currentThread?.id === thread.id\n ? 'rounded-[10px] border bg-[#EBF1FF] border-[#1664FF1A]'\n : 'hover:bg-gray-50 border border-transparent',\n )}\n >\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex justify-between items-center mb-1\">\n <h3\n className={cn(\n 'font-medium truncate leading-[22px]',\n currentThread?.id === thread.id\n ? 'text-[#1664FF]'\n : 'text-gray-900',\n )}\n >\n {thread.name || '新对话'}\n </h3>\n <ThreadOptionsMenu\n className=\"flex-shrink-0\"\n threadId={thread.id}\n />\n </div>\n <p className=\"text-xs text-[#808388]\">\n {formatTime(thread.updatedAt || thread.createdAt)}\n </p>\n </div>\n </div>\n ))}\n </div>\n ))}\n </div>\n </div>\n </div>\n );\n};\n\nexport default ThreadList;\n"],"names":["useChatkitRef","useMemo","dayjs","_jsx","_jsxs","cn"],"mappings":"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"}
|
|
@@ -87,7 +87,7 @@ const ThreadList = () => {
|
|
|
87
87
|
ref?.setCurrentThread(threadId);
|
|
88
88
|
// 这里可以添加线程切换的逻辑
|
|
89
89
|
};
|
|
90
|
-
return (jsx("div", { className: "bg-[#F6F8FA]", children: jsxs("div", { className: "flex flex-col h-full w-[
|
|
90
|
+
return (jsx("div", { className: "bg-[#F6F8FA]", children: jsxs("div", { className: "flex flex-col h-full w-[200px]", children: [jsx("div", { className: "flex items-center justify-between py-[12px] px-[15px]", children: jsx("div", { className: "flex items-center gap-2", children: jsx("h2", { className: "text-[16px] font-semibold", children: "Session" }) }) }), jsx("div", { className: "flex-1 overflow-y-auto scrollbar-thin", children: threadGroups.map(group => (jsxs("div", { className: "mb-3", children: [jsx("div", { className: "pl-[16px] h-[24px] text-[#808388] leading-[22px] mb-[4px]", children: group.title }), group.threads.map(thread => (jsx("div", { onClick: () => handleThreadClick(thread.id), className: cn('flex items-center justify-between p-3 cursor-pointer transition-colors m-[4px]', currentThread?.id === thread.id
|
|
91
91
|
? 'rounded-[10px] border bg-[#EBF1FF] border-[#1664FF1A]'
|
|
92
92
|
: 'hover:bg-gray-50 border border-transparent'), children: jsxs("div", { className: "flex-1 min-w-0", children: [jsxs("div", { className: "flex justify-between items-center mb-1", children: [jsx("h3", { className: cn('font-medium truncate leading-[22px]', currentThread?.id === thread.id
|
|
93
93
|
? 'text-[#1664FF]'
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"thread-list.js","sources":["../../src/components/thread-list.tsx"],"sourcesContent":["import React, { useMemo, useState } from 'react';\nimport dayjs from 'dayjs';\nimport { MoreHorizontal } from 'lucide-react';\nimport { cn } from '@/lib/utils';\nimport ThreadOptionsMenu from './ThreadOptionsMenu';\nimport { useChatkitRef } from '@/contexts/ChatkitContext';\nimport useThread from '@/hooks/useThread';\nimport { Thread } from '@chat-lab/core';\n\n// 定义线程组类型\ninterface ThreadGroup {\n id: string;\n title: string;\n threads: Thread[];\n}\n\nconst ThreadList = () => {\n // 状态管理\n const ref = useChatkitRef();\n const { currentThread, threadList } = useThread();\n\n const threadGroups: ThreadGroup[] = useMemo(() => {\n if (!threadList || threadList.length === 0) {\n return [];\n }\n\n const sortedThreads = [...(threadList as Thread[])].sort((a, b) => {\n const timeA = a.updatedAt || a.createdAt || 0;\n const timeB = b.updatedAt || b.createdAt || 0;\n return timeB - timeA;\n });\n\n const groups: { [key: string]: Thread[] } = {};\n const groupOrder: string[] = [];\n\n sortedThreads.forEach(thread => {\n const timestamp = thread.updatedAt || thread.createdAt || 0;\n const threadDate = dayjs.unix(timestamp);\n const today = dayjs().startOf('day');\n const yesterday = dayjs().subtract(1, 'day').startOf('day');\n\n let groupTitle: string;\n\n if (threadDate.isSame(today, 'day')) {\n groupTitle = '今天';\n } else if (threadDate.isSame(yesterday, 'day')) {\n groupTitle = '昨天';\n } else if (threadDate.isAfter(today.subtract(7, 'day'))) {\n groupTitle = '最近7天';\n } else {\n groupTitle = threadDate.format('YYYY年MM月');\n }\n\n if (!groups[groupTitle]) {\n groups[groupTitle] = [];\n groupOrder.push(groupTitle);\n }\n groups[groupTitle].push(thread);\n });\n\n // 确保分组顺序\n const groupTitleOrder = ['今天', '昨天', '最近7天'];\n const sortedGroupOrder = groupOrder.sort((a, b) => {\n const indexA = groupTitleOrder.indexOf(a);\n const indexB = groupTitleOrder.indexOf(b);\n if (indexA !== -1 && indexB !== -1) return indexA - indexB;\n if (indexA !== -1) return -1;\n if (indexB !== -1) return 1;\n return b.localeCompare(a);\n });\n\n return sortedGroupOrder.map(groupTitle => ({\n id: groupTitle,\n title: groupTitle,\n threads: groups[groupTitle],\n }));\n }, [threadList]);\n\n const formatTime = (timestamp?: number) => {\n if (!timestamp) return '';\n\n const date = dayjs.unix(timestamp);\n const now = dayjs();\n\n if (date.isSame(now, 'day')) {\n return date.format('HH:mm');\n } else if (date.isSame(now.subtract(1, 'day'), 'day')) {\n return `昨天`;\n } else if (date.isSame(now, 'year')) {\n return date.format('MM-DD');\n } else {\n return date.format('YYYY-MM-DD');\n }\n };\n\n // 处理线程点击\n const handleThreadClick = (threadId: string) => {\n ref?.setCurrentThread(threadId);\n // 这里可以添加线程切换的逻辑\n };\n\n // 处理新建线程\n const handleNewThread = () => {\n // 这里可以添加新建线程的逻辑\n ref?.addThread({\n id: `thread-${Date.now()}`,\n name: '新对话',\n sending: false,\n metadata: {},\n messages: [],\n createdAt: dayjs().unix(),\n });\n };\n\n return (\n <div className=\"bg-[#F6F8FA]\">\n <div className=\"flex flex-col h-full w-[240px]\">\n {/* 头部 */}\n <div className=\"flex items-center justify-between py-[12px] px-[15px]\">\n <div className=\"flex items-center gap-2\">\n <h2 className=\"text-lg font-semibold\">ChatKit</h2>\n </div>\n </div>\n\n {/* 线程列表 */}\n <div className=\"flex-1 overflow-y-auto scrollbar-thin\">\n {threadGroups.map(group => (\n <div key={group.id} className=\"mb-3\">\n <div className=\"pl-[16px] h-[24px] text-[#808388] leading-[22px] mb-[4px]\">\n {group.title}\n </div>\n {group.threads.map(thread => (\n <div\n key={thread.id}\n onClick={() => handleThreadClick(thread.id)}\n className={cn(\n 'flex items-center justify-between p-3 cursor-pointer transition-colors m-[4px]',\n currentThread?.id === thread.id\n ? 'rounded-[10px] border bg-[#EBF1FF] border-[#1664FF1A]'\n : 'hover:bg-gray-50 border border-transparent',\n )}\n >\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex justify-between items-center mb-1\">\n <h3\n className={cn(\n 'font-medium truncate leading-[22px]',\n currentThread?.id === thread.id\n ? 'text-[#1664FF]'\n : 'text-gray-900',\n )}\n >\n {thread.name || '新对话'}\n </h3>\n <ThreadOptionsMenu\n className=\"flex-shrink-0\"\n threadId={thread.id}\n />\n </div>\n <p className=\"text-xs text-[#808388]\">\n {formatTime(thread.updatedAt || thread.createdAt)}\n </p>\n </div>\n </div>\n ))}\n </div>\n ))}\n </div>\n </div>\n </div>\n );\n};\n\nexport default ThreadList;\n"],"names":["_jsx","_jsxs"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"thread-list.js","sources":["../../src/components/thread-list.tsx"],"sourcesContent":["import React, { useMemo, useState } from 'react';\nimport dayjs from 'dayjs';\nimport { MoreHorizontal } from 'lucide-react';\nimport { cn } from '@/lib/utils';\nimport ThreadOptionsMenu from './ThreadOptionsMenu';\nimport { useChatkitRef } from '@/contexts/ChatkitContext';\nimport useThread from '@/hooks/useThread';\nimport { Thread } from '@chat-lab/core';\n\n// 定义线程组类型\ninterface ThreadGroup {\n id: string;\n title: string;\n threads: Thread[];\n}\n\nconst ThreadList = () => {\n // 状态管理\n const ref = useChatkitRef();\n const { currentThread, threadList } = useThread();\n\n const threadGroups: ThreadGroup[] = useMemo(() => {\n if (!threadList || threadList.length === 0) {\n return [];\n }\n\n const sortedThreads = [...(threadList as Thread[])].sort((a, b) => {\n const timeA = a.updatedAt || a.createdAt || 0;\n const timeB = b.updatedAt || b.createdAt || 0;\n return timeB - timeA;\n });\n\n const groups: { [key: string]: Thread[] } = {};\n const groupOrder: string[] = [];\n\n sortedThreads.forEach(thread => {\n const timestamp = thread.updatedAt || thread.createdAt || 0;\n const threadDate = dayjs.unix(timestamp);\n const today = dayjs().startOf('day');\n const yesterday = dayjs().subtract(1, 'day').startOf('day');\n\n let groupTitle: string;\n\n if (threadDate.isSame(today, 'day')) {\n groupTitle = '今天';\n } else if (threadDate.isSame(yesterday, 'day')) {\n groupTitle = '昨天';\n } else if (threadDate.isAfter(today.subtract(7, 'day'))) {\n groupTitle = '最近7天';\n } else {\n groupTitle = threadDate.format('YYYY年MM月');\n }\n\n if (!groups[groupTitle]) {\n groups[groupTitle] = [];\n groupOrder.push(groupTitle);\n }\n groups[groupTitle].push(thread);\n });\n\n // 确保分组顺序\n const groupTitleOrder = ['今天', '昨天', '最近7天'];\n const sortedGroupOrder = groupOrder.sort((a, b) => {\n const indexA = groupTitleOrder.indexOf(a);\n const indexB = groupTitleOrder.indexOf(b);\n if (indexA !== -1 && indexB !== -1) return indexA - indexB;\n if (indexA !== -1) return -1;\n if (indexB !== -1) return 1;\n return b.localeCompare(a);\n });\n\n return sortedGroupOrder.map(groupTitle => ({\n id: groupTitle,\n title: groupTitle,\n threads: groups[groupTitle],\n }));\n }, [threadList]);\n\n const formatTime = (timestamp?: number) => {\n if (!timestamp) return '';\n\n const date = dayjs.unix(timestamp);\n const now = dayjs();\n\n if (date.isSame(now, 'day')) {\n return date.format('HH:mm');\n } else if (date.isSame(now.subtract(1, 'day'), 'day')) {\n return `昨天`;\n } else if (date.isSame(now, 'year')) {\n return date.format('MM-DD');\n } else {\n return date.format('YYYY-MM-DD');\n }\n };\n\n // 处理线程点击\n const handleThreadClick = (threadId: string) => {\n ref?.setCurrentThread(threadId);\n // 这里可以添加线程切换的逻辑\n };\n\n // 处理新建线程\n const handleNewThread = () => {\n // 这里可以添加新建线程的逻辑\n ref?.addThread({\n id: `thread-${Date.now()}`,\n name: '新对话',\n sending: false,\n metadata: {},\n messages: [],\n createdAt: dayjs().unix(),\n });\n };\n\n return (\n <div className=\"bg-[#F6F8FA]\">\n <div className=\"flex flex-col h-full w-[200px]\">\n {/* 头部 */}\n <div className=\"flex items-center justify-between py-[12px] px-[15px]\">\n <div className=\"flex items-center gap-2\">\n <h2 className=\"text-[16px] font-semibold\">Session</h2>\n </div>\n </div>\n\n {/* 线程列表 */}\n <div className=\"flex-1 overflow-y-auto scrollbar-thin\">\n {threadGroups.map(group => (\n <div key={group.id} className=\"mb-3\">\n <div className=\"pl-[16px] h-[24px] text-[#808388] leading-[22px] mb-[4px]\">\n {group.title}\n </div>\n {group.threads.map(thread => (\n <div\n key={thread.id}\n onClick={() => handleThreadClick(thread.id)}\n className={cn(\n 'flex items-center justify-between p-3 cursor-pointer transition-colors m-[4px]',\n currentThread?.id === thread.id\n ? 'rounded-[10px] border bg-[#EBF1FF] border-[#1664FF1A]'\n : 'hover:bg-gray-50 border border-transparent',\n )}\n >\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex justify-between items-center mb-1\">\n <h3\n className={cn(\n 'font-medium truncate leading-[22px]',\n currentThread?.id === thread.id\n ? 'text-[#1664FF]'\n : 'text-gray-900',\n )}\n >\n {thread.name || '新对话'}\n </h3>\n <ThreadOptionsMenu\n className=\"flex-shrink-0\"\n threadId={thread.id}\n />\n </div>\n <p className=\"text-xs text-[#808388]\">\n {formatTime(thread.updatedAt || thread.createdAt)}\n </p>\n </div>\n </div>\n ))}\n </div>\n ))}\n </div>\n </div>\n </div>\n );\n};\n\nexport default ThreadList;\n"],"names":["_jsx","_jsxs"],"mappings":"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"}
|