@@ -5,15 +5,15 @@ import {
5
5
} from "../../services/settings-service" ;
6
6
import { ChevronDown , RefreshCw } from "lucide-react" ;
7
7
import { useTranslation } from "react-i18next" ;
8
+ import { AIService } from "../../services/ai-service" ;
9
+ import { OPENAI_PROVIDER_NAME } from "../../services/providers/openai-service" ;
8
10
9
11
export const ImageGenerationPage = ( ) => {
10
12
const { t } = useTranslation ( ) ;
11
13
const [ prompt , setPrompt ] = useState ( "" ) ;
12
14
const [ isGenerating , setIsGenerating ] = useState ( false ) ;
13
15
const [ imageResult , setImageResult ] = useState < string | null > ( null ) ;
14
16
const [ error , setError ] = useState < Error | null > ( null ) ;
15
- const [ selectedModel , setSelectedModel ] = useState ( "" ) ;
16
- const [ selectedProvider , setSelectedProvider ] = useState ( "" ) ;
17
17
const [ isApiKeyMissing , setIsApiKeyMissing ] = useState ( true ) ;
18
18
const [ aspectRatio , setAspectRatio ] = useState ( "1:1" ) ;
19
19
const [ imageCount , setImageCount ] = useState ( 1 ) ;
@@ -24,12 +24,8 @@ export const ImageGenerationPage = () => {
24
24
// Check if API key is available
25
25
useEffect ( ( ) => {
26
26
setIsApiKeyMissing ( ! SettingsService . getInstance ( ) . getApiKey ( ) ) ;
27
- setSelectedProvider ( SettingsService . getInstance ( ) . getSelectedProvider ( ) ) ;
28
- setSelectedModel ( SettingsService . getInstance ( ) . getSelectedModel ( ) ) ;
29
27
30
28
const handleSettingsChange = ( ) => {
31
- setSelectedProvider ( SettingsService . getInstance ( ) . getSelectedProvider ( ) ) ;
32
- setSelectedModel ( SettingsService . getInstance ( ) . getSelectedModel ( ) ) ;
33
29
setIsApiKeyMissing ( ! SettingsService . getInstance ( ) . getApiKey ( ) ) ;
34
30
} ;
35
31
@@ -40,24 +36,51 @@ export const ImageGenerationPage = () => {
40
36
} ;
41
37
} , [ ] ) ;
42
38
43
- // Handle generating an image (mock function)
39
+ // Handle generating an image using OpenAI's DALL-E 3
44
40
const handleGenerateImage = async ( ) => {
45
41
if ( ! prompt . trim ( ) ) return ;
46
42
47
43
setIsGenerating ( true ) ;
48
44
setError ( null ) ;
49
45
50
46
try {
51
- // In a real implementation, this would call an actual image generation service
52
- // For now, just simulate the process with a timeout
53
- await new Promise ( ( resolve ) => setTimeout ( resolve , 2000 ) ) ;
47
+ // Get the OpenAI service from AIService
48
+ const openaiService = AIService . getInstance ( ) . getProvider ( OPENAI_PROVIDER_NAME ) ;
49
+
50
+ if ( ! openaiService ) {
51
+ throw new Error ( "OpenAI service not available" ) ;
52
+ }
54
53
55
- // For demo purposes, just show a placeholder result
56
- setImageResult (
57
- `https://placehold.co/512x512/eee/999?text=${ encodeURIComponent (
58
- prompt
59
- ) } `
60
- ) ;
54
+ // Map aspect ratio to size dimensions
55
+ const sizeMap : Record < string , `${number } x${number } `> = {
56
+ "1:1" : "1024x1024" ,
57
+ "1:2" : "512x1024" ,
58
+ "3:2" : "1024x768" ,
59
+ "3:4" : "768x1024" ,
60
+ "16:9" : "1792x1024" ,
61
+ "9:16" : "1024x1792"
62
+ } ;
63
+
64
+ // Generate the image
65
+ const images = await openaiService . getImageGeneration ( prompt , {
66
+ size : sizeMap [ aspectRatio ] || "1024x1024" ,
67
+ aspectRatio : aspectRatio as `${number } :${number } `,
68
+ style : "vivid"
69
+ } ) ;
70
+
71
+ // Set the result image
72
+ if ( images && images . length > 0 ) {
73
+ // Check if the image is already a full data URL
74
+ const base64Data = images [ 0 ] as string ;
75
+ if ( base64Data . startsWith ( 'data:image' ) ) {
76
+ setImageResult ( base64Data ) ;
77
+ } else {
78
+ // If it's just a base64 string without the data URI prefix, add it
79
+ setImageResult ( `data:image/png;base64,${ base64Data } ` ) ;
80
+ }
81
+ } else {
82
+ throw new Error ( "No images generated" ) ;
83
+ }
61
84
} catch ( err ) {
62
85
setError ( err as Error ) ;
63
86
} finally {
@@ -70,27 +93,6 @@ export const ImageGenerationPage = () => {
70
93
setRandomSeed ( Math . floor ( Math . random ( ) * 1000000 ) . toString ( ) ) ;
71
94
} ;
72
95
73
- // Get model name
74
- const getModelName = ( modelID : string , provider : string ) => {
75
- const providerSettings =
76
- SettingsService . getInstance ( ) . getProviderSettings ( provider ) ;
77
- if ( ! providerSettings . models ) return modelID ;
78
-
79
- const model = providerSettings . models ?. find ( ( m ) => m . modelId === modelID ) ;
80
- if ( ! model ) return modelID ;
81
-
82
- return model . modelName ;
83
- } ;
84
-
85
- // Get display provider name
86
- const getDisplayProviderName = ( ) => {
87
- if ( ! selectedProvider ) return "硅基流动" ;
88
-
89
- const providerSettings =
90
- SettingsService . getInstance ( ) . getProviderSettings ( selectedProvider ) ;
91
- return providerSettings . providerName || selectedProvider ;
92
- } ;
93
-
94
96
return (
95
97
< div className = "flex flex-col w-full h-full bg-white" >
96
98
{ isApiKeyMissing && (
@@ -120,19 +122,6 @@ export const ImageGenerationPage = () => {
120
122
/>
121
123
</ div >
122
124
123
- { /* Negative prompt */ }
124
- { /* <div className="mb-6">
125
- <label className="flex items-center block mb-2 text-sm font-medium text-gray-700">
126
- 反向提示词
127
- <div className="flex items-center justify-center w-4 h-4 ml-1 text-xs text-gray-500 bg-gray-200 rounded-full cursor-help" title="Elements to avoid in the image">?</div>
128
- </label>
129
- <textarea
130
- placeholder="输入不希望在生成的图像中出现的元素"
131
- className="w-full p-3 input-box"
132
- rows={3}
133
- />
134
- </div> */ }
135
-
136
125
{ /* Generation button */ }
137
126
< div className = "flex justify-center mb-6" >
138
127
< button
@@ -208,7 +197,7 @@ export const ImageGenerationPage = () => {
208
197
className = "flex items-center justify-between w-full p-3 text-left input-box"
209
198
disabled = { true }
210
199
>
211
- < span > { getDisplayProviderName ( ) } </ span >
200
+ < span > OpenAI </ span >
212
201
< ChevronDown size = { 18 } className = "text-gray-500" />
213
202
</ button >
214
203
</ div >
@@ -224,10 +213,7 @@ export const ImageGenerationPage = () => {
224
213
className = "flex items-center justify-between w-full p-3 text-left input-box"
225
214
disabled = { true }
226
215
>
227
- < span >
228
- { getModelName ( selectedModel , selectedProvider ) ||
229
- "FLUX.1 Schnell" }
230
- </ span >
216
+ < span > DALL-E 3</ span >
231
217
< ChevronDown size = { 18 } className = "text-gray-500" />
232
218
</ button >
233
219
</ div >
@@ -326,6 +312,7 @@ export const ImageGenerationPage = () => {
326
312
min = "1"
327
313
max = "4"
328
314
className = "w-full p-3 input-box"
315
+ disabled = { true }
329
316
/>
330
317
</ div >
331
318
@@ -346,11 +333,13 @@ export const ImageGenerationPage = () => {
346
333
value = { randomSeed }
347
334
onChange = { ( e ) => setRandomSeed ( e . target . value ) }
348
335
className = "flex-grow p-3 mr-2 input-box"
336
+ disabled = { true }
349
337
/>
350
338
< button
351
339
onClick = { generateNewSeed }
352
340
className = "p-2 rounded-lg image-generation-refresh-button"
353
341
title = { t ( "imageGeneration.randomSeed" ) }
342
+ disabled = { true }
354
343
>
355
344
< RefreshCw size = { 20 } />
356
345
</ button >
0 commit comments