File size: 3,565 Bytes
cc43e3c
 
 
052672d
c69ef3e
3ba9c0c
f80b091
 
 
c69ef3e
8e3dbd3
 
 
 
 
 
cc43e3c
8e3dbd3
 
3ba9c0c
 
8e3dbd3
f80b091
 
38448fc
8e3dbd3
3ba9c0c
 
 
f80b091
 
 
 
38448fc
8e3dbd3
 
3ba9c0c
f80b091
 
 
 
 
 
 
 
3ba9c0c
f80b091
 
 
 
 
 
 
 
 
 
 
 
38448fc
 
 
 
3a22cf3
 
 
 
 
38448fc
8e3dbd3
3a22cf3
8e3dbd3
38448fc
 
f80b091
 
 
 
 
 
 
 
 
38448fc
f80b091
8e3dbd3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f80b091
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3ba9c0c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
import * as React from 'react';
import Textarea from 'react-textarea-autosize';
import { UseChatHelpers } from 'ai/react';
import { useEnterSubmit } from '@/lib/hooks/useEnterSubmit';
import { Button, buttonVariants } from '@/components/ui/Button';
import {
  Tooltip,
  TooltipContent,
  TooltipTrigger,
} from '@/components/ui/Tooltip';
import {
  IconArrowElbow,
  IconPlus,
  IconRefresh,
  IconStop,
} from '@/components/ui/Icons';
import { useRouter } from 'next/navigation';
import Img from '../ui/Img';
import { MessageBase } from '@/lib/types';

export interface PromptProps
  extends Pick<UseChatHelpers, 'input' | 'setInput' | 'reload'> {
  onSubmit: (value: string) => void;
  isLoading: boolean;
  url?: string;
  messages: MessageBase[];
}

export function PromptForm({
  onSubmit,
  input,
  setInput,
  isLoading,
  url,
  messages,
  reload,
}: PromptProps) {
  const { formRef, onKeyDown } = useEnterSubmit();
  const inputRef = React.useRef<HTMLTextAreaElement>(null);
  const router = useRouter();
  React.useEffect(() => {
    if (inputRef.current) {
      inputRef.current.focus();
    }
  }, []);

  return (
    <form
      onSubmit={async e => {
        e.preventDefault();
        if (!input?.trim()) {
          return;
        }
        setInput('');
        await onSubmit(input);
      }}
      ref={formRef}
    >
      <div className="relative flex w-full px-8 pl-2 overflow-hidden max-h-60 grow bg-background sm:rounded-md sm:border sm:px-12 sm:pl-2">
        {url && (
          <Tooltip>
            <TooltipTrigger asChild>
              <Img
                alt="prompt-image"
                src={url}
                className="w-1/5 my-4 mx-2 cursor-zoom-in"
              />
            </TooltipTrigger>
            <TooltipContent>
              <Img alt="prompt-hovered-image" src={url} className="m-2" />
            </TooltipContent>
          </Tooltip>
        )}
        <Textarea
          ref={inputRef}
          tabIndex={0}
          onKeyDown={onKeyDown}
          rows={1}
          value={input}
          onChange={e => setInput(e.target.value)}
          placeholder="Ask questions about the images."
          spellCheck={false}
          className="min-h-[60px] w-4/5 resize-none bg-transparent px-4 py-[1.3rem] focus-within:outline-none sm:text-sm"
        />
        <div className="absolute left-1/2 -translate-x-1/2 bottom-0 h-12 z-40">
          {isLoading ? (
            <Button
              variant="outline"
              onClick={() => stop()}
              className="bg-background"
            >
              <IconStop className="mr-2" />
              Stop generating
            </Button>
          ) : (
            messages?.length >= 2 && (
              <div className="flex space-x-2">
                <Button variant="outline" onClick={() => reload()}>
                  <IconRefresh className="mr-2" />
                  Regenerate response
                </Button>
              </div>
            )
          )}
        </div>
        <div className="absolute top-1/2 -translate-y-1/2 right-4">
          <Tooltip>
            <TooltipTrigger asChild>
              <Button
                type="submit"
                size="icon"
                disabled={isLoading || input === ''}
              >
                <IconArrowElbow />
                <span className="sr-only">Send message</span>
              </Button>
            </TooltipTrigger>
            <TooltipContent>Send message</TooltipContent>
          </Tooltip>
        </div>
      </div>
    </form>
  );
}