diff --git a/src/app/[uid]/layout.tsx b/src/app/[uid]/layout.tsx index 7dd5ecd6..c58934d5 100644 --- a/src/app/[uid]/layout.tsx +++ b/src/app/[uid]/layout.tsx @@ -3,6 +3,7 @@ import { Header } from "@/components/header"; export const dynamic = "force-dynamic", revalidate = 0; import useStore from "@/store"; +import { useEffect, useRef } from "react"; export default function LoggedInLayout({ children, // will be a page or nested layout @@ -10,10 +11,21 @@ export default function LoggedInLayout({ children: React.ReactNode; }) { const store = useStore(); + const audioRef = useRef(null); + + useEffect(() => { + if (store.audioSrc && audioRef.current) { + audioRef.current.src = store.audioSrc; + audioRef.current.load(); + audioRef.current.play(); + } + }, [store.audioSrc]); + return (
{ const ids = getUserIdList(chatLive); // include ids of users who have not participated in the chat but viewing the chat const viewersIds = allPresenceIds?.filter((id) => !ids?.includes(id)); - console.log("viewersIds", viewersIds); if (ids.length) { if (viewersIds) { getUsers([...ids, ...viewersIds]); diff --git a/src/components/inputBar.tsx b/src/components/inputBar.tsx index ffa4f25f..acef9b08 100644 --- a/src/components/inputBar.tsx +++ b/src/components/inputBar.tsx @@ -67,6 +67,7 @@ const InputBar = (props: InputBarProps) => { role: "user", content: props.value, name: `${props.username},${props.userId}`, + audio: "", }; if (props.choosenAI === "universal") { props.append(message as Message); diff --git a/src/components/intermediatesteps.tsx b/src/components/intermediatesteps.tsx index 8014a621..1ecc689c 100644 --- a/src/components/intermediatesteps.tsx +++ b/src/components/intermediatesteps.tsx @@ -12,13 +12,13 @@ export function IntermediateStep(props: { message: Message }) { return (
setExpanded(!expanded)} > - + 🛠️ {parsedInput?.action.tool} 🔽 @@ -46,7 +46,7 @@ export function IntermediateStep(props: { message: Message }) {
diff --git a/src/lib/types/ai.ts b/src/lib/types/ai.ts new file mode 100644 index 00000000..58c728ee --- /dev/null +++ b/src/lib/types/ai.ts @@ -0,0 +1,7 @@ +// import ai from "ai" +import { Message as Message2 } from "ai"; +declare module "ai" { + interface Message extends Message2 { + audio?: string; + } +} diff --git a/src/lib/types/index.ts b/src/lib/types/index.ts index 865d91a0..7d7c6af9 100644 --- a/src/lib/types/index.ts +++ b/src/lib/types/index.ts @@ -8,6 +8,7 @@ export type ChatEntry = { role: ChatRole; content: string; name: string; + audio?: string; }; export type ChatLog = { diff --git a/src/utils/apiHelper.ts b/src/utils/apiHelper.ts index ff7f5b1b..46f23a0c 100644 --- a/src/utils/apiHelper.ts +++ b/src/utils/apiHelper.ts @@ -299,3 +299,36 @@ export const handleDBOperation = async ( .run(); } }; + +export const saveAudio = async ({ + buffer, + chatId, + messageId, +}: { + buffer: Buffer; + chatId: string; + messageId: string; +}): Promise => { + const s3 = new S3Client({ + region: env.AWS_REGION, + credentials: { + accessKeyId: env.AWS_ACCESS_KEY_ID, + secretAccessKey: env.AWS_SECRET_ACCESS_KEY, + }, + }); + const data = await s3.send( + new PutObjectCommand({ + Bucket: env.BUCKET_NAME, + Body: buffer, + Key: `chataudio/${chatId}/${messageId}.mpeg`, + Metadata: { + "Content-Type": "audio/mpeg", + "chat-id": chatId, + "message-id": messageId, + }, + }), + ); + + const audioUrl = `${env.IMAGE_PREFIX_URL}chataudio/${chatId}/${messageId}.mpeg`; + return audioUrl; +};