Skip to content

Commit

Permalink
feat: improve ui & ux and fix loading states
Browse files Browse the repository at this point in the history
  • Loading branch information
aykutkardas committed Mar 5, 2024
1 parent 0cb7aad commit eb8cf50
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 63 deletions.
135 changes: 75 additions & 60 deletions app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
UPSCALE_MODELS,
} from "@/components/model-dropdown";
import { Button } from "@/components/ui/button";
import { LoaderIcon } from "lucide-react";

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

Expand All @@ -26,9 +27,7 @@ interface ModelResult {

type CompareMode = "original" | "model";

UPSCALE_MODELS;

export default function Lightning() {
export default function UpscalerBattleground() {
const [mode, setMode] = useState<CompareMode>("original");
const [position, setPosition] = useState<number>(50);
const [originalImage, setOriginalImage] = useState<string | null>(null);
Expand Down Expand Up @@ -104,17 +103,23 @@ export default function Lightning() {
setSecondModelLoading(false);
};

const handleCompare = async () => {
if (!imageFile) return;

setPosition(50);

const blobUrl = URL.createObjectURL(imageFile);
setOriginalImage(blobUrl);
const handleImageSelect = (e: React.ChangeEvent<HTMLInputElement>) => {
const image = e.target?.files?.[0];

setFirstModelOutput(null);
setSecondModelOutput(null);

setImageFile(image || null);
setPosition(50);

if (image) {
const blobUrl = URL.createObjectURL(image);
setOriginalImage(blobUrl);
}
};
const handleCompare = async () => {
if (!imageFile) return;

upscaleWithFirstModel(imageFile);
upscaleWithSecondModel(imageFile);
};
Expand All @@ -128,67 +133,73 @@ 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 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">
<label className="text-neutral-500 dark:text-neutral-400 ml-4 uppercase text-xs">
Image
</label>
<Input
type="file"
onChange={(e) => {
setImageFile(e.target?.files?.[0] || null);
}}
className={cn(
"font-light mx-auto rounded-full h-10 pr-10 truncate",
!imageFile && "border-orange-400"
)}
placeholder="Type something..."
/>
</div>
<div className="flex flex-col space-y-2 text-sm items-center justify-center">
<label className="text-neutral-500 dark:text-neutral-400 uppercase text-xs">
Compare Mode
</label>
<div className="w-fit select-none text-neutral-600 dark:text-neutral-300 bg-neutral-200 dark:bg-neutral-900 p-1 rounded-full flex items-center justify-between space-x-2">
<span
onClick={() => setMode("original")}
className={cn(
mode === "original" &&
"bg-neutral-900 text-white dark:bg-neutral-200 dark:text-black",
"w-1/2 cursor-pointer text-sm rounded-full h-8 px-3 flex items-center"
)}
>
Original
</span>
<span
onClick={() => setMode("model")}
<div className="py-4 px-0 mx-auto w-full max-w-5xl">
<div className="container px-3 md:px-0 flex w-full items-center justify-between mt-10 pb-3">
<div className="flex w-full flex-row items-end justify-between space-x-3">
<div className="flex space-x-4">
<div className="flex flex-col md:flex-row space-y-2 md:space-y-0 text-sm items-center justify-center">
<label className="text-neutral-500 md:mr-1 dark:text-neutral-400 uppercase text-xs">
Mode:
</label>
<div className="w-fit select-none text-neutral-600 dark:text-neutral-300 bg-neutral-200 dark:bg-neutral-900 p-1 rounded-full flex items-center justify-between space-x-2">
<span
onClick={() => setMode("original")}
className={cn(
mode === "original" &&
"bg-neutral-900 text-white dark:bg-neutral-200 dark:text-black",
"w-1/2 cursor-pointer text-sm rounded-full h-8 px-3 flex items-center"
)}
>
Original
</span>
<span
onClick={() => setMode("model")}
className={cn(
mode === "model" &&
"bg-neutral-900 text-white dark:bg-neutral-200 dark:text-black",
"w-1/2 cursor-pointer text-sm rounded-full h-8 px-3 flex items-center"
)}
>
Model
</span>
</div>
</div>
<div className="flex flex-col md:flex-row space-y-2 md:space-y-0 text-sm items-center justify-center">
<label className="text-neutral-500 md:mr-1 dark:text-neutral-400 uppercase text-xs">
Image:
</label>
<Input
type="file"
onChange={handleImageSelect}
className={cn(
mode === "model" &&
"bg-neutral-900 text-white dark:bg-neutral-200 dark:text-black",
"w-1/2 cursor-pointer text-sm rounded-full h-8 px-3 flex items-center"
"font-light mx-auto rounded-full h-10 pr-10 truncate",
!imageFile && "border-orange-400/40"
)}
>
Model
</span>
placeholder="Type something..."
/>
</div>
</div>
<Button
size="lg"
onClick={handleCompare}
disabled={!imageFile || firstModelLoading || secondModelLoading}
>
Compare
{(firstModelLoading || secondModelLoading) && (
<LoaderIcon className="animate-spin w-4 h-4 ml-2 text-neutral-200 dark:text-neutral-900" />
)}
</Button>
</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">
<div className="flex w-full items-end justify-between border-y py-2 mb-3">
<div className="w-1/2 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">

<div className="w-1/2 flex justify-end">
<ModelDropdown
onSelect={(model) => setSecondModel(model)}
value={secondModel}
Expand All @@ -202,8 +213,10 @@ export default function Lightning() {
setPosition={setPosition}
firstModel={firstModel}
firstModelOutput={firstModelOutput}
firstModelLoading={firstModelLoading}
secondModel={secondModel}
secondModelOutput={secondModelOutput}
secondModelLoading={secondModelLoading}
/>
)}
{mode === "original" && (
Expand All @@ -213,8 +226,10 @@ export default function Lightning() {
setPosition={setPosition}
firstModel={firstModel}
firstModelOutput={firstModelOutput}
firstModelLoading={firstModelLoading}
secondModel={secondModel}
secondModelOutput={secondModelOutput}
secondModelLoading={secondModelLoading}
/>
)}
</div>
Expand Down
8 changes: 5 additions & 3 deletions components/compare-image-label.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@ import { LoaderIcon } from "lucide-react";
interface CompareImageLabelProps {
modelData: any;
name: string;
loading: boolean;
position?: "left" | "right";
}

const CompareImageLabel = ({
modelData,
name,
loading,
position = "left",
}: CompareImageLabelProps) => (
<div
Expand All @@ -19,12 +21,12 @@ const CompareImageLabel = ({
)}
>
<span>{name}</span>
{modelData ? (
{loading ? (
<LoaderIcon className="animate-spin w-4 h-4 text-green-400" />
) : (
<span className={!modelData ? "text-neutral-500" : "text-green-400"}>
{modelData ? formatTime(modelData.inferenceTime * 1000) : `n/a`}
</span>
) : (
<LoaderIcon className="animate-spin w-4 h-4 text-green-400" />
)}
</div>
);
Expand Down
6 changes: 6 additions & 0 deletions components/model-compare.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@ interface ModelCompareProps {
setPosition: (position: number) => void;
firstModel: any;
firstModelOutput: any;
firstModelLoading: boolean;
secondModel: any;
secondModelOutput: any;
secondModelLoading: boolean;
}

const ModelCompare = ({
Expand All @@ -22,8 +24,10 @@ const ModelCompare = ({
setPosition,
firstModel,
firstModelOutput,
firstModelLoading,
secondModel,
secondModelOutput,
secondModelLoading,
}: ModelCompareProps) => {
return (
<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">
Expand All @@ -45,6 +49,7 @@ const ModelCompare = ({
alt="Image one"
/>
<CompareImageLabel
loading={firstModelLoading}
modelData={firstModelOutput}
name={firstModel?.shortname}
/>
Expand All @@ -61,6 +66,7 @@ const ModelCompare = ({
alt="Image two"
/>
<CompareImageLabel
loading={secondModelLoading}
modelData={secondModelOutput}
name={secondModel?.shortname}
position="right"
Expand Down
6 changes: 6 additions & 0 deletions components/original-compare.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@ interface OriginalCompareProps {
setPosition: (position: number) => void;
firstModel: any;
firstModelOutput: any;
firstModelLoading: boolean;
secondModel: any;
secondModelOutput: any;
secondModelLoading: boolean;
}

const OriginalCompare = ({
Expand All @@ -22,8 +24,10 @@ const OriginalCompare = ({
setPosition,
firstModel,
firstModelOutput,
firstModelLoading,
secondModel,
secondModelOutput,
secondModelLoading,
}: OriginalCompareProps) => {
return (
<div className="container flex flex-col space-y-6 lg:flex-row lg:space-y-0 p-3 md:px-0 pt-0 lg:space-x-6">
Expand Down Expand Up @@ -57,6 +61,7 @@ const OriginalCompare = ({
alt="Image one"
/>
<CompareImageLabel
loading={firstModelLoading}
modelData={firstModelOutput}
name={firstModel?.shortname}
position="right"
Expand Down Expand Up @@ -127,6 +132,7 @@ const OriginalCompare = ({
alt="Image one"
/>
<CompareImageLabel
loading={secondModelLoading}
modelData={secondModelOutput}
name={secondModel?.shortname}
position="right"
Expand Down

0 comments on commit eb8cf50

Please sign in to comment.