idiomatic react

This commit is contained in:
Arjun Patel
2026-06-01 17:13:41 -07:00
parent c8ceacc385
commit e04010257a
+46 -40
View File
@@ -1,4 +1,4 @@
import { useEffect, useRef } from 'react';
import { useEffect, useEffectEvent, useRef } from 'react';
import beepSound from '../../assets/sounds/beep.wav';
import type { Network, Particle, StreamProperties } from '@/api/types';
import { apiClient } from '@/api/client';
@@ -22,6 +22,49 @@ export function useStreamAutoplay(
const userId = useAuthStore((s) => s.user?.id) ?? '';
const settledIdRef = useRef<string | undefined>(undefined);
// The autoplay action reads the latest userId/network/stream/networkId at the
// moment a new child settles, without making any of them a reactive trigger —
// the only thing that should fire this is a change in the latest child's id.
const onNewLatestChild = useEffectEvent((child: Particle) => {
if (child.created_by_human_id === userId) return;
if (useAutoplayStore.getState().muted) return;
if (child.type === 'text') {
// Browser autoplay policy can block this before user interaction; that's
// fine — the beep is a nice-to-have, not a critical signal.
new Audio(beepSound)
.play()
.catch((err) => logError(err, { scope: 'autoplay.beep' }));
return;
}
if (child.type !== 'media') return;
const { displayName, initials } = resolveHumanDisplay(
child.created_by_human_id,
network?.humans,
);
apiClient
.getParticleDownloadUrl(child.properties.object_id)
.then((downloadUrl) => {
platform.autoplay.play({
particleId: child.id,
streamId: streamParticle.id,
networkId,
downloadUrl,
mimeType: child.properties.mime_type,
durationMs: child.properties.duration_ms,
senderName: displayName,
senderInitials: initials,
});
})
.catch((err) =>
logError(err, { scope: 'autoplay.fetchUrl', particleId: child.id }),
);
});
useEffect(() => {
if (!latestChild) return;
@@ -34,43 +77,6 @@ export function useStreamAutoplay(
if (latestChild.id === settledIdRef.current) return;
settledIdRef.current = latestChild.id;
if (latestChild.created_by_human_id === userId) return;
if (useAutoplayStore.getState().muted) return;
if (latestChild.type === 'text') {
// Browser autoplay policy can block this before user interaction; that's
// fine — the beep is a nice-to-have, not a critical signal.
new Audio(beepSound)
.play()
.catch((err) => logError(err, { scope: 'autoplay.beep' }));
return;
}
if (latestChild.type !== 'media') return;
const particle = latestChild;
const { displayName, initials } = resolveHumanDisplay(
particle.created_by_human_id,
network?.humans,
);
apiClient
.getParticleDownloadUrl(particle.properties.object_id)
.then((downloadUrl) => {
platform.autoplay.play({
particleId: particle.id,
streamId: streamParticle.id,
networkId,
downloadUrl,
mimeType: particle.properties.mime_type,
durationMs: particle.properties.duration_ms,
senderName: displayName,
senderInitials: initials,
});
})
.catch((err) =>
logError(err, { scope: 'autoplay.fetchUrl', particleId: particle.id }),
);
}, [latestChild?.id]); // eslint-disable-line react-hooks/exhaustive-deps
onNewLatestChild(latestChild);
}, [latestChild]);
}