修复DMXAPI文生成画bug

This commit is contained in:
w 2025-05-25 00:42:37 +08:00 committed by 亢奋猫
parent 848ac4fa80
commit 08ba515241
2 changed files with 36 additions and 71 deletions

View File

@ -3,7 +3,7 @@ import FileManager from '@renderer/services/FileManager'
import { Painting } from '@renderer/types'
import { download } from '@renderer/utils/download'
import { Button, Dropdown, Spin } from 'antd'
import { FC } from 'react'
import React, { FC } from 'react'
import { useTranslation } from 'react-i18next'
import styled from 'styled-components'
@ -17,6 +17,7 @@ interface ArtboardProps {
onNextImage: () => void
onCancel: () => void
retry?: (painting: Painting) => void
imageCover?: React.ReactNode
}
const Artboard: FC<ArtboardProps> = ({
@ -26,7 +27,8 @@ const Artboard: FC<ArtboardProps> = ({
onPrevImage,
onNextImage,
onCancel,
retry
retry,
imageCover
}) => {
const { t } = useTranslation()
@ -108,8 +110,10 @@ const Artboard: FC<ArtboardProps> = ({
</div>
</div>
) : (
<div>{t('paintings.image_placeholder')}</div>
)}
imageCover ?
imageCover:
(<div>{t('paintings.image_placeholder')}</div>)
)}
</ImagePlaceholder>
)}
{isLoading && (

View File

@ -9,9 +9,7 @@ import { useTheme } from '@renderer/context/ThemeProvider'
import { usePaintings } from '@renderer/hooks/usePaintings'
import { useAllProviders } from '@renderer/hooks/useProvider'
import { useRuntime } from '@renderer/hooks/useRuntime'
import { useSettings } from '@renderer/hooks/useSettings'
import FileManager from '@renderer/services/FileManager'
import { translateText } from '@renderer/services/TranslateService'
import { useAppDispatch } from '@renderer/store'
import { setGenerating } from '@renderer/store/runtime'
import type { FileType, PaintingsState } from '@renderer/types'
@ -176,7 +174,7 @@ const DmxapiPage: FC<{ Options: string[] }> = ({ Options }) => {
}
// API请求函数
const callApi = async (requestConfig: { endpoint: string; body: any }) => {
const callApi = async (requestConfig: { endpoint: string; body: any }, controller: AbortController) => {
const { endpoint, body } = requestConfig
const headers = {}
@ -191,7 +189,8 @@ const DmxapiPage: FC<{ Options: string[] }> = ({ Options }) => {
const response = await fetch(endpoint, {
method: 'POST',
headers,
body
body,
signal: controller.signal
})
if (!response.ok) {
@ -239,6 +238,10 @@ const DmxapiPage: FC<{ Options: string[] }> = ({ Options }) => {
}
const onGenerate = async () => {
// 如果已经在生成过程中,直接返回
if (isLoading) {
return
}
try {
// 获取提示词
const prompt = textareaRef.current?.resizableTextArea?.textArea?.value || ''
@ -254,26 +257,28 @@ const DmxapiPage: FC<{ Options: string[] }> = ({ Options }) => {
centered: true
})
if (!confirmed) return
await FileManager.deleteFiles(painting.files)
}
setIsLoading(true)
// 设置请求状态
const controller = new AbortController()
setAbortController(controller)
setIsLoading(true)
dispatch(setGenerating(true))
// 准备请求配置
const requestConfig = prepareRequestConfig(prompt, painting)
// 发送API请求
const urls = await callApi(requestConfig)
const urls = await callApi(requestConfig, controller)
// 下载图像
if (urls.length > 0) {
const downloadedFiles = await downloadImages(urls)
const validFiles = downloadedFiles.filter((file): file is FileType => file !== null)
// 删除之前的图片
await FileManager.deleteFiles(painting.files)
// 保存文件并更新状态
await FileManager.addFiles(validFiles)
updatePaintingState({ files: validFiles, urls })
@ -325,51 +330,8 @@ const DmxapiPage: FC<{ Options: string[] }> = ({ Options }) => {
setCurrentImageIndex(0)
}
const { autoTranslateWithSpace } = useSettings()
const [spaceClickCount, setSpaceClickCount] = useState(0)
const [isTranslating, setIsTranslating] = useState(false)
const spaceClickTimer = useRef<NodeJS.Timeout>(null)
const translate = async () => {
if (isTranslating) {
return
}
if (!painting.prompt) {
return
}
try {
setIsTranslating(true)
const translatedText = await translateText(painting.prompt, 'english')
updatePaintingState({ prompt: translatedText })
} catch (error) {
console.error('Translation failed:', error)
} finally {
setIsTranslating(false)
}
}
const handleKeyDown = (event: React.KeyboardEvent<HTMLTextAreaElement>) => {
if (autoTranslateWithSpace && event.key === ' ') {
setSpaceClickCount((prev) => prev + 1)
if (spaceClickTimer.current) {
clearTimeout(spaceClickTimer.current)
}
spaceClickTimer.current = setTimeout(() => {
setSpaceClickCount(0)
}, 200)
if (spaceClickCount === 2) {
setSpaceClickCount(0)
setIsTranslating(true)
translate().then(() => {})
}
}
}
const handleProviderChange = (providerId: string) => {
const routeName = location.pathname.split('/').pop()
if (providerId !== routeName) {
@ -481,21 +443,21 @@ const DmxapiPage: FC<{ Options: string[] }> = ({ Options }) => {
</SliderContainer>
</LeftContainer>
<MainContainer>
{painting?.urls?.length > 0 || DMXAPIPaintings?.length > 1 ? (
<Artboard
painting={painting}
isLoading={isLoading}
currentImageIndex={currentImageIndex}
onPrevImage={prevImage}
onNextImage={nextImage}
onCancel={onCancel}
/>
) : (
<EmptyImgBox>
<EmptyImg></EmptyImg>
</EmptyImgBox>
)}
<Artboard
painting={painting}
isLoading={isLoading}
currentImageIndex={currentImageIndex}
onPrevImage={prevImage}
onNextImage={nextImage}
onCancel={onCancel}
imageCover={
painting?.urls?.length > 0 || DMXAPIPaintings?.length > 1 ? null : (
<EmptyImgBox>
<EmptyImg></EmptyImg>
</EmptyImgBox>
)
}
/>
<InputContainer>
<Textarea
ref={textareaRef}
@ -504,8 +466,7 @@ const DmxapiPage: FC<{ Options: string[] }> = ({ Options }) => {
value={painting.prompt}
spellCheck={false}
onChange={(e) => updatePaintingState({ prompt: e.target.value })}
placeholder={isTranslating ? t('paintings.translating') : t('paintings.prompt_placeholder')}
onKeyDown={handleKeyDown}
placeholder={t('paintings.prompt_placeholder')}
/>
<Toolbar>
<ToolbarMenu>