Compare commits

..
5 changed files with 77 additions and 30 deletions
-4
View File
@@ -93,10 +93,6 @@ Major areas
# Self Hosting with Vercel
[![Video](https://img.mytsi.org/i/nFOG479.png)](https://www.youtube.com/watch?v=hWvsEY1cS2M)
Tutorial Created by [Ross](https://github.com/rossman22590) and [Syn](https://github.com/mortlsyn)
Build command
```
+3 -1
View File
@@ -80,7 +80,9 @@
/* @apply rounded-lg p-2 overflow-x-scroll */
@apply p-2 max-w-full overflow-auto w-full
}
.vsc-controller{
position: absolute;
}
@layer base {
* {
@apply border-border;
+7 -1
View File
@@ -5,6 +5,7 @@ import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { cn } from "@/lib/utils";
import Link from "next/link";
import { usePathname } from "next/navigation";
import { useRouter } from "next/navigation";
import { useEffect, useState } from "react";
import { useMediaQuery } from "usehooks-ts";
@@ -24,6 +25,8 @@ export function NavbarMenu({
const pathnames = usePathname();
const pathname = `/${pathnames.split("/")[1]}`;
const router = useRouter();
const pages = [
{
name: "Workflows",
@@ -56,8 +59,11 @@ export function NavbarMenu({
<TabsTrigger
key={page.name}
value={page.path}
onClick={() => {
router.push(page.path);
}}
>
<Link href={page.path}>{page.name}</Link>
{page.name}
</TabsTrigger>
))}
</TabsList>
+25 -24
View File
@@ -60,6 +60,7 @@ import { callServerPromise } from "./callServerPromise";
import fetcher from "./fetcher";
import { ButtonAction } from "@/components/ButtonActionLoader";
import { editWorkflowOnMachine } from "@/server/editWorkflowOnMachine";
import { VisualizeImagesGrid } from "@/components/VisualizeImagesGrid";
export function VersionSelect({
workflow,
@@ -169,19 +170,21 @@ export function useSelectedMachine(
}
type PublicRunStore = {
image: string;
image: {
url: string;
}[] | null;
loading: boolean;
runId: string;
status: string;
setImage: (image: string) => void;
setImage: (image: { url: string; }[]) => void;
setLoading: (loading: boolean) => void;
setRunId: (runId: string) => void;
setStatus: (status: string) => void;
};
export const publicRunStore = create<PublicRunStore>((set) => ({
image: "",
image: null,
loading: false,
runId: "",
status: "",
@@ -205,7 +208,10 @@ export function PublicRunOutputs(props: {
console.log(res?.status);
if (res) setStatus(res.status);
if (res && res.status === "success") {
setImage(res.outputs[0]?.data.images[0].url);
const imageURLs = res.outputs[0]?.data.images.map((item: { url: string; }) => {
return { url: item.url };
});
setImage(imageURLs);
setLoading(false);
clearInterval(interval);
}
@@ -214,30 +220,25 @@ export function PublicRunOutputs(props: {
return () => clearInterval(interval);
}, [runId]);
return (
<div className="border border-gray-200 w-full square h-[400px] rounded-lg relative">
{!loading && !image && props.preview && props.preview.length > 0 && (
<>
<img
className="w-full h-full object-contain"
src={props.preview[0]?.url}
alt="Generated image"
/>
</>
)}
{!loading && image && (
<img
className="w-full h-full object-contain"
src={image}
alt="Generated image"
/>
)}
{loading && (
if (loading) {
return (
<div className="border border-gray-200 w-full h-[400px] square rounded-lg relative p-4 ">
<div className="absolute top-0 left-0 w-full h-full flex items-center justify-center gap-2">
{status} <LoadingIcon />
</div>
<Skeleton className="w-full h-full" />
</div>
);
}
return (
<div className="border border-gray-200 w-full min-h-[400px] square rounded-lg relative p-4 ">
{!image && props.preview && props.preview.length > 0 &&
<VisualizeImagesGrid images={props.preview} />
}
{image && (
<VisualizeImagesGrid images={image} />
)}
{loading && <Skeleton className="w-full h-full" />}
</div>
);
}
@@ -0,0 +1,42 @@
type imagesType = {
url: string;
width?: number;
height?: number;
};
type VisualizeImagesGridProps = {
images: imagesType[];
layout?: 'justify-between' | 'justify-center' | 'justify-start' | 'justify-end';
};
export function VisualizeImagesGrid({ images, layout }: VisualizeImagesGridProps) {
return (
<div className={`flex gap-4 flex-wrap ${layout || 'justify-center'}`}>
<>
{images && images.length > 0 &&
images.map(item => {
if (!item) {
return;
}
if (item?.url.endsWith(".mp4") || item?.url.endsWith(".webm")) {
return (
<video key={item?.url} controls autoPlay className="rounded-xl" style={{ maxHeight: item.height || 370, maxWidth: item.width || "auto" }}>
<source src={item?.url} type="video/mp4" />
<source src={item?.url} type="video/webm" />
Your browser does not support the video tag.
</video>
);
}
return <img
key={item?.url}
className="object-contain overflow-hidden rounded-xl"
src={item?.url}
alt="Generated image"
style={{ maxHeight: item.height || 370, maxWidth: item.width || "auto" }}
/>;
})
}
</>
</div>
);
}