Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 354cb6f322 | |||
| eb54b0470d | |||
| a5ecfde9db |
@@ -3,6 +3,7 @@ import { Icon } from '@iconify/react';
|
||||
import CharacterBadge from '../components/CharacterBadge';
|
||||
import { useState, useEffect, useRef, useCallback } from 'react';
|
||||
import { speechToText, characterChatMessage, getAudio } from '../logic/sdk';
|
||||
import { SyncLoader } from 'react-spinners';
|
||||
|
||||
export default function Character() {
|
||||
const location = useLocation();
|
||||
@@ -12,6 +13,8 @@ export default function Character() {
|
||||
type Message = { text: string, sender: string };
|
||||
const [messages, setMessages] = useState<Message[]>([]);
|
||||
const [isRecording, setIsRecording] = useState(false);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [isOtherLoading, setIsOtherLoading] = useState(false);
|
||||
|
||||
let chunks = [] as any;
|
||||
const mediaRecorder = useRef<MediaRecorder | null>(null);
|
||||
@@ -24,7 +27,7 @@ export default function Character() {
|
||||
|
||||
useEffect(() => {
|
||||
scrollToBottom()
|
||||
}, [messages]);
|
||||
}, [messages, isLoading]);
|
||||
|
||||
useEffect(() => {
|
||||
navigator.mediaDevices.getUserMedia({ audio: true }).then((stream) => {
|
||||
@@ -35,12 +38,17 @@ export default function Character() {
|
||||
|
||||
mediaRecorder.current.onstop = async (e) => {
|
||||
setIsRecording(false);
|
||||
setIsLoading(true);
|
||||
const blob = new Blob(chunks, { type: 'audio/wav' });
|
||||
chunks = [];
|
||||
|
||||
const audioFile = new File([blob], "audio.wav", { type: 'audio/wav' });
|
||||
|
||||
const text = await speechToText(audioFile);
|
||||
setMessages(prevMessages => [...prevMessages, { text: text, sender: 'me' }]);
|
||||
setIsLoading(false);
|
||||
|
||||
setIsOtherLoading(true);
|
||||
const response = await characterChatMessage(sessionId, text);
|
||||
const { msg, audio_id } = response;
|
||||
const audioBlob = await getAudio(audio_id);
|
||||
@@ -48,7 +56,8 @@ export default function Character() {
|
||||
const audioUrl = URL.createObjectURL(audioFileResponse);
|
||||
const audio = new Audio(audioUrl);
|
||||
audio.play();
|
||||
setMessages(prevMessages => [...prevMessages, { text: text, sender: 'me' }, { text: msg, sender: 'other' }]);
|
||||
setMessages(prevMessages => [...prevMessages, { text: msg, sender: 'other' }]);
|
||||
setIsOtherLoading(false);
|
||||
}
|
||||
});
|
||||
}, []);
|
||||
@@ -74,8 +83,8 @@ export default function Character() {
|
||||
<h1 className="text-center">Talk With...</h1>
|
||||
<CharacterBadge name={name} image={image} onClick={() => {}}/>
|
||||
<div className="chat-area pb-10">
|
||||
{messages.length === 0 ? (
|
||||
<p className='subtext'>Please record a message to start the conversation.</p>
|
||||
{messages.length === 0 && !isLoading ? (
|
||||
<p className="text-center text-gray-400">Please record a message to start the conversation.</p>
|
||||
) : (
|
||||
messages.map((message, index) => (
|
||||
<div key={index} className={`message ${message.sender}`}>
|
||||
@@ -83,6 +92,28 @@ export default function Character() {
|
||||
</div>
|
||||
))
|
||||
)}
|
||||
{isLoading && (
|
||||
<div className="message me">
|
||||
<SyncLoader
|
||||
color="white"
|
||||
loading={isLoading}
|
||||
aria-label="Loading Spinner"
|
||||
data-testid="loader"
|
||||
size={10}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
{isOtherLoading && (
|
||||
<div className="message other">
|
||||
<SyncLoader
|
||||
color="white"
|
||||
loading={isOtherLoading}
|
||||
aria-label="Loading Spinner"
|
||||
data-testid="loader"
|
||||
size={10}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div ref={messageEndRef} />
|
||||
</div>
|
||||
|
||||
@@ -2,6 +2,7 @@ import { useLocation, useNavigate } from 'react-router-dom';
|
||||
import { Icon } from '@iconify/react';
|
||||
import { useState, useRef, useEffect } from 'react';
|
||||
import { humanChatMessage } from '../logic/sdk';
|
||||
import { SyncLoader } from 'react-spinners';
|
||||
|
||||
export default function Character() {
|
||||
const location = useLocation();
|
||||
@@ -11,6 +12,7 @@ export default function Character() {
|
||||
type Message = { text: string, sender: string };
|
||||
const [messages, setMessages] = useState<Message[]>([]);
|
||||
const [message, setMessage] = useState('');
|
||||
const [isOtherLoading, setIsOtherLoading] = useState(false);
|
||||
|
||||
const messageEndRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
@@ -22,13 +24,16 @@ export default function Character() {
|
||||
scrollToBottom()
|
||||
}, [messages]);
|
||||
|
||||
const handleSendClick = () => {
|
||||
const handleSendClick = async () => {
|
||||
if (message !== '') {
|
||||
setMessages(prevMessages => [...prevMessages, { text: message, sender: 'me' }]);
|
||||
setMessage('');
|
||||
humanChatMessage(sessionId, message).then((response) => {
|
||||
setMessages(prevMessages => [...prevMessages, { text: response.msg, sender: 'other' }]);
|
||||
})
|
||||
|
||||
setIsOtherLoading(true);
|
||||
const response = await humanChatMessage(sessionId, message);
|
||||
const { msg } = response;
|
||||
setMessages(prevMessages => [...prevMessages, { text: msg, sender: 'other' }]);
|
||||
setIsOtherLoading(false);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -55,6 +60,17 @@ export default function Character() {
|
||||
</div>
|
||||
))
|
||||
)}
|
||||
{isOtherLoading && (
|
||||
<div className="message other">
|
||||
<SyncLoader
|
||||
color="white"
|
||||
loading={isOtherLoading}
|
||||
aria-label="Loading Spinner"
|
||||
data-testid="loader"
|
||||
size={10}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<div ref={messageEndRef} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user