1
0
mirror of https://github.com/upscayl/upscayl.git synced 2025-02-25 22:47:59 +01:00
upscayl/renderer/components/sidebar/upscayl-tab/select-model-dialog.tsx

183 lines
7.1 KiB
TypeScript
Raw Normal View History

2024-10-06 12:45:44 +05:30
"use client";
import React, { useState } from "react";
import { Button } from "@/components/ui/button";
import {
Dialog,
DialogContent,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "@/components/ui/dialog";
import { ScrollArea } from "@/components/ui/scroll-area";
import { Maximize2, SwatchBookIcon, X } from "lucide-react";
import { ModelId, MODELS } from "@common/models-list";
import { useAtom, useAtomValue } from "jotai";
import { selectedModelIdAtom } from "@/atoms/user-settings-atom";
import { customModelIdsAtom } from "@/atoms/models-list-atom";
2024-11-25 19:20:05 +05:30
import useTranslation from "@/components/hooks/use-translation";
2024-12-16 16:18:57 +05:30
import posthog from "posthog-js";
2024-10-06 12:45:44 +05:30
2024-12-15 14:25:18 +05:30
const SelectModelDialog = () => {
2024-11-25 19:20:05 +05:30
const t = useTranslation();
2024-10-06 12:45:44 +05:30
const [selectedModelId, setSelectedModelId] = useAtom(selectedModelIdAtom);
2024-10-30 19:03:41 +05:30
2024-10-06 12:45:44 +05:30
const customModelIds = useAtomValue(customModelIdsAtom);
const [open, setOpen] = useState(false);
const [zoomedModel, setZoomedModel] = useState<ModelId | null>(null);
const handleModelSelect = (model: ModelId | string) => {
setSelectedModelId(model);
setOpen(false);
2024-12-16 16:18:57 +05:30
posthog.capture("model_selected", {
$ip: "0.0.0.0",
$geoip_disable: true,
model,
});
2024-10-06 12:45:44 +05:30
};
const handleZoom = (event: React.MouseEvent, model: ModelId) => {
event.stopPropagation();
setZoomedModel(model);
};
return (
<div className="flex flex-col gap-4">
<Dialog open={open} onOpenChange={setOpen}>
<DialogTrigger asChild>
<button className="btn btn-primary justify-start border-border">
<SwatchBookIcon className="mr-2 h-5 w-5" />
{selectedModelId in MODELS
? t(
`APP.MODEL_SELECTION.MODELS.${MODELS[selectedModelId]?.id}.NAME` as any,
)
: selectedModelId}
2024-10-06 12:45:44 +05:30
</button>
</DialogTrigger>
<DialogContent className="z-50 sm:max-w-lg">
<DialogHeader>
2024-11-25 19:20:05 +05:30
<DialogTitle>{t("APP.MODEL_SELECTION.DESCRIPTION")}</DialogTitle>
2024-10-06 12:45:44 +05:30
</DialogHeader>
<ScrollArea className="max-h-[600px] pr-4">
2024-12-15 14:41:03 +05:30
<div className="flex flex-col gap-4">
2024-10-06 12:45:44 +05:30
{Object.entries(MODELS).map((modelData) => {
const modelId = modelData[0] as ModelId;
const model = modelData[1];
return (
2024-10-06 13:01:25 +05:30
<button
2024-10-06 12:45:44 +05:30
key={modelId}
className="btn !h-auto !w-full !flex-col !items-start !rounded-sm !p-4"
2024-10-06 12:45:44 +05:30
onClick={() => handleModelSelect(modelId)}
>
2024-12-16 16:18:57 +05:30
<p className="font-semibold">
2024-12-15 23:23:20 +05:30
{t(`APP.MODEL_SELECTION.MODELS.${modelId}.NAME`)}
2024-12-16 16:18:57 +05:30
</p>
<p className="mb-2 text-left font-normal leading-normal text-base-content/70">
2024-12-15 23:23:20 +05:30
{t(`APP.MODEL_SELECTION.MODELS.${modelId}.DESCRIPTION`)}
2024-12-16 16:18:57 +05:30
</p>
<div className="relative h-52 w-full overflow-hidden rounded-sm">
2024-10-06 12:45:44 +05:30
<div className="flex h-full w-full">
<img
2024-12-20 09:07:34 +05:30
src={`public:///model-comparison/${model.id}/before.webp`}
2024-12-15 23:23:20 +05:30
alt={`Model Before`}
2024-10-06 12:45:44 +05:30
className="h-full w-1/2 object-cover"
/>
<img
2024-12-20 09:07:34 +05:30
src={`public:///model-comparison/${model.id}/after.webp`}
2024-12-15 23:23:20 +05:30
alt={`Model After`}
2024-10-06 12:45:44 +05:30
className="h-full w-1/2 object-cover"
/>
</div>
<div className="pointer-events-none absolute inset-0 flex items-center justify-center">
<div className="h-full w-px bg-white opacity-50"></div>
</div>
<div className="absolute bottom-2 left-2 rounded bg-black bg-opacity-50 px-1 text-xs text-white">
2024-12-15 23:23:20 +05:30
{t("APP.MODEL_SELECTION.BEFORE")}
2024-10-06 12:45:44 +05:30
</div>
<div className="absolute bottom-2 right-2 rounded bg-black bg-opacity-50 px-1 text-xs text-white">
2024-12-15 23:23:20 +05:30
{t("APP.MODEL_SELECTION.AFTER")}
2024-10-06 12:45:44 +05:30
</div>
<Button
variant="secondary"
size="icon"
className="absolute right-2 top-2"
onClick={(e) => handleZoom(e, modelId)}
>
<Maximize2 className="h-4 w-4" />
2024-12-15 23:23:20 +05:30
<span className="sr-only">
{t("APP.MODEL_SELECTION.ZOOM")}
</span>
2024-10-06 12:45:44 +05:30
</Button>
</div>
2024-10-06 13:01:25 +05:30
</button>
2024-10-06 12:45:44 +05:30
);
})}
{customModelIds.length > 0 && (
<p className="font-semibold text-base-content">
{t("APP.MODEL_SELECTION.IMPORTED_CUSTOM_MODELS")}
</p>
)}
2024-10-06 12:45:44 +05:30
{customModelIds.map((customModel) => {
return (
2024-10-06 13:01:25 +05:30
<button
2024-10-06 12:45:44 +05:30
key={customModel}
2024-10-06 13:01:25 +05:30
className="btn h-auto w-full flex-col items-start p-4"
2024-10-06 12:45:44 +05:30
onClick={() => handleModelSelect(customModel)}
>
{customModel}
2024-10-06 13:01:25 +05:30
</button>
2024-10-06 12:45:44 +05:30
);
})}
</div>
</ScrollArea>
</DialogContent>
</Dialog>
<Dialog
open={!!zoomedModel}
onOpenChange={(open) => !open && setZoomedModel(null)}
>
<DialogContent
className="h-screen w-screen max-w-full p-0"
hideCloseButton
>
<div className="relative flex h-full w-full items-center justify-center bg-black">
<div className="flex h-full w-full">
<div className="relative h-full w-1/2">
<img
2024-12-20 09:07:34 +05:30
src={`public:///model-comparison/${MODELS[zoomedModel]?.id}/before.webp`}
2024-12-15 23:23:20 +05:30
alt={`Zoomed in Image - Before`}
2024-10-06 12:45:44 +05:30
className="h-full w-full object-contain"
/>
<div className="absolute bottom-4 left-4 rounded bg-black bg-opacity-50 px-2 py-1 text-sm text-white">
Before
</div>
</div>
<div className="relative h-full w-1/2">
<img
2024-12-20 09:07:34 +05:30
src={`public:///model-comparison/${MODELS[zoomedModel]?.id}/after.webp`}
2024-12-15 23:23:20 +05:30
alt={`Zoomed in Image - After`}
2024-10-06 12:45:44 +05:30
className="h-full w-full object-contain"
/>
<div className="absolute bottom-4 right-4 rounded bg-black bg-opacity-50 px-2 py-1 text-sm text-white">
After
</div>
</div>
</div>
2024-10-06 13:01:25 +05:30
<button
className="btn btn-circle btn-secondary absolute right-4 top-4"
2024-10-06 12:45:44 +05:30
onClick={() => setZoomedModel(null)}
>
<X className="h-4 w-4" />
<span className="sr-only">Close</span>
2024-10-06 13:01:25 +05:30
</button>
2024-10-06 12:45:44 +05:30
</div>
</DialogContent>
</Dialog>
</div>
);
2024-12-15 14:25:18 +05:30
};
export default SelectModelDialog;