@codingfactory/socialkit-vue 0.7.5 → 0.7.7

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.
@@ -323,6 +323,78 @@ export function createDiscussionStoreDefinition(config: DiscussionStoreConfig) {
323
323
  }
324
324
  }
325
325
 
326
+ function hasQuotedReplyBody(quotedReply: Reply['quoted_reply']): boolean {
327
+ return typeof quotedReply?.body === 'string' && quotedReply.body.trim().length > 0
328
+ }
329
+
330
+ function hasQuotedReplyAuthorName(quotedReply: Reply['quoted_reply']): boolean {
331
+ return typeof quotedReply?.author?.name === 'string' && quotedReply.author.name.trim().length > 0
332
+ }
333
+
334
+ function buildQuotedReplyFromReply(sourceReply: Reply | null | undefined): Reply['quoted_reply'] {
335
+ if (!sourceReply?.id || !sourceReply.author_id || typeof sourceReply.body !== 'string' || sourceReply.body.trim().length === 0) {
336
+ return null
337
+ }
338
+
339
+ return {
340
+ id: sourceReply.id,
341
+ author_id: sourceReply.author_id,
342
+ author: sourceReply.author
343
+ ? {
344
+ id: sourceReply.author.id,
345
+ name: sourceReply.author.name,
346
+ ...(sourceReply.author.handle ? { handle: sourceReply.author.handle } : {}),
347
+ }
348
+ : null,
349
+ body: sourceReply.body,
350
+ }
351
+ }
352
+
353
+ function resolveQuotedReply(reply: Reply, existingReply?: Reply | null): Reply['quoted_reply'] {
354
+ const quotedReplyId = typeof reply.quoted_reply_id === 'string'
355
+ ? reply.quoted_reply_id.trim()
356
+ : ''
357
+
358
+ if (quotedReplyId.length === 0) {
359
+ return null
360
+ }
361
+
362
+ const incomingQuotedReply = reply.quoted_reply ?? null
363
+ if (hasQuotedReplyBody(incomingQuotedReply) && hasQuotedReplyAuthorName(incomingQuotedReply)) {
364
+ return incomingQuotedReply
365
+ }
366
+
367
+ const referencedReply = replies.value.find((candidate) => candidate.id === quotedReplyId)
368
+ const hydratedQuotedReply = buildQuotedReplyFromReply(referencedReply)
369
+ if (hydratedQuotedReply) {
370
+ return hydratedQuotedReply
371
+ }
372
+
373
+ const existingQuotedReply = existingReply?.quoted_reply ?? null
374
+ if (hasQuotedReplyBody(existingQuotedReply) && hasQuotedReplyAuthorName(existingQuotedReply)) {
375
+ return existingQuotedReply
376
+ }
377
+
378
+ return hasQuotedReplyBody(incomingQuotedReply) ? incomingQuotedReply : null
379
+ }
380
+
381
+ function normalizeReplyPayload(reply: Reply, existingReply?: Reply | null): Reply {
382
+ const normalized: Reply = { ...reply }
383
+ const hasQuotedReplyId = typeof normalized.quoted_reply_id === 'string'
384
+ && normalized.quoted_reply_id.trim().length > 0
385
+
386
+ if (!hasQuotedReplyId) {
387
+ normalized.quoted_reply_id = null
388
+ normalized.quoted_reply = null
389
+ normalized.quote_data = null
390
+ return normalized
391
+ }
392
+
393
+ normalized.quoted_reply = resolveQuotedReply(normalized, existingReply)
394
+
395
+ return normalized
396
+ }
397
+
326
398
  function mergeUniqueById<TItem extends { id: string }>(
327
399
  existingItems: TItem[],
328
400
  incomingItems: TItem[]
@@ -1210,7 +1282,8 @@ export function createDiscussionStoreDefinition(config: DiscussionStoreConfig) {
1210
1282
  })
1211
1283
 
1212
1284
  const responseData = toRecord(response.data)
1213
- const newReply = (responseData?.data ?? null) as Reply | null
1285
+ const createdReply = (responseData?.data ?? null) as Reply | null
1286
+ const newReply = createdReply ? normalizeReplyPayload(createdReply) : null
1214
1287
 
1215
1288
  if (newReply?.id) {
1216
1289
  locallyCreatedReplyIds.add(newReply.id)
@@ -1306,6 +1379,9 @@ export function createDiscussionStoreDefinition(config: DiscussionStoreConfig) {
1306
1379
  .listen('.Discussion.ReplyCreated', (payload: unknown) => {
1307
1380
  handleRealtimeReplyDetail(payload as Reply | null | undefined)
1308
1381
  })
1382
+ .listen('.Discussion.ReplyUpdated', (payload: unknown) => {
1383
+ handleRealtimeReplyUpdated(payload as Reply | null | undefined)
1384
+ })
1309
1385
  .listen('.Discussion.ReplyReactionToggled', (payload: unknown) => {
1310
1386
  handleRealtimeReplyReaction(payload as ReplyReactionRealtimePayload | null | undefined)
1311
1387
  })
@@ -1401,19 +1477,8 @@ export function createDiscussionStoreDefinition(config: DiscussionStoreConfig) {
1401
1477
  return
1402
1478
  }
1403
1479
 
1404
- const normalizedPayload: Reply = (() => {
1405
- const normalized: Reply = { ...payload }
1406
-
1407
- const quotedReplyId = normalized.quoted_reply_id
1408
- const hasQuotedReplyId = typeof quotedReplyId === 'string' && quotedReplyId.trim().length > 0
1409
- if (!hasQuotedReplyId) {
1410
- normalized.quoted_reply_id = null
1411
- normalized.quoted_reply = null
1412
- normalized.quote_data = null
1413
- }
1414
-
1415
- return normalized
1416
- })()
1480
+ const existingReply = replies.value.find((candidate) => candidate.id === payload.id) ?? null
1481
+ const normalizedPayload = normalizeReplyPayload(payload, existingReply)
1417
1482
 
1418
1483
  const didInsertReply = insertReplyIntoActiveThread(
1419
1484
  normalizedPayload,
@@ -1427,6 +1492,34 @@ export function createDiscussionStoreDefinition(config: DiscussionStoreConfig) {
1427
1492
  }
1428
1493
  }
1429
1494
 
1495
+ function handleRealtimeReplyUpdated(payload: Reply | null | undefined): void {
1496
+ if (!payload?.id || !payload.thread_id) {
1497
+ return
1498
+ }
1499
+
1500
+ if (currentThread.value?.id !== payload.thread_id) {
1501
+ return
1502
+ }
1503
+
1504
+ const replyIndex = replies.value.findIndex((candidate) => candidate.id === payload.id)
1505
+ if (replyIndex === -1) {
1506
+ return
1507
+ }
1508
+
1509
+ const existingReply = replies.value[replyIndex]
1510
+ if (!existingReply) {
1511
+ return
1512
+ }
1513
+
1514
+ replies.value[replyIndex] = normalizeReplyPayload(
1515
+ {
1516
+ ...existingReply,
1517
+ ...payload,
1518
+ },
1519
+ existingReply
1520
+ )
1521
+ }
1522
+
1430
1523
  function handleRealtimeReplyReaction(payload: ReplyReactionRealtimePayload | null | undefined): void {
1431
1524
  if (!payload?.reply_id || !payload.thread_id || !payload.user_id) {
1432
1525
  return