improvements, see comments: https://github.com/cogentapps/chat-with-gpt/pull/58
parent
e3f4dfef82
commit
39e175bef6
|
@ -104,7 +104,7 @@ export default function MessageInput(props: MessageInputProps) {
|
||||||
}
|
}
|
||||||
}, [context, message, dispatch]);
|
}, [context, message, dispatch]);
|
||||||
|
|
||||||
const onSpeechStart = () => {
|
const onSpeechStart = useCallback(() => {
|
||||||
|
|
||||||
if (!recording) {
|
if (!recording) {
|
||||||
setRecording(true);
|
setRecording(true);
|
||||||
|
@ -141,27 +141,30 @@ export default function MessageInput(props: MessageInputProps) {
|
||||||
data.append('file', file);
|
data.append('file', file);
|
||||||
data.append('model', 'whisper-1')
|
data.append('model', 'whisper-1')
|
||||||
|
|
||||||
const response = await fetch("https://api.openai.com/v1/audio/transcriptions", {
|
try {
|
||||||
method: "POST",
|
const response = await fetch("https://api.openai.com/v1/audio/transcriptions", {
|
||||||
headers: {
|
method: "POST",
|
||||||
'Authorization': `Bearer ${openAIApiKey}`,
|
headers: {
|
||||||
},
|
'Authorization': `Bearer ${openAIApiKey}`,
|
||||||
body: data,
|
},
|
||||||
});
|
body: data,
|
||||||
|
});
|
||||||
|
|
||||||
const json = await response.json()
|
const json = await response.json()
|
||||||
|
|
||||||
if (json.text) {
|
if (json.text) {
|
||||||
dispatch(setMessage(json.text));
|
dispatch(setMessage(json.text));
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
}).catch((e: any) => console.error(e));
|
}).catch((e: any) => console.error(e));
|
||||||
} else {
|
} else {
|
||||||
speechRecognition.stop();
|
speechRecognition.stop();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}, [recording, message, dispatch]);
|
||||||
|
|
||||||
|
|
||||||
const onKeyDown = useCallback((e: React.KeyboardEvent<HTMLTextAreaElement>) => {
|
const onKeyDown = useCallback((e: React.KeyboardEvent<HTMLTextAreaElement>) => {
|
||||||
|
@ -192,14 +195,14 @@ export default function MessageInput(props: MessageInputProps) {
|
||||||
</>)}
|
</>)}
|
||||||
{!context.generating && (
|
{!context.generating && (
|
||||||
<>
|
<>
|
||||||
<ActionIcon size="xl"
|
|
||||||
onClick={onSubmit}>
|
|
||||||
<i className="fa fa-paper-plane" style={{ fontSize: '90%' }} />
|
|
||||||
</ActionIcon>
|
|
||||||
<ActionIcon size="xl"
|
<ActionIcon size="xl"
|
||||||
onClick={onSpeechStart}>
|
onClick={onSpeechStart}>
|
||||||
<i className="fa fa-microphone" style={{ fontSize: '90%', color: recording ? 'red' : 'inherit' }} />
|
<i className="fa fa-microphone" style={{ fontSize: '90%', color: recording ? 'red' : 'inherit' }} />
|
||||||
</ActionIcon>
|
</ActionIcon>
|
||||||
|
<ActionIcon size="xl"
|
||||||
|
onClick={onSubmit}>
|
||||||
|
<i className="fa fa-paper-plane" style={{ fontSize: '90%' }} />
|
||||||
|
</ActionIcon>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import SettingsTab from "./tab";
|
import SettingsTab from "./tab";
|
||||||
import SettingsOption from "./option";
|
import SettingsOption from "./option";
|
||||||
import { TextInput } from "@mantine/core";
|
import { Checkbox, TextInput } from "@mantine/core";
|
||||||
import { useCallback, useMemo } from "react";
|
import { useCallback, useMemo } from "react";
|
||||||
import { useAppDispatch, useAppSelector } from "../../store";
|
import { useAppDispatch, useAppSelector } from "../../store";
|
||||||
import { selectOpenAIApiKey, setOpenAIApiKeyFromEvent, selectUseOpenAIWhisper, setUseOpenAIWhisperFromEvent } from "../../store/api-keys";
|
import { selectOpenAIApiKey, setOpenAIApiKeyFromEvent, selectUseOpenAIWhisper, setUseOpenAIWhisperFromEvent } from "../../store/api-keys";
|
||||||
|
@ -30,9 +30,13 @@ export default function UserOptionsTab(props: any) {
|
||||||
<FormattedMessage defaultMessage="Find your API key here." description="Label for the link that takes the user to the page on the OpenAI website where they can find their API key." />
|
<FormattedMessage defaultMessage="Find your API key here." description="Label for the link that takes the user to the page on the OpenAI website where they can find their API key." />
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
|
||||||
<input type="checkbox" id="use-openai-whisper-api" checked={useOpenAIWhisper!} onChange={onUseOpenAIWhisperChange} /> Use the OpenAI Whisper API for speech recognition.
|
<Checkbox
|
||||||
</p>
|
style={{ marginTop: '1rem' }}
|
||||||
|
id="use-openai-whisper-api" checked={useOpenAIWhisper!} onChange={onUseOpenAIWhisperChange}
|
||||||
|
label="Use the OpenAI Whisper API for speech recognition."
|
||||||
|
/>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<FormattedMessage defaultMessage="Your API key is stored only on this device and never transmitted to anyone except OpenAI." />
|
<FormattedMessage defaultMessage="Your API key is stored only on this device and never transmitted to anyone except OpenAI." />
|
||||||
</p>
|
</p>
|
||||||
|
|
|
@ -3,12 +3,12 @@ import type { RootState } from '.';
|
||||||
|
|
||||||
const initialState: {
|
const initialState: {
|
||||||
openAIApiKey?: string | null | undefined;
|
openAIApiKey?: string | null | undefined;
|
||||||
useOpenAIWhisper?: boolean | null | undefined;
|
useOpenAIWhisper: boolean;
|
||||||
elevenLabsApiKey?: string | null | undefined;
|
elevenLabsApiKey?: string | null | undefined;
|
||||||
|
|
||||||
} = {
|
} = {
|
||||||
openAIApiKey: localStorage.getItem('openai-api-key'),
|
openAIApiKey: localStorage.getItem('openai-api-key'),
|
||||||
useOpenAIWhisper: localStorage.getItem('use-openai-whisper') === 'true',
|
useOpenAIWhisper: false,
|
||||||
elevenLabsApiKey: localStorage.getItem('elevenlabs-api-key'),
|
elevenLabsApiKey: localStorage.getItem('elevenlabs-api-key'),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue