mirror of
https://github.com/storytold/artcraft.git
synced 2026-10-20 17:02:53 -04:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8b3e75cda9 |
@@ -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,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user