blixify-ui-web-mcp 0.1.1 → 0.1.3
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/lib/components/chart/ganttChart/README.md +96 -110
- package/lib/components/chart/ganttChart/ganttChart.stories.tsx +132 -116
- package/lib/components/chart/heatmapChart/README.md +93 -82
- package/lib/components/chart/heatmapChart/heatmapChart.stories.tsx +118 -74
- package/lib/components/chat/chatAnchor/README.md +61 -79
- package/lib/components/chat/chatBase/README.md +166 -199
- package/lib/components/chat/chatBase/chatBase.stories.tsx +243 -265
- package/lib/components/chat/chatDashboard/README.md +87 -129
- package/lib/components/chat/chatDashboard/chatDashboard.stories.tsx +84 -107
- package/lib/components/data/dataGraph/README.md +135 -1
- package/lib/components/data/dataGraph/dataGraph.stories.tsx +86 -67
- package/lib/components/data/dataReference/README.md +141 -43
- package/lib/components/data/dataReference/dataReference.stories.tsx +107 -35
- package/lib/components/data/dataWrapper/README.md +2 -1
- package/lib/components/display/table/README.md +1 -1
- package/lib/components/navigation/bars/README.md +90 -17
- package/lib/components/navigation/bars/bars.stories.tsx +125 -51
- package/lib/components/navigation/breadcrumb/README.md +40 -20
- package/lib/components/navigation/breadcrumb/breadcrumb.stories.tsx +30 -4
- package/lib/components/navigation/header/README.md +67 -108
- package/lib/components/navigation/header/header.stories.tsx +143 -39
- package/lib/components/navigation/leftNav/README.md +121 -66
- package/lib/components/navigation/leftNav/leftNav.stories.tsx +176 -83
- package/lib/components/navigation/tabs/tabs.stories.tsx +53 -29
- package/lib/mcp/server.d.ts +1 -0
- package/lib/mcp/server.js +1 -0
- package/lib/mcp/server.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { TrashIcon } from "@heroicons/react/24/outline";
|
|
2
2
|
import { storiesOf } from "@storybook/react";
|
|
3
3
|
import moment from "moment";
|
|
4
|
-
import React, {
|
|
4
|
+
import React, { useState } from "react";
|
|
5
5
|
import { v4 as uuidv4 } from "uuid";
|
|
6
6
|
import { ChatBase, ChatBaseAction, Conversation } from ".";
|
|
7
7
|
import Logo from "../../../assets/logo.png";
|
|
8
|
+
import { StorySection } from "../../storyUtils";
|
|
8
9
|
import { TextButton } from "../../action/textButton";
|
|
9
|
-
import { Loading } from "../../display/loading";
|
|
10
10
|
import README from "./README.md";
|
|
11
11
|
|
|
12
12
|
const stories = storiesOf("Chat", module);
|
|
@@ -17,290 +17,268 @@ stories.addParameters({
|
|
|
17
17
|
},
|
|
18
18
|
});
|
|
19
19
|
|
|
20
|
+
const botUser = {
|
|
21
|
+
id: "bot",
|
|
22
|
+
name: "Bot",
|
|
23
|
+
imageUrl:
|
|
24
|
+
"https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?ixlib=rb-1.2.1&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80",
|
|
25
|
+
};
|
|
26
|
+
const currentUser = { id: "me", name: "You" };
|
|
27
|
+
|
|
28
|
+
const seedMessages = [
|
|
29
|
+
{
|
|
30
|
+
sender: botUser,
|
|
31
|
+
messageBody: "Hi! How can I help you? 🤖",
|
|
32
|
+
createdAt: moment("2023-11-03 12:00").toDate(),
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
sender: currentUser,
|
|
36
|
+
messageBody: "My computer keeps crashing.",
|
|
37
|
+
createdAt: moment("2023-11-03 12:01").toDate(),
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
sender: botUser,
|
|
41
|
+
messageBody:
|
|
42
|
+
"**Quick Tips**\n1. Restart your machine.\n2. Check for updates.\n3. Free up disk space.",
|
|
43
|
+
createdAt: moment("2023-11-03 12:02").toDate(),
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
sender: currentUser,
|
|
47
|
+
messageBody: "Thanks, I'll try that!",
|
|
48
|
+
createdAt: moment("2023-11-03 12:03").toDate(),
|
|
49
|
+
},
|
|
50
|
+
];
|
|
51
|
+
|
|
52
|
+
const makeConversation = (messages = seedMessages): Conversation => ({
|
|
53
|
+
id: "1",
|
|
54
|
+
members: [currentUser, botUser],
|
|
55
|
+
messageList: messages,
|
|
56
|
+
});
|
|
57
|
+
|
|
20
58
|
stories.add("Chat Base", () => {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
imageUrl:
|
|
25
|
-
"https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80",
|
|
26
|
-
};
|
|
27
|
-
const currentUser = { id: "2", name: "Guest" };
|
|
59
|
+
// --- Default ---
|
|
60
|
+
const [msg1, setMsg1] = useState("");
|
|
61
|
+
const [conv1, setConv1] = useState(makeConversation());
|
|
28
62
|
|
|
29
|
-
|
|
30
|
-
const [
|
|
63
|
+
// --- Custom header/footer ---
|
|
64
|
+
const [msg2, setMsg2] = useState("");
|
|
65
|
+
const [conv2, setConv2] = useState(makeConversation());
|
|
66
|
+
const messageLimit = 8;
|
|
67
|
+
|
|
68
|
+
// --- Search ---
|
|
69
|
+
const [msg3, setMsg3] = useState("");
|
|
31
70
|
const [search, setSearch] = useState("");
|
|
32
|
-
const [
|
|
33
|
-
|
|
71
|
+
const [conv3, setConv3] = useState(makeConversation());
|
|
72
|
+
const [filteredConv, setFilteredConv] = useState<Conversation | null>(null);
|
|
73
|
+
|
|
74
|
+
// --- File upload ---
|
|
75
|
+
const [msg4, setMsg4] = useState("");
|
|
76
|
+
const [conv4, setConv4] = useState(makeConversation());
|
|
34
77
|
const [file, setFile] = useState<File | any>(undefined);
|
|
35
|
-
const [loading, setLoading] = useState(false);
|
|
36
78
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
{
|
|
42
|
-
sender: botUser,
|
|
43
|
-
messageBody: "Hi! How can I help you? 🤖",
|
|
44
|
-
createdAt: moment(
|
|
45
|
-
"Fri Nov 03 2023 12:21:14 GMT+0800 (Malaysia Time)"
|
|
46
|
-
).toDate(),
|
|
47
|
-
},
|
|
48
|
-
{
|
|
49
|
-
sender: currentUser,
|
|
50
|
-
messageBody: "Yo, my computer's acting up.",
|
|
51
|
-
createdAt: moment(
|
|
52
|
-
"Fri Nov 03 2023 13:21:14 GMT+0800 (Malaysia Time)"
|
|
53
|
-
).toDate(),
|
|
54
|
-
},
|
|
55
|
-
{
|
|
56
|
-
sender: currentUser,
|
|
57
|
-
messageBody:
|
|
58
|
-
"It keeps saying 'Error 404: Coffee not found' when I start it up.",
|
|
59
|
-
createdAt: moment(
|
|
60
|
-
"Fri Nov 03 2023 14:21:14 GMT+0800 (Malaysia Time)"
|
|
61
|
-
).toDate(),
|
|
62
|
-
},
|
|
63
|
-
{
|
|
64
|
-
sender: botUser,
|
|
65
|
-
messageBody:
|
|
66
|
-
"Sounds like a caffeine emergency!\nHave you tried offering it coffee?",
|
|
67
|
-
createdAt: moment(
|
|
68
|
-
"Fri Nov 03 2023 15:21:14 GMT+0800 (Malaysia Time)"
|
|
69
|
-
).toDate(),
|
|
70
|
-
},
|
|
71
|
-
{
|
|
72
|
-
sender: currentUser,
|
|
73
|
-
messageBody: "Seriously?",
|
|
74
|
-
createdAt: moment(
|
|
75
|
-
"Fri Nov 03 2023 16:21:14 GMT+0800 (Malaysia Time)"
|
|
76
|
-
).toDate(),
|
|
77
|
-
},
|
|
78
|
-
{
|
|
79
|
-
sender: botUser,
|
|
80
|
-
messageBody:
|
|
81
|
-
"Well, computers do like a jolt of energy, but don't spill, that could be 'mocha-nical' trouble!",
|
|
82
|
-
createdAt: moment(
|
|
83
|
-
"Fri Nov 03 2023 17:21:14 GMT+0800 (Malaysia Time)"
|
|
84
|
-
).toDate(),
|
|
85
|
-
},
|
|
86
|
-
{
|
|
87
|
-
sender: currentUser,
|
|
88
|
-
messageBody: "Cringe. I'll give it a shot.Thanks.",
|
|
89
|
-
createdAt: moment(
|
|
90
|
-
"Fri Nov 03 2023 18:21:14 GMT+0800 (Malaysia Time)"
|
|
91
|
-
).toDate(),
|
|
92
|
-
},
|
|
93
|
-
{
|
|
94
|
-
sender: botUser,
|
|
95
|
-
messageBody:
|
|
96
|
-
"**Quick Tips for Productivity**\n1. Set timers.\n2. Prioritize tasks.\n3. Take breaks.\n\n**Healthy Habits**\n 1. Stay hydrated.\n2. Eat well.\n3. Exercise daily.",
|
|
97
|
-
createdAt: moment(
|
|
98
|
-
"Fri Nov 03 2023 19:21:14 GMT+0800 (Malaysia Time)"
|
|
99
|
-
).toDate(),
|
|
100
|
-
},
|
|
101
|
-
{
|
|
102
|
-
sender: botUser,
|
|
103
|
-
messageBody: "Hey check out my dog!",
|
|
104
|
-
createdAt: moment(
|
|
105
|
-
"Fri Nov 03 2023 19:21:10 GMT+0800 (Malaysia Time)"
|
|
106
|
-
).toDate(),
|
|
107
|
-
},
|
|
108
|
-
{
|
|
109
|
-
sender: botUser,
|
|
110
|
-
messageBody: {
|
|
111
|
-
fileName:
|
|
112
|
-
"https://player.vimeo.com/external/364708250.sd.mp4?s=7382fdedda817a193bcffb6ff74624fa245ee666&profile_id=164&oauth2_token_id=57447761",
|
|
113
|
-
token: "A",
|
|
114
|
-
type: "video/mp4",
|
|
115
|
-
},
|
|
116
|
-
createdAt: moment(
|
|
117
|
-
"Fri Nov 03 2023 19:21:14 GMT+0800 (Malaysia Time)"
|
|
118
|
-
).toDate(),
|
|
119
|
-
},
|
|
120
|
-
{
|
|
121
|
-
sender: currentUser,
|
|
122
|
-
messageBody: {
|
|
123
|
-
fileName:
|
|
124
|
-
"https://images.pexels.com/photos/3726314/pexels-photo-3726314.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1",
|
|
125
|
-
token: "B",
|
|
126
|
-
type: "image/png",
|
|
127
|
-
},
|
|
128
|
-
createdAt: moment(
|
|
129
|
-
"Fri Nov 03 2023 19:21:18 GMT+0800 (Malaysia Time)"
|
|
130
|
-
).toDate(),
|
|
131
|
-
},
|
|
132
|
-
{
|
|
133
|
-
sender: currentUser,
|
|
134
|
-
messageBody: "Here's mine! He says hello!",
|
|
135
|
-
createdAt: moment(
|
|
136
|
-
"Fri Nov 03 2023 19:22:14 GMT+0800 (Malaysia Time)"
|
|
137
|
-
).toDate(),
|
|
138
|
-
},
|
|
139
|
-
],
|
|
140
|
-
});
|
|
79
|
+
// --- Loading reply ---
|
|
80
|
+
const [msg5, setMsg5] = useState("");
|
|
81
|
+
const [conv5, setConv5] = useState(makeConversation());
|
|
82
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
141
83
|
|
|
142
|
-
const
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
84
|
+
const sendMessage =
|
|
85
|
+
(
|
|
86
|
+
conv: Conversation,
|
|
87
|
+
setConv: (c: Conversation) => void,
|
|
88
|
+
setMsg: (s: string) => void
|
|
89
|
+
) =>
|
|
90
|
+
(updated: Conversation) => {
|
|
91
|
+
setConv(updated);
|
|
92
|
+
setMsg("");
|
|
93
|
+
};
|
|
147
94
|
|
|
148
|
-
const
|
|
149
|
-
if (searchMessage
|
|
95
|
+
const handleSearch = (searchMessage: string) => {
|
|
96
|
+
if (!searchMessage) {
|
|
150
97
|
setSearch("");
|
|
151
|
-
|
|
152
|
-
} else {
|
|
153
|
-
const dupMessageList = conversation.messageList.filter((eachMessage) => {
|
|
154
|
-
if (typeof eachMessage.messageBody === "string") {
|
|
155
|
-
return eachMessage.messageBody
|
|
156
|
-
.toLowerCase()
|
|
157
|
-
.includes(searchMessage.toLowerCase());
|
|
158
|
-
}
|
|
159
|
-
return null;
|
|
160
|
-
});
|
|
161
|
-
const dupConversation = {
|
|
162
|
-
id: conversation.id,
|
|
163
|
-
members: [...conversation.members],
|
|
164
|
-
messageList: [...dupMessageList],
|
|
165
|
-
};
|
|
166
|
-
setFilteredConversation(dupConversation);
|
|
167
|
-
}
|
|
168
|
-
};
|
|
169
|
-
|
|
170
|
-
const handleOnClearMessage = () => {
|
|
171
|
-
setFilteredConversation(null);
|
|
172
|
-
setConversation({
|
|
173
|
-
id: "1",
|
|
174
|
-
members: [currentUser, botUser],
|
|
175
|
-
messageList: [],
|
|
176
|
-
});
|
|
177
|
-
};
|
|
178
|
-
|
|
179
|
-
const handleOnChangeUpload = (e: any) => {
|
|
180
|
-
if (e && e.target.files.length > 0) {
|
|
181
|
-
setFile(e.target.files[0]);
|
|
98
|
+
setFilteredConv(null);
|
|
182
99
|
} else {
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
const dupConversation = {
|
|
191
|
-
id: conversation.id,
|
|
192
|
-
members: [...conversation.members],
|
|
193
|
-
messageList: [...conversation.messageList],
|
|
194
|
-
};
|
|
195
|
-
const fileUrl = URL.createObjectURL(file);
|
|
196
|
-
const fileObj = {
|
|
197
|
-
fileName: fileUrl,
|
|
198
|
-
token: uuidv4(),
|
|
199
|
-
type: file.type,
|
|
200
|
-
};
|
|
201
|
-
dupConversation.messageList.push({
|
|
202
|
-
sender: currentUser,
|
|
203
|
-
messageBody: fileObj,
|
|
204
|
-
createdAt: moment().toDate(),
|
|
100
|
+
setFilteredConv({
|
|
101
|
+
...conv3,
|
|
102
|
+
messageList: conv3.messageList.filter(
|
|
103
|
+
(m) =>
|
|
104
|
+
typeof m.messageBody === "string" &&
|
|
105
|
+
m.messageBody.toLowerCase().includes(searchMessage.toLowerCase())
|
|
106
|
+
),
|
|
205
107
|
});
|
|
206
|
-
setTimeout(() => {
|
|
207
|
-
setConversation(dupConversation);
|
|
208
|
-
setMessage("");
|
|
209
|
-
setFile(undefined);
|
|
210
|
-
setLoading(false);
|
|
211
|
-
}, 5000);
|
|
212
108
|
}
|
|
213
109
|
};
|
|
214
110
|
|
|
215
|
-
const
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
onClick={handleOnClearMessage}
|
|
234
|
-
className="mt-2"
|
|
235
|
-
/>
|
|
236
|
-
</div>
|
|
237
|
-
</div>
|
|
238
|
-
);
|
|
239
|
-
else return undefined;
|
|
111
|
+
const handleSendWithReply = (updated: Conversation) => {
|
|
112
|
+
setConv5(updated);
|
|
113
|
+
setMsg5("");
|
|
114
|
+
setIsLoading(true);
|
|
115
|
+
setTimeout(() => {
|
|
116
|
+
setConv5((prev) => ({
|
|
117
|
+
...prev,
|
|
118
|
+
messageList: [
|
|
119
|
+
...prev.messageList,
|
|
120
|
+
{
|
|
121
|
+
sender: botUser,
|
|
122
|
+
messageBody: "Got it! Let me look into that for you.",
|
|
123
|
+
createdAt: moment().toDate(),
|
|
124
|
+
},
|
|
125
|
+
],
|
|
126
|
+
}));
|
|
127
|
+
setIsLoading(false);
|
|
128
|
+
}, 2000);
|
|
240
129
|
};
|
|
241
|
-
const footerElement = renderFooterElement();
|
|
242
130
|
|
|
243
|
-
const
|
|
131
|
+
const clearAction = (
|
|
132
|
+
setConv: (c: Conversation) => void
|
|
133
|
+
): ChatBaseAction[] => [
|
|
244
134
|
{
|
|
245
135
|
text: "Clear",
|
|
246
|
-
onClick:
|
|
247
|
-
icon: <TrashIcon className="w-3 h-3"
|
|
136
|
+
onClick: () => setConv(makeConversation([])),
|
|
137
|
+
icon: <TrashIcon className="w-3 h-3" />,
|
|
248
138
|
},
|
|
249
139
|
];
|
|
250
140
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
<
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
141
|
+
return (
|
|
142
|
+
<>
|
|
143
|
+
<StorySection
|
|
144
|
+
title="Default"
|
|
145
|
+
description="Basic chat with send and receive. Sent messages appear on the right; received messages on the left with the sender's avatar. Received messages support markdown rendering."
|
|
146
|
+
>
|
|
147
|
+
<ChatBase
|
|
148
|
+
open
|
|
149
|
+
value={msg1}
|
|
150
|
+
currentUser={currentUser}
|
|
151
|
+
conversation={conv1}
|
|
152
|
+
onSendMessage={sendMessage(conv1, setConv1, setMsg1)}
|
|
153
|
+
onChangeMessage={(e) => setMsg1(e.target.value)}
|
|
154
|
+
additionalAction={clearAction(setConv1)}
|
|
155
|
+
sizeClassName="h-[500px] w-96"
|
|
156
|
+
disableMobileResize
|
|
157
|
+
/>
|
|
158
|
+
</StorySection>
|
|
257
159
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
160
|
+
<StorySection
|
|
161
|
+
title="Custom Header & Footer"
|
|
162
|
+
description="headerElement replaces the default blue header bar. footerElement renders above the message input — useful for limit warnings, disclaimers, or action prompts."
|
|
163
|
+
>
|
|
164
|
+
<ChatBase
|
|
165
|
+
open
|
|
166
|
+
value={msg2}
|
|
167
|
+
currentUser={currentUser}
|
|
168
|
+
conversation={conv2}
|
|
169
|
+
onSendMessage={sendMessage(conv2, setConv2, setMsg2)}
|
|
170
|
+
onChangeMessage={(e) => setMsg2(e.target.value)}
|
|
171
|
+
headerElement={
|
|
172
|
+
<div className="p-3 bg-primary-500 rounded-t-md flex items-center">
|
|
173
|
+
<img src={Logo} alt="Logo" className="h-8" />
|
|
174
|
+
<span className="ml-3 text-white text-sm font-medium">
|
|
175
|
+
Support Chat
|
|
176
|
+
</span>
|
|
177
|
+
</div>
|
|
178
|
+
}
|
|
179
|
+
footerElement={
|
|
180
|
+
conv2.messageList.length >= messageLimit ? (
|
|
181
|
+
<div className="p-2">
|
|
182
|
+
<div className="p-2 text-xs border rounded-md bg-primary-50 border-primary-300">
|
|
183
|
+
Message limit reached ({messageLimit}).{" "}
|
|
184
|
+
<TextButton
|
|
185
|
+
text="Clear"
|
|
186
|
+
onClick={() => setConv2(makeConversation([]))}
|
|
187
|
+
className="inline"
|
|
188
|
+
/>
|
|
189
|
+
</div>
|
|
190
|
+
</div>
|
|
191
|
+
) : undefined
|
|
192
|
+
}
|
|
193
|
+
disableMessageInput={conv2.messageList.length >= messageLimit}
|
|
194
|
+
sizeClassName="h-[500px] w-96"
|
|
195
|
+
disableMobileResize
|
|
196
|
+
/>
|
|
197
|
+
</StorySection>
|
|
273
198
|
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
199
|
+
<StorySection
|
|
200
|
+
title="Message Search"
|
|
201
|
+
description="onSearch filters the conversation to matching messages. The search box is opened via the ⋮ actions menu. onChangeSearch updates the search input value."
|
|
202
|
+
>
|
|
203
|
+
<ChatBase
|
|
204
|
+
open
|
|
205
|
+
value={msg3}
|
|
206
|
+
currentUser={currentUser}
|
|
207
|
+
conversation={filteredConv ?? conv3}
|
|
208
|
+
searchMessage={search}
|
|
209
|
+
onSendMessage={sendMessage(conv3, setConv3, setMsg3)}
|
|
210
|
+
onChangeMessage={(e) => setMsg3(e.target.value)}
|
|
211
|
+
onSearch={handleSearch}
|
|
212
|
+
onChangeSearch={(e) => setSearch(e.target.value)}
|
|
213
|
+
additionalAction={clearAction(setConv3)}
|
|
214
|
+
sizeClassName="h-[500px] w-96"
|
|
215
|
+
disableMobileResize
|
|
216
|
+
/>
|
|
217
|
+
</StorySection>
|
|
218
|
+
|
|
219
|
+
<StorySection
|
|
220
|
+
title="File Upload"
|
|
221
|
+
description="fileUpload.allowFileUpload=true shows a paperclip button. The selected file is previewed before sending. onSendUpload is called with the current conversation when the send button is clicked."
|
|
222
|
+
>
|
|
223
|
+
<ChatBase
|
|
224
|
+
open
|
|
225
|
+
value={msg4}
|
|
226
|
+
currentUser={currentUser}
|
|
227
|
+
conversation={conv4}
|
|
228
|
+
fileUpload={{
|
|
229
|
+
allowFileUpload: true,
|
|
230
|
+
file,
|
|
231
|
+
acceptFileType: ".jpg,.jpeg,.png,.mp4,.webm",
|
|
232
|
+
onChangeUpload: (e) => {
|
|
233
|
+
if (e?.target?.files?.length > 0) setFile(e.target.files[0]);
|
|
234
|
+
else setFile(undefined);
|
|
235
|
+
},
|
|
236
|
+
onSendUpload: (conversation) => {
|
|
237
|
+
if (file) {
|
|
238
|
+
const fileUrl = URL.createObjectURL(file);
|
|
239
|
+
setConv4({
|
|
240
|
+
...conversation,
|
|
241
|
+
messageList: [
|
|
242
|
+
...conversation.messageList,
|
|
243
|
+
{
|
|
244
|
+
sender: currentUser,
|
|
245
|
+
messageBody: {
|
|
246
|
+
fileName: fileUrl,
|
|
247
|
+
token: uuidv4(),
|
|
248
|
+
type: file.type,
|
|
249
|
+
},
|
|
250
|
+
createdAt: moment().toDate(),
|
|
251
|
+
},
|
|
252
|
+
],
|
|
253
|
+
});
|
|
254
|
+
setFile(undefined);
|
|
255
|
+
setMsg4("");
|
|
256
|
+
}
|
|
257
|
+
},
|
|
258
|
+
}}
|
|
259
|
+
onSendMessage={sendMessage(conv4, setConv4, setMsg4)}
|
|
260
|
+
onChangeMessage={(e) => setMsg4(e.target.value)}
|
|
261
|
+
sizeClassName="h-[500px] w-96"
|
|
262
|
+
disableMobileResize
|
|
263
|
+
/>
|
|
264
|
+
</StorySection>
|
|
265
|
+
|
|
266
|
+
<StorySection
|
|
267
|
+
title="Loading Reply"
|
|
268
|
+
description="isLoadingReply=true shows an animated typing indicator above the input and disables the message input while waiting for a response. Send a message to see the effect."
|
|
269
|
+
>
|
|
270
|
+
<ChatBase
|
|
271
|
+
open
|
|
272
|
+
value={msg5}
|
|
273
|
+
currentUser={currentUser}
|
|
274
|
+
conversation={conv5}
|
|
275
|
+
isLoadingReply={isLoading}
|
|
276
|
+
onSendMessage={handleSendWithReply}
|
|
277
|
+
onChangeMessage={(e) => setMsg5(e.target.value)}
|
|
278
|
+
sizeClassName="h-[500px] w-96"
|
|
279
|
+
disableMobileResize
|
|
280
|
+
/>
|
|
281
|
+
</StorySection>
|
|
282
|
+
</>
|
|
305
283
|
);
|
|
306
284
|
});
|