-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathuseSpaceUnreadById.ts
More file actions
117 lines (110 loc) · 3.14 KB
/
Copy pathuseSpaceUnreadById.ts
File metadata and controls
117 lines (110 loc) · 3.14 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
import type { Ref, ComputedRef } from 'vue'
import type { RoomUnreadState } from '~/utils/roomUnread'
import {
buildRoomIdToSpaceIdsMap,
buildSpaceUnreadById,
collectSpaceIdsForChangedRooms,
diffUnreadRoomIds,
patchSpaceUnreadById,
type BuildSpaceUnreadByIdOptions,
type SidebarRoomRef,
type SpaceUnreadState,
} from '~/utils/spaceUnread'
export function useSpaceUnreadById(options: {
matrixSyncPrepared: Ref<boolean>
unreadByRoomId: ComputedRef<Record<string, RoomUnreadState>>
spaceIds: ComputedRef<string[]>
sidebarRooms: ComputedRef<SidebarRoomRef[]>
matrixRooms: Ref<Array<Record<string, unknown>>>
homeRoomIds: ComputedRef<string[]>
getRoomType: (room: unknown) => string | undefined
getParentSpaceIds: (room: unknown) => string[]
}) {
const spaceUnreadById = shallowRef<Record<string, SpaceUnreadState>>({})
const roomIdToSpaceIds = shallowRef<Map<string, Set<string>>>(
new Map(),
)
let lastUnreadSnapshot: Record<string, RoomUnreadState> = {}
function buildUnreadOptions(): BuildSpaceUnreadByIdOptions {
const matrixRoomsById = new Map<string, unknown>(
options.matrixRooms.value.map((room) => [
String((room as { roomId: string }).roomId),
room,
]),
)
return {
spaceIds: options.spaceIds.value,
sidebarRooms: options.sidebarRooms.value,
unreadByRoomId: options.unreadByRoomId.value,
matrixRoomsById,
getRoomType: options.getRoomType,
getParentSpaceIds: options.getParentSpaceIds,
homeRoomIds: options.homeRoomIds.value,
}
}
function fullRebuild(): void {
const unreadOptions = buildUnreadOptions()
spaceUnreadById.value = buildSpaceUnreadById(unreadOptions)
roomIdToSpaceIds.value = buildRoomIdToSpaceIdsMap(
unreadOptions.spaceIds,
unreadOptions,
)
lastUnreadSnapshot = { ...options.unreadByRoomId.value }
}
function clearState(): void {
spaceUnreadById.value = {}
roomIdToSpaceIds.value = new Map()
lastUnreadSnapshot = {}
}
watch(
[
options.matrixSyncPrepared,
options.spaceIds,
options.sidebarRooms,
options.matrixRooms,
options.homeRoomIds,
],
() => {
if (!options.matrixSyncPrepared.value) {
clearState()
return
}
fullRebuild()
},
{ deep: true, immediate: true },
)
watch(
options.unreadByRoomId,
(nextUnread) => {
if (!options.matrixSyncPrepared.value) {
return
}
const changedRoomIds = diffUnreadRoomIds(
lastUnreadSnapshot,
nextUnread,
)
lastUnreadSnapshot = { ...nextUnread }
if (changedRoomIds.length === 0) {
return
}
const unreadOptions = buildUnreadOptions()
const affectedSpaceIds = collectSpaceIdsForChangedRooms(
changedRoomIds,
roomIdToSpaceIds.value,
)
if (affectedSpaceIds.length === 0) {
fullRebuild()
return
}
spaceUnreadById.value = patchSpaceUnreadById(
spaceUnreadById.value,
affectedSpaceIds,
unreadOptions,
)
},
{ flush: 'sync' },
)
return {
spaceUnreadById: computed(() => spaceUnreadById.value),
}
}