@mieweb/ui 0.10.0-dev.8 → 0.10.0-dev.9
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/{chunk-7G3ZIYFY.js → chunk-4A3W4TQF.js} +15 -2
- package/dist/chunk-4A3W4TQF.js.map +1 -0
- package/dist/{chunk-WNAA6CLE.cjs → chunk-AR7AKDM2.cjs} +2 -2
- package/dist/{chunk-WNAA6CLE.cjs.map → chunk-AR7AKDM2.cjs.map} +1 -1
- package/dist/{chunk-EZSSESEU.cjs → chunk-ASSDGS4F.cjs} +15 -2
- package/dist/chunk-ASSDGS4F.cjs.map +1 -0
- package/dist/{chunk-JHULS3EC.js → chunk-AWJBOND5.js} +2 -2
- package/dist/{chunk-JHULS3EC.js.map → chunk-AWJBOND5.js.map} +1 -1
- package/dist/chunk-BM35CACB.js +148 -0
- package/dist/chunk-BM35CACB.js.map +1 -0
- package/dist/{chunk-WIAQQNFU.cjs → chunk-FS4VZUFV.cjs} +31 -2
- package/dist/chunk-FS4VZUFV.cjs.map +1 -0
- package/dist/{chunk-22CYDCXA.js → chunk-HACNIFO3.js} +31 -3
- package/dist/chunk-HACNIFO3.js.map +1 -0
- package/dist/chunk-VPTASZ2O.cjs +171 -0
- package/dist/chunk-VPTASZ2O.cjs.map +1 -0
- package/dist/components/SuperChat/index.cjs +261 -112
- package/dist/components/SuperChat/index.cjs.map +1 -1
- package/dist/components/SuperChat/index.js +255 -106
- package/dist/components/SuperChat/index.js.map +1 -1
- package/dist/hooks/index.cjs +22 -13
- package/dist/hooks/index.d.cts +101 -1
- package/dist/hooks/index.d.ts +101 -1
- package/dist/hooks/index.js +2 -1
- package/dist/index.cjs +193 -70
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +146 -30
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/tailwind-preset.cjs +4 -4
- package/dist/tailwind-preset.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-22CYDCXA.js.map +0 -1
- package/dist/chunk-7G3ZIYFY.js.map +0 -1
- package/dist/chunk-EZSSESEU.cjs.map +0 -1
- package/dist/chunk-WIAQQNFU.cjs.map +0 -1
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { TextRenderContext } from '../../chunk-I6CY5C6A.js';
|
|
2
2
|
export { TextRenderContext, useTextRenderContext } from '../../chunk-I6CY5C6A.js';
|
|
3
|
-
import { ChatBubble, MCPToolCallDisplay, AITypingIndicator, SparklesIcon, CloseIcon } from '../../chunk-
|
|
3
|
+
import { ChatBubble, MCPToolCallDisplay, AITypingIndicator, SparklesIcon, CloseIcon, JumpToBottomButton } from '../../chunk-HACNIFO3.js';
|
|
4
4
|
import { notifyComposerMigrationOnce, ChatComposer } from '../../chunk-ACCAXVOG.js';
|
|
5
5
|
import { Dropdown, DropdownSubmenu, DropdownItem } from '../../chunk-ZGRCSNPK.js';
|
|
6
6
|
import { Avatar } from '../../chunk-HZ4MBUC3.js';
|
|
7
7
|
import '../../chunk-IQ4KQJAO.js';
|
|
8
|
+
import { useStickToBottom, useStreamEndedBelowFold } from '../../chunk-BM35CACB.js';
|
|
8
9
|
import '../../chunk-VVDE4CHU.js';
|
|
9
10
|
import '../../chunk-6NZXWKUE.js';
|
|
10
11
|
import '../../chunk-3IMM2PM4.js';
|
|
@@ -12,11 +13,12 @@ import '../../chunk-62ZOA6PX.js';
|
|
|
12
13
|
import '../../chunk-WSNMQQ4P.js';
|
|
13
14
|
import '../../chunk-T4ME7QCT.js';
|
|
14
15
|
import '../../chunk-BKSPDTX4.js';
|
|
16
|
+
import { usePrefersReducedMotion } from '../../chunk-HB7C7NB5.js';
|
|
15
17
|
import { Badge } from '../../chunk-BMSG4NBH.js';
|
|
16
18
|
import '../../chunk-XCP454Q6.js';
|
|
17
19
|
import { cn } from '../../chunk-TQONQSJO.js';
|
|
18
20
|
import '../../chunk-PX6F3LHL.js';
|
|
19
|
-
import * as
|
|
21
|
+
import * as React3 from 'react';
|
|
20
22
|
import Markdown, { defaultUrlTransform } from 'react-markdown';
|
|
21
23
|
import remarkGfm from 'remark-gfm';
|
|
22
24
|
import rehypeSanitize, { defaultSchema } from 'rehype-sanitize';
|
|
@@ -269,7 +271,7 @@ var transformUrl = (url, key, node) => {
|
|
|
269
271
|
}
|
|
270
272
|
return defaultUrlTransform(url);
|
|
271
273
|
};
|
|
272
|
-
var MarkdownContent =
|
|
274
|
+
var MarkdownContent = React3.memo(function MarkdownContent2({
|
|
273
275
|
text,
|
|
274
276
|
messageId,
|
|
275
277
|
streaming,
|
|
@@ -472,11 +474,11 @@ function useMessageCopy({
|
|
|
472
474
|
getText,
|
|
473
475
|
defaultFormat
|
|
474
476
|
}) {
|
|
475
|
-
const [copied, setCopied] =
|
|
476
|
-
const copiedTimer =
|
|
477
|
+
const [copied, setCopied] = React3.useState(false);
|
|
478
|
+
const copiedTimer = React3.useRef(
|
|
477
479
|
void 0
|
|
478
480
|
);
|
|
479
|
-
|
|
481
|
+
React3.useEffect(() => () => window.clearTimeout(copiedTimer.current), []);
|
|
480
482
|
const flash = () => {
|
|
481
483
|
setCopied(true);
|
|
482
484
|
window.clearTimeout(copiedTimer.current);
|
|
@@ -529,7 +531,7 @@ function FooterActionButton({
|
|
|
529
531
|
action,
|
|
530
532
|
isSelf
|
|
531
533
|
}) {
|
|
532
|
-
const [open, setOpen] =
|
|
534
|
+
const [open, setOpen] = React3.useState(false);
|
|
533
535
|
const onClickCapture = action.submenu ? (e) => {
|
|
534
536
|
if (e.metaKey || e.ctrlKey) {
|
|
535
537
|
e.preventDefault();
|
|
@@ -572,7 +574,7 @@ function FooterActionButton({
|
|
|
572
574
|
}
|
|
573
575
|
);
|
|
574
576
|
}
|
|
575
|
-
var MessageActionsBar =
|
|
577
|
+
var MessageActionsBar = React3.forwardRef(function MessageActionsBar2({ actions, isSelf }, ref) {
|
|
576
578
|
return /* @__PURE__ */ jsx(
|
|
577
579
|
"div",
|
|
578
580
|
{
|
|
@@ -588,7 +590,7 @@ function MessageOverflowMenu({
|
|
|
588
590
|
actions,
|
|
589
591
|
footerVisible
|
|
590
592
|
}) {
|
|
591
|
-
const [open, setOpen] =
|
|
593
|
+
const [open, setOpen] = React3.useState(false);
|
|
592
594
|
const select = (fn) => {
|
|
593
595
|
setOpen(false);
|
|
594
596
|
fn();
|
|
@@ -641,7 +643,7 @@ function MessageOverflowMenu({
|
|
|
641
643
|
}
|
|
642
644
|
);
|
|
643
645
|
}
|
|
644
|
-
var MessageRow =
|
|
646
|
+
var MessageRow = React3.memo(function MessageRow2({
|
|
645
647
|
message,
|
|
646
648
|
participant,
|
|
647
649
|
isSelf,
|
|
@@ -654,18 +656,18 @@ var MessageRow = React2.memo(function MessageRow2({
|
|
|
654
656
|
}) {
|
|
655
657
|
const streaming = message.status === "streaming";
|
|
656
658
|
const hasBody = !!message.text || (message.content?.length ?? 0) > 0;
|
|
657
|
-
const [isEditing, setIsEditing] =
|
|
658
|
-
const [draft, setDraft] =
|
|
659
|
-
const [editMinWidth, setEditMinWidth] =
|
|
660
|
-
const editRef =
|
|
661
|
-
const bubbleRef =
|
|
662
|
-
const autosize =
|
|
659
|
+
const [isEditing, setIsEditing] = React3.useState(false);
|
|
660
|
+
const [draft, setDraft] = React3.useState(message.text ?? "");
|
|
661
|
+
const [editMinWidth, setEditMinWidth] = React3.useState();
|
|
662
|
+
const editRef = React3.useRef(null);
|
|
663
|
+
const bubbleRef = React3.useRef(null);
|
|
664
|
+
const autosize = React3.useCallback(() => {
|
|
663
665
|
const el = editRef.current;
|
|
664
666
|
if (!el) return;
|
|
665
667
|
el.style.height = "auto";
|
|
666
668
|
el.style.height = `${el.scrollHeight}px`;
|
|
667
669
|
}, []);
|
|
668
|
-
|
|
670
|
+
React3.useEffect(() => {
|
|
669
671
|
if (!isEditing) return;
|
|
670
672
|
const el = editRef.current;
|
|
671
673
|
if (!el) return;
|
|
@@ -696,9 +698,9 @@ ${block.text}
|
|
|
696
698
|
getText: () => bubbleRef.current?.textContent ?? "",
|
|
697
699
|
defaultFormat: defaultCopyFormat
|
|
698
700
|
});
|
|
699
|
-
const actionsBarRef =
|
|
700
|
-
const [footerVisible, setFooterVisible] =
|
|
701
|
-
|
|
701
|
+
const actionsBarRef = React3.useRef(null);
|
|
702
|
+
const [footerVisible, setFooterVisible] = React3.useState(true);
|
|
703
|
+
React3.useEffect(() => {
|
|
702
704
|
const el = actionsBarRef.current;
|
|
703
705
|
if (!el || typeof globalThis.IntersectionObserver === "undefined") return;
|
|
704
706
|
const observer = new globalThis.IntersectionObserver(([entry]) => {
|
|
@@ -1049,32 +1051,23 @@ function VirtualThread({
|
|
|
1049
1051
|
editable,
|
|
1050
1052
|
onMessageEdited,
|
|
1051
1053
|
defaultCopyFormat,
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
+
scrollRef,
|
|
1055
|
+
contentRef,
|
|
1054
1056
|
containerProps
|
|
1055
1057
|
}) {
|
|
1056
|
-
const parentRef = React2.useRef(null);
|
|
1057
1058
|
const virtualizer = useVirtualizer({
|
|
1058
1059
|
count: items.length,
|
|
1059
|
-
getScrollElement: () =>
|
|
1060
|
+
getScrollElement: () => scrollRef.current,
|
|
1060
1061
|
// Rough first guess; real heights are measured via measureElement.
|
|
1061
1062
|
estimateSize: () => 88,
|
|
1062
1063
|
overscan: 10,
|
|
1063
1064
|
getItemKey: (index) => items[index]?.id ?? index
|
|
1064
1065
|
});
|
|
1065
|
-
const count = items.length;
|
|
1066
|
-
React2.useEffect(() => {
|
|
1067
|
-
if (count === 0) return;
|
|
1068
|
-
if (order === "desc") {
|
|
1069
|
-
virtualizer.scrollToIndex(0, { align: "start" });
|
|
1070
|
-
} else {
|
|
1071
|
-
virtualizer.scrollToIndex(count - 1, { align: "end" });
|
|
1072
|
-
}
|
|
1073
|
-
}, [count, conversationId, order]);
|
|
1074
1066
|
const virtualItems = virtualizer.getVirtualItems();
|
|
1075
|
-
return /* @__PURE__ */ jsx("div", { ...containerProps, ref:
|
|
1067
|
+
return /* @__PURE__ */ jsx("div", { ...containerProps, ref: scrollRef, children: /* @__PURE__ */ jsx(
|
|
1076
1068
|
"div",
|
|
1077
1069
|
{
|
|
1070
|
+
ref: contentRef,
|
|
1078
1071
|
style: {
|
|
1079
1072
|
height: virtualizer.getTotalSize(),
|
|
1080
1073
|
position: "relative",
|
|
@@ -1135,38 +1128,180 @@ function SuperChat({
|
|
|
1135
1128
|
onReferenceClick,
|
|
1136
1129
|
onBack
|
|
1137
1130
|
}) {
|
|
1138
|
-
const headingId =
|
|
1139
|
-
|
|
1131
|
+
const headingId = React3.useId();
|
|
1132
|
+
React3.useEffect(() => {
|
|
1140
1133
|
notifyComposerMigrationOnce("SuperChat");
|
|
1141
1134
|
}, []);
|
|
1142
|
-
const renderText =
|
|
1135
|
+
const renderText = React3.useMemo(
|
|
1143
1136
|
() => renderTextContent ?? createMarkdownRenderer({
|
|
1144
1137
|
plugins: renderPlugins,
|
|
1145
1138
|
trusted: trustedContent
|
|
1146
1139
|
}),
|
|
1147
1140
|
[renderTextContent, renderPlugins, trustedContent]
|
|
1148
1141
|
);
|
|
1149
|
-
const
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1142
|
+
const prefersReducedMotion = usePrefersReducedMotion();
|
|
1143
|
+
const {
|
|
1144
|
+
containerRef: threadRef,
|
|
1145
|
+
contentRef: threadContentRef,
|
|
1146
|
+
isAtBottom,
|
|
1147
|
+
scrollToBottom,
|
|
1148
|
+
anchorToTurnStart,
|
|
1149
|
+
followIfPinned,
|
|
1150
|
+
stopFollowing
|
|
1151
|
+
} = useStickToBottom({ disabled: order === "desc" });
|
|
1152
|
+
const [hasNewBelow, setHasNewBelow] = React3.useState(false);
|
|
1153
|
+
const [turnStartId, setTurnStartId] = React3.useState(null);
|
|
1154
|
+
const [turnMinHeight, setTurnMinHeight] = React3.useState();
|
|
1155
|
+
const anchoredTurnRef = React3.useRef(null);
|
|
1156
|
+
React3.useEffect(() => {
|
|
1157
|
+
setTurnStartId(null);
|
|
1158
|
+
anchoredTurnRef.current = null;
|
|
1159
|
+
if (order === "desc") {
|
|
1160
|
+
const el = threadRef.current;
|
|
1161
|
+
if (el) el.scrollTop = 0;
|
|
1162
|
+
} else {
|
|
1163
|
+
scrollToBottom("auto");
|
|
1164
|
+
}
|
|
1165
|
+
setHasNewBelow(false);
|
|
1166
|
+
}, [conversation.id, order]);
|
|
1167
|
+
const threadLength = conversation.thread.length;
|
|
1168
|
+
const prevThreadLengthRef = React3.useRef(threadLength);
|
|
1169
|
+
const prevMessageIdsRef = React3.useRef(
|
|
1170
|
+
new Set(conversation.thread.map((message) => message.id))
|
|
1171
|
+
);
|
|
1172
|
+
const policyConversationRef = React3.useRef(conversation.id);
|
|
1173
|
+
const policyBaselinedRef = React3.useRef(false);
|
|
1174
|
+
React3.useEffect(() => {
|
|
1175
|
+
if (!policyBaselinedRef.current || policyConversationRef.current !== conversation.id) {
|
|
1176
|
+
policyBaselinedRef.current = true;
|
|
1177
|
+
policyConversationRef.current = conversation.id;
|
|
1178
|
+
prevThreadLengthRef.current = threadLength;
|
|
1179
|
+
prevMessageIdsRef.current = new Set(
|
|
1180
|
+
conversation.thread.map((message) => message.id)
|
|
1181
|
+
);
|
|
1182
|
+
if (order !== "desc" && [...conversation.thread].sort(byTime).at(-1)?.status === "streaming") {
|
|
1183
|
+
stopFollowing();
|
|
1184
|
+
}
|
|
1185
|
+
return;
|
|
1186
|
+
}
|
|
1187
|
+
if (threadLength === prevThreadLengthRef.current) return;
|
|
1188
|
+
const grew = threadLength > prevThreadLengthRef.current;
|
|
1189
|
+
prevThreadLengthRef.current = threadLength;
|
|
1190
|
+
if (order === "desc") {
|
|
1191
|
+
const el = threadRef.current;
|
|
1192
|
+
if (el) el.scrollTop = 0;
|
|
1193
|
+
return;
|
|
1194
|
+
}
|
|
1195
|
+
const prevIds = prevMessageIdsRef.current;
|
|
1196
|
+
let turnStart;
|
|
1197
|
+
if (grew && currentParticipantId) {
|
|
1198
|
+
for (const message of [...conversation.thread].sort(byTime)) {
|
|
1199
|
+
if (!prevIds.has(message.id) && message.participantId === currentParticipantId) {
|
|
1200
|
+
turnStart = message.id;
|
|
1201
|
+
}
|
|
1202
|
+
}
|
|
1203
|
+
}
|
|
1204
|
+
if (turnStart) {
|
|
1205
|
+
if (virtualized) {
|
|
1206
|
+
scrollToBottom("auto");
|
|
1207
|
+
} else {
|
|
1208
|
+
setTurnStartId(turnStart);
|
|
1209
|
+
}
|
|
1210
|
+
} else if (grew) {
|
|
1211
|
+
const newest = [...conversation.thread].sort(byTime).at(-1);
|
|
1212
|
+
if (newest?.status === "streaming") {
|
|
1213
|
+
followIfPinned("auto");
|
|
1214
|
+
stopFollowing();
|
|
1215
|
+
} else if (!followIfPinned("auto")) {
|
|
1216
|
+
setHasNewBelow(true);
|
|
1217
|
+
}
|
|
1218
|
+
} else {
|
|
1219
|
+
followIfPinned("auto");
|
|
1220
|
+
}
|
|
1221
|
+
}, [threadLength, order, isAtBottom, conversation.id]);
|
|
1222
|
+
React3.useLayoutEffect(() => {
|
|
1223
|
+
if (!turnStartId || anchoredTurnRef.current === turnStartId) return;
|
|
1224
|
+
const container = threadRef.current;
|
|
1225
|
+
if (!container) return;
|
|
1226
|
+
const reserve = Math.max(0, container.clientHeight - 32);
|
|
1227
|
+
if (turnMinHeight !== reserve) {
|
|
1228
|
+
setTurnMinHeight(reserve);
|
|
1229
|
+
return;
|
|
1230
|
+
}
|
|
1231
|
+
const target = container.querySelector(
|
|
1232
|
+
'[data-slot="superchat-turn"]'
|
|
1233
|
+
);
|
|
1234
|
+
if (target) {
|
|
1235
|
+
anchorToTurnStart(target, prefersReducedMotion ? "auto" : "smooth");
|
|
1236
|
+
anchoredTurnRef.current = turnStartId;
|
|
1237
|
+
}
|
|
1238
|
+
}, [
|
|
1239
|
+
turnStartId,
|
|
1240
|
+
turnMinHeight,
|
|
1241
|
+
anchorToTurnStart,
|
|
1242
|
+
prefersReducedMotion,
|
|
1243
|
+
threadRef
|
|
1244
|
+
]);
|
|
1245
|
+
React3.useEffect(() => {
|
|
1246
|
+
prevMessageIdsRef.current = new Set(
|
|
1247
|
+
conversation.thread.map((message) => message.id)
|
|
1248
|
+
);
|
|
1249
|
+
});
|
|
1250
|
+
React3.useEffect(() => {
|
|
1251
|
+
if (isAtBottom) setHasNewBelow(false);
|
|
1252
|
+
}, [isAtBottom]);
|
|
1253
|
+
const newestMessage = React3.useMemo(
|
|
1254
|
+
() => [...conversation.thread].sort(byTime).at(-1),
|
|
1255
|
+
[conversation]
|
|
1256
|
+
);
|
|
1257
|
+
const raiseNewBelow = React3.useCallback(() => {
|
|
1258
|
+
if (order !== "desc") setHasNewBelow(true);
|
|
1259
|
+
}, [order]);
|
|
1260
|
+
const resumeFollowing = React3.useCallback(() => {
|
|
1261
|
+
if (order !== "desc") scrollToBottom("auto");
|
|
1262
|
+
}, [order, scrollToBottom]);
|
|
1263
|
+
useStreamEndedBelowFold(
|
|
1264
|
+
newestMessage,
|
|
1265
|
+
isAtBottom,
|
|
1266
|
+
raiseNewBelow,
|
|
1267
|
+
resumeFollowing
|
|
1268
|
+
);
|
|
1269
|
+
const handleJumpToBottom = React3.useCallback(() => {
|
|
1270
|
+
scrollToBottom(prefersReducedMotion ? "auto" : "smooth");
|
|
1271
|
+
}, [scrollToBottom, prefersReducedMotion]);
|
|
1272
|
+
const participantById = React3.useMemo(() => {
|
|
1157
1273
|
const map = /* @__PURE__ */ new Map();
|
|
1158
1274
|
conversation.participants.forEach((p) => map.set(p.id, p));
|
|
1159
1275
|
return map;
|
|
1160
1276
|
}, [conversation]);
|
|
1161
|
-
const orderedThread =
|
|
1277
|
+
const orderedThread = React3.useMemo(() => {
|
|
1162
1278
|
const sorted = [...conversation.thread].sort(byTime);
|
|
1163
1279
|
return order === "desc" ? sorted.reverse() : sorted;
|
|
1164
1280
|
}, [conversation, order]);
|
|
1165
|
-
const
|
|
1281
|
+
const turnIndex = React3.useMemo(
|
|
1282
|
+
() => turnStartId && order !== "desc" ? orderedThread.findIndex((message) => message.id === turnStartId) : -1,
|
|
1283
|
+
[orderedThread, turnStartId, order]
|
|
1284
|
+
);
|
|
1285
|
+
const renderMessageRow = (m) => /* @__PURE__ */ jsx(
|
|
1286
|
+
MessageRow,
|
|
1287
|
+
{
|
|
1288
|
+
message: m,
|
|
1289
|
+
participant: participantById.get(m.participantId),
|
|
1290
|
+
isSelf: !!currentParticipantId && m.participantId === currentParticipantId,
|
|
1291
|
+
renderText,
|
|
1292
|
+
linkBuilder,
|
|
1293
|
+
onReferenceClick,
|
|
1294
|
+
editable,
|
|
1295
|
+
onMessageEdited: handleMessageEdited,
|
|
1296
|
+
defaultCopyFormat
|
|
1297
|
+
},
|
|
1298
|
+
m.id
|
|
1299
|
+
);
|
|
1300
|
+
const onMessageEditedRef = React3.useRef(onMessageEdited);
|
|
1166
1301
|
onMessageEditedRef.current = onMessageEdited;
|
|
1167
|
-
const conversationRef =
|
|
1302
|
+
const conversationRef = React3.useRef(conversation);
|
|
1168
1303
|
conversationRef.current = conversation;
|
|
1169
|
-
const handleMessageEdited =
|
|
1304
|
+
const handleMessageEdited = React3.useCallback(
|
|
1170
1305
|
(messageId, text) => {
|
|
1171
1306
|
onMessageEditedRef.current?.(messageId, text, {
|
|
1172
1307
|
conversation: conversationRef.current
|
|
@@ -1175,7 +1310,7 @@ function SuperChat({
|
|
|
1175
1310
|
[]
|
|
1176
1311
|
);
|
|
1177
1312
|
const editable = !readOnly && !!onMessageEdited;
|
|
1178
|
-
const mentionOptions =
|
|
1313
|
+
const mentionOptions = React3.useMemo(
|
|
1179
1314
|
() => conversation.participants.filter((p) => p.kind !== "system").map((p) => ({
|
|
1180
1315
|
id: p.id,
|
|
1181
1316
|
label: p.name,
|
|
@@ -1185,17 +1320,17 @@ function SuperChat({
|
|
|
1185
1320
|
})),
|
|
1186
1321
|
[conversation.participants]
|
|
1187
1322
|
);
|
|
1188
|
-
const composerAccept =
|
|
1323
|
+
const composerAccept = React3.useMemo(
|
|
1189
1324
|
() => acceptTokensFor(acceptedFileTypes),
|
|
1190
1325
|
[acceptedFileTypes]
|
|
1191
1326
|
);
|
|
1192
|
-
const [draft, setDraft] =
|
|
1193
|
-
const draftEpochRef =
|
|
1194
|
-
const handleDraftChange =
|
|
1327
|
+
const [draft, setDraft] = React3.useState("");
|
|
1328
|
+
const draftEpochRef = React3.useRef(0);
|
|
1329
|
+
const handleDraftChange = React3.useCallback((value) => {
|
|
1195
1330
|
draftEpochRef.current += 1;
|
|
1196
1331
|
setDraft(value);
|
|
1197
1332
|
}, []);
|
|
1198
|
-
const handleComposerSend =
|
|
1333
|
+
const handleComposerSend = React3.useCallback(
|
|
1199
1334
|
async (message) => {
|
|
1200
1335
|
const epoch = draftEpochRef.current;
|
|
1201
1336
|
try {
|
|
@@ -1291,55 +1426,69 @@ function SuperChat({
|
|
|
1291
1426
|
]
|
|
1292
1427
|
}
|
|
1293
1428
|
),
|
|
1294
|
-
|
|
1295
|
-
VirtualThread,
|
|
1296
|
-
{
|
|
1297
|
-
items: orderedThread,
|
|
1298
|
-
participantById,
|
|
1299
|
-
currentParticipantId,
|
|
1300
|
-
renderText,
|
|
1301
|
-
linkBuilder,
|
|
1302
|
-
onReferenceClick,
|
|
1303
|
-
editable,
|
|
1304
|
-
onMessageEdited: handleMessageEdited,
|
|
1305
|
-
defaultCopyFormat,
|
|
1306
|
-
order,
|
|
1307
|
-
conversationId: conversation.id,
|
|
1308
|
-
containerProps: {
|
|
1309
|
-
"data-slot": "superchat-thread",
|
|
1310
|
-
role: "log",
|
|
1311
|
-
"aria-label": "Messages",
|
|
1312
|
-
"aria-live": "polite",
|
|
1313
|
-
// Focusable so keyboard-only users can scroll the message history.
|
|
1314
|
-
tabIndex: 0,
|
|
1315
|
-
className: "flex-1 overflow-y-auto p-4"
|
|
1316
|
-
}
|
|
1317
|
-
}
|
|
1318
|
-
) : /* @__PURE__ */ jsx(
|
|
1429
|
+
/* @__PURE__ */ jsxs(
|
|
1319
1430
|
"div",
|
|
1320
1431
|
{
|
|
1321
|
-
"data-slot": "superchat-thread",
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1432
|
+
"data-slot": "superchat-thread-viewport",
|
|
1433
|
+
className: "relative flex min-h-0 flex-1 flex-col",
|
|
1434
|
+
children: [
|
|
1435
|
+
virtualized ? /* @__PURE__ */ jsx(
|
|
1436
|
+
VirtualThread,
|
|
1437
|
+
{
|
|
1438
|
+
items: orderedThread,
|
|
1439
|
+
participantById,
|
|
1440
|
+
currentParticipantId,
|
|
1441
|
+
renderText,
|
|
1442
|
+
linkBuilder,
|
|
1443
|
+
onReferenceClick,
|
|
1444
|
+
editable,
|
|
1445
|
+
onMessageEdited: handleMessageEdited,
|
|
1446
|
+
defaultCopyFormat,
|
|
1447
|
+
scrollRef: threadRef,
|
|
1448
|
+
contentRef: threadContentRef,
|
|
1449
|
+
containerProps: {
|
|
1450
|
+
"data-slot": "superchat-thread",
|
|
1451
|
+
role: "log",
|
|
1452
|
+
"aria-label": "Messages",
|
|
1453
|
+
"aria-live": "polite",
|
|
1454
|
+
// Focusable so keyboard-only users can scroll the message history.
|
|
1455
|
+
tabIndex: 0,
|
|
1456
|
+
className: "flex-1 overflow-y-auto p-4"
|
|
1457
|
+
}
|
|
1458
|
+
}
|
|
1459
|
+
) : /* @__PURE__ */ jsx(
|
|
1460
|
+
"div",
|
|
1461
|
+
{
|
|
1462
|
+
"data-slot": "superchat-thread",
|
|
1463
|
+
ref: threadRef,
|
|
1464
|
+
role: "log",
|
|
1465
|
+
"aria-label": "Messages",
|
|
1466
|
+
"aria-live": "polite",
|
|
1467
|
+
tabIndex: 0,
|
|
1468
|
+
className: "flex-1 overflow-y-auto p-4",
|
|
1469
|
+
children: /* @__PURE__ */ jsxs("div", { ref: threadContentRef, className: "space-y-4", children: [
|
|
1470
|
+
(turnIndex === -1 ? orderedThread : orderedThread.slice(0, turnIndex)).map(renderMessageRow),
|
|
1471
|
+
turnIndex !== -1 && /* @__PURE__ */ jsx(
|
|
1472
|
+
"div",
|
|
1473
|
+
{
|
|
1474
|
+
"data-slot": "superchat-turn",
|
|
1475
|
+
className: "space-y-4",
|
|
1476
|
+
style: { minHeight: turnMinHeight },
|
|
1477
|
+
children: orderedThread.slice(turnIndex).map(renderMessageRow)
|
|
1478
|
+
}
|
|
1479
|
+
)
|
|
1480
|
+
] })
|
|
1481
|
+
}
|
|
1482
|
+
),
|
|
1483
|
+
order !== "desc" && !isAtBottom && /* @__PURE__ */ jsx(
|
|
1484
|
+
JumpToBottomButton,
|
|
1485
|
+
{
|
|
1486
|
+
dataSlot: "superchat-jump-to-bottom",
|
|
1487
|
+
hasNewMessages: hasNewBelow,
|
|
1488
|
+
onClick: handleJumpToBottom
|
|
1489
|
+
}
|
|
1490
|
+
)
|
|
1491
|
+
]
|
|
1343
1492
|
}
|
|
1344
1493
|
),
|
|
1345
1494
|
/* @__PURE__ */ jsx(
|
|
@@ -1371,12 +1520,12 @@ function SuperChatConversations({
|
|
|
1371
1520
|
onConversationOpened,
|
|
1372
1521
|
onNewConversation
|
|
1373
1522
|
}) {
|
|
1374
|
-
const [internalActive, setInternalActive] =
|
|
1523
|
+
const [internalActive, setInternalActive] = React3.useState(
|
|
1375
1524
|
defaultActiveConversationId ?? conversations[0]?.id
|
|
1376
1525
|
);
|
|
1377
1526
|
const requestedId = activeConversationId ?? internalActive;
|
|
1378
1527
|
const activeId = conversations.some((c) => c.id === requestedId) ? requestedId : conversations[0]?.id;
|
|
1379
|
-
const sortedConversations =
|
|
1528
|
+
const sortedConversations = React3.useMemo(
|
|
1380
1529
|
() => [...conversations].sort((a, b) => lastActivityOf(b) - lastActivityOf(a)),
|
|
1381
1530
|
[conversations]
|
|
1382
1531
|
);
|
|
@@ -1465,13 +1614,13 @@ function SuperChatInbox({
|
|
|
1465
1614
|
onNewConversation,
|
|
1466
1615
|
onReferenceClick
|
|
1467
1616
|
}) {
|
|
1468
|
-
const [internalActive, setInternalActive] =
|
|
1617
|
+
const [internalActive, setInternalActive] = React3.useState(
|
|
1469
1618
|
defaultActiveConversationId ?? conversations[0]?.id
|
|
1470
1619
|
);
|
|
1471
1620
|
const requestedId = activeConversationId ?? internalActive;
|
|
1472
1621
|
const active = conversations.find((c) => c.id === requestedId) ?? conversations[0];
|
|
1473
1622
|
const activeId = active?.id;
|
|
1474
|
-
const [mobileView, setMobileView] =
|
|
1623
|
+
const [mobileView, setMobileView] = React3.useState("list");
|
|
1475
1624
|
const handleOpen = (c) => {
|
|
1476
1625
|
if (activeConversationId === void 0) setInternalActive(c.id);
|
|
1477
1626
|
setMobileView("chat");
|