Skip to content

Commit fd07ee6

Browse files
committed
feat: gpt image
1 parent b6e6c0a commit fd07ee6

File tree

2 files changed

+135
-31
lines changed

2 files changed

+135
-31
lines changed

src/pages/home/index.jsx

Lines changed: 119 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -80,11 +80,13 @@ import {
8080
prettyObject,
8181
// randomNum,
8282
getDirection,
83+
oneApiImage,
8384
} from '@utils/aidFn'
8485
import { fireConfetti } from '@utils/confetti'
8586
import Zoom from 'react-medium-image-zoom'
8687
import 'react-medium-image-zoom/dist/styles.css'
8788
import styles from './index.module.less'
89+
import { image } from 'd3'
8890

8991
// const boxList = Array.apply(null, Array(10))
9092

@@ -149,6 +151,8 @@ const Home = () => {
149151
const [dateTime, setDateTime] = useState('')
150152
const curController = useRef(null)
151153

154+
const [aiImageList, setAiImageList] = useState([])
155+
152156
const mouseEnterRef = useRef(null)
153157
const [enterDirection, setEnterDirection] = useState('left')
154158
const handleMouseEnter = (event) => {
@@ -203,6 +207,14 @@ const Home = () => {
203207
curController.current = controller
204208
fetchAi(chatText, apiKey, controller)
205209
}
210+
const onSubmitImage = () => {
211+
if (chatText.trim() === '') {
212+
return
213+
}
214+
const controller = new AbortController()
215+
curController.current = controller
216+
fetchAiImage(chatText, apiKey, controller)
217+
}
206218

207219
const onStop = () => {
208220
curController.current.abort()
@@ -294,6 +306,60 @@ const Home = () => {
294306
setAiText(error.message)
295307
})
296308
}
309+
const fetchAiImage = (text, key, controller) => {
310+
aiTextRef.current = ''
311+
setAiText(aiTextRef.current)
312+
setAiImageList([])
313+
const { signal } = controller
314+
setIsStream(true)
315+
oneApiImage(
316+
[
317+
{
318+
content: text,
319+
role: 'user',
320+
},
321+
],
322+
key,
323+
signal
324+
)
325+
.then((response) => {
326+
const contentType = response.headers.get('content-type')
327+
if (!response.ok || response.status !== 200) {
328+
if (contentType?.startsWith('text/html') || contentType?.startsWith('text/plain')) {
329+
const textPlain = response.clone().text()
330+
textPlain.then((plainText) => {
331+
setAiText(plainText)
332+
})
333+
} else if (contentType?.startsWith('application/json')) {
334+
const resJson = response.clone().json()
335+
resJson.then((res) => {
336+
setAiText(prettyObject(res))
337+
})
338+
} else {
339+
setAiText(response.statusText)
340+
}
341+
setIsStream(false)
342+
} else {
343+
const resJson = response.clone().json()
344+
resJson.then((res) => {
345+
// setAiText(prettyObject(res))
346+
console.log('res', res)
347+
if (res.error) return
348+
setAiImageList(
349+
res.data.map((item) => ({
350+
imageUrl: item.url,
351+
imagePrompt: item.revised_prompt,
352+
}))
353+
)
354+
})
355+
setIsStream(false)
356+
}
357+
})
358+
.catch((error) => {
359+
setIsStream(false)
360+
setAiText(error.message)
361+
})
362+
}
297363

298364
const scrollRef = useRef(null)
299365
const [customElement, setCustomElement] = useState()
@@ -340,10 +406,63 @@ const Home = () => {
340406
<section className={styles.avatar} style={{ margin: '10px 0', fontSize: 24 }}>
341407
<ColorfulText text={`React version: ${version}`} />
342408
</section>
409+
<section style={{ width: 600, margin: '30px 0' }}>
410+
<Input defaultValue={apiKey} placeholder="api key" onChange={changeApiKey} style={{ marginBottom: 20 }} />
411+
<Flex align="center">
412+
<Input.TextArea
413+
ref={textareaRef}
414+
defaultValue={chatText}
415+
placeholder="来,说点什么呗...Meta + Enter发送"
416+
onChange={changeChatText}
417+
onKeyDown={onInputKeyDown}
418+
autoSize
419+
style={{ width: 300, height: 30, caretColor: '#ff0000' }}
420+
/>
421+
<Button
422+
style={{ margin: '0 10px' }}
423+
icon={<SendOutlined rotate={-60} />}
424+
type="primary"
425+
disabled={isStream}
426+
onClick={onSubmit}
427+
>
428+
发送
429+
</Button>
430+
<Button
431+
style={{ margin: '0 10px' }}
432+
icon={<SendOutlined rotate={-60} />}
433+
type="primary"
434+
disabled={isStream}
435+
onClick={onSubmitImage}
436+
>
437+
生成图片
438+
</Button>
439+
<Button icon={<SendOutlined rotate={-60} />} type="primary" disabled={!isStream} onClick={onStop}>
440+
停止
441+
</Button>
442+
</Flex>
443+
</section>
444+
<section className="mb-10">
445+
{isStream && <div>正在输入...</div>}
446+
<section style={{ textAlign: 'right', color: '#666' }}>{dateTime}</section>
447+
<ReMarkdown markdownText={aiText} isLoading={isStream} />
448+
<section className="aiImage">
449+
{aiImageList.length > 0 && (
450+
<>
451+
{aiImageList.map((item, index) => (
452+
<div key={index}>
453+
<div>{item.imagePrompt}</div>
454+
<img src={item.imageUrl} width="100%" alt={item.url} />
455+
</div>
456+
))}
457+
</>
458+
)}
459+
</section>
460+
</section>
343461
<section style={{ marginBottom: 15, fontSize: 20 }}>
344462
I love <span className={styles.circledHighlight}>coding</span> in{' '}
345463
<AlternatingText alternateText={['JavaScript', 'TypeScript', 'React', 'Vue', 'Remix', 'Node.js']} />.
346464
</section>
465+
347466
<section style={{ marginBottom: 15, fontSize: 20 }}>
348467
X岁的你,正处在一个特殊的位置:
349468
<TypeWriter
@@ -815,37 +934,6 @@ const Home = () => {
815934
<section style={{ margin: '20px 0', fontSize: 40 }}>
816935
<NumberFlowFix />
817936
</section>
818-
<section style={{ width: 600, margin: '30px 0' }}>
819-
<Input defaultValue={apiKey} placeholder="api key" onChange={changeApiKey} style={{ marginBottom: 20 }} />
820-
<Flex align="center">
821-
<Input.TextArea
822-
ref={textareaRef}
823-
defaultValue={chatText}
824-
placeholder="来,说点什么呗...Meta + Enter发送"
825-
onChange={changeChatText}
826-
onKeyDown={onInputKeyDown}
827-
autoSize
828-
style={{ width: 300, height: 30, caretColor: '#ff0000' }}
829-
/>
830-
<Button
831-
style={{ margin: '0 10px' }}
832-
icon={<SendOutlined rotate={-60} />}
833-
type="primary"
834-
disabled={isStream}
835-
onClick={onSubmit}
836-
>
837-
发送
838-
</Button>
839-
<Button icon={<SendOutlined rotate={-60} />} type="primary" disabled={!isStream} onClick={onStop}>
840-
停止
841-
</Button>
842-
</Flex>
843-
</section>
844-
<section>
845-
{isStream && <div>正在输入...</div>}
846-
<section style={{ textAlign: 'right', color: '#666' }}>{dateTime}</section>
847-
<ReMarkdown markdownText={aiText} isLoading={isStream} />
848-
</section>
849937

850938
<section style={{ position: 'relative', fontSize: 36 }}>
851939
I build

src/utils/aidFn.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,22 @@ export const oneApiChat = (chatList, token, signal) =>
345345
}),
346346
})
347347

348+
export const oneApiImage = (chatList, token, signal) =>
349+
fetch('https://api.zhizengzeng.com/v1/images/generations', {
350+
method: 'POST',
351+
signal,
352+
headers: {
353+
Authorization: token,
354+
'Content-Type': 'application/json',
355+
},
356+
body: JSON.stringify({
357+
model: 'dall-e-3',
358+
prompt: chatList[0].content,
359+
n: 1,
360+
size: '1792x1024',
361+
response_format: 'url',
362+
}),
363+
})
348364
export const getCurrentDate = () => {
349365
const date = new Date()
350366
const day = date.getDate()

0 commit comments

Comments
 (0)