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 }); };