@convokitapp/vue-ui 0.2.0 → 0.2.1
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 +5 -0
- package/README.md +4 -0
- package/dist/index.cjs +40 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +40 -7
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -165,6 +165,8 @@ function useConversation(options) {
|
|
|
165
165
|
let sentTyping = false;
|
|
166
166
|
let typingTimer = null;
|
|
167
167
|
let subscriptions = [];
|
|
168
|
+
const pendingIds = /* @__PURE__ */ new Set();
|
|
169
|
+
let pendingSequence = 0;
|
|
168
170
|
const unsubscribe = async () => {
|
|
169
171
|
const active = subscriptions;
|
|
170
172
|
subscriptions = [];
|
|
@@ -188,7 +190,12 @@ function useConversation(options) {
|
|
|
188
190
|
subscriptions = [
|
|
189
191
|
client.onMessage(conversationId, (message) => {
|
|
190
192
|
if (disposed || activeGeneration !== generation) return;
|
|
191
|
-
messages.value
|
|
193
|
+
const pending = messages.value.find((candidate) => pendingIds.has(candidate.id) && message.senderId === client.currentUserId && candidate.text === message.text && candidate.media.length === message.media.length);
|
|
194
|
+
if (pending) pendingIds.delete(pending.id);
|
|
195
|
+
messages.value = mergeMessages(
|
|
196
|
+
pending ? messages.value.filter((candidate) => candidate.id !== pending.id) : messages.value,
|
|
197
|
+
[message]
|
|
198
|
+
);
|
|
192
199
|
if ((options.markReadOnReceive ?? true) && message.senderId !== client.currentUserId) void markRead();
|
|
193
200
|
}, report),
|
|
194
201
|
client.onReadReceipt(conversationId, ({ userId, readAt }) => {
|
|
@@ -212,6 +219,7 @@ function useConversation(options) {
|
|
|
212
219
|
await unsubscribe();
|
|
213
220
|
if (disposed || activeGeneration !== generation) return;
|
|
214
221
|
messages.value = [];
|
|
222
|
+
pendingIds.clear();
|
|
215
223
|
conversation.value = null;
|
|
216
224
|
typingUserIds.value = /* @__PURE__ */ new Set();
|
|
217
225
|
readAtByUserId.value = /* @__PURE__ */ new Map();
|
|
@@ -251,7 +259,7 @@ function useConversation(options) {
|
|
|
251
259
|
const page = await client.getMessages({
|
|
252
260
|
conversationId,
|
|
253
261
|
limit: messagePageSize,
|
|
254
|
-
offset: messages.value.length
|
|
262
|
+
offset: messages.value.filter((message) => !pendingIds.has(message.id)).length
|
|
255
263
|
});
|
|
256
264
|
if (disposed || activeGeneration !== generation) return;
|
|
257
265
|
messages.value = mergeMessages(messages.value, page);
|
|
@@ -282,6 +290,18 @@ function useConversation(options) {
|
|
|
282
290
|
const normalizedText = text?.trim();
|
|
283
291
|
if (!normalizedText && (!media || media.length === 0)) return null;
|
|
284
292
|
if (isSending.value) return null;
|
|
293
|
+
const pendingId = `convokit-pending-${Date.now()}-${++pendingSequence}`;
|
|
294
|
+
const pendingMessage = {
|
|
295
|
+
id: pendingId,
|
|
296
|
+
conversationId: toValue(options.conversationId),
|
|
297
|
+
senderId: toValue(options.client).currentUserId,
|
|
298
|
+
text: normalizedText ?? null,
|
|
299
|
+
media: media ?? [],
|
|
300
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
301
|
+
updatedAt: null
|
|
302
|
+
};
|
|
303
|
+
pendingIds.add(pendingId);
|
|
304
|
+
messages.value = mergeMessages(messages.value, [pendingMessage]);
|
|
285
305
|
isSending.value = true;
|
|
286
306
|
error.value = null;
|
|
287
307
|
const activeGeneration = generation;
|
|
@@ -291,11 +311,21 @@ function useConversation(options) {
|
|
|
291
311
|
...normalizedText ? { text: normalizedText } : {},
|
|
292
312
|
...media?.length ? { media } : {}
|
|
293
313
|
});
|
|
294
|
-
|
|
314
|
+
pendingIds.delete(pendingId);
|
|
315
|
+
if (!disposed && activeGeneration === generation) {
|
|
316
|
+
messages.value = mergeMessages(
|
|
317
|
+
messages.value.filter((candidate) => candidate.id !== pendingId),
|
|
318
|
+
[message]
|
|
319
|
+
);
|
|
320
|
+
}
|
|
295
321
|
await updateTyping(false);
|
|
296
322
|
return message;
|
|
297
323
|
} catch (cause) {
|
|
298
|
-
|
|
324
|
+
pendingIds.delete(pendingId);
|
|
325
|
+
if (!disposed) {
|
|
326
|
+
messages.value = messages.value.filter((candidate) => candidate.id !== pendingId);
|
|
327
|
+
error.value = cause;
|
|
328
|
+
}
|
|
299
329
|
return null;
|
|
300
330
|
} finally {
|
|
301
331
|
if (!disposed && activeGeneration === generation) isSending.value = false;
|
|
@@ -651,7 +681,9 @@ var ConversationView = defineComponent3({
|
|
|
651
681
|
...props.styles ? { styles: props.styles } : {}
|
|
652
682
|
});
|
|
653
683
|
const draft = () => props.modelValue ?? internalDraft.value;
|
|
684
|
+
let latestDraft = draft();
|
|
654
685
|
const setDraft = (value) => {
|
|
686
|
+
latestDraft = value;
|
|
655
687
|
if (props.modelValue === void 0) internalDraft.value = value;
|
|
656
688
|
props.onDraftChange?.(value);
|
|
657
689
|
emit("update:modelValue", value);
|
|
@@ -659,12 +691,14 @@ var ConversationView = defineComponent3({
|
|
|
659
691
|
void props.onTypingChange?.(isTyping);
|
|
660
692
|
};
|
|
661
693
|
const submit = async () => {
|
|
662
|
-
const
|
|
694
|
+
const originalDraft = draft();
|
|
695
|
+
const text = originalDraft.trim();
|
|
663
696
|
if (!text || props.isSending || submitting.value) return;
|
|
664
697
|
submitting.value = true;
|
|
698
|
+
setDraft("");
|
|
665
699
|
try {
|
|
666
700
|
const shouldClear = await props.onSendMessage(text);
|
|
667
|
-
if (shouldClear
|
|
701
|
+
if (shouldClear === false && latestDraft.length === 0) setDraft(originalDraft);
|
|
668
702
|
} finally {
|
|
669
703
|
submitting.value = false;
|
|
670
704
|
}
|
|
@@ -757,7 +791,6 @@ var ConversationView = defineComponent3({
|
|
|
757
791
|
class: cx(!props.unstyled && "ckui-composer__input", props.classNames?.input, props.composerProps?.class),
|
|
758
792
|
style: [props.styles?.input, props.composerProps?.style],
|
|
759
793
|
value: draft(),
|
|
760
|
-
disabled: props.isSending || submitting.value,
|
|
761
794
|
onInput: (event) => {
|
|
762
795
|
const handler = props.composerProps?.onInput;
|
|
763
796
|
if (typeof handler === "function") handler(event);
|