@ai-matrx/messaging 0.15.9 → 0.15.11
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/CHANGELOG.md +12 -0
- package/dist/index.cjs +43 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +43 -6
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +334 -63
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +24 -45
- package/dist/react.d.ts +24 -45
- package/dist/react.js +335 -64
- package/dist/react.js.map +1 -1
- package/package.json +1 -1
package/dist/react.cjs
CHANGED
|
@@ -361,7 +361,7 @@ function splitText(content) {
|
|
|
361
361
|
}
|
|
362
362
|
function summarizeText(content, maxLength = 140) {
|
|
363
363
|
const parts = splitText(content).map(
|
|
364
|
-
(segment) => segment.type === "text" ? segment.value : segment.type === "reference" ? segment.reference.label : (
|
|
364
|
+
(segment) => segment.type === "text" ? segment.value.replace(/```[^\n]*\n([\s\S]*?)```/g, "$1").replace(/!\[([^\]]*)\]\([^)]*\)/g, "$1").replace(/\[([^\]]+)\]\([^)]*\)/g, "$1").replace(/^\s{0,3}(?:#{1,6}\s+|>\s*|[-*+]\s+|\d+\.\s+)/gm, "").replace(/([*_`~])\1*(.*?)\1+/g, "$2") : segment.type === "reference" ? segment.reference.label : (
|
|
365
365
|
// A fence we cannot read still SAYS something. Collapsing it to
|
|
366
366
|
// nothing is how a reference-only message becomes an inbox row that
|
|
367
367
|
// reads "No messages yet" — a screen telling a lie.
|
|
@@ -830,8 +830,7 @@ function projectMessageAction(value) {
|
|
|
830
830
|
payload: jsonObject(record["payload"])
|
|
831
831
|
};
|
|
832
832
|
}
|
|
833
|
-
function
|
|
834
|
-
const raw = metadata["attachments"];
|
|
833
|
+
function projectAttachmentList(raw) {
|
|
835
834
|
if (!Array.isArray(raw)) return [];
|
|
836
835
|
const attachments = [];
|
|
837
836
|
for (const entry of raw) {
|
|
@@ -853,8 +852,13 @@ function projectAttachments(metadata) {
|
|
|
853
852
|
}
|
|
854
853
|
return attachments;
|
|
855
854
|
}
|
|
855
|
+
function projectAttachments(metadata) {
|
|
856
|
+
return projectAttachmentList(metadata["attachments"]);
|
|
857
|
+
}
|
|
856
858
|
function projectReferences(metadata) {
|
|
857
|
-
|
|
859
|
+
return projectReferenceList(metadata["references"]);
|
|
860
|
+
}
|
|
861
|
+
function projectReferenceList(raw) {
|
|
858
862
|
if (!Array.isArray(raw)) return [];
|
|
859
863
|
const references = [];
|
|
860
864
|
for (const entry of raw) {
|
|
@@ -873,6 +877,35 @@ function projectReferences(metadata) {
|
|
|
873
877
|
}
|
|
874
878
|
return references;
|
|
875
879
|
}
|
|
880
|
+
function projectBroadcastMessage(value) {
|
|
881
|
+
const operation = "projectBroadcastMessage";
|
|
882
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
883
|
+
throw invalidResponse(operation, "broadcast payload was not an object");
|
|
884
|
+
}
|
|
885
|
+
const record = value;
|
|
886
|
+
const kindRaw = str(record, "kind") ?? str(record, "messageType") ?? "text";
|
|
887
|
+
const stateRaw = str(record, "deliveryState") ?? str(record, "status") ?? "sent";
|
|
888
|
+
const metadata = jsonObject(record["metadata"]);
|
|
889
|
+
return {
|
|
890
|
+
id: requiredStr(record, "id", operation),
|
|
891
|
+
conversationId: requiredStr(record, "conversationId", operation),
|
|
892
|
+
senderId: requiredStr(record, "senderId", operation),
|
|
893
|
+
organizationId: requiredStr(record, "organizationId", operation),
|
|
894
|
+
content: typeof record["content"] === "string" ? record["content"] : "",
|
|
895
|
+
kind: MESSAGE_KINDS.has(kindRaw) ? kindRaw : "text",
|
|
896
|
+
deliveryState: DELIVERY_STATES.has(stateRaw) ? stateRaw : "sent",
|
|
897
|
+
replyToId: str(record, "replyToId"),
|
|
898
|
+
clientMessageId: str(record, "clientMessageId"),
|
|
899
|
+
createdAt: requiredStr(record, "createdAt", operation),
|
|
900
|
+
editedAt: str(record, "editedAt"),
|
|
901
|
+
deletedAt: str(record, "deletedAt"),
|
|
902
|
+
deletedForEveryone: bool(record, "deletedForEveryone", false),
|
|
903
|
+
action: projectMessageAction(record["action"]),
|
|
904
|
+
attachments: projectAttachmentList(record["attachments"]),
|
|
905
|
+
references: projectReferenceList(record["references"]),
|
|
906
|
+
metadata
|
|
907
|
+
};
|
|
908
|
+
}
|
|
876
909
|
function projectMessage(row, fallbackOrganizationId) {
|
|
877
910
|
const operation = "projectMessage";
|
|
878
911
|
const metadata = jsonObject(row["metadata"]);
|
|
@@ -1346,6 +1379,7 @@ function createMessagingEngine(options) {
|
|
|
1346
1379
|
store,
|
|
1347
1380
|
outbox,
|
|
1348
1381
|
identity,
|
|
1382
|
+
reportDiagnostic: report,
|
|
1349
1383
|
async start() {
|
|
1350
1384
|
if (options.archiveFilter !== void 0) {
|
|
1351
1385
|
store.setArchiveFilter(options.archiveFilter);
|
|
@@ -1487,8 +1521,11 @@ function createMessagingEngine(options) {
|
|
|
1487
1521
|
{
|
|
1488
1522
|
event: MESSAGING_EVENTS.message,
|
|
1489
1523
|
onMessage: ({ data }) => {
|
|
1490
|
-
|
|
1491
|
-
|
|
1524
|
+
try {
|
|
1525
|
+
store.ingest(projectBroadcastMessage(data));
|
|
1526
|
+
} catch (error) {
|
|
1527
|
+
reportError(error, "broadcastMessage");
|
|
1528
|
+
}
|
|
1492
1529
|
}
|
|
1493
1530
|
}
|
|
1494
1531
|
],
|
|
@@ -2397,6 +2434,7 @@ function MessagingRuntime(props) {
|
|
|
2397
2434
|
}, [renderers]);
|
|
2398
2435
|
const renderReference = props.renderReference ?? null;
|
|
2399
2436
|
const renderFence = props.renderFence ?? null;
|
|
2437
|
+
const renderAttachment = props.renderAttachment ?? null;
|
|
2400
2438
|
const wrapMessage = props.wrapMessage ?? null;
|
|
2401
2439
|
const wrapConversationRow = props.wrapConversationRow ?? null;
|
|
2402
2440
|
const host = (0, import_react.useMemo)(() => {
|
|
@@ -2410,6 +2448,7 @@ function MessagingRuntime(props) {
|
|
|
2410
2448
|
actionRenderers: rendererMap,
|
|
2411
2449
|
renderReference,
|
|
2412
2450
|
renderFence,
|
|
2451
|
+
renderAttachment,
|
|
2413
2452
|
wrapMessage,
|
|
2414
2453
|
wrapConversationRow
|
|
2415
2454
|
};
|
|
@@ -2420,6 +2459,7 @@ function MessagingRuntime(props) {
|
|
|
2420
2459
|
rendererMap,
|
|
2421
2460
|
renderReference,
|
|
2422
2461
|
renderFence,
|
|
2462
|
+
renderAttachment,
|
|
2423
2463
|
wrapMessage,
|
|
2424
2464
|
wrapConversationRow
|
|
2425
2465
|
]);
|
|
@@ -2631,11 +2671,117 @@ function useConversation(id) {
|
|
|
2631
2671
|
}
|
|
2632
2672
|
};
|
|
2633
2673
|
}
|
|
2674
|
+
var EMPTY_COMPOSER_SESSION = {
|
|
2675
|
+
drafts: {},
|
|
2676
|
+
replies: {},
|
|
2677
|
+
additions: {}
|
|
2678
|
+
};
|
|
2679
|
+
var emptyComposerSnapshot = () => EMPTY_COMPOSER_SESSION;
|
|
2680
|
+
var subscribeToNothing = () => () => void 0;
|
|
2681
|
+
var composerSessions = /* @__PURE__ */ new WeakMap();
|
|
2682
|
+
var composerStorageFailures = /* @__PURE__ */ new WeakSet();
|
|
2683
|
+
function composerStorageKey(engine) {
|
|
2684
|
+
return `ai-matrx.messaging.composer.${engine.identity.userId}`;
|
|
2685
|
+
}
|
|
2686
|
+
function readComposerSession(engine) {
|
|
2687
|
+
try {
|
|
2688
|
+
if (typeof sessionStorage === "undefined") return EMPTY_COMPOSER_SESSION;
|
|
2689
|
+
const serialized = sessionStorage.getItem(composerStorageKey(engine));
|
|
2690
|
+
if (serialized === null) return EMPTY_COMPOSER_SESSION;
|
|
2691
|
+
const parsed = JSON.parse(serialized);
|
|
2692
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
2693
|
+
throw new Error("saved composer state was not an object");
|
|
2694
|
+
}
|
|
2695
|
+
const source = parsed;
|
|
2696
|
+
const drafts = {};
|
|
2697
|
+
if (typeof source["drafts"] === "object" && source["drafts"] !== null) {
|
|
2698
|
+
for (const [id, value] of Object.entries(source["drafts"])) {
|
|
2699
|
+
if (typeof value === "string") drafts[id] = value;
|
|
2700
|
+
}
|
|
2701
|
+
}
|
|
2702
|
+
const replies = {};
|
|
2703
|
+
if (typeof source["replies"] === "object" && source["replies"] !== null) {
|
|
2704
|
+
for (const [id, value] of Object.entries(source["replies"])) {
|
|
2705
|
+
if (value === null) replies[id] = null;
|
|
2706
|
+
else replies[id] = projectBroadcastMessage(value);
|
|
2707
|
+
}
|
|
2708
|
+
}
|
|
2709
|
+
const additions = {};
|
|
2710
|
+
if (typeof source["additions"] === "object" && source["additions"] !== null) {
|
|
2711
|
+
for (const [id, value] of Object.entries(source["additions"])) {
|
|
2712
|
+
if (!Array.isArray(value)) continue;
|
|
2713
|
+
additions[id] = value.filter((item) => {
|
|
2714
|
+
if (typeof item !== "object" || item === null || Array.isArray(item)) return false;
|
|
2715
|
+
const record = item;
|
|
2716
|
+
return typeof record["id"] === "string" && typeof record["label"] === "string";
|
|
2717
|
+
});
|
|
2718
|
+
}
|
|
2719
|
+
}
|
|
2720
|
+
return { drafts, replies, additions };
|
|
2721
|
+
} catch (error) {
|
|
2722
|
+
if (!composerStorageFailures.has(engine)) {
|
|
2723
|
+
composerStorageFailures.add(engine);
|
|
2724
|
+
engine.reportDiagnostic({
|
|
2725
|
+
level: "warn",
|
|
2726
|
+
message: `A saved message draft could not be restored: ${String(error?.message ?? error)}`,
|
|
2727
|
+
remedy: "The current draft remains usable. Re-add any missing attachments before sending."
|
|
2728
|
+
});
|
|
2729
|
+
}
|
|
2730
|
+
return EMPTY_COMPOSER_SESSION;
|
|
2731
|
+
}
|
|
2732
|
+
}
|
|
2733
|
+
function writeComposerSession(engine, snapshot) {
|
|
2734
|
+
try {
|
|
2735
|
+
if (typeof sessionStorage === "undefined") return;
|
|
2736
|
+
sessionStorage.setItem(composerStorageKey(engine), JSON.stringify(snapshot));
|
|
2737
|
+
} catch (error) {
|
|
2738
|
+
if (!composerStorageFailures.has(engine)) {
|
|
2739
|
+
composerStorageFailures.add(engine);
|
|
2740
|
+
engine.reportDiagnostic({
|
|
2741
|
+
level: "warn",
|
|
2742
|
+
message: `The current message draft could not be saved for reload recovery: ${String(error?.message ?? error)}`,
|
|
2743
|
+
remedy: "Keep this tab open until the message is sent, or copy the draft before reloading."
|
|
2744
|
+
});
|
|
2745
|
+
}
|
|
2746
|
+
}
|
|
2747
|
+
}
|
|
2748
|
+
function getComposerSession(engine) {
|
|
2749
|
+
const existing = composerSessions.get(engine);
|
|
2750
|
+
if (existing !== void 0) return existing;
|
|
2751
|
+
let snapshot = readComposerSession(engine);
|
|
2752
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
2753
|
+
const store = {
|
|
2754
|
+
getSnapshot: () => snapshot,
|
|
2755
|
+
subscribe: (listener) => {
|
|
2756
|
+
listeners.add(listener);
|
|
2757
|
+
return () => listeners.delete(listener);
|
|
2758
|
+
},
|
|
2759
|
+
update: (change) => {
|
|
2760
|
+
snapshot = change(snapshot);
|
|
2761
|
+
writeComposerSession(engine, snapshot);
|
|
2762
|
+
listeners.forEach((listener) => listener());
|
|
2763
|
+
}
|
|
2764
|
+
};
|
|
2765
|
+
composerSessions.set(engine, store);
|
|
2766
|
+
return store;
|
|
2767
|
+
}
|
|
2634
2768
|
function useComposer(conversationId) {
|
|
2635
2769
|
const host = useMessagingHost();
|
|
2636
|
-
const
|
|
2637
|
-
const
|
|
2638
|
-
|
|
2770
|
+
const session = host === null ? null : getComposerSession(host.engine);
|
|
2771
|
+
const composer = (0, import_react3.useSyncExternalStore)(
|
|
2772
|
+
session?.subscribe ?? subscribeToNothing,
|
|
2773
|
+
session?.getSnapshot ?? emptyComposerSnapshot,
|
|
2774
|
+
emptyComposerSnapshot
|
|
2775
|
+
);
|
|
2776
|
+
const replyTo = conversationId === null ? null : composer.replies[conversationId] ?? null;
|
|
2777
|
+
const additions = conversationId === null ? [] : composer.additions[conversationId] ?? [];
|
|
2778
|
+
const setReplyTo = (message) => {
|
|
2779
|
+
if (conversationId !== null) session?.update((current) => ({
|
|
2780
|
+
...current,
|
|
2781
|
+
replies: { ...current.replies, [conversationId]: message }
|
|
2782
|
+
}));
|
|
2783
|
+
};
|
|
2784
|
+
const value = conversationId === null ? "" : composer.drafts[conversationId] ?? "";
|
|
2639
2785
|
const typing = (0, import_react4.useTyping)(
|
|
2640
2786
|
{
|
|
2641
2787
|
topic: conversationId === null ? "" : conversationTopic(conversationId),
|
|
@@ -2646,26 +2792,57 @@ function useComposer(conversationId) {
|
|
|
2646
2792
|
const setValue = (0, import_react3.useCallback)(
|
|
2647
2793
|
(next) => {
|
|
2648
2794
|
if (conversationId === null) return;
|
|
2649
|
-
|
|
2795
|
+
session?.update((current) => ({
|
|
2796
|
+
...current,
|
|
2797
|
+
drafts: { ...current.drafts, [conversationId]: next }
|
|
2798
|
+
}));
|
|
2650
2799
|
},
|
|
2651
|
-
[conversationId]
|
|
2800
|
+
[conversationId, session]
|
|
2652
2801
|
);
|
|
2653
2802
|
return {
|
|
2654
2803
|
value,
|
|
2655
2804
|
setValue,
|
|
2656
|
-
|
|
2805
|
+
additions,
|
|
2806
|
+
add: (item) => {
|
|
2807
|
+
if (conversationId !== null) session?.update((current) => ({
|
|
2808
|
+
...current,
|
|
2809
|
+
additions: {
|
|
2810
|
+
...current.additions,
|
|
2811
|
+
[conversationId]: [
|
|
2812
|
+
...(current.additions[conversationId] ?? []).filter((existing) => existing.id !== item.id),
|
|
2813
|
+
item
|
|
2814
|
+
]
|
|
2815
|
+
}
|
|
2816
|
+
}));
|
|
2817
|
+
},
|
|
2818
|
+
removeAddition: (id) => {
|
|
2819
|
+
if (conversationId !== null) session?.update((current) => ({
|
|
2820
|
+
...current,
|
|
2821
|
+
additions: {
|
|
2822
|
+
...current.additions,
|
|
2823
|
+
[conversationId]: (current.additions[conversationId] ?? []).filter((item) => item.id !== id)
|
|
2824
|
+
}
|
|
2825
|
+
}));
|
|
2826
|
+
},
|
|
2827
|
+
canSend: (value.trim().length > 0 || additions.length > 0) && conversationId !== null && host !== null,
|
|
2657
2828
|
send: () => {
|
|
2658
|
-
if (host === null || conversationId === null) return;
|
|
2659
|
-
const content = value.trim();
|
|
2660
|
-
|
|
2829
|
+
if (host === null || conversationId === null || session === null) return;
|
|
2830
|
+
const content = [value.trim(), ...additions.map((item) => item.content ?? "")].filter(Boolean).join("\n\n");
|
|
2831
|
+
const attachments = additions.flatMap((item) => item.attachment ? [item.attachment] : []);
|
|
2832
|
+
if (content.length === 0 && attachments.length === 0) return;
|
|
2661
2833
|
const draft = {
|
|
2662
2834
|
conversationId,
|
|
2663
2835
|
content,
|
|
2836
|
+
attachments,
|
|
2664
2837
|
...replyTo !== null ? { replyToId: replyTo.id } : {}
|
|
2665
2838
|
};
|
|
2666
2839
|
host.engine.send(draft);
|
|
2667
|
-
|
|
2668
|
-
|
|
2840
|
+
session.update((current) => ({
|
|
2841
|
+
...current,
|
|
2842
|
+
drafts: { ...current.drafts, [conversationId]: "" },
|
|
2843
|
+
replies: { ...current.replies, [conversationId]: null },
|
|
2844
|
+
additions: { ...current.additions, [conversationId]: [] }
|
|
2845
|
+
}));
|
|
2669
2846
|
typing.stopTyping();
|
|
2670
2847
|
},
|
|
2671
2848
|
onKeystroke: typing.onKeystroke,
|
|
@@ -3176,6 +3353,7 @@ function ConversationList(props) {
|
|
|
3176
3353
|
} = useConversations();
|
|
3177
3354
|
const RowChrome = useMessagingHost()?.wrapConversationRow ?? null;
|
|
3178
3355
|
const [query, setQuery] = (0, import_react5.useState)("");
|
|
3356
|
+
const favoritePageRequestCount = (0, import_react5.useRef)(null);
|
|
3179
3357
|
const showingArchive = archiveFilter === "archived";
|
|
3180
3358
|
const archiveReveal = (0, import_react5.useMemo)(() => {
|
|
3181
3359
|
if (showingArchive) {
|
|
@@ -3201,6 +3379,51 @@ function ConversationList(props) {
|
|
|
3201
3379
|
(item) => item.displayName.toLowerCase().includes(needle) || (item.lastMessageContent ?? "").toLowerCase().includes(needle)
|
|
3202
3380
|
);
|
|
3203
3381
|
}, [conversations, query]);
|
|
3382
|
+
const loadNextPage = () => {
|
|
3383
|
+
if (favoritePageRequestCount.current === conversations.length) return;
|
|
3384
|
+
favoritePageRequestCount.current = conversations.length;
|
|
3385
|
+
loadMore();
|
|
3386
|
+
};
|
|
3387
|
+
const hasUnloadedFavorites = (props.pinnedConversationIds ?? []).some(
|
|
3388
|
+
(id) => !conversations.some((item) => String(item.conversation.id) === id)
|
|
3389
|
+
);
|
|
3390
|
+
(0, import_react5.useEffect)(() => {
|
|
3391
|
+
if (!hasUnloadedFavorites || !hasMore || isInitialLoading || loadError !== null || favoritePageRequestCount.current === conversations.length) {
|
|
3392
|
+
return;
|
|
3393
|
+
}
|
|
3394
|
+
loadNextPage();
|
|
3395
|
+
}, [
|
|
3396
|
+
conversations,
|
|
3397
|
+
hasMore,
|
|
3398
|
+
hasUnloadedFavorites,
|
|
3399
|
+
isInitialLoading,
|
|
3400
|
+
loadError,
|
|
3401
|
+
loadMore,
|
|
3402
|
+
loadNextPage
|
|
3403
|
+
]);
|
|
3404
|
+
const { favoriteItems, otherPinnedItems, unpinnedItems } = (0, import_react5.useMemo)(() => {
|
|
3405
|
+
const visibleById = new Map(
|
|
3406
|
+
visible.map((item) => [String(item.conversation.id), item])
|
|
3407
|
+
);
|
|
3408
|
+
const pinnedItems = (props.pinnedConversationIds ?? []).map((id) => visibleById.get(id)).filter((item) => item !== void 0);
|
|
3409
|
+
const uniquePinnedItems = Array.from(
|
|
3410
|
+
new Map(pinnedItems.map((item) => [item.conversation.id, item])).values()
|
|
3411
|
+
).sort((left, right) => {
|
|
3412
|
+
const byRecency = Date.parse(right.sortAt) - Date.parse(left.sortAt);
|
|
3413
|
+
return Number.isNaN(byRecency) || byRecency === 0 ? String(left.conversation.id).localeCompare(String(right.conversation.id)) : byRecency;
|
|
3414
|
+
});
|
|
3415
|
+
const pinnedIds = new Set(uniquePinnedItems.map((item) => item.conversation.id));
|
|
3416
|
+
return {
|
|
3417
|
+
favoriteItems: uniquePinnedItems.slice(0, 3),
|
|
3418
|
+
otherPinnedItems: uniquePinnedItems.slice(3),
|
|
3419
|
+
unpinnedItems: visible.filter((item) => !pinnedIds.has(item.conversation.id))
|
|
3420
|
+
};
|
|
3421
|
+
}, [visible, props.pinnedConversationIds]);
|
|
3422
|
+
const selectItem = (item) => {
|
|
3423
|
+
select(item.conversation.id);
|
|
3424
|
+
props.onSelect?.(item.conversation.id);
|
|
3425
|
+
};
|
|
3426
|
+
const wrapRow = (item, row) => RowChrome !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(RowChrome, { conversation: item, children: row }) : row;
|
|
3204
3427
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: `mx-msg__list${props.className !== void 0 ? ` ${props.className}` : ""}`, children: [
|
|
3205
3428
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-msg__search", children: [
|
|
3206
3429
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(SearchIcon, { style: { color: "var(--mx-msg-text-faint)" } }),
|
|
@@ -3256,33 +3479,67 @@ function ConversationList(props) {
|
|
|
3256
3479
|
title: query.length > 0 ? "No matches" : showingArchive ? "No archived conversations" : "No conversations yet",
|
|
3257
3480
|
body: query.length > 0 ? "Try a different name or word." : showingArchive ? "Archiving a conversation moves it here." : "Start one and it will appear here."
|
|
3258
3481
|
}
|
|
3259
|
-
) : /* @__PURE__ */ (0, import_jsx_runtime4.
|
|
3260
|
-
|
|
3261
|
-
|
|
3262
|
-
|
|
3263
|
-
|
|
3264
|
-
|
|
3265
|
-
|
|
3266
|
-
|
|
3267
|
-
props.onSelect?.(item.conversation.id);
|
|
3482
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
|
|
3483
|
+
favoriteItems.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("ul", { className: "mx-msg__favorites", "aria-label": "Favorite conversations", children: favoriteItems.map((item) => {
|
|
3484
|
+
const row = /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
3485
|
+
ConversationFavorite,
|
|
3486
|
+
{
|
|
3487
|
+
summary: item,
|
|
3488
|
+
isActive: item.conversation.id === activeConversationId,
|
|
3489
|
+
onSelect: () => selectItem(item)
|
|
3268
3490
|
}
|
|
3269
|
-
|
|
3270
|
-
|
|
3271
|
-
|
|
3272
|
-
|
|
3491
|
+
);
|
|
3492
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("li", { children: wrapRow(item, row) }, item.conversation.id);
|
|
3493
|
+
}) }) : null,
|
|
3494
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("ul", { className: "mx-msg__rows", children: [...otherPinnedItems, ...unpinnedItems].map((item) => {
|
|
3495
|
+
const row = /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
3496
|
+
ConversationRow,
|
|
3497
|
+
{
|
|
3498
|
+
summary: item,
|
|
3499
|
+
isActive: item.conversation.id === activeConversationId,
|
|
3500
|
+
onSelect: () => selectItem(item)
|
|
3501
|
+
}
|
|
3502
|
+
);
|
|
3503
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("li", { children: wrapRow(item, row) }, item.conversation.id);
|
|
3504
|
+
}) })
|
|
3505
|
+
] }),
|
|
3273
3506
|
hasMore && !isInitialLoading ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
3274
3507
|
"button",
|
|
3275
3508
|
{
|
|
3276
3509
|
type: "button",
|
|
3277
3510
|
className: "mx-msg__chip",
|
|
3278
3511
|
style: { margin: "8px auto", display: "block" },
|
|
3279
|
-
onClick:
|
|
3512
|
+
onClick: loadNextPage,
|
|
3280
3513
|
children: "Load older conversations"
|
|
3281
3514
|
}
|
|
3282
3515
|
) : null
|
|
3283
3516
|
] })
|
|
3284
3517
|
] });
|
|
3285
3518
|
}
|
|
3519
|
+
function ConversationFavorite(props) {
|
|
3520
|
+
const { summary } = props;
|
|
3521
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
3522
|
+
"button",
|
|
3523
|
+
{
|
|
3524
|
+
type: "button",
|
|
3525
|
+
className: "mx-msg__favorite",
|
|
3526
|
+
"aria-current": props.isActive,
|
|
3527
|
+
"aria-label": `Open favorite conversation with ${summary.displayName}`,
|
|
3528
|
+
onClick: props.onSelect,
|
|
3529
|
+
children: [
|
|
3530
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
3531
|
+
Avatar,
|
|
3532
|
+
{
|
|
3533
|
+
name: summary.displayName,
|
|
3534
|
+
imageUrl: summary.displayImageUrl,
|
|
3535
|
+
seed: summary.conversation.id
|
|
3536
|
+
}
|
|
3537
|
+
),
|
|
3538
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-msg__favorite-name", children: summary.displayName })
|
|
3539
|
+
]
|
|
3540
|
+
}
|
|
3541
|
+
);
|
|
3542
|
+
}
|
|
3286
3543
|
function ConversationRow(props) {
|
|
3287
3544
|
const { summary } = props;
|
|
3288
3545
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
@@ -3457,6 +3714,8 @@ function ConversationView(props) {
|
|
|
3457
3714
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
3458
3715
|
MessageGroupView,
|
|
3459
3716
|
{
|
|
3717
|
+
allMessages: messages,
|
|
3718
|
+
showAuthor: conversation.summary?.conversation.type !== "direct",
|
|
3460
3719
|
messages: group.messages,
|
|
3461
3720
|
actor,
|
|
3462
3721
|
isMine,
|
|
@@ -3488,37 +3747,41 @@ function MessageGroupView(props) {
|
|
|
3488
3747
|
const first = props.messages[0];
|
|
3489
3748
|
if (first === void 0) return null;
|
|
3490
3749
|
const actor = props.actor;
|
|
3491
|
-
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
3492
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
3493
|
-
|
|
3494
|
-
|
|
3495
|
-
|
|
3496
|
-
imageUrl: actor.avatarUrl,
|
|
3497
|
-
seed: actor.isAgent ? `agent:${actor.displayName}` : actor.principalUserId,
|
|
3498
|
-
small: true
|
|
3499
|
-
}
|
|
3500
|
-
),
|
|
3501
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-msg__group-body", children: [
|
|
3502
|
-
!props.isMine || actor.isAgent ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-msg__author", children: [
|
|
3503
|
-
actor.displayName,
|
|
3504
|
-
actor.isAgent ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(AgentTag, {}) : null,
|
|
3505
|
-
actor.onBehalfOfName !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { style: { fontWeight: 400, color: "var(--mx-msg-text-faint)" }, children: [
|
|
3506
|
-
"via ",
|
|
3507
|
-
actor.onBehalfOfName
|
|
3508
|
-
] }) : null
|
|
3509
|
-
] }) : null,
|
|
3510
|
-
props.messages.map((message, index) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
3511
|
-
MessageBubble,
|
|
3750
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
|
|
3751
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "mx-msg__group-time", children: formatMessageTime(first.createdAt) }),
|
|
3752
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: `mx-msg__group${props.isMine ? " mx-msg__group--mine" : ""}`, children: [
|
|
3753
|
+
props.showAuthor || actor.isAgent ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
3754
|
+
Avatar,
|
|
3512
3755
|
{
|
|
3513
|
-
|
|
3514
|
-
|
|
3515
|
-
|
|
3516
|
-
|
|
3517
|
-
|
|
3518
|
-
|
|
3519
|
-
|
|
3520
|
-
|
|
3521
|
-
|
|
3756
|
+
name: actor.displayName,
|
|
3757
|
+
imageUrl: actor.avatarUrl,
|
|
3758
|
+
seed: actor.isAgent ? `agent:${actor.displayName}` : actor.principalUserId,
|
|
3759
|
+
small: true
|
|
3760
|
+
}
|
|
3761
|
+
) : null,
|
|
3762
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-msg__group-body", children: [
|
|
3763
|
+
props.showAuthor && !props.isMine || actor.isAgent ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mx-msg__author", children: [
|
|
3764
|
+
actor.displayName,
|
|
3765
|
+
actor.isAgent ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(AgentTag, {}) : null,
|
|
3766
|
+
actor.onBehalfOfName !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { style: { fontWeight: 400, color: "var(--mx-msg-text-faint)" }, children: [
|
|
3767
|
+
"via ",
|
|
3768
|
+
actor.onBehalfOfName
|
|
3769
|
+
] }) : null
|
|
3770
|
+
] }) : null,
|
|
3771
|
+
props.messages.map((message, index) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
3772
|
+
MessageBubble,
|
|
3773
|
+
{
|
|
3774
|
+
message,
|
|
3775
|
+
replyTo: props.allMessages.find((parent) => parent.id === message.replyToId),
|
|
3776
|
+
isMine: props.isMine,
|
|
3777
|
+
isLast: index === props.messages.length - 1,
|
|
3778
|
+
onRetry: props.onRetry,
|
|
3779
|
+
onReply: props.onReply,
|
|
3780
|
+
failedEntryId: message.clientMessageId !== null ? props.failedEntryIdByClientId.get(message.clientMessageId) ?? null : null
|
|
3781
|
+
},
|
|
3782
|
+
message.id
|
|
3783
|
+
))
|
|
3784
|
+
] })
|
|
3522
3785
|
] })
|
|
3523
3786
|
] });
|
|
3524
3787
|
}
|
|
@@ -3539,7 +3802,12 @@ function MessageBubble(props) {
|
|
|
3539
3802
|
message.deliveryState === "failed" ? "mx-msg__bubble--failed" : ""
|
|
3540
3803
|
].filter(Boolean).join(" ");
|
|
3541
3804
|
const bubble = /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
|
|
3542
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: classes, children: [
|
|
3805
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: classes, title: formatMessageTime(message.createdAt), children: [
|
|
3806
|
+
message.replyToId !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("blockquote", { className: "mx-msg__quoted-reply", children: props.replyTo ? props.replyTo.deletedAt ? "Message deleted" : summarizeText(props.replyTo.content, 180) || "Attachment" : "Earlier message" }) : null,
|
|
3807
|
+
message.attachments.map((attachment) => {
|
|
3808
|
+
const RenderAttachment = props.renderAttachment ?? host?.renderAttachment;
|
|
3809
|
+
return RenderAttachment ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(RenderAttachment, { attachment }, attachment.fileId) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ReferenceCard, { reference: { entityType: "file", entityId: attachment.fileId, label: attachment.fileName }, onOpen: host?.openReference ?? null }, attachment.fileId);
|
|
3810
|
+
}),
|
|
3543
3811
|
splitText(message.content).map(
|
|
3544
3812
|
(segment, index) => segment.type === "text" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "mx-msg__markdown", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_markdown.default, { remarkPlugins: [import_remark_gfm.default, import_remark_breaks.default], children: segment.value }) }, index) : segment.type === "fence" ? HostFence !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(HostFence, { body: segment.body }, `fence:${index}`) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(UnreadableReference, {}, `fence:${index}`) : HostReference !== null ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
3545
3813
|
HostReference,
|
|
@@ -3579,7 +3847,7 @@ function MessageBubble(props) {
|
|
|
3579
3847
|
{
|
|
3580
3848
|
className: `mx-msg__meta${message.deliveryState === "failed" ? " mx-msg__meta--failed" : ""}`,
|
|
3581
3849
|
children: [
|
|
3582
|
-
props.isLast ? formatMessageTime(message.createdAt) : null,
|
|
3850
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "mx-msg__message-time", children: props.isLast ? formatMessageTime(message.createdAt) : null }),
|
|
3583
3851
|
message.editedAt !== null ? " \xB7 edited" : null,
|
|
3584
3852
|
isMine ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(DeliveryTick, { state: message.deliveryState }) : null,
|
|
3585
3853
|
message.deliveryState === "failed" && props.failedEntryId != null && props.onRetry !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
@@ -3674,6 +3942,9 @@ function ComposerView(props) {
|
|
|
3674
3942
|
)
|
|
3675
3943
|
] }) : null,
|
|
3676
3944
|
props.renderInput !== void 0 ? props.renderInput({
|
|
3945
|
+
additions: composer.additions,
|
|
3946
|
+
add: composer.add,
|
|
3947
|
+
removeAddition: composer.removeAddition,
|
|
3677
3948
|
value: composer.value,
|
|
3678
3949
|
disabled: props.disabled,
|
|
3679
3950
|
canSend: composer.canSend,
|