Compare commits

...
5 changed files with 57 additions and 181 deletions
-172
View File
@@ -404,175 +404,3 @@ export class Api extends ApiManager {
};
}
}
export class EngineApi extends ApiManager {
public async uploadSceneSnapshot({
screenshot,
sceneMediaToken,
}: {
screenshot: File; // base64 encoded PNG
sceneMediaToken?: string;
}): Promise<ApiResponse<string>> {
const endpoint = `${this.ApiTargets.BaseApi}/v1/image_studio/scene_snapshot`;
const formData = new FormData();
formData.append("snapshot", screenshot); // Changed from "screenshot" to "snapshot" to match API spec
if (sceneMediaToken) {
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
const response = await fetch(endpoint, {
method: "POST",
headers: {
Accept: "application/json",
},
credentials: "include",
body: formData,
});
const postResponse = await response.json();
console.log(postResponse);
let result: { success: boolean; data?: string; errorMessage?: string };
if (postResponse.success) {
result = {
success: true,
data: postResponse.snapshot_media_token,
errorMessage: undefined,
};
} else {
result = {
success: false,
errorMessage: postResponse.BadInput,
};
}
return result;
}
public async enqueueImageGeneration({
prompt,
snapshotMediaToken,
additionalImages,
}: {
prompt: string;
snapshotMediaToken: string;
additionalImages?: string[];
}): Promise<ApiResponse<string>> {
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,
prompt,
snapshot_media_token: snapshotMediaToken, // Changed from scene_media_token to snapshot_media_token
additional_images: additionalImages,
};
const postResponse = await this.post<
{
uuid_idempotency_token: string;
prompt: string;
snapshot_media_token: string;
additional_images?: string[];
},
{ success?: boolean; job_token?: string; BadInput?: string }
>({
endpoint,
body,
});
// Check if the response is successful
const isSuccess = postResponse.success ?? false;
// Prepare the result object
const result = {
success: isSuccess,
data: isSuccess ? postResponse.job_token : undefined,
errorMessage: isSuccess ? undefined : postResponse.BadInput,
};
return result;
}
public async pollJobSession(jobToken: string): Promise<
ApiResponse<{
status: string;
result: {
generated_images?: string[];
error?: string;
};
}>
> {
const endpoint = `${this.ApiTargets.BaseApi}/v1/jobs/session/${jobToken}`;
const response = await this.get<{
success?: boolean;
status?: string;
result?: {
generated_images?: string[];
error?: string;
};
BadInput?: string;
}>({
endpoint,
});
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 },
errorMessage,
};
}
public async pollStudioSessionJobs(jobToken: string): Promise<
ApiResponse<{
status: string;
result: {
generated_images?: string[];
error?: string;
};
}>
> {
const endpoint = `${this.ApiTargets.BaseApi}/v1/image_studio/session_jobs/${jobToken}`;
const response = await this.get<{
success?: boolean;
status?: string;
result?: {
generated_images?: string[];
error?: string;
};
BadInput?: string;
}>({
endpoint,
});
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 },
errorMessage,
};
}
}
+11 -7
View File
@@ -6,7 +6,7 @@ import { router } from "./router";
import { posthog } from "posthog-js";
import { PostHogProvider } from "posthog-js/react";
import { Toaster } from "~/components/ui/Toast";
import { JobProvider } from "~/components/JobContext";
import "./global.css";
import { useRenderCounter } from "~/hooks/useRenderCounter";
@@ -30,17 +30,21 @@ const App = () => {
if (useStrictMode) {
return (
<StrictMode>
<PostHogProvider client={posthog}>
<RouterProvider router={router} />
<Toaster />
</PostHogProvider>
<JobProvider>
<PostHogProvider client={posthog}>
<RouterProvider router={router} />
<Toaster />
</PostHogProvider>
</JobProvider>
</StrictMode>
);
}
return (
<>
<RouterProvider router={router} />
<Toaster />
<JobProvider>
<RouterProvider router={router} />
<Toaster />
</JobProvider>
</>
);
};
@@ -0,0 +1,28 @@
import React, { createContext, useContext, useState } from "react";
interface JobContextType {
jobToken: string | null;
setJobToken: (token: string | null) => void;
}
const JobContext = createContext<JobContextType | undefined>(undefined);
export const JobProvider: React.FC<{ children: React.ReactNode }> = ({
children,
}) => {
const [jobToken, setJobToken] = useState<string | null>(null);
return (
<JobContext.Provider value={{ jobToken, setJobToken }}>
{children}
</JobContext.Provider>
);
};
export const useJobContext = () => {
const context = useContext(JobContext);
if (context === undefined) {
throw new Error("useJobContext must be used within a JobProvider");
}
return context;
};
+11 -1
View File
@@ -33,6 +33,7 @@ import { EncodeImageBitmapToBase64 } from "~/utilities/EncodeImageBitmapToBase64
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { PopoverItem } from "~/components/reusable/Popover";
import { Api, ApiManager } from "~/KonvaApp/Api";
import { useJobContext } from "~/components/JobContext";
interface ReferenceImage {
id: string;
url: string;
@@ -45,6 +46,8 @@ export const PromptBox = () => {
const isDesktopApp = window.navigator.userAgent.includes("Tauri");
console.log("Is this a desktop app?", isDesktopApp);
const { jobToken, setJobToken } = useJobContext();
//const { lastRenderedBitmap } = useCanvasSignal();
const [prompt, setPrompt] = useState("");
const [isEnqueueing, setisEnqueueing] = useState(false);
@@ -217,9 +220,11 @@ export const PromptBox = () => {
const mimeString = "image/png";
const ab = new ArrayBuffer(byteString.length);
const ia = new Uint8Array(ab);
for (let i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
const uuid = crypto.randomUUID(); // Generate a new UUID
const file = new File([ab], `${uuid}.png`, { type: mimeString });
@@ -244,9 +249,14 @@ export const PromptBox = () => {
if (response.success === true) {
console.error("Successfully enqueued image generation.");
if (response.data) {
setJobToken(response.data);
}
return;
} else {
console.log("Image generation Not Successfull.");
console.log("Image generation Not Successful.");
}
}
} finally {
@@ -4,7 +4,7 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { PopoverMenu } from "~/components/reusable/Popover";
import { CompletedCard } from "./CompletedCard";
import { InProgressCard } from "./InProgressCard";
import { useJobContext } from "~/components/JobContext";
// Dummy data types
interface CompletedItem {
token: string;
@@ -64,6 +64,7 @@ const dummyJobs: ActiveJob[] = [
];
export function Activity() {
const { jobToken, setJobToken } = useJobContext();
const [completedItems, setCompletedItems] = useState<CompletedItem[]>([]);
const [jobs, setJobs] = useState<ActiveJob[]>([]);
const [loading, setLoading] = useState(true);
@@ -72,6 +73,11 @@ export function Activity() {
useEffect(() => {
const pollData = () => {
// Simulate API calls
if (jobToken) {
console.log("Current Job Token:", jobToken);
} else {
console.log("No Job Token available.");
}
setCompletedItems(dummyCompletedItems);
setJobs(dummyJobs);
setLoading(false);