Skip to content

Commit 6594b34

Browse files
Merge pull request #144 from rijnb/pasteimage
Add paste image support
2 parents 02412cf + 04ec6e9 commit 6594b34

File tree

9 files changed

+915
-495
lines changed

9 files changed

+915
-495
lines changed

components/Chat/ChatInput.tsx

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,18 @@ export const ChatInput = ({modelId, onSend, onRegenerate, stopConversationRef, t
267267
}, 3000)
268268
}
269269

270+
const handlePaste = (e: React.ClipboardEvent<HTMLTextAreaElement>) => {
271+
const items = e.clipboardData.items
272+
for (const item of items) {
273+
if (item.kind === "file" && item.type.startsWith("image/")) {
274+
const file = item.getAsFile()
275+
if (file) {
276+
addImageToPrompt(file)
277+
}
278+
}
279+
}
280+
}
281+
270282
const handleKeyDown = (e: KeyboardEvent<HTMLTextAreaElement>) => {
271283
if (showPromptList) {
272284
if (e.key === "ArrowDown") {
@@ -460,6 +472,7 @@ export const ChatInput = ({modelId, onSend, onRegenerate, stopConversationRef, t
460472
onCompositionEnd={() => setIsTyping(false)}
461473
onChange={handleContentChange}
462474
onKeyDown={handleKeyDown}
475+
onPaste={handlePaste}
463476
/>
464477
<button
465478
data-testid="chat-send"

components/Chat/PromptInputVars.tsx

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,15 @@
1515
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
1616
* SOFTWARE.
1717
*/
18+
import { useAppInsightsContext } from "@microsoft/applicationinsights-react-js";
19+
import { ChangeEvent, DragEvent, useEffect, useRef, useState } from "react";
1820

19-
import {useAppInsightsContext} from "@microsoft/applicationinsights-react-js"
20-
import {ChangeEvent, DragEvent, useEffect, useRef, useState} from "react"
2121

22-
import {Button, Dialog, FormHeader, FormLabel, FormText, TextArea} from "@/components/Styled"
23-
import {Prompt} from "@/types/prompt"
24-
import {isLanguageSupported} from "@/utils/app/codeblock"
22+
23+
import { Button, Dialog, FormHeader, FormLabel, FormText, TextArea } from "@/components/Styled";
24+
import { Prompt } from "@/types/prompt";
25+
import { isLanguageSupported } from "@/utils/app/codeblock";
26+
2527

2628
interface Props {
2729
prompt: Prompt
@@ -168,7 +170,7 @@ export const PromptInputVars = ({prompt, promptVariables, onSubmit, onCancel}: P
168170
ref={index === 0 ? nameInputRef : undefined}
169171
placeholder={`${variable.key}...`}
170172
value={variable.value}
171-
onChange={(e) => handleChange(index, e.target.value)}
173+
onChange={(e: ChangeEvent<HTMLInputElement>) => handleChange(index, e.target.value)}
172174
rows={5}
173175
/>
174176
</>

components/ChatBar/components/PluginKeyList.tsx

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,18 @@
1515
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
1616
* SOFTWARE.
1717
*/
18+
import { IconKey } from "@tabler/icons-react";
19+
import React, { ChangeEvent, useContext, useState } from "react";
20+
import { useTranslation } from "react-i18next";
1821

19-
import {IconKey} from "@tabler/icons-react"
20-
import React, {useContext, useState} from "react"
21-
import {useTranslation} from "react-i18next"
2222

23-
import ChatBarContext from "@/components/ChatBar/ChatBar.context"
24-
import SidebarButton from "@/components/Sidebar/SidebarButton"
25-
import {Button, Dialog, FormHeader, FormLabel, FormText, Input} from "@/components/Styled"
26-
import {useHomeContext} from "@/pages/api/home/home.context"
27-
import {PluginID} from "@/types/plugin"
23+
24+
import ChatBarContext from "@/components/ChatBar/ChatBar.context";
25+
import SidebarButton from "@/components/Sidebar/SidebarButton";
26+
import { Button, Dialog, FormHeader, FormLabel, FormText, Input } from "@/components/Styled";
27+
import { useHomeContext } from "@/pages/api/home/home.context";
28+
import { PluginID } from "@/types/plugin";
29+
2830

2931
export const PluginKeyList = () => {
3032
const {t} = useTranslation("common")
@@ -82,7 +84,7 @@ export const PluginKeyList = () => {
8284
<Input
8385
type="password"
8486
value={googleApiKey}
85-
onChange={(e) => {
87+
onChange={(e: ChangeEvent<HTMLInputElement>) => {
8688
setGoogleApiKey(e.target.value)
8789
}}
8890
/>
@@ -91,7 +93,7 @@ export const PluginKeyList = () => {
9193
<Input
9294
type="password"
9395
value={googleCseId}
94-
onChange={(e) => {
96+
onChange={(e: ChangeEvent<HTMLInputElement>) => {
9597
setGoogleCseId(e.target.value)
9698
}}
9799
/>

components/PromptBar/components/PromptEditModal.tsx

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,14 @@
1515
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
1616
* SOFTWARE.
1717
*/
18+
import { useTranslation } from "next-i18next";
19+
import { ChangeEvent, useEffect, useMemo, useRef, useState } from "react";
1820

19-
import {useTranslation} from "next-i18next"
20-
import {useEffect, useMemo, useRef, useState} from "react"
2121

22-
import {Button, Dialog, FormDisclaimer, FormLabel, Input, TextArea} from "@/components/Styled"
23-
import {Prompt} from "@/types/prompt"
22+
23+
import { Button, Dialog, FormDisclaimer, FormLabel, Input, TextArea } from "@/components/Styled";
24+
import { Prompt } from "@/types/prompt";
25+
2426

2527
interface Props {
2628
prompt: Prompt
@@ -57,16 +59,16 @@ export const PromptEditModal = ({prompt, onClose, onUpdatePrompt}: Props) => {
5759
ref={nameInputRef}
5860
placeholder={t("A name for your prompt.")}
5961
value={name}
60-
onChange={(e) => setName(e.target.value)}
61-
onBlur={(e) => setName(e.target.value)}
62+
onChange={(e: ChangeEvent<HTMLInputElement>) => setName(e.target.value)}
63+
onBlur={(e: ChangeEvent<HTMLInputElement>) => setName(e.target.value)}
6264
/>
6365

6466
<FormLabel className="mt-2">{t("Description")}</FormLabel>
6567
<TextArea
6668
placeholder={t("A description for your prompt.")}
6769
value={description}
68-
onChange={(e) => setDescription(e.target.value)}
69-
onBlur={(e) => setDescription(e.target.value)}
70+
onChange={(e: ChangeEvent<HTMLInputElement>) => setDescription(e.target.value)}
71+
onBlur={(e: ChangeEvent<HTMLInputElement>) => setDescription(e.target.value)}
7072
rows={3}
7173
/>
7274

@@ -76,8 +78,8 @@ export const PromptEditModal = ({prompt, onClose, onUpdatePrompt}: Props) => {
7678
"Use {{...}} to specify one or more prompt variables. For example:\n\n| Translate: {{Paste your text}} \n| Into this language: {{Specify target language}}\n\nThis will show 2 input boxes, one for the text and one for the target language. If you specify {{#DROP}} as the last parameter, a drop zone for files to be read is shown."
7779
)}
7880
value={content}
79-
onChange={(e) => setContent(e.target.value)}
80-
onBlur={(e) => setContent(e.target.value)}
81+
onChange={(e: ChangeEvent<HTMLInputElement>) => setContent(e.target.value)}
82+
onBlur={(e: ChangeEvent<HTMLInputElement>) => setContent(e.target.value)}
8183
rows={9}
8284
/>
8385

components/Styled/StyledComponents.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,9 @@ function createStyledComponent<P extends HTMLAttributes<HTMLElement>>(
2323
baseStyles: string,
2424
extraProps?: P
2525
) {
26+
// TODO [techdebt]: The 'any' type was 'P' but is no usuable. This is a workaround.
2627
const component = React.forwardRef(
27-
({className, children, ...props}: P, ref: ForwardedRef<HTMLElement>): ReactElement => {
28+
({className, children, ...props}: any, ref: ForwardedRef<HTMLElement>): ReactElement => {
2829
const classes = [className, baseStyles].filter(Boolean).join(" ")
2930

3031
const allProps = {

0 commit comments

Comments
 (0)