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
|
import { useMemo } from 'preact/hooks';
export const GroupContainer = ({ items, first, render }) => {
const groups = useMemo(
() => {
const groupMap = Object.fromEntries(
Object.values(items).map(item => [
item.id,
{
id: item.id,
items: [item],
next: {},
depth: {},
},
]),
);
for (const item of Object.values(items)) {
const parent = item.inReplyTo.length === 1 && item.inReplyTo[0].id;
if (parent && items[parent].replies.length === 1) {
const self = groupMap[item.id];
for (const s of self.items) {
groupMap[parent].items.push(s);
groupMap[s.id] = groupMap[parent];
}
}
}
const uniqueGroups = new Set(Object.values(groupMap));
const groups = {};
for (const group of uniqueGroups) {
group.next.up = group.items[0].inReplyTo.map(i => groupMap[i.id].id);
group.next.down = group.items[group.items.length-1].replies.map(i => groupMap[i.id].id);
groups[group.items[0].id] = group;
}
const updateDepth = (group, dir) => {
if (group.depth[dir] !== undefined) {
return group.depth[dir];
}
// @TODO: count nodes properly using Set,
// this counts nodes multiple times if subgraphs converge
let count = group.items.length;
for (const id of group.next[dir]) {
// go through groupMap here, since when moving 'up',
// were not hitting only group-headers
count += updateDepth(groupMap[id], dir);
if (count >= 9) {
count = Infinity;
break;
}
}
group.depth[dir] = count;
return count;
};
for (const group of Object.values(groups)) {
updateDepth(group, 'up');
updateDepth(group, 'down');
}
return groups;
},
[items]
);
first = groups[first].id;
return render({ groups, first });
};
|