@triadxyz/widgets 0.0.1 → 0.0.2
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/.yarnrc.yml +1 -0
- package/package.json +1 -1
- package/src/components/LiveChat.tsx +162 -88
- package/src/hooks/useChat.ts +2 -2
package/.yarnrc.yml
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
nodeLinker: node-modules
|
package/package.json
CHANGED
|
@@ -34,8 +34,13 @@ export interface LiveChatProps {
|
|
|
34
34
|
// slots
|
|
35
35
|
renderMessage?: (message: ChatMessage) => React.ReactNode;
|
|
36
36
|
renderHeader?: () => React.ReactNode;
|
|
37
|
-
authority: string;
|
|
37
|
+
authority: string | null;
|
|
38
38
|
customerAuthority: string;
|
|
39
|
+
onConnectWallet?: () => void;
|
|
40
|
+
fallbackMessages?: {
|
|
41
|
+
connectWallet: string;
|
|
42
|
+
description: string;
|
|
43
|
+
};
|
|
39
44
|
}
|
|
40
45
|
|
|
41
46
|
export function LiveChat({
|
|
@@ -48,13 +53,16 @@ export function LiveChat({
|
|
|
48
53
|
renderHeader,
|
|
49
54
|
authority,
|
|
50
55
|
customerAuthority,
|
|
56
|
+
fallbackMessages,
|
|
57
|
+
onConnectWallet,
|
|
51
58
|
}: LiveChatProps) {
|
|
52
59
|
const [inputValue, setInputValue] = useState("");
|
|
53
60
|
const messagesEndRef = useRef<HTMLDivElement>(null);
|
|
54
61
|
const primary = theme?.primaryColor || "#FF3D00";
|
|
55
62
|
const background = theme?.background || "var(--chat-bg)";
|
|
63
|
+
|
|
56
64
|
const { sendMessage, onlineCount, messages } = useChat({
|
|
57
|
-
authority: authority ||
|
|
65
|
+
authority: authority || undefined,
|
|
58
66
|
customerAuthority: customerAuthority,
|
|
59
67
|
});
|
|
60
68
|
|
|
@@ -102,7 +110,7 @@ export function LiveChat({
|
|
|
102
110
|
style={{
|
|
103
111
|
top: "75px",
|
|
104
112
|
width: "340px",
|
|
105
|
-
height: "800px",
|
|
113
|
+
height: !authority ? "auto" : "800px",
|
|
106
114
|
maxHeight: "calc(100vh - 90px)",
|
|
107
115
|
background,
|
|
108
116
|
}}
|
|
@@ -123,94 +131,133 @@ export function LiveChat({
|
|
|
123
131
|
</h2>
|
|
124
132
|
<div className="flex items-center gap-1.5">
|
|
125
133
|
<div className="size-2 rounded-full bg-green-500 animate-pulse" />
|
|
126
|
-
<span className="text-xs text-
|
|
134
|
+
<span className="text-xs text-app-gray-400 dark:text-app-gray-100">
|
|
127
135
|
{onlineCount} online
|
|
128
136
|
</span>
|
|
129
137
|
</div>
|
|
130
138
|
</div>
|
|
131
139
|
<button onClick={onClose}>
|
|
132
|
-
<X size={18} />
|
|
140
|
+
<X className="dark:text-white text-black" size={18} />
|
|
133
141
|
</button>
|
|
134
142
|
</div>
|
|
135
143
|
)}
|
|
136
144
|
|
|
137
145
|
{/* Messages */}
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
renderMessage(
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
key={idx}
|
|
150
|
-
className={`flex flex-col gap-1 ${
|
|
151
|
-
message.authority === authority ? "items-end" : "items-start"
|
|
152
|
-
}`}
|
|
153
|
-
>
|
|
154
|
-
{message.authority !== authority && (
|
|
155
|
-
<span className="text-xs font-medium text-triad-dark-100 dark:text-white">
|
|
156
|
-
{message.name}
|
|
157
|
-
</span>
|
|
158
|
-
)}
|
|
159
|
-
|
|
146
|
+
{authority && (
|
|
147
|
+
<div
|
|
148
|
+
className={cn(
|
|
149
|
+
"flex-1 overflow-y-auto px-6 py-4 space-y-4",
|
|
150
|
+
classNames?.messages,
|
|
151
|
+
)}
|
|
152
|
+
>
|
|
153
|
+
{messages.map((message, idx) =>
|
|
154
|
+
renderMessage ? (
|
|
155
|
+
renderMessage(message)
|
|
156
|
+
) : (
|
|
160
157
|
<div
|
|
161
|
-
|
|
162
|
-
|
|
158
|
+
key={idx}
|
|
159
|
+
className={`flex flex-col gap-1 ${
|
|
163
160
|
message.authority === authority
|
|
164
|
-
? "
|
|
165
|
-
: "
|
|
166
|
-
|
|
167
|
-
style={
|
|
168
|
-
message.authority === authority
|
|
169
|
-
? { backgroundColor: primary }
|
|
170
|
-
: undefined
|
|
171
|
-
}
|
|
161
|
+
? "items-end"
|
|
162
|
+
: "items-start"
|
|
163
|
+
}`}
|
|
172
164
|
>
|
|
173
|
-
|
|
165
|
+
{message.authority !== authority && (
|
|
166
|
+
<span className="text-xs font-medium text-triad-dark-100 dark:text-white">
|
|
167
|
+
{message.name}
|
|
168
|
+
</span>
|
|
169
|
+
)}
|
|
170
|
+
|
|
171
|
+
<div
|
|
172
|
+
className={cn(
|
|
173
|
+
"max-w-[75%] rounded-2xl px-4 py-2.5",
|
|
174
|
+
message.authority === authority
|
|
175
|
+
? "text-white rounded-br-sm"
|
|
176
|
+
: "bg-black/5 dark:bg-white/5 text-triad-dark-100 dark:text-white rounded-bl-sm",
|
|
177
|
+
)}
|
|
178
|
+
style={
|
|
179
|
+
message.authority === authority
|
|
180
|
+
? { backgroundColor: primary }
|
|
181
|
+
: undefined
|
|
182
|
+
}
|
|
183
|
+
>
|
|
184
|
+
<p className="text-sm break-words">{message.message}</p>
|
|
185
|
+
</div>
|
|
186
|
+
|
|
187
|
+
<span className="text-[10px] opacity-50">
|
|
188
|
+
{format(message.timestamp, "HH:mm")}
|
|
189
|
+
</span>
|
|
174
190
|
</div>
|
|
191
|
+
),
|
|
192
|
+
)}
|
|
193
|
+
<div ref={messagesEndRef} />
|
|
194
|
+
</div>
|
|
195
|
+
)}
|
|
196
|
+
{/* Input */}
|
|
197
|
+
<div className="px-6 py-4 border-t border-black/10 dark:border-white/10">
|
|
198
|
+
{!authority ? (
|
|
199
|
+
<div className="flex flex-col items-center justify-center gap-3 py-4 px-3 text-center">
|
|
200
|
+
{/* Icon */}
|
|
201
|
+
<div
|
|
202
|
+
className="flex items-center justify-center size-12 rounded-2xl"
|
|
203
|
+
style={{
|
|
204
|
+
background: `${primary}15`,
|
|
205
|
+
}}
|
|
206
|
+
>
|
|
207
|
+
<span className="text-xl">💬</span>
|
|
208
|
+
</div>
|
|
175
209
|
|
|
176
|
-
|
|
177
|
-
|
|
210
|
+
{/* Text */}
|
|
211
|
+
<div className="flex flex-col gap-1">
|
|
212
|
+
<span className="text-sm font-semibold text-black dark:text-white">
|
|
213
|
+
{fallbackMessages?.connectWallet || "Entre no chat"}
|
|
214
|
+
</span>
|
|
215
|
+
<span className="text-xs text-black/60 dark:text-white max-w-[220px]">
|
|
216
|
+
{fallbackMessages?.description ||
|
|
217
|
+
"Conecte sua carteira para participar das conversas em tempo real"}
|
|
178
218
|
</span>
|
|
179
219
|
</div>
|
|
180
|
-
),
|
|
181
|
-
)}
|
|
182
|
-
<div ref={messagesEndRef} />
|
|
183
|
-
</div>
|
|
184
220
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
"flex-1 px-4 py-2.5 rounded-xl bg-black/5 dark:bg-white/5 dark:text-white text-sm outline-none",
|
|
195
|
-
classNames?.input,
|
|
221
|
+
{/* Button */}
|
|
222
|
+
{onConnectWallet && (
|
|
223
|
+
<button
|
|
224
|
+
onClick={onConnectWallet}
|
|
225
|
+
style={{ backgroundColor: primary }}
|
|
226
|
+
className="mt-2 w-full max-w-[220px] px-4 py-2.5 text-white text-sm font-semibold rounded-xl transition-all hover:opacity-90 active:scale-95 shadow-sm"
|
|
227
|
+
>
|
|
228
|
+
Conectar Carteira
|
|
229
|
+
</button>
|
|
196
230
|
)}
|
|
197
|
-
|
|
231
|
+
</div>
|
|
232
|
+
) : (
|
|
233
|
+
<div className="flex items-center gap-2">
|
|
234
|
+
<input
|
|
235
|
+
value={inputValue}
|
|
236
|
+
onChange={(e) => setInputValue(e.target.value)}
|
|
237
|
+
onKeyDown={handleKeyDown}
|
|
238
|
+
placeholder="Digite sua mensagem..."
|
|
239
|
+
className={cn(
|
|
240
|
+
"flex-1 px-4 py-2.5 rounded-xl bg-black/5 dark:bg-white/5 dark:text-white text-sm outline-none",
|
|
241
|
+
classNames?.input,
|
|
242
|
+
)}
|
|
243
|
+
/>
|
|
198
244
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
245
|
+
<button
|
|
246
|
+
onClick={handleSendMessage}
|
|
247
|
+
disabled={!inputValue.trim()}
|
|
248
|
+
className={cn(
|
|
249
|
+
"flex items-center justify-center size-10 rounded-xl transition-colors",
|
|
250
|
+
classNames?.button,
|
|
251
|
+
)}
|
|
252
|
+
style={{
|
|
253
|
+
backgroundColor: inputValue.trim() ? primary : undefined,
|
|
254
|
+
opacity: inputValue.trim() ? 1 : 0.5,
|
|
255
|
+
}}
|
|
256
|
+
>
|
|
257
|
+
<Send size={18} className="dark:text-white text-app-gay-400" />
|
|
258
|
+
</button>
|
|
259
|
+
</div>
|
|
260
|
+
)}
|
|
214
261
|
</div>
|
|
215
262
|
</div>
|
|
216
263
|
|
|
@@ -235,23 +282,50 @@ export function LiveChat({
|
|
|
235
282
|
</div>
|
|
236
283
|
|
|
237
284
|
{/* Input */}
|
|
238
|
-
<div className="p-4 border-t flex gap-2">
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
285
|
+
<div className="p-4 border-t flex flex-col gap-2">
|
|
286
|
+
{!authority ? (
|
|
287
|
+
<div className="flex-1 flex flex-col items-center justify-center gap-2 py-2">
|
|
288
|
+
<span className="text-sm font-medium text-black/60 dark:text-white/60 text-center">
|
|
289
|
+
{fallbackMessages?.description ||
|
|
290
|
+
"Faça login para participar do chat"}
|
|
291
|
+
</span>
|
|
292
|
+
{onConnectWallet && (
|
|
293
|
+
<button
|
|
294
|
+
onClick={onConnectWallet}
|
|
295
|
+
style={{ backgroundColor: primary }}
|
|
296
|
+
className="px-4 py-2 text-white text-sm font-semibold rounded-xl transition-opacity hover:opacity-90 active:scale-95"
|
|
297
|
+
>
|
|
298
|
+
{fallbackMessages?.connectWallet || "Fazer Login"}
|
|
299
|
+
</button>
|
|
300
|
+
)}
|
|
301
|
+
</div>
|
|
302
|
+
) : (
|
|
303
|
+
<div className="flex gap-2 w-full">
|
|
304
|
+
<input
|
|
305
|
+
value={inputValue}
|
|
306
|
+
onChange={(e) => setInputValue(e.target.value)}
|
|
307
|
+
onKeyDown={handleKeyDown}
|
|
308
|
+
className="flex-1 bg-black/5 dark:bg-white/5 dark:text-white px-4 py-2.5 rounded-xl text-sm outline-none"
|
|
309
|
+
placeholder="Digite sua mensagem..."
|
|
310
|
+
/>
|
|
311
|
+
<button
|
|
312
|
+
className={cn(
|
|
313
|
+
"flex items-center justify-center size-10 rounded-xl transition-colors",
|
|
314
|
+
classNames?.button,
|
|
315
|
+
)}
|
|
316
|
+
style={{
|
|
317
|
+
backgroundColor: inputValue.trim() ? primary : undefined,
|
|
318
|
+
opacity: inputValue.trim() ? 1 : 0.5,
|
|
319
|
+
}}
|
|
320
|
+
onClick={handleSendMessage}
|
|
321
|
+
>
|
|
322
|
+
<Send
|
|
323
|
+
className="dark:text-white text-app-gay-400"
|
|
324
|
+
size={18}
|
|
325
|
+
/>
|
|
326
|
+
</button>
|
|
327
|
+
</div>
|
|
328
|
+
)}
|
|
255
329
|
</div>
|
|
256
330
|
</div>
|
|
257
331
|
</div>
|
package/src/hooks/useChat.ts
CHANGED
|
@@ -2,7 +2,7 @@ import socket from "@/utils/socket";
|
|
|
2
2
|
import { useEffect, useState } from "react";
|
|
3
3
|
|
|
4
4
|
export interface ChatMessage {
|
|
5
|
-
authority
|
|
5
|
+
authority?: string;
|
|
6
6
|
name: string;
|
|
7
7
|
image: string;
|
|
8
8
|
predictionsCount: number;
|
|
@@ -14,7 +14,7 @@ export function useChat({
|
|
|
14
14
|
authority,
|
|
15
15
|
customerAuthority,
|
|
16
16
|
}: {
|
|
17
|
-
authority
|
|
17
|
+
authority?: string;
|
|
18
18
|
customerAuthority: string;
|
|
19
19
|
}) {
|
|
20
20
|
const [messages, setMessages] = useState<ChatMessage[]>([]);
|