diff --git a/js/src/features/compose/controls-indicator.tsx b/js/src/features/compose/controls-indicator.tsx
index ffc0101..e46da0a 100644
--- a/js/src/features/compose/controls-indicator.tsx
+++ b/js/src/features/compose/controls-indicator.tsx
@@ -2,11 +2,12 @@ import { Video, Mic } from "lucide-react";
import { cn } from "@/lib/utils";
import { useMediaSettingsStore } from "@/stores/media-settings-store";
import { Button } from "@/components/ui/button";
+import { PropsWithChildren } from "react";
-interface ControlsIndicatorProps {
+interface ControlsIndicatorProps extends PropsWithChildren {
type: "reply" | "new";
}
-export default function ControlsIndicator({ type }: ControlsIndicatorProps) {
+export default function ControlsIndicator({ type, children }: ControlsIndicatorProps) {
const recordingMode = useMediaSettingsStore((s) => s.recordingMode);
const setRecordingMode = useMediaSettingsStore((s) => s.setRecordingMode);
@@ -39,7 +40,10 @@ export default function ControlsIndicator({ type }: ControlsIndicatorProps) {
>
)}
-
+ {children ? {children}
:
+
+ }
+ {children && ยท}
Hold{" "}
-
+
+
+
);
}
+
+// Shows a list of avatars of users who have seen the current particle, based on playback markers in the stream particle.
+const SeenIndicator = ({ stream, currentParticle, networkId }: { stream: Particle & { type: "stream" }, currentParticle: Particle, networkId: string }) => {
+ const network = useNetwork(networkId);
+ const playbackMarkers = stream.playback_markers ?? {};
+
+ const seenUserIds = Object.entries(playbackMarkers)
+ .filter(([_, timestamp]) => timestamp.getTime() >= currentParticle.created_at.getTime())
+ .map(([userId, _]) => userId);
+
+ const seenUserEmails = seenUserIds
+ .map((userId) => network?.humans?.find((h) => h.id === userId)?.email)
+ .filter((email): email is string => !!email);
+
+ if (seenUserIds.length === 0) return null;
+
+ return (
+
+ {seenUserEmails.map((email) => (
+
+
+
+
+ {email.split("@")[0].slice(0, 2)}
+
+
+
+
+ Seen by {email.split("@")[0]}
+
+
+ ))}
+
+ );
+}
diff --git a/js/src/hooks/use-networks.ts b/js/src/hooks/use-networks.ts
index a770741..7e2174d 100644
--- a/js/src/hooks/use-networks.ts
+++ b/js/src/hooks/use-networks.ts
@@ -7,3 +7,8 @@ export function useNetworks() {
queryFn: () => apiClient.listNetworks(),
});
}
+
+export function useNetwork(networkId: string) {
+ const { data: networks } = useNetworks();
+ return networks?.find((n) => n.id === networkId) || null;
+}