Skip to content

Commit

Permalink
Add UI for instructions and voice
Browse files Browse the repository at this point in the history
  • Loading branch information
third774 committed Dec 18, 2024
1 parent 35d5d88 commit 5357006
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 22 deletions.
34 changes: 13 additions & 21 deletions app/components/AiButton.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { useSearchParams } from '@remix-run/react'
import { useRoomContext } from '~/hooks/useRoomContext'
import type { ClientMessage, User } from '~/types/Messages'
import { AiPushToTalkButtion } from './AiPushToTalkButton'
import { Button } from './Button'
import { Trigger } from './Dialog'
import { InviteAiDialog } from './InviteAiDialog'
import { RecordAiVoiceActivity } from './RecordAiVoiceActivity'

function RemoveAiButton() {
Expand All @@ -16,7 +17,7 @@ function RemoveAiButton() {
JSON.stringify({ type: 'disableAi' } satisfies ClientMessage)
)
}
className="text-xs"
className="text-xs text-zinc-800"
displayType="ghost"
>
Remove AI
Expand All @@ -27,7 +28,6 @@ function RemoveAiButton() {
export function AiButton(props: { recordActivity: (user: User) => void }) {
const {
room: {
websocket,
roomState: {
ai: { connectionPending, error },
users,
Expand All @@ -36,9 +36,6 @@ export function AiButton(props: { recordActivity: (user: User) => void }) {
} = useRoomContext()

const aiUser = users.find((u) => u.id === 'ai')
const [params] = useSearchParams()
const voice = params.get('voice') ?? undefined
const instructions = params.get('instructions') ?? undefined

return (
<>
Expand All @@ -53,21 +50,16 @@ export function AiButton(props: { recordActivity: (user: User) => void }) {
/>
</>
) : (
<Button
onClick={() =>
websocket.send(
JSON.stringify({
type: 'enableAi',
voice,
instructions,
} satisfies ClientMessage)
)
}
className="text-xs flex items-center gap-2"
disabled={connectionPending}
>
<span>Invite AI</span>
</Button>
<InviteAiDialog>
<Trigger asChild>
<Button
className="text-xs flex items-center gap-2"
disabled={connectionPending}
>
<span>Invite AI</span>
</Button>
</Trigger>
</InviteAiDialog>
)}
</>
)
Expand Down
2 changes: 1 addition & 1 deletion app/components/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const displayTypeMap = {
'border-zinc-200 hover:border-zinc-300 dark:border-zinc-700 dark:hover:border-zinc-600',
],
ghost: [
'text-white hover:text-zinc-900',
'text-white dark:text-zinc-800 hover:text-zinc-900',
'bg-transparent hover:bg-white',
'border-transparent hover:border-white',
],
Expand Down
87 changes: 87 additions & 0 deletions app/components/InviteAiDialog.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import { useSearchParams } from '@remix-run/react'
import { useState, type ReactNode } from 'react'
import { useRoomContext } from '~/hooks/useRoomContext'
import type { ClientMessage } from '~/types/Messages'
import { Button } from './Button'
import { Dialog, DialogContent, DialogOverlay, Portal } from './Dialog'

export function InviteAiDialog(props: { children?: ReactNode }) {
const [open, setOpen] = useState(false)

const {
room: { websocket },
} = useRoomContext()

const [params] = useSearchParams()

const instructions = params.get('instructions')
const voice = params.get('voice')

return (
<Dialog open={open} onOpenChange={setOpen}>
{props.children}
<Portal>
<DialogOverlay />
<DialogContent>
<form
className="flex flex-col gap-4 mt-8"
onSubmit={(e) => {
e.preventDefault()
websocket.send(
JSON.stringify({
type: 'enableAi',
...Object.fromEntries(new FormData(e.currentTarget)),
} satisfies ClientMessage)
)
setOpen(false)
}}
>
<div className="flex flex-col gap-2">
<div>
<label className="font-medium" htmlFor="instructions">
Instructions
</label>
</div>

<div>
<textarea
className="bg-gray-100 dark:bg-zinc-800 w-full"
id="instructions"
name="instructions"
rows={15}
defaultValue={
instructions ??
'You are a helpful AI assistant for a video chat application called Orange Meets'
}
/>
</div>
</div>
<div className="flex flex-col gap-2">
<div>
<label className="font-medium" htmlFor="voice">
Voice
</label>
</div>

<div>
<select
className="bg-gray-100 dark:bg-zinc-800 w-full"
id="voice"
name="voice"
defaultValue={voice ?? 'ash'}
>
<option value="ash">Ash</option>
<option value="ballad">Ballad</option>
</select>
</div>
</div>

<Button type="submit" className="self-end text-xs">
Invite AI
</Button>
</form>
</DialogContent>
</Portal>
</Dialog>
)
}

0 comments on commit 5357006

Please sign in to comment.