1
0
mirror of https://github.com/upscayl/upscayl.git synced 2025-02-03 13:13:32 +01:00

283 lines
8.7 KiB
TypeScript
Raw Normal View History

2023-11-10 17:11:35 +05:30
import { useAtom, useAtomValue } from "jotai";
2024-10-06 12:45:44 +05:30
import React, { useEffect, useMemo } from "react";
import { Tooltip } from "react-tooltip";
2022-12-08 08:55:26 +05:30
import { themeChange } from "theme-change";
import useLogger from "../../hooks/use-logger";
2023-09-19 20:21:38 +05:30
import {
2024-04-09 23:41:24 +05:30
savedOutputPathAtom,
2023-11-10 17:11:35 +05:30
progressAtom,
2024-02-14 12:02:52 +05:30
rememberOutputFolderAtom,
2023-09-19 20:21:38 +05:30
scaleAtom,
customWidthAtom,
useCustomWidthAtom,
} from "../../../atoms/user-settings-atom";
import { FEATURE_FLAGS } from "@common/feature-flags";
import { ELECTRON_COMMANDS } from "@common/electron-commands";
2024-04-21 19:34:59 +05:30
import { useToast } from "@/components/ui/use-toast";
import { translationAtom } from "@/atoms/translations-atom";
import { SelectImageScale } from "../settings-tab/select-image-scale";
2024-10-06 12:45:44 +05:30
import SelectModel from "./select-model";
import { ImageFormat } from "@/lib/valid-formats";
2022-11-12 02:09:28 +05:30
2022-11-15 20:24:06 +05:30
interface IProps {
selectImageHandler: () => Promise<void>;
selectFolderHandler: () => Promise<void>;
upscaylHandler: () => Promise<void>;
batchMode: boolean;
2023-03-12 13:11:43 +05:30
setBatchMode: React.Dispatch<React.SetStateAction<boolean>>;
2022-11-15 20:24:06 +05:30
imagePath: string;
doubleUpscayl: boolean;
2023-03-12 13:11:43 +05:30
setDoubleUpscayl: React.Dispatch<React.SetStateAction<boolean>>;
2022-12-24 12:47:54 +05:30
dimensions: {
width: number | null;
height: number | null;
};
2024-10-06 12:45:44 +05:30
setSaveImageAs: React.Dispatch<React.SetStateAction<ImageFormat>>;
2023-05-01 14:53:11 +05:30
setGpuId: React.Dispatch<React.SetStateAction<string>>;
2022-11-15 20:24:06 +05:30
}
function UpscaylSteps({
2022-11-15 20:24:06 +05:30
selectImageHandler,
selectFolderHandler,
upscaylHandler,
batchMode,
setBatchMode,
imagePath,
doubleUpscayl,
setDoubleUpscayl,
2022-12-24 12:47:54 +05:30
dimensions,
2022-11-15 20:24:06 +05:30
}: IProps) {
2024-04-21 22:57:16 +05:30
const [scale, setScale] = useAtom(scaleAtom);
2024-04-09 23:41:24 +05:30
const [outputPath, setOutputPath] = useAtom(savedOutputPathAtom);
2023-11-10 17:11:35 +05:30
const [progress, setProgress] = useAtom(progressAtom);
2024-02-14 12:02:52 +05:30
const rememberOutputFolder = useAtomValue(rememberOutputFolderAtom);
const customWidth = useAtomValue(customWidthAtom);
const useCustomWidth = useAtomValue(useCustomWidthAtom);
2023-03-12 13:11:43 +05:30
const logit = useLogger();
2024-04-21 19:34:59 +05:30
const { toast } = useToast();
const t = useAtomValue(translationAtom);
2023-05-01 14:53:11 +05:30
2024-02-14 12:02:52 +05:30
const outputHandler = async () => {
const path = await window.electron.invoke(ELECTRON_COMMANDS.SELECT_FOLDER);
2024-02-14 12:02:52 +05:30
if (path !== null) {
logit("🗂 Setting Output Path: ", path);
setOutputPath(path);
} else {
setOutputPath(null);
}
};
2023-05-01 14:53:11 +05:30
useEffect(() => {
themeChange(false);
}, []);
const upscaylResolution = useMemo(() => {
2023-06-03 06:19:13 +05:30
const newDimensions = {
width: dimensions.width,
height: dimensions.height,
};
2023-08-30 11:05:40 +05:30
2023-09-19 20:21:38 +05:30
let doubleScale = parseInt(scale) * parseInt(scale);
let singleScale = parseInt(scale);
2023-06-03 06:19:13 +05:30
if (doubleUpscayl) {
2024-04-21 23:03:02 +05:30
if (useCustomWidth) {
newDimensions.width = customWidth;
newDimensions.height = Math.round(
customWidth * (dimensions.height / dimensions.width),
);
} else {
const newWidth = dimensions.width * doubleScale;
const newHeight = dimensions.height * doubleScale;
newDimensions.width = newWidth;
newDimensions.height = newHeight;
}
2023-06-03 06:19:13 +05:30
} else {
2024-04-21 23:03:02 +05:30
if (useCustomWidth) {
newDimensions.width = customWidth;
newDimensions.height = Math.round(
customWidth * (dimensions.height / dimensions.width),
);
} else {
newDimensions.width = dimensions.width * singleScale;
newDimensions.height = dimensions.height * singleScale;
}
2023-06-03 06:19:13 +05:30
}
return newDimensions;
2023-08-30 11:05:40 +05:30
}, [dimensions.width, dimensions.height, doubleUpscayl, scale]);
2023-06-03 06:19:13 +05:30
2022-11-12 02:09:28 +05:30
return (
2023-08-30 10:24:16 +05:30
<div
2024-02-07 07:16:01 +05:30
className={`animate-step-in animate flex h-screen flex-col gap-7 overflow-y-auto overflow-x-hidden p-5`}
>
2022-11-12 02:09:28 +05:30
{/* BATCH OPTION */}
2022-11-12 03:02:24 +05:30
<div className="flex flex-row items-center gap-2">
<input
type="checkbox"
2022-11-15 20:12:20 +05:30
className="toggle"
2023-04-15 10:30:19 +05:30
defaultChecked={batchMode}
2023-11-10 17:11:35 +05:30
onClick={() => {
2024-02-14 12:02:52 +05:30
if (!rememberOutputFolder) {
setOutputPath("");
}
2023-11-10 17:11:35 +05:30
setProgress("");
setBatchMode((oldValue) => !oldValue);
2024-02-07 07:16:01 +05:30
}}
></input>
2022-11-23 23:54:30 +05:30
<p
2023-08-30 10:24:16 +05:30
className="mr-1 inline-block cursor-help text-sm"
data-tooltip-id="tooltip"
data-tooltip-content={t("APP.BATCH_MODE.DESCRIPTION")}
2024-02-07 07:16:01 +05:30
>
{t("APP.BATCH_MODE.TITLE")}
2022-11-23 23:54:30 +05:30
</p>
2022-11-12 02:09:28 +05:30
</div>
{/* STEP 1 */}
<div className="animate-step-in">
<p className="step-heading">{t("APP.FILE_SELECTION.TITLE")}</p>
2022-11-12 02:09:28 +05:30
<button
2024-02-07 07:16:01 +05:30
className="btn btn-primary"
onClick={!batchMode ? selectImageHandler : selectFolderHandler}
data-tooltip-id="tooltip"
data-tooltip-content={imagePath}
2024-02-07 07:16:01 +05:30
>
{batchMode
? t("APP.FILE_SELECTION.BATCH_MODE_TYPE")
: t("APP.FILE_SELECTION.SINGLE_MODE_TYPE")}
2022-11-12 02:09:28 +05:30
</button>
</div>
{/* STEP 2 */}
2024-04-21 22:57:16 +05:30
<div className="animate-step-in group flex flex-col gap-4">
<div>
<p className="step-heading">{t("APP.MODEL_SELECTION.TITLE")}</p>
<p className="mb-2 text-sm">{t("APP.MODEL_SELECTION.DESCRIPTION")}</p>
2022-11-12 02:09:28 +05:30
2024-10-06 12:45:44 +05:30
<SelectModel />
2024-04-21 22:57:16 +05:30
</div>
2022-11-12 02:09:28 +05:30
2023-03-18 18:03:17 +05:30
{!batchMode && (
2024-04-21 22:57:16 +05:30
<div className="flex items-center gap-1">
2022-11-12 02:09:28 +05:30
<input
type="checkbox"
2022-11-12 03:02:24 +05:30
className="checkbox"
2022-11-15 20:24:06 +05:30
checked={doubleUpscayl}
2022-11-12 02:09:28 +05:30
onChange={(e) => {
if (e.target.checked) {
2022-11-15 20:24:06 +05:30
setDoubleUpscayl(true);
2022-11-12 02:09:28 +05:30
} else {
2022-11-15 20:24:06 +05:30
setDoubleUpscayl(false);
2022-11-12 02:09:28 +05:30
}
}}
/>
<p
2022-11-12 03:02:24 +05:30
className="cursor-pointer text-sm"
2022-11-12 02:09:28 +05:30
onClick={(e) => {
2024-10-30 19:03:41 +05:30
setDoubleUpscayl((prev) => !prev);
2024-02-07 07:16:01 +05:30
}}
>
{t("APP.DOUBLE_UPSCAYL.TITLE")}
2022-11-12 02:09:28 +05:30
</p>
2022-11-23 23:54:30 +05:30
<button
2024-02-07 07:16:01 +05:30
className="badge badge-neutral badge-sm cursor-help"
data-tooltip-id="tooltip"
data-tooltip-content={t("APP.DOUBLE_UPSCAYL.DESCRIPTION")}
2024-02-07 07:16:01 +05:30
>
?
2022-11-23 23:54:30 +05:30
</button>
2022-11-12 02:09:28 +05:30
</div>
)}
2024-04-21 22:57:16 +05:30
<SelectImageScale scale={scale} setScale={setScale} hideInfo />
2022-11-12 02:09:28 +05:30
</div>
{/* STEP 3 */}
<div className="animate-step-in">
2024-01-15 18:43:16 +05:30
<div className="flex flex-col pb-2">
<div className="step-heading flex items-center gap-2">
<span className="leading-none">
{t("APP.OUTPUT_PATH_SELECTION.TITLE")}
</span>
{FEATURE_FLAGS.APP_STORE_BUILD && (
2024-01-15 18:43:16 +05:30
<button
2024-02-07 07:16:01 +05:30
className="badge badge-outline badge-sm cursor-pointer"
2024-01-15 18:43:16 +05:30
onClick={() =>
alert(t("APP.OUTPUT_PATH_SELECTION.MAC_APP_STORE_ALERT"))
2024-02-07 07:16:01 +05:30
}
>
2024-01-15 18:43:16 +05:30
?
</button>
)}
</div>
{!outputPath && FEATURE_FLAGS.APP_STORE_BUILD && (
2023-11-02 20:33:21 +05:30
<div className="text-xs">
2024-02-07 07:16:01 +05:30
<span className="rounded-btn bg-base-200 px-2 font-medium uppercase text-base-content/50">
{t("APP.OUTPUT_PATH_SELECTION.NOT_SELECTED")}
2023-11-02 20:33:21 +05:30
</span>
</div>
)}
</div>
{!batchMode && !FEATURE_FLAGS.APP_STORE_BUILD && (
2023-11-02 20:33:21 +05:30
<p className="mb-2 text-sm">
{!batchMode
? t("APP.OUTPUT_PATH_SELECTION.DEFAULT_IMG_PATH")
: t("APP.OUTPUT_PATH_SELECTION.DEFAULT_FOLDER_PATH")}
2023-11-02 20:33:21 +05:30
</p>
)}
<button
className="btn btn-primary"
data-tooltip-content={outputPath}
data-tooltip-id="tooltip"
onClick={outputHandler}
>
{t("APP.OUTPUT_PATH_SELECTION.BUTTON_TITLE")}
2022-11-12 02:09:28 +05:30
</button>
</div>
{/* STEP 4 */}
<div className="animate-step-in">
<p className="step-heading">{t("APP.SCALE_SELECTION.TITLE")}</p>
2022-12-24 12:47:54 +05:30
{dimensions.width && dimensions.height && (
<p className="mb-2 text-sm">
{t("APP.SCALE_SELECTION.FROM_TITLE")}
2022-12-24 12:47:54 +05:30
<span className="font-bold">
{dimensions.width}x{dimensions.height}
</span>
{t("APP.SCALE_SELECTION.TO_TITLE")}
2024-02-08 20:27:35 +05:30
<span className="font-bold">
{upscaylResolution.width}x{upscaylResolution.height}
2024-02-08 20:27:35 +05:30
</span>
2022-12-24 12:47:54 +05:30
</p>
)}
2022-11-12 02:09:28 +05:30
<button
className="btn btn-secondary"
2023-11-10 17:11:35 +05:30
onClick={
progress.length > 0 || !outputPath
2024-04-21 19:34:59 +05:30
? () =>
toast({
description: t(
"APP.SCALE_SELECTION.NO_OUTPUT_FOLDER_ALERT",
),
2024-04-21 19:34:59 +05:30
})
2023-11-10 17:11:35 +05:30
: upscaylHandler
2024-02-07 07:16:01 +05:30
}
>
{progress.length > 0
? t("APP.SCALE_SELECTION.IN_PROGRESS_BUTTON_TITLE")
: t("APP.SCALE_SELECTION.START_BUTTON_TITLE")}
2022-11-12 02:09:28 +05:30
</button>
</div>
2022-11-23 23:54:30 +05:30
<Tooltip
className="z-[999] max-w-sm break-words !bg-secondary"
id="tooltip"
/>
2022-11-12 02:09:28 +05:30
</div>
);
}
export default UpscaylSteps;