Files
podman/examples/livekit-gemini-hacker-starter/frontend/hooks/useGeneratedImages.tsx
T
2026-06-28 07:20:54 +00:00

72 lines
2.1 KiB
TypeScript

'use client';
import { createContext, useContext, useEffect, useRef, useState } from 'react';
import { useRoomContext } from '@livekit/components-react';
export interface GeneratedImage {
id: string;
imageUrl: string;
mimeType: string;
prompt: string;
timestamp: number;
}
const GeneratedImagesContext = createContext<GeneratedImage[]>([]);
/**
* Registers the "generated-image" byte stream handler once for the whole tree.
* Wrap this around any subtree that contains components using useGeneratedImages().
*/
export function GeneratedImagesProvider({ children }: { children: React.ReactNode }) {
const room = useRoomContext();
const [images, setImages] = useState<GeneratedImage[]>([]);
const registeredRef = useRef(false);
useEffect(() => {
if (registeredRef.current) return;
registeredRef.current = true;
room.registerByteStreamHandler('generated-image', async (reader) => {
try {
const chunks = await reader.readAll();
const mimeType = reader.info.mimeType || 'image/png';
const blobParts = chunks.map((chunk) => {
const copy = new Uint8Array(chunk.byteLength);
copy.set(chunk);
return copy.buffer;
});
const blob = new Blob(blobParts, { type: mimeType });
const imageUrl = URL.createObjectURL(blob);
const image: GeneratedImage = {
id: `${Date.now()}-${Math.random().toString(36).slice(2)}`,
imageUrl,
mimeType,
prompt: reader.info.attributes?.prompt ?? '',
timestamp: Date.now(),
};
setImages((prev) => [...prev, image]);
} catch (err) {
console.error('Failed to receive generated-image byte stream:', err);
}
});
return () => {
room.unregisterByteStreamHandler('generated-image');
registeredRef.current = false;
};
}, [room]);
return (
<GeneratedImagesContext.Provider value={images}>{children}</GeneratedImagesContext.Provider>
);
}
/**
* Returns all images generated by the agent. Must be used inside GeneratedImagesProvider.
*/
export function useGeneratedImages(): GeneratedImage[] {
return useContext(GeneratedImagesContext);
}