import clsx from 'clsx'; import { useMutation, useQuery } from 'convex/react'; import { KeyboardEvent, useRef, useState } from 'react'; import { api } from '../../convex/_generated/api'; import { Id } from '../../convex/_generated/dataModel'; import { useSendInput } from '../hooks/sendInput'; import { Player } from '../../convex/aiTown/player'; import { Conversation } from '../../convex/aiTown/conversation'; export function MessageInput({ worldId, engineId, humanPlayer, conversation, }: { worldId: Id<'worlds'>; engineId: Id<'engines'>; humanPlayer: Player; conversation: Conversation; }) { const descriptions = useQuery(api.world.gameDescriptions, { worldId }); const humanName = descriptions?.playerDescriptions.find((p) => p.playerId === humanPlayer.id) ?.name; const inputRef = useRef(null); const inflightUuid = useRef(); const writeMessage = useMutation(api.messages.writeMessage); const startTyping = useSendInput(engineId, 'startTyping'); const currentlyTyping = conversation.isTyping; const onKeyDown = async (e: KeyboardEvent) => { e.stopPropagation(); // Set the typing indicator if we're not submitting. if (e.key !== 'Enter') { console.log(inflightUuid.current); if (currentlyTyping || inflightUuid.current !== undefined) { return; } inflightUuid.current = crypto.randomUUID(); try { // Don't show a toast on error. await startTyping({ playerId: humanPlayer.id, conversationId: conversation.id, messageUuid: inflightUuid.current, }); } finally { inflightUuid.current = undefined; } return; } // Send the current message. e.preventDefault(); if (!inputRef.current) { return; } const text = inputRef.current.innerText; inputRef.current.innerText = ''; if (!text) { return; } let messageUuid = inflightUuid.current; if (currentlyTyping && currentlyTyping.playerId === humanPlayer.id) { messageUuid = currentlyTyping.messageUuid; } messageUuid = messageUuid || crypto.randomUUID(); await writeMessage({ worldId, playerId: humanPlayer.id, conversationId: conversation.id, text, messageUuid, }); }; return (
{humanName}

onKeyDown(e)} />

); }