Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit0205c72

Browse files
committed
[Feat]: Add chat component
1 parentbf9f269 commit0205c72

File tree

8 files changed

+449
-313
lines changed

8 files changed

+449
-313
lines changed

‎client/packages/lowcoder/src/comps/comps/chatComp/chatView.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// client/packages/lowcoder/src/comps/comps/chatComp/chatView.tsx
22
importReactfrom"react";
33
import{ChatCompProps}from"./chatCompTypes";
4-
import{ChatApp}from"./components/ChatWithThreads";
4+
import{ChatApp}from"./components/ChatApp";
55

66
import"@assistant-ui/styles/index.css";
77
import"@assistant-ui/styles/markdown.css";
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import{ChatProvider}from"./context/ChatContext";
2+
import{ChatMain}from"./ChatMain";
3+
4+
exportfunctionChatApp(){
5+
return(
6+
<ChatProvider>
7+
<ChatMain/>
8+
</ChatProvider>
9+
);
10+
}
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,47 @@
1-
importReact,{useState,useEffect}from"react";
1+
importReact,{useState}from"react";
22
import{
33
useExternalStoreRuntime,
44
ThreadMessageLike,
55
AppendMessage,
66
AssistantRuntimeProvider,
77
ExternalStoreThreadListAdapter,
88
}from"@assistant-ui/react";
9-
import{useThreadContext,MyMessage,ThreadProvider}from"./context/ThreadContext";
109
import{Thread}from"./assistant-ui/thread";
1110
import{ThreadList}from"./assistant-ui/thread-list";
12-
import{chatStorage,ThreadDataasStoredThreadData}from"../utils/chatStorage";
13-
import{useChatStorage}from"../hooks/useChatStorage";
11+
import{
12+
useChatContext,
13+
MyMessage,
14+
ThreadData,
15+
RegularThreadData,
16+
ArchivedThreadData
17+
}from"./context/ChatContext";
1418
importstyledfrom"styled-components";
1519

