Skip to content

Commit

Permalink
feat: add model select support
Browse files Browse the repository at this point in the history
  • Loading branch information
aykutkardas committed Mar 5, 2024
1 parent 8f55295 commit 0cb7aad
Show file tree
Hide file tree
Showing 4 changed files with 269 additions and 125 deletions.
112 changes: 79 additions & 33 deletions app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,32 +10,50 @@ import { ModelIcon } from "@/components/icons/model-icon";
import { cn } from "@/lib/utils";
import ModelCompare from "@/components/model-compare";
import OriginalCompare from "@/components/original-compare";
import {
type Model,
ModelDropdown,
UPSCALE_MODELS,
} from "@/components/model-dropdown";
import { Button } from "@/components/ui/button";

fal.config({ proxyUrl: "/api/proxy" });

interface ModelResult {
name: string;
image: string;
inferenceTime: number;
}

type CompareMode = "original" | "model";

UPSCALE_MODELS;

export default function Lightning() {
const [mode, setMode] = useState<CompareMode>("original");
const [position, setPosition] = useState<number>(50);
const [originalImage, setOriginalImage] = useState<string | null>(null);
const [imageFile, setImageFile] = useState<File | null>(null);

const [firstModelLoading, setFirstModelLoading] = useState<boolean>(false);
const [secondModelLoading, setSecondModelLoading] = useState<boolean>(false);
const [firstModel, setFirstModel] = useState<Model | null>(UPSCALE_MODELS[0]);
const [secondModel, setSecondModel] = useState<Model | null>(
UPSCALE_MODELS[1]
);
const [firstModelOutput, setFirstModelOutput] = useState<ModelResult | null>(
null
);
const [secondModelOutput, setSecondModelOutput] =
useState<ModelResult | null>(null);

const [modelOne, setModelOne] = useState<ModelResult | null>(null);
const [modelOneLoading, setModelOneLoading] = useState<boolean>(false);
const [modelTwo, setModelTwo] = useState<ModelResult | null>(null);
const [modelTwoLoading, setModelTwoLoading] = useState<boolean>(false);
const upscaleWithFirstModel = async (file: File) => {
if (!firstModel) return;

setFirstModelLoading(true);

const upscaleWithModelOne = async (file: File) => {
let inferenceTime;
setModelOneLoading(true);

const result: Record<string, any> = await fal.subscribe("fal-ai/ccsr", {
const result: Record<string, any> = await fal.subscribe(firstModel.model, {
input: {
image_url: file,
},
Expand All @@ -48,22 +66,23 @@ export default function Lightning() {
});

if (result) {
setModelOne({
name: "CCSR",
setFirstModelOutput({
image: result.image.url as string,
inferenceTime,
});
}

setModelOneLoading(false);
setFirstModelLoading(false);
};

const upscaleWithModelTwo = async (file: File) => {
let inferenceTime;
const upscaleWithSecondModel = async (file: File) => {
if (!secondModel) return;

setSecondModelLoading(true);

setModelTwoLoading(true);
let inferenceTime;

const result: Record<string, any> = await fal.subscribe("fal-ai/supir", {
const result: Record<string, any> = await fal.subscribe(secondModel.model, {
input: {
image_url: file,
},
Expand All @@ -76,25 +95,28 @@ export default function Lightning() {
});

if (result) {
setModelTwo({
name: "SUPIR",
setSecondModelOutput({
image: result.image.url as string,
inferenceTime,
});
}

setModelTwoLoading(false);
setSecondModelLoading(false);
};

const handleOnChange = async (file: File) => {
const blobUrl = URL.createObjectURL(file);
const handleCompare = async () => {
if (!imageFile) return;

setPosition(50);

const blobUrl = URL.createObjectURL(imageFile);
setOriginalImage(blobUrl);

setModelOne(null);
setModelTwo(null);
setFirstModelOutput(null);
setSecondModelOutput(null);

upscaleWithModelOne(file);
upscaleWithModelTwo(file);
upscaleWithFirstModel(imageFile);
upscaleWithSecondModel(imageFile);
};

useEffect(() => {
Expand All @@ -106,7 +128,7 @@ export default function Lightning() {
return (
<main>
<div className="flex flex-col justify-between h-[calc(100vh-56px)]">
<div className="py-4 md:pb-10 px-0 space-y-4 lg:space-y-8 mx-auto w-full max-w-5xl">
<div className="py-4 md:pb-10 px-0 mx-auto w-full max-w-5xl">
<div className="container px-3 md:px-0 flex flex-col mt-10">
<div className="flex flex-row items-center justify-center space-x-3">
<div className="w-80 flex flex-col justify-center items-center space-y-2">
Expand All @@ -116,11 +138,12 @@ export default function Lightning() {
<Input
type="file"
onChange={(e) => {
if (e.target?.files?.[0]) {
handleOnChange(e.target?.files?.[0]);
}
setImageFile(e.target?.files?.[0] || null);
}}
className="font-light mx-auto rounded-full h-10 pr-10 truncate"
className={cn(
"font-light mx-auto rounded-full h-10 pr-10 truncate",
!imageFile && "border-orange-400"
)}
placeholder="Type something..."
/>
</div>
Expand Down Expand Up @@ -153,22 +176,45 @@ export default function Lightning() {
</div>
</div>
</div>
<div className="flex w-full items-end justify-between mb-1 mt-10 border-b pb-2">
<div className="w-1/3 flex justify-start">
<ModelDropdown
onSelect={(model) => setFirstModel(model)}
value={firstModel}
/>
</div>
<div className="w-1/3 flex justify-center">
<Button size="lg" onClick={handleCompare} disabled={!imageFile}>
Compare
</Button>
</div>
<div className="w-1/3 flex justify-end">
<ModelDropdown
onSelect={(model) => setSecondModel(model)}
value={secondModel}
/>
</div>
</div>
{mode === "model" && (
<ModelCompare
originalImage={originalImage}
position={position}
setPosition={setPosition}
modelOne={modelOne}
modelTwo={modelTwo}
firstModel={firstModel}
firstModelOutput={firstModelOutput}
secondModel={secondModel}
secondModelOutput={secondModelOutput}
/>
)}
{mode === "original" && (
<OriginalCompare
originalImage={originalImage}
position={position}
setPosition={setPosition}
modelOne={modelOne}
modelTwo={modelTwo}
firstModel={firstModel}
firstModelOutput={firstModelOutput}
secondModel={secondModel}
secondModelOutput={secondModelOutput}
/>
)}
</div>
Expand Down
107 changes: 60 additions & 47 deletions components/model-compare.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,52 +10,24 @@ interface ModelCompareProps {
originalImage: string | null;
position: number;
setPosition: (position: number) => void;
modelOne: any;
modelTwo: any;
firstModel: any;
firstModelOutput: any;
secondModel: any;
secondModelOutput: any;
}

const ModelCompare = ({
originalImage,
position,
setPosition,
modelOne,
modelTwo,
firstModel,
firstModelOutput,
secondModel,
secondModelOutput,
}: ModelCompareProps) => {
return (
<div className="container flex flex-col space-y-6 lg:flex-row lg:space-y-0 p-3 md:px-0 pt-7 space-x-6">
<div className="container flex flex-col space-y-6 lg:flex-row lg:space-y-0 p-3 md:px-0 pt-2 space-x-6">
<div className="flex-1 flex-col flex w-full items-center justify-center">
<div className="flex items-center justify-between w-full md:w-1/2">
<div className="flex items-center justify-end space-x-2 mb-1">
<Image
alt=""
src="https://fal.ai/fal-icon.svg"
width={16}
height={16}
/>
<a
href="https://fal.ai/models/ccsr"
className="text-indigo-400 font-medium text-sm"
target="_blank"
>
fal-ai/ccsr
</a>
</div>
<div className="flex items-center justify-end space-x-2 mb-1">
<Image
alt=""
src="https://fal.ai/fal-icon.svg"
width={16}
height={16}
/>
<a
href="https://fal.ai/models/supir"
className="text-indigo-400 font-medium text-sm"
target="_blank"
>
fal-ai/supir
</a>
</div>
</div>
{originalImage ? (
<div className="md:min-h-[512px] w-full md:w-1/2 bg-neutral-900 flex">
<ReactCompareSlider
Expand All @@ -65,25 +37,32 @@ const ModelCompare = ({
itemOne={
<>
<ReactCompareSliderImage
className={cn(!modelOne && "blur-md")}
src={(modelOne?.image || originalImage) as string}
srcSet={(modelOne?.image || originalImage) as string}
className={cn(!firstModelOutput && "blur-md")}
src={(firstModelOutput?.image || originalImage) as string}
srcSet={
(firstModelOutput?.image || originalImage) as string
}
alt="Image one"
/>
<CompareImageLabel modelData={modelOne} name="CCSR" />
<CompareImageLabel
modelData={firstModelOutput}
name={firstModel?.shortname}
/>
</>
}
itemTwo={
<>
<ReactCompareSliderImage
className={cn(!modelTwo && "blur-md")}
src={(modelTwo?.image || originalImage) as string}
srcSet={(modelTwo?.image || originalImage) as string}
alt="Image one"
className={cn(!secondModelOutput && "blur-md")}
src={(secondModelOutput?.image || originalImage) as string}
srcSet={
(secondModelOutput?.image || originalImage) as string
}
alt="Image two"
/>
<CompareImageLabel
modelData={modelTwo}
name="SUPIR"
modelData={secondModelOutput}
name={secondModel?.shortname}
position="right"
/>
</>
Expand All @@ -102,6 +81,40 @@ const ModelCompare = ({
/>
</div>
)}
{firstModel && secondModel && (
<div className="flex items-center justify-between w-full md:w-1/2 mt-2">
<div className="flex items-center justify-end space-x-2 mb-1">
<Image
alt=""
src="https://fal.ai/fal-icon.svg"
width={16}
height={16}
/>
<a
href={firstModel?.link}
className="text-indigo-400 font-medium text-sm"
target="_blank"
>
{firstModel?.model}
</a>
</div>
<div className="flex items-center justify-end space-x-2 mb-1">
<Image
alt=""
src="https://fal.ai/fal-icon.svg"
width={16}
height={16}
/>
<a
href={secondModel?.link}
className="text-indigo-400 font-medium text-sm"
target="_blank"
>
{secondModel?.model}
</a>
</div>
</div>
)}
</div>
</div>
);
Expand Down
Loading

0 comments on commit 0cb7aad

Please sign in to comment.