|
|
|
|
@ -60,6 +60,8 @@ export function FreeFlow(){ |
|
|
|
|
|
|
|
|
|
const [padInput, setPadInput] = useState(null); |
|
|
|
|
|
|
|
|
|
const [showMessage, setShowMessage] = useState(false); |
|
|
|
|
|
|
|
|
|
const { userId, setUserId, getFileId, setPassword, reset:resetUser, uploadHistory, setSummary, summary,setChoice,choice, getUploadFolder,getDataId, writeSheet } = useUser(); |
|
|
|
|
|
|
|
|
|
const refTimer=useRef(); |
|
|
|
|
@ -83,6 +85,7 @@ export function FreeFlow(){ |
|
|
|
|
const refHintTimeout=useRef(); |
|
|
|
|
|
|
|
|
|
const refFadeOutInterval=useRef(); |
|
|
|
|
const refVolDownInterval=useRef(); |
|
|
|
|
|
|
|
|
|
const { history, status, reset, sendMessage, setStatus, audioOutput, setAudioOutput, stop:stopChat, |
|
|
|
|
audioUrl }=useChat(); |
|
|
|
|
@ -183,6 +186,26 @@ export function FreeFlow(){ |
|
|
|
|
refAudioAnnounce.current.play().catch(error => { |
|
|
|
|
console.error("Audio announce playback error:", error); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// lower audio |
|
|
|
|
if(refAudio.current) { |
|
|
|
|
// fade out current audio |
|
|
|
|
if(refVolDownInterval.current){ |
|
|
|
|
clearInterval(refVolDownInterval.current); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const dest=0.5; |
|
|
|
|
let fadeOutInterval = setInterval(() => { |
|
|
|
|
if (refAudio.current.volume > dest) { |
|
|
|
|
refAudio.current.volume =Math.max(dest, refAudio.current.volume - 1.0/(AUDIO_FADE_TIME/100)); // Decrease volume gradually |
|
|
|
|
} else { |
|
|
|
|
clearInterval(fadeOutInterval); |
|
|
|
|
} |
|
|
|
|
}, 100); |
|
|
|
|
refVolDownInterval.current=fadeOutInterval; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@ -659,6 +682,11 @@ export function FreeFlow(){ |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function blurText(text) { |
|
|
|
|
if(!text) return ''; |
|
|
|
|
return text.replace(/./g, '*'); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
useEffect(()=>{ |
|
|
|
|
if(audioInput && isMicrophoneAvailable) { |
|
|
|
|
|
|
|
|
|
@ -895,17 +923,17 @@ export function FreeFlow(){ |
|
|
|
|
</div> |
|
|
|
|
</section> |
|
|
|
|
<section className="flex-1 self-stretch overflow-y-auto flex flex-col justify-end gap-2 "> |
|
|
|
|
<div ref={refContainer} className="flex-1 flex flex-col overflow-y-auto gap-2"> |
|
|
|
|
<div ref={refContainer} className="flex-1 flex flex-col overflow-y-auto gap-2 blur-sm" > |
|
|
|
|
{history?.map((msg, index) => ( |
|
|
|
|
<div key={index} className={`w-5/6 ${msg.role=='user'? 'self-end':''}`}> |
|
|
|
|
<div className={`${msg.role=='user'? 'bg-green-300':'bg-pink-300'} px-2`}>{msg.content}</div> |
|
|
|
|
{msg.prompt && <div className="text-xs bg-gray-200">{msg.prompt}</div>} |
|
|
|
|
<div className={`${msg.role=='user'? 'bg-green-300':'bg-pink-300'} px-2`}>{blurText(msg.content)}</div> |
|
|
|
|
{msg.prompt && <div className="text-xs bg-gray-200">{blurText(msg.prompt)}</div>} |
|
|
|
|
</div> |
|
|
|
|
))} |
|
|
|
|
{summary && <div className="w-full self-center bg-blue-200 px-2">{summary}</div>} |
|
|
|
|
</div> |
|
|
|
|
<textarea ref={refInput} name="message" rows={2} |
|
|
|
|
className={`w-full border-1 resize-none p-2 disabled:bg-gray-500`} |
|
|
|
|
className={`w-full border-1 resize-none p-2 disabled:bg-gray-500 blur-sm`} |
|
|
|
|
disabled={chatStatus!=ChatStatus.User && chatStatus!=ChatStatus.Message}></textarea> |
|
|
|
|
<div className="flex flex-row justify-end gap-2 flex-wrap"> |
|
|
|
|
<span className="flex flex-row gap-1"> |
|
|
|
|
|