diff --git a/src/hooks/useGenerateResult.ts b/src/hooks/useGenerateResult.ts index d7f07bf..bb5965f 100644 --- a/src/hooks/useGenerateResult.ts +++ b/src/hooks/useGenerateResult.ts @@ -2,15 +2,17 @@ import { RATE_LIMIT_COUNT } from '@/utils/constants' import { loadOpenAIKey } from '@/utils/localData' import { GenerateApiInput } from '@/utils/types' import { useRouter } from 'next/router' -import { useState } from 'react' +import { useRef, useState } from 'react' import { toast } from 'react-hot-toast' export const useGenerateResult = () => { const router = useRouter() const [generatedResults, setGeneratedResults] = useState('') + const isStreamingRef = useRef(true) async function generate(body: GenerateApiInput) { setGeneratedResults('') + isStreamingRef.current = true const response = await fetch('/api/generate', { method: 'POST', @@ -41,13 +43,25 @@ export const useGenerateResult = () => { const decoder = new TextDecoder() let done = false - while (!done) { + while (!done && isStreamingRef.current) { const { value, done: doneReading } = await reader.read() done = doneReading const chunkValue = decoder.decode(value) setGeneratedResults((prev) => prev + chunkValue) } + + reader.cancel().then(() => { + readyStream() + }) + } + + function stopStream() { + isStreamingRef.current = false + } + + function readyStream() { + isStreamingRef.current = true } - return { generatedResults, generate } + return { generatedResults, generate, stopStream } } diff --git a/src/pages/app/[id].tsx b/src/pages/app/[id].tsx index 406690a..8ce86a1 100644 --- a/src/pages/app/[id].tsx +++ b/src/pages/app/[id].tsx @@ -62,7 +62,8 @@ const OpenGptApp = ( const { id, demoInput, description, icon, name } = props.appConfig const [loading, setLoading] = useState(false) const [userInput, setUserInput] = useState(demoInput) - const { generate, generatedResults } = useGenerateResult() + const { generate, generatedResults, stopStream } = + useGenerateResult() const incUsage = api.app.incUsage.useMutation() @@ -83,10 +84,25 @@ const OpenGptApp = ( e.preventDefault() await generate({ userInput, id }) incUsage.mutate(id) - scrollToResults() setLoading(false) } + const handleStop = async (e: any) => { + if (!loading) { + return + } + stopStream() + setLoading(false) + e.preventDefault() + } + + const handleAction = async (e: any) => { + if (loading) { + await handleStop(e) + } else { + await handleRun(e) + } + } return ( @@ -122,9 +138,8 @@ const OpenGptApp = ( /> @@ -142,10 +157,13 @@ const OpenGptApp = (
{ - navigator.clipboard.writeText(generatedResults) - toast('Result copied to clipboard', { - icon: '✂️', - }) + navigator.clipboard + .writeText(generatedResults) + .then(() => { + toast('Result copied to clipboard', { + icon: '✂️', + }) + }) }} >