@@ -36,6 +36,8 @@ type MediaItemRowProps = {
3636 draggable ?: boolean ;
3737} & HTMLAttributes < HTMLDivElement > ;
3838
39+ type GeneratedMediaItem = Extract < MediaItem , { kind : "generated" } > ;
40+
3941export function MediaItemRow ( {
4042 data,
4143 className,
@@ -151,53 +153,177 @@ export function MediaItemRow({
151153 } else {
152154 console . log ( "[DEBUG] Runware item - checking for thumbnail generation" ) ;
153155
154- if ( data . status === "completed" ) {
155- if ( data . mediaType === "video" && ! data . metadata ?. thumbnail_url ) {
156+ if ( data . kind !== "generated" ) {
157+ return null ;
158+ }
159+
160+ let currentData : GeneratedMediaItem = data ;
161+
162+ if ( data . status !== "completed" ) {
163+ if ( ! data . taskUUID ) {
164+ console . error ( "[DEBUG] taskUUID is missing for Runware job!" , data ) ;
165+ throw new Error ( "taskUUID is required for runware provider" ) ;
166+ }
167+
168+ const runware = await getRunwareClient ( ) ;
169+
170+ if ( ! runware ) {
171+ console . error ( "[DEBUG] Runware client is not initialized" ) ;
172+ return null ;
173+ }
174+
175+ const response = await runware . getResponse ( {
176+ taskUUID : data . taskUUID ,
177+ } ) ;
178+
179+ const result = Array . isArray ( ( response as any ) ?. data )
180+ ? ( response as any ) . data [ 0 ]
181+ : ( response as any ) ?. data || response ;
182+
183+ console . log ( "[DEBUG] Runware getResponse result:" , result ) ;
184+
185+ if ( ! result ) {
186+ return null ;
187+ }
188+
189+ if ( result . error || result . status === "failed" ) {
190+ await db . media . update ( data . id , {
191+ ...data ,
192+ status : "failed" ,
193+ } ) ;
194+
195+ toast ( {
196+ title : t ( "generationFailed" ) ,
197+ description : t ( "generationFailedDesc" , {
198+ mediaType : data . mediaType ,
199+ } ) ,
200+ } ) ;
201+
202+ await queryClient . invalidateQueries ( {
203+ queryKey : queryKeys . projectMediaItems ( data . projectId ) ,
204+ } ) ;
205+
206+ return null ;
207+ }
208+
209+ const hasOutput = Boolean (
210+ result . imageURL ||
211+ result . videoURL ||
212+ result . audioURL ||
213+ result . audioDataURI ||
214+ result . audioBase64Data ,
215+ ) ;
216+
217+ if ( ! hasOutput && result . status !== "completed" ) {
218+ if ( data . status !== "running" ) {
219+ await db . media . update ( data . id , {
220+ ...data ,
221+ status : "running" ,
222+ } ) ;
223+
224+ await queryClient . invalidateQueries ( {
225+ queryKey : queryKeys . projectMediaItems ( data . projectId ) ,
226+ } ) ;
227+ }
228+
229+ return null ;
230+ }
231+
232+ currentData = {
233+ ...data ,
234+ output : result ,
235+ status : "completed" ,
236+ } as GeneratedMediaItem ;
237+
238+ await db . media . update ( data . id , currentData ) ;
239+
240+ toast ( {
241+ title : t ( "generationCompleted" ) ,
242+ description : t ( "generationCompletedDesc" , {
243+ mediaType : data . mediaType ,
244+ } ) ,
245+ } ) ;
246+
247+ await queryClient . invalidateQueries ( {
248+ queryKey : queryKeys . projectMediaItems ( data . projectId ) ,
249+ } ) ;
250+ }
251+
252+ if ( currentData . status === "completed" ) {
253+ if (
254+ currentData . mediaType === "video" &&
255+ ! currentData . metadata ?. thumbnail_url
256+ ) {
156257 console . log ( "[DEBUG] Generating thumbnail for Runware video" ) ;
157- const videoUrl = resolveMediaUrl ( data ) ;
258+ const videoUrl = resolveMediaUrl ( currentData ) ;
158259 if ( videoUrl ) {
159260 const thumbnailUrl = await extractVideoThumbnail ( videoUrl ) ;
160261 await db . media . update ( data . id , {
161- ...data ,
262+ ...currentData ,
162263 metadata : {
163- ...data . metadata ,
264+ ...currentData . metadata ,
164265 thumbnail_url : thumbnailUrl ,
165266 } ,
166267 } ) ;
167268 await queryClient . invalidateQueries ( {
168269 queryKey : queryKeys . projectMediaItems ( data . projectId ) ,
169270 } ) ;
170271 console . log ( "[DEBUG] Thumbnail generated:" , thumbnailUrl ) ;
272+
273+ currentData = {
274+ ...currentData ,
275+ metadata : {
276+ ...currentData . metadata ,
277+ thumbnail_url : thumbnailUrl ,
278+ } ,
279+ } as GeneratedMediaItem ;
171280 }
172281 }
173282
174- if ( data . mediaType !== "image" && ! data . metadata ?. duration ) {
283+ if (
284+ currentData . mediaType !== "image" &&
285+ ! currentData . metadata ?. duration
286+ ) {
175287 console . log (
176288 "[DEBUG] Extracting metadata for Runware" ,
177- data . mediaType ,
289+ currentData . mediaType ,
178290 ) ;
179- const mediaMetadata = await getMediaMetadata ( data as MediaItem ) ;
291+ const mediaMetadata = await getMediaMetadata ( currentData ) ;
180292 await db . media . update ( data . id , {
181- ...data ,
293+ ...currentData ,
182294 metadata : {
183- ...( data . metadata || { } ) ,
295+ ...( currentData . metadata || { } ) ,
184296 ...( mediaMetadata ?. media || { } ) ,
185297 } ,
186298 } ) ;
187299 await queryClient . invalidateQueries ( {
188300 queryKey : queryKeys . projectMediaItems ( data . projectId ) ,
189301 } ) ;
190302 console . log ( "[DEBUG] Metadata extracted:" , mediaMetadata ?. media ) ;
303+
304+ currentData = {
305+ ...currentData ,
306+ metadata : {
307+ ...( currentData . metadata || { } ) ,
308+ ...( mediaMetadata ?. media || { } ) ,
309+ } ,
310+ } as GeneratedMediaItem ;
191311 }
192312
193- if ( ! data . metadata ?. thumbnail_url && ! data . metadata ?. duration ) {
313+ if (
314+ ! currentData . metadata ?. thumbnail_url &&
315+ ! currentData . metadata ?. duration
316+ ) {
194317 console . log (
195318 "[DEBUG] Runware item should already be completed, skipping polling" ,
196319 ) ;
197320 await db . media . update ( data . id , {
198- ...data ,
321+ ...currentData ,
199322 status : "completed" ,
200323 } ) ;
324+ await queryClient . invalidateQueries ( {
325+ queryKey : queryKeys . projectMediaItems ( data . projectId ) ,
326+ } ) ;
201327 }
202328 }
203329 return null ;
0 commit comments