mirror of
https://github.com/storytold/artcraft.git
synced 2026-10-28 20:42:50 -04:00
Compare commits
12
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bd9d85058c | ||
|
|
c4c4d77bdb | ||
|
|
8e120e02de | ||
|
|
d8607168fb | ||
|
|
bb611b850d | ||
|
|
3ef364fdbd | ||
|
|
5016bc64bd | ||
|
|
8aa3f2ba56 | ||
|
|
6871f5ea45 | ||
|
|
1b198e2334 | ||
|
|
17a0204131 | ||
|
|
52c361ed8e |
@@ -1,5 +1,5 @@
|
||||
[build]
|
||||
command = "./apps/editor2d/script/netlify_build.sh"
|
||||
#command = "./script/netlify_build.sh"
|
||||
publish = "apps/editor2d/dist/"
|
||||
|
||||
#[build.environment]
|
||||
@@ -16,6 +16,7 @@ publish = "apps/editor2d/dist/"
|
||||
for = "/build/*"
|
||||
|
||||
[headers.values]
|
||||
|
||||
"Cache-Control" = "public, max-age=31560000, immutable"
|
||||
|
||||
# [[redirects]]
|
||||
|
||||
@@ -15,6 +15,6 @@ cp _redirects dist/
|
||||
echo "Copy netlify 404.html page into dist"
|
||||
cp "404.html" dist/
|
||||
|
||||
echo "List final files in build"
|
||||
echo "List files after build"
|
||||
find dist/
|
||||
|
||||
|
||||
@@ -148,6 +148,7 @@ export class ApiManager {
|
||||
formData.append("file", blob);
|
||||
}
|
||||
|
||||
// console.log(`HELLO${formData}`);
|
||||
return this.fetchMultipartFormData<T>(endpoint, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
@@ -326,10 +327,7 @@ export class Api extends ApiManager {
|
||||
return result;
|
||||
}
|
||||
|
||||
public async pollJobSession(
|
||||
jobToken: string,
|
||||
thumbnailWidth: number = 256,
|
||||
): Promise<
|
||||
public async pollJobSession(jobToken: string): Promise<
|
||||
ApiResponse<{
|
||||
job_token: string;
|
||||
request: {
|
||||
@@ -340,9 +338,6 @@ export class Api extends ApiManager {
|
||||
progress_percentage: number;
|
||||
};
|
||||
result: {
|
||||
image_url: string;
|
||||
thumbnail_url: string;
|
||||
public_bucket_path: string;
|
||||
generated_images?: string[];
|
||||
error?: string;
|
||||
};
|
||||
@@ -350,53 +345,41 @@ export class Api extends ApiManager {
|
||||
> {
|
||||
const endpoint = `${this.ApiTargets.BaseApi}/v1/jobs/job/${jobToken}`;
|
||||
|
||||
const response = await this.get<any>({
|
||||
const response = await this.get<{
|
||||
success?: boolean;
|
||||
status?: string;
|
||||
result?: {
|
||||
generated_images?: string[];
|
||||
error?: string;
|
||||
};
|
||||
BadInput?: string;
|
||||
}>({
|
||||
endpoint,
|
||||
});
|
||||
console.log("Job Polling Response:");
|
||||
console.log(response);
|
||||
|
||||
let image_url = response.state.maybe_result?.media_links?.cdn_url;
|
||||
let public_bucket_path =
|
||||
response.state.maybe_result?.maybe_public_bucket_media_path;
|
||||
|
||||
let thumbnail_url =
|
||||
response.state.maybe_result?.media_links?.maybe_thumbnail_template?.replace(
|
||||
"{WIDTH}",
|
||||
thumbnailWidth.toString(),
|
||||
);
|
||||
|
||||
let progress_percentage = response.state.status.progress_percentage;
|
||||
let status_string = response.state.status.status;
|
||||
|
||||
console.log("Image URL:", image_url);
|
||||
console.log("Thumbnail URL:", thumbnail_url);
|
||||
console.log("Progress Percentage:", progress_percentage);
|
||||
console.log("Status", status_string);
|
||||
|
||||
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: {
|
||||
result: {
|
||||
image_url: image_url || "",
|
||||
thumbnail_url: thumbnail_url || "",
|
||||
public_bucket_path: public_bucket_path || "",
|
||||
error: undefined,
|
||||
},
|
||||
result,
|
||||
job_token: jobToken,
|
||||
request: {
|
||||
maybe_model_title: "Image Generation",
|
||||
},
|
||||
status: {
|
||||
status: status_string.toLowerCase(),
|
||||
progress_percentage: progress_percentage,
|
||||
status: status.toLowerCase(),
|
||||
progress_percentage: 0,
|
||||
},
|
||||
},
|
||||
errorMessage,
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
import React, { createContext, useContext, useState } from "react";
|
||||
|
||||
interface JobContextType {
|
||||
jobTokens: string[];
|
||||
addJobToken: (token: string) => void;
|
||||
removeJobToken: (token: string) => void;
|
||||
clearJobTokens: () => void;
|
||||
jobToken: string | null;
|
||||
setJobToken: (token: string | null) => void;
|
||||
}
|
||||
|
||||
const JobContext = createContext<JobContextType | undefined>(undefined);
|
||||
@@ -12,24 +10,10 @@ const JobContext = createContext<JobContextType | undefined>(undefined);
|
||||
export const JobProvider: React.FC<{ children: React.ReactNode }> = ({
|
||||
children,
|
||||
}) => {
|
||||
const [jobTokens, setJobTokens] = useState<string[]>([]);
|
||||
|
||||
const addJobToken = (token: string) => {
|
||||
setJobTokens((prevTokens) => [...prevTokens, token]);
|
||||
};
|
||||
|
||||
const removeJobToken = (token: string) => {
|
||||
setJobTokens((prevTokens) => prevTokens.filter((t) => t !== token));
|
||||
};
|
||||
|
||||
const clearJobTokens = () => {
|
||||
setJobTokens([]);
|
||||
};
|
||||
const [jobToken, setJobToken] = useState<string | null>(null);
|
||||
|
||||
return (
|
||||
<JobContext.Provider
|
||||
value={{ jobTokens, addJobToken, removeJobToken, clearJobTokens }}
|
||||
>
|
||||
<JobContext.Provider value={{ jobToken, setJobToken }}>
|
||||
{children}
|
||||
</JobContext.Provider>
|
||||
);
|
||||
|
||||
@@ -47,8 +47,7 @@ export const PromptBox = () => {
|
||||
const isDesktopApp = window.navigator.userAgent.includes("Tauri");
|
||||
console.log("Is this a desktop app?", isDesktopApp);
|
||||
|
||||
const { jobTokens, addJobToken, removeJobToken, clearJobTokens } =
|
||||
useJobContext();
|
||||
const { jobToken, setJobToken } = useJobContext();
|
||||
|
||||
//const { lastRenderedBitmap } = useCanvasSignal();
|
||||
const [prompt, setPrompt] = useState("");
|
||||
@@ -120,7 +119,7 @@ export const PromptBox = () => {
|
||||
setUploadingImages((prev) =>
|
||||
prev.filter((img) => img.id !== uploadId),
|
||||
);
|
||||
toast.success("Reference image added.");
|
||||
console.log("Reference image added:", referenceImage);
|
||||
} else if (
|
||||
newState.status === UploaderStates.assetError ||
|
||||
newState.status === UploaderStates.imageCreateError
|
||||
@@ -128,8 +127,7 @@ export const PromptBox = () => {
|
||||
setUploadingImages((prev) =>
|
||||
prev.filter((img) => img.id !== uploadId),
|
||||
);
|
||||
|
||||
toast.error("Upload failed. Please try again.");
|
||||
console.error("Upload failed");
|
||||
}
|
||||
},
|
||||
});
|
||||
@@ -208,7 +206,7 @@ export const PromptBox = () => {
|
||||
const api = new Api();
|
||||
let image = getCanvasRenderBitmap();
|
||||
if (image === undefined) {
|
||||
toast.error(
|
||||
console.error(
|
||||
"Error: Unable to generate image. Please check the input and try again.",
|
||||
);
|
||||
return;
|
||||
@@ -231,9 +229,7 @@ export const PromptBox = () => {
|
||||
});
|
||||
|
||||
if (snapshotMediaToken.data === undefined) {
|
||||
toast.error(
|
||||
"Error: Unable to upload scene snapshot Please try again.",
|
||||
);
|
||||
console.error("Error: Unable to upload scene snapshot.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -246,13 +242,17 @@ export const PromptBox = () => {
|
||||
});
|
||||
|
||||
if (response.success === true) {
|
||||
toast.success("Please wait while we process your image.");
|
||||
console.error("Successfully enqueued image generation.");
|
||||
|
||||
if (response.data) {
|
||||
addJobToken(response.data);
|
||||
console.log("Response:", response.data);
|
||||
setJobToken(response.data);
|
||||
}
|
||||
|
||||
return;
|
||||
} else {
|
||||
toast.error("Failed to enqueue image generation. Please try again.");
|
||||
console.log("Image generation Not Successful.");
|
||||
toast.error("Failed to generate image. Please try again.");
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
|
||||
@@ -63,11 +63,12 @@ export const ToolbarMain = ({
|
||||
buttonProps={buttonProps.SELECT}
|
||||
tooltip="Select"
|
||||
/>
|
||||
<ToolbarButton
|
||||
{/* <ToolbarButton
|
||||
icon={faText}
|
||||
buttonProps={buttonProps.ADD_TEXT}
|
||||
tooltip="Add Text"
|
||||
/>
|
||||
/> */}
|
||||
|
||||
<Popover className="relative">
|
||||
{({ close }) => (
|
||||
<>
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { twMerge } from "tailwind-merge";
|
||||
import { Login } from "~/app/pages/login";
|
||||
import { Activity } from "~/components/ui/Activity/Activity";
|
||||
// import { paperWrapperStyles } from "~/components/styles";
|
||||
// import { faPlus, faQuestion } from "@fortawesome/pro-solid-svg-icons";
|
||||
|
||||
@@ -6,8 +6,6 @@ import { CompletedCard } from "./CompletedCard";
|
||||
import { InProgressCard } from "./InProgressCard";
|
||||
import { useJobContext } from "~/components/JobContext";
|
||||
import { Api } from "~/KonvaApp/Api";
|
||||
import { toast } from "sonner";
|
||||
|
||||
// Dummy data types
|
||||
interface CompletedItem {
|
||||
token: string;
|
||||
@@ -67,72 +65,90 @@ const dummyCompletedItems: CompletedItem[] = [
|
||||
// ];
|
||||
|
||||
export function Activity() {
|
||||
const { jobTokens, addJobToken, removeJobToken, clearJobTokens } =
|
||||
useJobContext();
|
||||
const { jobToken, setJobToken } = useJobContext();
|
||||
const [completedItems, setCompletedItems] = useState<CompletedItem[]>([]);
|
||||
const [jobs, setJobs] = useState<ActiveJob[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
// Dummy polling function
|
||||
useEffect(() => {
|
||||
const pollData = async () => {
|
||||
if (jobTokens.length > 0) {
|
||||
console.log("Current Job Tokens:", jobTokens);
|
||||
if (jobToken) {
|
||||
console.log("Current Job Token:", jobToken);
|
||||
const api = new Api();
|
||||
const job = await api.pollJobSession(jobToken);
|
||||
console.log("Job response:", job);
|
||||
|
||||
// Create a map to store the latest job data
|
||||
const updatedJobs = new Map<string, ActiveJob>();
|
||||
if (job.success && job.data) {
|
||||
const { status, progress_percentage } = job.data.status;
|
||||
const { job_token } = job.data;
|
||||
|
||||
for (const jobToken of jobTokens) {
|
||||
const job = await api.pollJobSession(jobToken);
|
||||
console.log("Job status:", status);
|
||||
console.log("Progress percentage:", progress_percentage);
|
||||
console.log("Job token:", job_token);
|
||||
|
||||
if (job.success && job.data) {
|
||||
const { status, progress_percentage } = job.data.status;
|
||||
const { job_token } = job.data;
|
||||
// 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() === "complete_success" ||
|
||||
status.toLowerCase() === "failed"
|
||||
status.toLowerCase() === "completed" &&
|
||||
job.data.result.generated_images
|
||||
) {
|
||||
// If job is complete_success or failed, we'll remove it later
|
||||
removeJobToken(job_token);
|
||||
|
||||
// Add to complete_success items if it was successful
|
||||
if (status.toLowerCase() === "complete_success") {
|
||||
const newCompletedItem: CompletedItem = {
|
||||
token: job_token,
|
||||
maybe_title:
|
||||
job.data.request.maybe_model_title || "Image Generation",
|
||||
public_bucket_path: job.data.result.image_url || "",
|
||||
updated_at: new Date().toISOString(),
|
||||
};
|
||||
setCompletedItems((prev) => [newCompletedItem, ...prev]);
|
||||
toast.success("Done Processing Image");
|
||||
}
|
||||
} else {
|
||||
// Store the job in our map
|
||||
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,
|
||||
},
|
||||
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] || "",
|
||||
};
|
||||
updatedJobs.set(job_token, updatedJob);
|
||||
|
||||
setCompletedItems((prev) => [newCompletedItem, ...prev]);
|
||||
}
|
||||
} else {
|
||||
console.error("Failed to fetch job status:", job.errorMessage);
|
||||
}
|
||||
}
|
||||
// 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,
|
||||
},
|
||||
};
|
||||
|
||||
// Update jobs state with the deduplicated jobs
|
||||
setJobs(Array.from(updatedJobs.values()));
|
||||
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.");
|
||||
}
|
||||
if (jobTokens.length === 0) {
|
||||
setJobs([]);
|
||||
|
||||
if (jobs.length === 0) {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
@@ -147,7 +163,7 @@ export function Activity() {
|
||||
}, 5000);
|
||||
|
||||
return () => clearInterval(interval);
|
||||
}, [jobTokens, removeJobToken]);
|
||||
}, [jobToken]);
|
||||
|
||||
return (
|
||||
<PopoverMenu
|
||||
|
||||
@@ -17,10 +17,8 @@ interface Props {
|
||||
export function CompletedCard({ job }: Props) {
|
||||
const [loadError, setLoadError] = useState(false);
|
||||
const [isModalOpen, setIsModalOpen] = useState(false);
|
||||
const imageUrl = job.public_bucket_path;
|
||||
const imageUrl = job.public_bucket_path + "-thumb.gif";
|
||||
const fullImageUrl = job.public_bucket_path;
|
||||
console.log("I am hjere");
|
||||
console.log(job);
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
[build]
|
||||
command = "./apps/editor3d/script/netlify_build.sh"
|
||||
#command = "./script/netlify_build.sh"
|
||||
#publish = "build/client"
|
||||
publish = "apps/editor3d/dist/"
|
||||
|
||||
[build.environment]
|
||||
REACT_APP_PUBLIC_POSTHOG_KEY = "phc_jBFgac0mVALAFk3negnSfYCcHgvkT00yBLQDmCDYNBb"
|
||||
REACT_APP_PUBLIC_POSTHOG_UI = "https://us.i.posthog.com"
|
||||
|
||||
#[dev]
|
||||
#command = "npm run dev"
|
||||
#framework = "vite"
|
||||
[dev]
|
||||
command = "npm run dev"
|
||||
framework = "vite"
|
||||
|
||||
# Set immutable caching for static files, because they have fingerprinted filenames
|
||||
|
||||
@@ -16,6 +17,7 @@ REACT_APP_PUBLIC_POSTHOG_UI = "https://us.i.posthog.com"
|
||||
for = "/build/*"
|
||||
|
||||
[headers.values]
|
||||
|
||||
"Cache-Control" = "public, max-age=31560000, immutable"
|
||||
|
||||
[[redirects]]
|
||||
|
||||
@@ -1,27 +1,96 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -euxo pipefail
|
||||
#set -euxo pipefail
|
||||
|
||||
echo "Build Editor 3D"
|
||||
# echo "Run build script"
|
||||
# npm install
|
||||
# npm run build
|
||||
#
|
||||
# #echo "Emit built files."
|
||||
# #pwd
|
||||
# #find .
|
||||
#
|
||||
# # echo "Copy test files into dist"
|
||||
# # cp -r test/* dist/
|
||||
# #
|
||||
# # echo "Copy netlify configs into dist"
|
||||
# # cp _headers dist/
|
||||
# # cp _redirects dist/
|
||||
# #
|
||||
# # echo "Copy netlify 404.html page into dist"
|
||||
# # cp "404.html" dist/
|
||||
# #
|
||||
# # echo "List files after build"
|
||||
# # find dist/
|
||||
|
||||
#printf "==================================="
|
||||
#echo "List Env"
|
||||
#env
|
||||
|
||||
printf "==================================="
|
||||
echo "Run build script (TODO: Make strict)"
|
||||
nx build editor3d
|
||||
|
||||
printf "==================================="
|
||||
echo "Current dir (1)"
|
||||
pwd
|
||||
|
||||
printf "==================================="
|
||||
echo "List directory files (1)"
|
||||
pwd
|
||||
ls -lA .
|
||||
|
||||
printf "==================================="
|
||||
echo "List directory files (2)"
|
||||
#find / | grep build/server
|
||||
find / 2> /dev/null | grep build/server
|
||||
|
||||
|
||||
printf "==================================="
|
||||
echo "LIST DIRECTORY FILES (3)"
|
||||
#find / | grep build/server
|
||||
find / 2> /dev/null | grep EnvironmentVar
|
||||
find / 2> /dev/null | grep PageEnigma
|
||||
|
||||
|
||||
printf "==================================="
|
||||
echo "Find build manifest"
|
||||
find . | grep manifest.json
|
||||
|
||||
printf "==================================="
|
||||
echo "Change to project dir"
|
||||
pushd apps/editor3d/
|
||||
|
||||
printf "==================================="
|
||||
echo "Current dir (2)"
|
||||
pwd
|
||||
|
||||
printf "==================================="
|
||||
echo "List directory files (4)"
|
||||
pwd
|
||||
ls -lA .
|
||||
|
||||
printf "==================================="
|
||||
echo "List build directory files"
|
||||
ls -lA build/
|
||||
|
||||
echo "Make output directory"
|
||||
mkdir dist/
|
||||
|
||||
echo "Copy files to putput directory"
|
||||
printf "==================================="
|
||||
echo "Copy files"
|
||||
cp -r build/server/* dist/
|
||||
cp -r build/client/* dist/
|
||||
|
||||
#echo "Copy netlify configs into dist"
|
||||
cp _headers dist/
|
||||
#cp _redirects dist/
|
||||
|
||||
#echo "Copy netlify 404.html page into dist"
|
||||
#cp "404.html" dist/
|
||||
|
||||
echo "List final files in build"
|
||||
|
||||
printf "==================================="
|
||||
echo "List files after build"
|
||||
find dist/
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user