import { useMemo } from "react"; import type { Human, Particle } from "@/api/types"; export interface HumanPresence { humanId: string; email: string; emailPrefix: string; } /** * Maps playback markers to segment indices, returning which users are present at each particle. */ export function usePresencePositions( playbackMarkers: Record | undefined, children: Particle[], networkHumans: Human[] | undefined, currentUserId: string | undefined, ): Map { return useMemo(() => { const result = new Map(); if (!playbackMarkers || !networkHumans || children.length === 0) return result; for (const [userId, markerTimestamp] of Object.entries(playbackMarkers)) { if (userId === currentUserId) continue; const human = networkHumans.find((h) => h.id === userId); if (!human) continue; // Find the last particle whose created_at <= marker timestamp let segmentIndex = -1; for (let i = children.length - 1; i >= 0; i--) { if (children[i].created_at.getTime() <= markerTimestamp.getTime()) { segmentIndex = i; break; } } if (segmentIndex === -1) continue; const existing = result.get(segmentIndex); const presence: HumanPresence = { humanId: human.id, email: human.email, emailPrefix: human.email_prefix }; if (existing) { existing.push(presence); } else { result.set(segmentIndex, [presence]); } } // Sort each segment's presence list by humanId for stable render order for (const presenceList of result.values()) { presenceList.sort((a, b) => a.humanId.localeCompare(b.humanId)); } return result; }, [playbackMarkers, children, networkHumans, currentUserId]); }