From 201a13cc78e66f6cd7d8fc7bbf73f5586662dab6 Mon Sep 17 00:00:00 2001 From: Long Chen Date: Wed, 12 Mar 2025 10:27:51 +0800 Subject: [PATCH] configurable room name and perform RPC calls (#127) --- src/components/config/NameValueRow.tsx | 40 ++++++++++ src/components/playground/Playground.tsx | 96 ++++++++++++++++++++---- src/hooks/useConfig.tsx | 6 ++ src/hooks/useConnection.tsx | 11 ++- src/pages/api/token.ts | 9 ++- 5 files changed, 146 insertions(+), 16 deletions(-) diff --git a/src/components/config/NameValueRow.tsx b/src/components/config/NameValueRow.tsx index 43d88d5..4606d7d 100644 --- a/src/components/config/NameValueRow.tsx +++ b/src/components/config/NameValueRow.tsx @@ -20,3 +20,43 @@ export const NameValueRow: React.FC = ({ ); }; + +type EditableNameValueRowProps = { + name: string; + value: string; + valueColor?: string; + onValueChange?: (value: string) => void; + placeholder?: string; + editable: boolean; +}; + +export const EditableNameValueRow: React.FC = ({ + name, + value, + valueColor = "gray-300", + onValueChange, + placeholder, + editable, +}) => { + if (editable && onValueChange) { + return ( +
+
{name}
+ onValueChange(e.target.value)} + className={`text-xs shrink text-${valueColor} text-right bg-transparent border-b border-gray-800 focus:outline-none focus:border-gray-600 px-2 py-0`} + placeholder={placeholder} + /> +
+ ); + } + return ( + + ); +}; diff --git a/src/components/playground/Playground.tsx b/src/components/playground/Playground.tsx index 81b912a..8986fa1 100644 --- a/src/components/playground/Playground.tsx +++ b/src/components/playground/Playground.tsx @@ -23,11 +23,13 @@ import { useRoomInfo, useTracks, useVoiceAssistant, + useRoomContext, } from "@livekit/components-react"; import { ConnectionState, LocalParticipant, Track } from "livekit-client"; import { QRCodeSVG } from "qrcode.react"; import { ReactNode, useCallback, useEffect, useMemo, useState } from "react"; import tailwindTheme from "../../lib/tailwindTheme.preval"; +import { EditableNameValueRow } from "@/components/config/NameValueRow"; export interface PlaygroundMeta { name: string; @@ -56,6 +58,10 @@ export default function Playground({ const roomState = useConnectionState(); const tracks = useTracks(); + const room = useRoomContext(); + + const [rpcMethod, setRpcMethod] = useState(""); + const [rpcPayload, setRpcPayload] = useState(""); useEffect(() => { if (roomState === ConnectionState.Connected) { @@ -212,6 +218,21 @@ export default function Playground({ return <>; }, [config.settings.theme_color, voiceAssistant.audioTrack]); + const handleRpcCall = useCallback(async () => { + if (!voiceAssistant.agent || !room) return; + + try { + const response = await room.localParticipant.performRpc({ + destinationIdentity: voiceAssistant.agent.identity, + method: rpcMethod, + payload: rpcPayload, + }); + console.log('RPC response:', response); + } catch (e) { + console.error('RPC call failed:', e); + } + }, [room, rpcMethod, rpcPayload, voiceAssistant.agent]); + const settingsTileContent = useMemo(() => { return (
@@ -222,19 +243,65 @@ export default function Playground({ )} - {localParticipant && ( -
- - -
- )} +
+ { + const newSettings = { ...config.settings }; + newSettings.room_name = value; + setUserSettings(newSettings); + }} + placeholder="Enter room name" + editable={roomState !== ConnectionState.Connected} + /> + { + const newSettings = { ...config.settings }; + newSettings.participant_name = value; + setUserSettings(newSettings); + }} + placeholder="Enter participant id" + editable={roomState !== ConnectionState.Connected} + /> +
+
+
RPC Method
+ setRpcMethod(e.target.value)} + className="w-full text-white text-sm bg-transparent border border-gray-800 rounded-sm px-3 py-2" + placeholder="RPC method name" + /> + +
RPC Payload
+