@codingfactory/socialkit-vue 0.7.19 → 0.7.20
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/services/auth.d.ts.map +1 -1
- package/dist/services/auth.js +1 -3
- package/dist/services/auth.js.map +1 -1
- package/dist/services/circles.d.ts +4 -0
- package/dist/services/circles.d.ts.map +1 -1
- package/dist/services/circles.js +11 -3
- package/dist/services/circles.js.map +1 -1
- package/dist/services/echo.d.ts.map +1 -1
- package/dist/services/echo.js +12 -0
- package/dist/services/echo.js.map +1 -1
- package/dist/stores/circles.d.ts.map +1 -1
- package/dist/stores/circles.js +16 -0
- package/dist/stores/circles.js.map +1 -1
- package/dist/stores/content.d.ts.map +1 -1
- package/dist/stores/content.js +33 -3
- package/dist/stores/content.js.map +1 -1
- package/dist/stores/discussion.d.ts.map +1 -1
- package/dist/stores/discussion.js +91 -12
- package/dist/stores/discussion.js.map +1 -1
- package/dist/types/discussion.d.ts +1 -0
- package/dist/types/discussion.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/services/auth.ts +1 -5
- package/src/services/circles.ts +12 -3
- package/src/services/echo.ts +13 -0
- package/src/stores/circles.ts +20 -0
- package/src/stores/content.ts +40 -3
- package/src/stores/discussion.ts +108 -13
- package/src/types/discussion.ts +1 -0
package/src/stores/discussion.ts
CHANGED
|
@@ -219,6 +219,18 @@ function isTransientThreadListError(error: unknown): boolean {
|
|
|
219
219
|
return status === 502 || status === 503 || status === 504
|
|
220
220
|
}
|
|
221
221
|
|
|
222
|
+
const DISCUSSION_SPACE_CHANNEL_PREFIX = 'discussions.space.'
|
|
223
|
+
const DISCUSSION_THREAD_CHANNEL_PREFIX = 'discussions.thread.'
|
|
224
|
+
|
|
225
|
+
function extractRealtimeChannelId(channelName: string | null, prefix: string): string | null {
|
|
226
|
+
if (!channelName || !channelName.startsWith(prefix)) {
|
|
227
|
+
return null
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
const channelId = channelName.slice(prefix.length)
|
|
231
|
+
return channelId.length > 0 ? channelId : null
|
|
232
|
+
}
|
|
233
|
+
|
|
222
234
|
export type DiscussionStoreReturn = ReturnType<ReturnType<typeof createDiscussionStoreDefinition>>
|
|
223
235
|
|
|
224
236
|
export function createDiscussionStoreDefinition(config: DiscussionStoreConfig) {
|
|
@@ -226,6 +238,7 @@ export function createDiscussionStoreDefinition(config: DiscussionStoreConfig) {
|
|
|
226
238
|
client,
|
|
227
239
|
getCurrentUserId,
|
|
228
240
|
getEcho,
|
|
241
|
+
onEchoInitialized,
|
|
229
242
|
onEchoReconnected,
|
|
230
243
|
createLoadingState,
|
|
231
244
|
logger = console,
|
|
@@ -257,6 +270,8 @@ export function createDiscussionStoreDefinition(config: DiscussionStoreConfig) {
|
|
|
257
270
|
|
|
258
271
|
let activeSpaceChannel: string | null = null
|
|
259
272
|
let activeThreadChannel: string | null = null
|
|
273
|
+
let desiredSpaceChannel: string | null = null
|
|
274
|
+
let desiredThreadChannel: string | null = null
|
|
260
275
|
|
|
261
276
|
const locallyCreatedReplyIds = new Set<string>()
|
|
262
277
|
const pendingReplyCreations = new Map<string, number>()
|
|
@@ -420,6 +435,71 @@ export function createDiscussionStoreDefinition(config: DiscussionStoreConfig) {
|
|
|
420
435
|
return mergedItems
|
|
421
436
|
}
|
|
422
437
|
|
|
438
|
+
/**
|
|
439
|
+
* Reorder a flat list of replies (which may arrive in chronological or
|
|
440
|
+
* score order from the API) into depth-first tree order so that children
|
|
441
|
+
* always appear directly after their parent branch. The relative order
|
|
442
|
+
* of siblings (as returned by the backend sort) is preserved.
|
|
443
|
+
*/
|
|
444
|
+
function reorderIntoTreeOrder(flatReplies: Reply[]): Reply[] {
|
|
445
|
+
if (flatReplies.length <= 1) {
|
|
446
|
+
return flatReplies
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
const replyIds = new Set<string>()
|
|
450
|
+
for (const reply of flatReplies) {
|
|
451
|
+
replyIds.add(reply.id)
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
// Group children by their parent. Replies whose parent is not in the
|
|
455
|
+
// current list are treated as roots (parentKey = '').
|
|
456
|
+
const childrenMap = new Map<string, Reply[]>()
|
|
457
|
+
childrenMap.set('', [])
|
|
458
|
+
|
|
459
|
+
for (const reply of flatReplies) {
|
|
460
|
+
const parentId = reply.parent_reply_id
|
|
461
|
+
const key = typeof parentId === 'string' && parentId !== '' && replyIds.has(parentId)
|
|
462
|
+
? parentId
|
|
463
|
+
: ''
|
|
464
|
+
|
|
465
|
+
const siblings = childrenMap.get(key)
|
|
466
|
+
if (siblings) {
|
|
467
|
+
siblings.push(reply)
|
|
468
|
+
} else {
|
|
469
|
+
childrenMap.set(key, [reply])
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
const result: Reply[] = []
|
|
474
|
+
|
|
475
|
+
function dfs(parentKey: string): void {
|
|
476
|
+
const children = childrenMap.get(parentKey)
|
|
477
|
+
if (!children) {
|
|
478
|
+
return
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
for (const child of children) {
|
|
482
|
+
result.push(child)
|
|
483
|
+
dfs(child.id)
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
dfs('')
|
|
488
|
+
|
|
489
|
+
// If some replies were unreachable (orphaned cycles), append them so
|
|
490
|
+
// nothing is silently dropped.
|
|
491
|
+
if (result.length < flatReplies.length) {
|
|
492
|
+
const included = new Set(result.map((reply) => reply.id))
|
|
493
|
+
for (const reply of flatReplies) {
|
|
494
|
+
if (!included.has(reply.id)) {
|
|
495
|
+
result.push(reply)
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
return result
|
|
501
|
+
}
|
|
502
|
+
|
|
423
503
|
function extractResponsePayload(responseData: unknown): unknown {
|
|
424
504
|
const responseRecord = toRecord(responseData)
|
|
425
505
|
if (!responseRecord) {
|
|
@@ -1026,9 +1106,9 @@ export function createDiscussionStoreDefinition(config: DiscussionStoreConfig) {
|
|
|
1026
1106
|
currentReplySort.value = sortBy
|
|
1027
1107
|
|
|
1028
1108
|
if (cursor) {
|
|
1029
|
-
replies.value = mergeUniqueById(replies.value, filteredReplyBatch)
|
|
1109
|
+
replies.value = reorderIntoTreeOrder(mergeUniqueById(replies.value, filteredReplyBatch))
|
|
1030
1110
|
} else {
|
|
1031
|
-
replies.value = filteredReplyBatch
|
|
1111
|
+
replies.value = reorderIntoTreeOrder(filteredReplyBatch)
|
|
1032
1112
|
hiddenOpeningReplyCountByThread.set(threadId, openingRepliesFilteredInBatch)
|
|
1033
1113
|
subscribeToThreadRealtime(threadId)
|
|
1034
1114
|
}
|
|
@@ -1217,6 +1297,9 @@ export function createDiscussionStoreDefinition(config: DiscussionStoreConfig) {
|
|
|
1217
1297
|
}
|
|
1218
1298
|
|
|
1219
1299
|
function cleanupRealtimeChannels(): void {
|
|
1300
|
+
desiredSpaceChannel = null
|
|
1301
|
+
desiredThreadChannel = null
|
|
1302
|
+
|
|
1220
1303
|
const echo = getEcho()
|
|
1221
1304
|
if (!echo) {
|
|
1222
1305
|
activeSpaceChannel = null
|
|
@@ -1328,13 +1411,14 @@ export function createDiscussionStoreDefinition(config: DiscussionStoreConfig) {
|
|
|
1328
1411
|
}
|
|
1329
1412
|
|
|
1330
1413
|
function subscribeToSpaceRealtime(spaceId: string): void {
|
|
1414
|
+
const channelName = `${DISCUSSION_SPACE_CHANNEL_PREFIX}${spaceId}`
|
|
1415
|
+
desiredSpaceChannel = channelName
|
|
1416
|
+
|
|
1331
1417
|
const echo = getEcho()
|
|
1332
1418
|
if (!echo) {
|
|
1333
1419
|
return
|
|
1334
1420
|
}
|
|
1335
1421
|
|
|
1336
|
-
const channelName = `discussions.space.${spaceId}`
|
|
1337
|
-
|
|
1338
1422
|
if (activeSpaceChannel === channelName) {
|
|
1339
1423
|
return
|
|
1340
1424
|
}
|
|
@@ -1358,13 +1442,14 @@ export function createDiscussionStoreDefinition(config: DiscussionStoreConfig) {
|
|
|
1358
1442
|
}
|
|
1359
1443
|
|
|
1360
1444
|
function subscribeToThreadRealtime(threadId: string): void {
|
|
1445
|
+
const channelName = `${DISCUSSION_THREAD_CHANNEL_PREFIX}${threadId}`
|
|
1446
|
+
desiredThreadChannel = channelName
|
|
1447
|
+
|
|
1361
1448
|
const echo = getEcho()
|
|
1362
1449
|
if (!echo) {
|
|
1363
1450
|
return
|
|
1364
1451
|
}
|
|
1365
1452
|
|
|
1366
|
-
const channelName = `discussions.thread.${threadId}`
|
|
1367
|
-
|
|
1368
1453
|
if (activeThreadChannel === channelName) {
|
|
1369
1454
|
return
|
|
1370
1455
|
}
|
|
@@ -2291,28 +2376,38 @@ export function createDiscussionStoreDefinition(config: DiscussionStoreConfig) {
|
|
|
2291
2376
|
error.value = message
|
|
2292
2377
|
}
|
|
2293
2378
|
|
|
2294
|
-
|
|
2295
|
-
const
|
|
2296
|
-
const
|
|
2379
|
+
function rehydrateRealtimeSubscriptions(): void {
|
|
2380
|
+
const savedDesiredSpaceChannel = desiredSpaceChannel
|
|
2381
|
+
const savedDesiredThreadChannel = desiredThreadChannel
|
|
2382
|
+
const spaceId = extractRealtimeChannelId(savedDesiredSpaceChannel, DISCUSSION_SPACE_CHANNEL_PREFIX)
|
|
2383
|
+
const threadId = extractRealtimeChannelId(savedDesiredThreadChannel, DISCUSSION_THREAD_CHANNEL_PREFIX)
|
|
2297
2384
|
|
|
2298
2385
|
activeSpaceChannel = null
|
|
2299
2386
|
activeThreadChannel = null
|
|
2300
2387
|
|
|
2301
|
-
if (
|
|
2302
|
-
const spaceId = savedSpace.replace('discussions.space.', '')
|
|
2388
|
+
if (spaceId) {
|
|
2303
2389
|
subscribeToSpaceRealtime(spaceId)
|
|
2304
2390
|
}
|
|
2305
2391
|
|
|
2306
|
-
if (
|
|
2307
|
-
const threadId = savedThread.replace('discussions.thread.', '')
|
|
2392
|
+
if (threadId) {
|
|
2308
2393
|
subscribeToThreadRealtime(threadId)
|
|
2309
2394
|
}
|
|
2395
|
+
}
|
|
2396
|
+
|
|
2397
|
+
const stopListeningToEchoReconnect = onEchoReconnected(() => {
|
|
2398
|
+
rehydrateRealtimeSubscriptions()
|
|
2399
|
+
})
|
|
2400
|
+
const stopListeningToEchoInitialized = onEchoInitialized?.(() => {
|
|
2401
|
+
rehydrateRealtimeSubscriptions()
|
|
2310
2402
|
})
|
|
2311
2403
|
|
|
2312
2404
|
onScopeDispose(() => {
|
|
2313
2405
|
if (typeof stopListeningToEchoReconnect === 'function') {
|
|
2314
2406
|
stopListeningToEchoReconnect()
|
|
2315
2407
|
}
|
|
2408
|
+
if (typeof stopListeningToEchoInitialized === 'function') {
|
|
2409
|
+
stopListeningToEchoInitialized()
|
|
2410
|
+
}
|
|
2316
2411
|
cleanupRealtimeChannels()
|
|
2317
2412
|
})
|
|
2318
2413
|
|
package/src/types/discussion.ts
CHANGED
|
@@ -267,6 +267,7 @@ export interface DiscussionStoreConfig {
|
|
|
267
267
|
client: AxiosInstance
|
|
268
268
|
getCurrentUserId: () => string | null
|
|
269
269
|
getEcho: () => DiscussionRealtimeClientLike | null
|
|
270
|
+
onEchoInitialized?: (callback: () => void) => (() => void) | void
|
|
270
271
|
onEchoReconnected: (callback: () => void) => (() => void) | void
|
|
271
272
|
createLoadingState: () => DiscussionLoadingState
|
|
272
273
|
logger?: Pick<Console, 'error'>
|