16-
17-
18-
1920
constChatContainer=styled.div`
2021
display: flex;
2122
height: 500px;
2223
2324
.aui-thread-list-root {
2425
width: 250px;
25-
background-color: #333;
26+
background-color: #fff;
27+
padding: 10px;
2628
}
2729
2830
.aui-thread-root {
2931
flex: 1;
30-
background-color: #f0f0f0;
32+
background-color: #f9fafb;
3133
}
3234
33-
`;
34-
35-
// Define thread data interfaces to match ExternalStoreThreadData requirements
36-
interfaceRegularThreadData{
37-
threadId:string;
38-
status:"regular";
39-
title:string;
40-
}
35+
.aui-thread-list-item {
36+
cursor: pointer;
37+
transition: background-color 0.2s ease;
4138
42-
interfaceArchivedThreadData{
43-
threadId:string;
44-
status:"archived";
45-
title:string;
46-
}
47-
48-
typeThreadData=RegularThreadData|ArchivedThreadData;
39+
&[data-active="true"] {
40+
background-color: #dbeafe;
41+
border: 1px solid #bfdbfe;
42+
}
43+
}
44+
`;
4945

5046
constgenerateId=()=>Math.random().toString(36).substr(2,9);
5147

@@ -59,22 +55,14 @@ const callYourAPI = async (text: string) => {
5955
};
6056
};
6157

62-
functionChatWithThreads(){
63-
const{ currentThreadId, setCurrentThreadId, threads, setThreads}=
64-
useThreadContext();
58+
exportfunctionChatMain(){
59+
const{ state, actions}=useChatContext();
6560
const[isRunning,setIsRunning]=useState(false);
66-
const[threadList,setThreadList]=useState<ThreadData[]>([
67-
{threadId:"default",status:"regular",title:"New Chat"}asRegularThreadData,
68-
]);
69-
const{ isInitialized}=useChatStorage({
70-
threadList,
71-
threads,
72-
setThreadList,
73-
setThreads,
74-
setCurrentThreadId,
75-
});
61+
62+
console.log("STATE",state);
63+
7664
// Get messages for current thread
77-
constcurrentMessages=threads.get(currentThreadId)||[];
65+
constcurrentMessages=actions.getCurrentMessages();
7866

7967
// Convert custom format to ThreadMessageLike
8068
constconvertMessage=(message:MyMessage):ThreadMessageLike=>({
@@ -99,8 +87,7 @@ function ChatWithThreads() {
9987
};
10088

10189
// Update current thread with new user message
102-
constupdatedMessages=[...currentMessages,userMessage];
103-
setThreads(prev=>newMap(prev).set(currentThreadId,updatedMessages));
90+
awaitactions.addMessage(state.currentThreadId,userMessage);
10491
setIsRunning(true);
10592

10693
try{
@@ -115,8 +102,7 @@ function ChatWithThreads() {
115102
};
116103

117104
// Update current thread with assistant response
118-
constfinalMessages=[...updatedMessages,assistantMessage];
119-
setThreads(prev=>newMap(prev).set(currentThreadId,finalMessages));
105+
awaitactions.addMessage(state.currentThreadId,assistantMessage);
120106
}catch(error){
121107
// Handle errors gracefully
122108
consterrorMessage:MyMessage={
@@ -126,8 +112,7 @@ function ChatWithThreads() {
126112
timestamp:Date.now(),
127113
};
128114

129-
constfinalMessages=[...updatedMessages,errorMessage];
130-
setThreads(prev=>newMap(prev).set(currentThreadId,finalMessages));
115+
awaitactions.addMessage(state.currentThreadId,errorMessage);
131116
}finally{
132117
setIsRunning(false);
133118
}
@@ -155,7 +140,8 @@ function ChatWithThreads() {
155140
};
156141
newMessages.push(editedMessage);
157142

158-
setThreads(prev=>newMap(prev).set(currentThreadId,newMessages));
143+
// Update messages using the new context action
144+
awaitactions.updateMessages(state.currentThreadId,newMessages);
159145
setIsRunning(true);
160146

161147
try{
@@ -170,7 +156,7 @@ function ChatWithThreads() {
170156
};
171157

172158
newMessages.push(assistantMessage);
173-
setThreads(prev=>newMap(prev).set(currentThreadId,newMessages));
159+
awaitactions.updateMessages(state.currentThreadId,newMessages);
174160
}catch(error){
175161
// Handle errors gracefully
176162
consterrorMessage:MyMessage={
@@ -181,89 +167,44 @@ function ChatWithThreads() {
181167
};
182168

183169
newMessages.push(errorMessage);
184-
setThreads(prev=>newMap(prev).set(currentThreadId,newMessages));
170+
awaitactions.updateMessages(state.currentThreadId,newMessages);
185171
}finally{
186172
setIsRunning(false);
187173
}
188174
};
189175

190176
// Thread list adapter for managing multiple threads
191177
constthreadListAdapter:ExternalStoreThreadListAdapter={
192-
threadId:currentThreadId,
193-
threads:threadList.filter((t):t isRegularThreadData=>t.status==="regular"),
194-
archivedThreads:threadList.filter((t):t isArchivedThreadData=>t.status==="archived"),
178+
threadId:state.currentThreadId,
179+
threads:state.threadList.filter((t):t isRegularThreadData=>t.status==="regular"),
180+
archivedThreads:state.threadList.filter((t):t isArchivedThreadData=>t.status==="archived"),
195181

196182
onSwitchToNewThread:async()=>{
197-
constnewId=`thread-${Date.now()}`;
198-
constnewThread:RegularThreadData={
199-
threadId:newId,
200-
status:"regular",
201-
title:"New Chat",
202-
};
203-
204-
setThreadList((prev)=>[...prev,newThread]);
205-
setThreads((prev)=>newMap(prev).set(newId,[]));
206-
setCurrentThreadId(newId);
207-
208-
// Save new thread to storage
209-
try{
210-
conststoredThread:StoredThreadData={
211-
threadId:newId,
212-
status:"regular",
213-
title:"New Chat",
214-
createdAt:Date.now(),
215-
updatedAt:Date.now(),
216-
};
217-
awaitchatStorage.saveThread(storedThread);
218-
}catch(error){
219-
console.error("Failed to save new thread:",error);
220-
}
183+
constthreadId=awaitactions.createThread("New Chat");
184+
actions.setCurrentThread(threadId);
221185
},
222186

223187
onSwitchToThread:(threadId)=>{
224-
setCurrentThreadId(threadId);
188+
actions.setCurrentThread(threadId);
225189
},
226190

227-
onRename:(threadId,newTitle)=>{
228-
setThreadList((prev)=>
229-
prev.map((t)=>
230-
t.threadId===threadId ?{ ...t,title:newTitle} :t,
231-
),
232-
);
191+
onRename:async(threadId,newTitle)=>{
192+
awaitactions.updateThread(threadId,{title:newTitle});
233193
},
234194

235-
onArchive:(threadId)=>{
236-
setThreadList((prev)=>
237-
prev.map((t)=>
238-
t.threadId===threadId ?{ ...t,status:"archived"} :t,
239-
),
240-
);
195+
onArchive:async(threadId)=>{
196+
awaitactions.updateThread(threadId,{status:"archived"});
241197
},
242198

243199
onDelete:async(threadId)=>{
244-
setThreadList((prev)=>prev.filter((t)=>t.threadId!==threadId));
245-
setThreads((prev)=>{
246-
constnext=newMap(prev);
247-
next.delete(threadId);
248-
returnnext;
249-
});
250-
if(currentThreadId===threadId){
251-
setCurrentThreadId("default");
252-
}
253-
254-
// Delete thread from storage
255-
try{
256-
awaitchatStorage.deleteThread(threadId);
257-
}catch(error){
258-
console.error("Failed to delete thread from storage:",error);
259-
}
200+
awaitactions.deleteThread(threadId);
260201
},
261202
};
262203

263204
construntime=useExternalStoreRuntime({
264205
messages:currentMessages,
265206
setMessages:(messages)=>{
266-
setThreads((prev)=>newMap(prev).set(currentThreadId,messages));
207+
actions.updateMessages(state.currentThreadId,messages);
267208
},
268209
convertMessage,
269210
isRunning,
@@ -274,7 +215,7 @@ function ChatWithThreads() {
274215
},
275216
});
276217

277-
if(!isInitialized){
218+
if(!state.isInitialized){
278219
return<div>Loading...</div>;
279220
}
280221

@@ -288,13 +229,3 @@ function ChatWithThreads() {
288229
);
289230
}
290231

291-
// Main App component with proper context wrapping
292-
exportfunctionChatApp(){
293-
return(
294-
<ThreadProvider>
295-
<ChatWithThreads/>
296-
</ThreadProvider>
297-
);
298-
}
299-
300-
export{ChatWithThreads};

‎client/packages/lowcoder/src/comps/comps/chatComp/components/assistant-ui/thread-list.tsx

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,18 @@ import {
55
}from"@assistant-ui/react";
66
import{PencilIcon,PlusIcon,Trash2Icon}from"lucide-react";
77

8-
import{Button}from"../ui/button";
98
import{TooltipIconButton}from"./tooltip-icon-button";
109
import{useThreadListItemRuntime}from"@assistant-ui/react";
10+
import{Button}from"antd";
11+
12+
importstyledfrom"styled-components";
13+
import{useChatContext}from"../context/ChatContext";
14+
15+
constStyledPrimaryButton=styled(Button)`
16+
padding: 20px;
17+
margin-bottom: 20px;
18+
`;
19+
1120

1221
exportconstThreadList:FC=()=>{
1322
return(
@@ -21,10 +30,9 @@ export const ThreadList: FC = () => {
2130
constThreadListNew:FC=()=>{
2231
return(
2332
<ThreadListPrimitive.NewasChild>
24-
<ButtonclassName="aui-thread-list-new"variant="ghost">
25-
<PlusIcon/>
33+
<StyledPrimaryButtonsize="large"type="primary"icon={<PlusIcon/>}>
2634
New Thread
27-
</Button>
35+
</StyledPrimaryButton>
2836
</ThreadListPrimitive.New>
2937
);
3038
};
@@ -46,6 +54,7 @@ const ThreadListItem: FC = () => {
4654
};
4755

4856
constThreadListItemTitle:FC=()=>{
57+
4958
return(
5059
<pclassName="aui-thread-list-item-title">
5160
<ThreadListItemPrimitive.Titlefallback="New Chat"/>

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp