···
// eslint-disable-next-line svelte/prefer-svelte-reactivity
const threadMap = new Map<ResourceUri, ThreadPost[]>();
224
-
// Single pass: create posts and group by thread
224
+
// group posts by root uri into "thread" chains
for (const [, timeline] of timelines) {
for (const [uri, data] of timeline) {
const parsedUri = expect(parseCanonicalResourceUri(uri));
···
// eslint-disable-next-line svelte/prefer-svelte-reactivity
const childrenMap = new Map<ResourceUri | null, ThreadPost[]>();
253
-
// Calculate depth and group by parent
253
+
// calculate depths
for (const post of posts) {
let currentUri = post.parentUri;
···
childrenMap.get(post.parentUri)!.push(post);
269
-
// Sort children by time (newest first)
.forEach((children) => children.sort((a, b) => b.newestTime - a.newestTime));
274
-
// Helper to create a thread from posts
···
288
-
// Helper to collect all posts in a subtree
const collectSubtree = (startPost: ThreadPost): ThreadPost[] => {
const result: ThreadPost[] = [];
const addWithChildren = (post: ThreadPost) => {
···
300
-
// Find branching points (posts with 2+ children)
297
+
// find posts with >2 children to split them into separate chains
const branchingPoints = Array.from(childrenMap.entries())
.filter(([, children]) => children.length > 1)
if (branchingPoints.length === 0) {
306
-
// No branches - single thread
const roots = childrenMap.get(null) || [];
const allPosts = roots.flatMap((root) => collectSubtree(root));
threads.push(createThread(allPosts, rootUri));
311
-
// Has branches - split into separate threads
for (const branchParentUri of branchingPoints) {
const branches = childrenMap.get(branchParentUri) || [];
315
-
// Sort branches oldest to newest for processing
const sortedBranches = [...branches].sort((a, b) => a.newestTime - b.newestTime);
sortedBranches.forEach((branchRoot, index) => {
const isOldestBranch = index === 0;
const branchPosts: ThreadPost[] = [];
322
-
// If oldest branch, include parent chain
316
+
// the oldest branch has the full context
317
+
// todo: consider letting the user decide this..?
if (isOldestBranch && branchParentUri !== null) {
const parentChain: ThreadPost[] = [];
let currentUri: ResourceUri | null = branchParentUri;
···
branchPosts.push(...parentChain);
333
-
// Add branch posts
branchPosts.push(...collectSubtree(branchRoot));
336
-
// Recalculate depths for display
const minDepth = Math.min(...branchPosts.map((p) => p.depth));
branchPosts.forEach((p) => (p.depth = p.depth - minDepth));
···
352
-
// Sort threads by newest time (descending) so older branches appear first
threads.sort((a, b) => b.newestTime - a.newestTime);
···
360
-
// Filtering functions
352
+
// todo: add more filtering options
const isOwnPost = (post: ThreadPost, accounts: Account[]) =>
accounts.some((account) => account.did === post.did);
const hasNonOwnPost = (posts: ThreadPost[], accounts: Account[]) =>