diff --git a/frontend/editor2d/src/KonvaApp/Api.ts b/frontend/editor2d/src/KonvaApp/Api.ts index 3e1f807810..45f19dcef5 100644 --- a/frontend/editor2d/src/KonvaApp/Api.ts +++ b/frontend/editor2d/src/KonvaApp/Api.ts @@ -148,7 +148,7 @@ export class ApiManager { formData.append("file", blob); } - console.log(`HELLO${formData}`); + // console.log(`HELLO${formData}`); return this.fetchMultipartFormData(endpoint, { method: "POST", headers: { @@ -248,7 +248,6 @@ export class Api extends ApiManager { formData.append("scene_media_token", sceneMediaToken); } - // for now ... const uuidIdempotencyToken = crypto.randomUUID(); // Generate a new UUID formData.append("uuid_idempotency_token", uuidIdempotencyToken); // Added uuid_idempotency_token @@ -262,9 +261,7 @@ export class Api extends ApiManager { }); const postResponse = await response.json(); - console.log(postResponse); - let result: { success: boolean; data?: string; errorMessage?: string }; if (postResponse.success) { @@ -276,7 +273,7 @@ export class Api extends ApiManager { } else { result = { success: false, - errorMessage: postResponse.BadInput, + errorMessage: "Failed to generate snapshot.", }; } @@ -293,7 +290,7 @@ export class Api extends ApiManager { additionalImages?: string[]; }): Promise> { const endpoint = `${this.ApiTargets.BaseApi}/v1/image_studio/prompt`; - // for now ... + const uuidIdempotencyToken = crypto.randomUUID(); // Generate a new UUID const body = { uuid_idempotency_token: uuidIdempotencyToken, @@ -317,11 +314,13 @@ export class Api extends ApiManager { // Check if the response is successful const isSuccess = postResponse.success ?? false; - // Prepare the result object + console.log("postResponse FOR ENQUEUE IMAGE GENERATION"); + console.log(postResponse); + const result = { success: isSuccess, - data: isSuccess ? postResponse.job_token : undefined, + data: isSuccess ? postResponse.inference_job_token : undefined, errorMessage: isSuccess ? undefined : postResponse.BadInput, }; @@ -330,14 +329,21 @@ export class Api extends ApiManager { public async pollJobSession(jobToken: string): Promise< ApiResponse<{ - status: string; + job_token: string; + request: { + maybe_model_title: string; + }; + status: { + status: string; + progress_percentage: number; + }; result: { generated_images?: string[]; error?: string; }; }> > { - const endpoint = `${this.ApiTargets.BaseApi}/v1/jobs/session/${jobToken}`; + const endpoint = `${this.ApiTargets.BaseApi}/v1/jobs/job/${jobToken}`; const response = await this.get<{ success?: boolean; @@ -351,17 +357,31 @@ export class Api extends ApiManager { endpoint, }); + console.log("response FROM JOBS"); + console.log(response); + const success = response.success ?? false; const status = response.status ?? ""; const result = response.result ?? { generated_images: [], error: undefined, }; + const errorMessage = response.BadInput; return { success, - data: { status, result }, + data: { + result, + job_token: jobToken, + request: { + maybe_model_title: "Image Generation", + }, + status: { + status: status.toLowerCase(), + progress_percentage: 0, + }, + }, errorMessage, }; } diff --git a/frontend/editor2d/src/components/PromptBox.tsx b/frontend/editor2d/src/components/PromptBox.tsx index 7dc0105771..2530059ac2 100644 --- a/frontend/editor2d/src/components/PromptBox.tsx +++ b/frontend/editor2d/src/components/PromptBox.tsx @@ -1,6 +1,7 @@ import { useState, useRef, useEffect } from "react"; import { invoke } from "@tauri-apps/api/core"; import { useSignals } from "@preact/signals-react/runtime"; +import { toast } from "sonner"; import { UploaderStates, // UploaderState, @@ -11,7 +12,7 @@ import { PopoverMenu } from "~/components/reusable/Popover"; import { Tooltip } from "~/components/reusable/Tooltip"; import { Button } from "~/components/reusable/Button"; import { ToggleButton } from "~/components/reusable/ToggleButton"; - +import { Toaster } from "~/components/ui/Toast"; import { faMessageXmark, faMessageCheck, @@ -245,20 +246,25 @@ export const PromptBox = () => { additionalImages: referenceImages.map((image) => image.mediaToken), }); - console.log("Response:", response); - if (response.success === true) { console.error("Successfully enqueued image generation."); if (response.data) { + console.log("Response:", response.data); setJobToken(response.data); } return; } else { console.log("Image generation Not Successful."); + toast.error("Failed to generate image. Please try again."); } } + } catch (error) { + console.error("Error during image generation:", error); + toast.error( + "An error occurred while generating the image. Please try again.", + ); } finally { setisEnqueueing(false); } diff --git a/frontend/editor2d/src/components/ui/Activity/Activity.tsx b/frontend/editor2d/src/components/ui/Activity/Activity.tsx index 1172c3540e..ac77528852 100644 --- a/frontend/editor2d/src/components/ui/Activity/Activity.tsx +++ b/frontend/editor2d/src/components/ui/Activity/Activity.tsx @@ -5,6 +5,7 @@ import { PopoverMenu } from "~/components/reusable/Popover"; import { CompletedCard } from "./CompletedCard"; import { InProgressCard } from "./InProgressCard"; import { useJobContext } from "~/components/JobContext"; +import { Api } from "~/KonvaApp/Api"; // Dummy data types interface CompletedItem { token: string; @@ -40,28 +41,28 @@ const dummyCompletedItems: CompletedItem[] = [ }, ]; -const dummyJobs: ActiveJob[] = [ - { - job_token: "job1", - request: { - maybe_model_title: "In Progress Job 1", - }, - status: { - status: "STARTED", - progress_percentage: 45, - }, - }, - { - job_token: "job2", - request: { - maybe_model_title: "In Progress Job 2", - }, - status: { - status: "PENDING", - progress_percentage: 0, - }, - }, -]; +// const dummyJobs: ActiveJob[] = [ +// { +// job_token: "job1", +// request: { +// maybe_model_title: "In Progress Job 1", +// }, +// status: { +// status: "STARTED", +// progress_percentage: 45, +// }, +// }, +// { +// job_token: "job2", +// request: { +// maybe_model_title: "In Progress Job 2", +// }, +// status: { +// status: "PENDING", +// progress_percentage: 0, +// }, +// }, +// ]; export function Activity() { const { jobToken, setJobToken } = useJobContext(); @@ -71,26 +72,98 @@ export function Activity() { // Dummy polling function useEffect(() => { - const pollData = () => { - // Simulate API calls + const pollData = async () => { if (jobToken) { console.log("Current Job Token:", jobToken); + const api = new Api(); + const job = await api.pollJobSession(jobToken); + console.log("Job response:", job); + + if (job.success && job.data) { + const { status, progress_percentage } = job.data.status; + const { job_token } = job.data; + + console.log("Job status:", status); + console.log("Progress percentage:", progress_percentage); + console.log("Job token:", job_token); + + // Update jobs with real job data + if ( + status.toLowerCase() === "completed" || + status.toLowerCase() === "failed" + ) { + // If job is completed or failed, remove it from active jobs + setJobs((prevJobs) => + prevJobs.filter((j) => j.job_token !== job_token), + ); + + // Add to completed items if it was successful + if ( + status.toLowerCase() === "completed" && + job.data.result.generated_images + ) { + const newCompletedItem: CompletedItem = { + id: job_token, + title: job.data.request.maybe_model_title || "Image Generation", + timestamp: new Date().toISOString(), + type: "image", + imageUrl: job.data.result.generated_images[0] || "", + }; + + setCompletedItems((prev) => [newCompletedItem, ...prev]); + } + } else { + // Update or add the job to the active jobs list + const updatedJob: ActiveJob = { + job_token, + request: { + maybe_model_title: + job.data.request.maybe_model_title || "Image Generation", + }, + status: { + status: status.toUpperCase(), + progress_percentage: progress_percentage || 0, + }, + }; + + setJobs((prevJobs) => { + const existingJobIndex = prevJobs.findIndex( + (j) => j.job_token === job_token, + ); + if (existingJobIndex >= 0) { + // Update existing job + const newJobs = [...prevJobs]; + newJobs[existingJobIndex] = updatedJob; + return newJobs; + } else { + // Add new job + return [updatedJob, ...prevJobs]; + } + }); + } + } else { + console.error("Failed to fetch job status:", job.errorMessage); + } } else { console.log("No Job Token available."); } - setCompletedItems(dummyCompletedItems); - setJobs(dummyJobs); - setLoading(false); + + if (jobs.length === 0) { + setLoading(false); + } }; // Initial load + // Initial call to pollData pollData(); // Set up polling interval (every 5 seconds) - const interval = setInterval(pollData, 5000); + const interval = setInterval(async () => { + await pollData(); + }, 5000); return () => clearInterval(interval); - }, []); + }, [jobToken]); return (