1
0
mirror of https://github.com/upscayl/upscayl.git synced 2025-02-21 04:59:34 +01:00
upscayl/renderer/pages/index.tsx

385 lines
12 KiB
TypeScript
Raw Normal View History

2023-09-03 14:46:48 +05:30
"use client";
2024-09-24 20:06:23 +05:30
import { useState, useEffect } from "react";
2024-09-24 20:05:33 +05:30
import ELECTRON_COMMANDS from "../../common/commands";
2023-11-22 21:24:02 +05:30
import { useAtom, useAtomValue } from "jotai";
2023-04-09 11:18:53 +05:30
import { modelsListAtom } from "../atoms/modelsListAtom";
2023-09-03 14:46:48 +05:30
import {
batchModeAtom,
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-03 14:46:48 +05:30
} from "../atoms/userSettingsAtom";
2023-04-30 07:14:47 +05:30
import useLog from "../components/hooks/useLog";
2023-11-26 13:34:03 +05:30
import { newsAtom, showNewsModalAtom } from "@/atoms/newsAtom";
import matter from "gray-matter";
2024-04-21 19:34:59 +05:30
import { useToast } from "@/components/ui/use-toast";
import { ToastAction } from "@/components/ui/toast";
2024-04-24 16:38:27 +05:30
import Logo from "@/components/icons/Logo";
import { translationAtom } from "@/atoms/translations-atom";
2024-09-24 20:05:33 +05:30
import Sidebar from "@/components/sidebar";
import MainContent from "@/components/main-content";
import getDirectoryFromPath from "@common/get-directory-from-path";
import { FEATURE_FLAGS } from "@common/feature-flags";
import { VALID_IMAGE_FORMATS } from "@/lib/valid-formats";
2023-03-31 16:03:48 +05:30
2022-11-12 02:09:28 +05:30
const Home = () => {
const t = useAtomValue(translationAtom);
2024-09-24 20:05:33 +05:30
const { logit } = useLog();
const { toast } = useToast();
2024-09-24 20:05:33 +05:30
// * SHARED HOOKS AND STATES
2023-11-23 14:23:09 +05:30
const [imagePath, setImagePath] = useState("");
2024-09-24 20:05:33 +05:30
const rememberOutputFolder = useAtomValue(rememberOutputFolderAtom);
const [outputPath, setOutputPath] = useAtom(savedOutputPathAtom);
2022-12-24 12:47:54 +05:30
const [dimensions, setDimensions] = useState({
width: null,
height: null,
});
2023-11-22 21:24:02 +05:30
const [progress, setProgress] = useAtom(progressAtom);
2024-09-24 20:05:33 +05:30
const [upscaledImagePath, setUpscaledImagePath] = useState("");
const [batchFolderPath, setBatchFolderPath] = useState("");
const [upscaledBatchFolderPath, setUpscaledBatchFolderPath] = useState("");
const [isLoading, setIsLoading] = useState(true);
const [doubleUpscaylCounter, setDoubleUpscaylCounter] = useState(0);
2023-04-09 11:18:53 +05:30
const [modelOptions, setModelOptions] = useAtom(modelsListAtom);
2023-11-23 11:28:29 +05:30
const [news, setNews] = useAtom(newsAtom);
2023-11-26 13:34:03 +05:30
const [showNewsModal, setShowNewsModal] = useAtom(showNewsModalAtom);
2024-09-24 20:05:33 +05:30
const [batchMode, setBatchMode] = useAtom(batchModeAtom);
2024-09-24 20:05:33 +05:30
// * SHARED FUNCTIONS
const selectImageHandler = async () => {
resetImagePaths();
var path = await window.electron.invoke(ELECTRON_COMMANDS.SELECT_FILE);
if (path === null) return;
logit("🖼 Selected Image Path: ", path);
setImagePath(path);
var dirname = getDirectoryFromPath(path);
logit("📁 Selected Image Directory: ", dirname);
if (!FEATURE_FLAGS.APP_STORE_BUILD) {
if (!rememberOutputFolder) {
setOutputPath(dirname);
}
}
validateImagePath(path);
};
const validateImagePath = (path: string) => {
if (path.length > 0) {
logit("🖼 imagePath: ", path);
const extension = path.toLocaleLowerCase().split(".").pop();
logit("🔤 Extension: ", extension);
if (!VALID_IMAGE_FORMATS.includes(extension.toLowerCase())) {
toast({
title: t("ERRORS.INVALID_IMAGE_ERROR.TITLE"),
description: t("ERRORS.INVALID_IMAGE_ERROR.DESCRIPTION"),
});
resetImagePaths();
}
} else {
resetImagePaths();
}
};
const selectFolderHandler = async () => {
resetImagePaths();
var path = await window.electron.invoke(ELECTRON_COMMANDS.SELECT_FOLDER);
if (path !== null) {
logit("🖼 Selected Folder Path: ", path);
setBatchFolderPath(path);
if (!rememberOutputFolder) {
setOutputPath(path);
}
} else {
logit("🚫 Folder selection cancelled");
setBatchFolderPath("");
if (!rememberOutputFolder) {
setOutputPath("");
}
2024-09-22 07:06:13 +05:30
}
2024-01-23 14:14:32 +05:30
};
2023-11-23 14:23:09 +05:30
2023-11-23 14:55:55 +05:30
// ELECTRON EVENT LISTENERS
2023-11-23 14:23:09 +05:30
useEffect(() => {
2023-04-08 12:23:32 +05:30
const handleErrors = (data: string) => {
2024-04-21 19:34:59 +05:30
if (data.includes("Invalid GPU")) {
toast({
title: t("ERRORS.GPU_ERROR.TITLE"),
description: t("ERRORS.GPU_ERROR.DESCRIPTION", { data }),
2024-04-21 19:34:59 +05:30
action: (
2024-04-22 13:25:44 +05:30
<div className="flex flex-col gap-2">
<ToastAction
altText={t("ERRORS.COPY_ERROR.TITLE")}
2024-04-22 13:25:44 +05:30
onClick={() => {
navigator.clipboard.writeText(data);
}}
>
{t("ERRORS.COPY_ERROR.TITLE")}
2024-04-22 13:25:44 +05:30
</ToastAction>
2024-04-25 01:58:03 +05:30
<a href="https://docs.upscayl.org/" target="_blank">
<ToastAction altText={t("ERRORS.OPEN_DOCS_TITLE")}>
{t("ERRORS.OPEN_DOCS_BUTTON_TITLE")}
</ToastAction>
2024-04-22 13:25:44 +05:30
</a>
</div>
2024-04-21 19:34:59 +05:30
),
});
2022-11-12 02:09:28 +05:30
resetImagePaths();
2024-04-21 19:34:59 +05:30
} else if (data.includes("write") || data.includes("read")) {
2022-11-12 02:09:28 +05:30
if (batchMode) return;
2024-04-21 19:34:59 +05:30
toast({
title: t("ERRORS.READ_WRITE_ERROR.TITLE"),
description: t("ERRORS.READ_WRITE_ERROR.DESCRIPTION", { data }),
2024-04-21 19:34:59 +05:30
action: (
2024-04-22 13:25:44 +05:30
<div className="flex flex-col gap-2">
<ToastAction
altText="Copy Error"
onClick={() => {
navigator.clipboard.writeText(data);
}}
>
{t("ERRORS.COPY_ERROR.TITLE")}
2024-04-22 13:25:44 +05:30
</ToastAction>
2024-04-25 01:58:03 +05:30
<a href="https://docs.upscayl.org/" target="_blank">
<ToastAction altText={t("ERRORS.OPEN_DOCS_TITLE")}>
{t("ERRORS.OPEN_DOCS_BUTTON_TITLE")}
</ToastAction>
2024-04-22 13:25:44 +05:30
</a>
</div>
2024-04-21 19:34:59 +05:30
),
});
resetImagePaths();
} else if (data.includes("tile size")) {
toast({
title: t("ERRORS.TILE_SIZE_ERROR.TITLE"),
description: t("ERRORS.TILE_SIZE_ERROR.DESCRIPTION", { data }),
2024-04-21 19:34:59 +05:30
});
2022-11-12 02:09:28 +05:30
resetImagePaths();
} else if (data.includes("uncaughtException")) {
2024-04-21 19:34:59 +05:30
toast({
title: t("ERRORS.EXCEPTION_ERROR.TITLE"),
description: t("ERRORS.EXCEPTION_ERROR.DESCRIPTION"),
2024-04-21 19:34:59 +05:30
});
2022-11-12 02:09:28 +05:30
resetImagePaths();
}
};
2023-04-14 16:01:37 +05:30
// LOG
2024-09-24 20:05:33 +05:30
window.electron.on(ELECTRON_COMMANDS.LOG, (_, data: string) => {
2024-04-25 16:13:16 +05:30
logit(`🎒 BACKEND REPORTED: `, data);
2023-04-14 16:01:37 +05:30
});
2023-11-23 14:23:09 +05:30
// SCALING AND CONVERTING
2024-09-24 20:05:33 +05:30
window.electron.on(
ELECTRON_COMMANDS.SCALING_AND_CONVERTING,
(_, data: string) => {
setProgress(t("APP.PROGRESS.PROCESSING_TITLE"));
},
);
2023-11-23 14:23:09 +05:30
// UPSCAYL ERROR
2024-09-24 20:05:33 +05:30
window.electron.on(ELECTRON_COMMANDS.UPSCAYL_ERROR, (_, data: string) => {
2024-04-21 19:34:59 +05:30
toast({
title: t("ERRORS.GENERIC_ERROR.TITLE"),
2024-04-21 19:34:59 +05:30
description: data,
});
2023-09-09 16:33:16 +05:30
resetImagePaths();
});
2022-12-16 21:50:46 +05:30
// UPSCAYL PROGRESS
2024-09-24 20:05:33 +05:30
window.electron.on(
ELECTRON_COMMANDS.UPSCAYL_PROGRESS,
(_, data: string) => {
if (data.length > 0 && data.length < 10) {
setProgress(data);
} else if (data.includes("converting")) {
setProgress(t("APP.PROGRESS.SCALING_CONVERTING_TITLE"));
} else if (data.includes("Successful")) {
setProgress(t("APP.PROGRESS.SUCCESS_TITLE"));
}
handleErrors(data);
logit(`🚧 UPSCAYL_PROGRESS: `, data);
},
);
2022-12-16 21:50:46 +05:30
// FOLDER UPSCAYL PROGRESS
2024-09-24 20:05:33 +05:30
window.electron.on(
ELECTRON_COMMANDS.FOLDER_UPSCAYL_PROGRESS,
(_, data: string) => {
if (data.includes("Successful")) {
setProgress(t("APP.PROGRESS.SUCCESS_TITLE"));
}
if (data.length > 0 && data.length < 10) {
setProgress(data);
}
handleErrors(data);
logit(`🚧 FOLDER_UPSCAYL_PROGRESS: `, data);
},
);
2022-12-16 21:50:46 +05:30
// DOUBLE UPSCAYL PROGRESS
2024-09-24 20:05:33 +05:30
window.electron.on(
ELECTRON_COMMANDS.DOUBLE_UPSCAYL_PROGRESS,
(_, data: string) => {
if (data.length > 0 && data.length < 10) {
if (data === "0.00%") {
setDoubleUpscaylCounter(doubleUpscaylCounter + 1);
}
setProgress(data);
2022-12-02 19:51:42 +05:30
}
2024-09-24 20:05:33 +05:30
handleErrors(data);
logit(`🚧 DOUBLE_UPSCAYL_PROGRESS: `, data);
},
);
2022-12-16 21:50:46 +05:30
// UPSCAYL DONE
2024-09-24 20:05:33 +05:30
window.electron.on(ELECTRON_COMMANDS.UPSCAYL_DONE, (_, data: string) => {
2022-11-12 02:09:28 +05:30
setProgress("");
2023-09-13 21:45:42 +05:30
setUpscaledImagePath(data);
2023-07-22 18:30:46 +05:30
logit("upscaledImagePath: ", data);
logit(`💯 UPSCAYL_DONE: `, data);
2022-11-12 02:09:28 +05:30
});
2022-12-16 21:50:46 +05:30
// FOLDER UPSCAYL DONE
2024-09-24 20:05:33 +05:30
window.electron.on(
ELECTRON_COMMANDS.FOLDER_UPSCAYL_DONE,
(_, data: string) => {
setProgress("");
setUpscaledBatchFolderPath(data);
logit(`💯 FOLDER_UPSCAYL_DONE: `, data);
},
);
2022-12-16 21:50:46 +05:30
// DOUBLE UPSCAYL DONE
2024-09-24 20:05:33 +05:30
window.electron.on(
ELECTRON_COMMANDS.DOUBLE_UPSCAYL_DONE,
(_, data: string) => {
setProgress("");
setTimeout(() => setUpscaledImagePath(data), 500);
setDoubleUpscaylCounter(0);
logit(`💯 DOUBLE_UPSCAYL_DONE: `, data);
},
);
2023-04-09 11:18:53 +05:30
// CUSTOM FOLDER LISTENER
2024-09-24 20:05:33 +05:30
window.electron.on(
ELECTRON_COMMANDS.CUSTOM_MODEL_FILES_LIST,
(_, data: string[]) => {
logit(`📜 CUSTOM_MODEL_FILES_LIST: `, data);
const newModelOptions = data.map((model) => {
return {
value: model,
label: model,
};
});
// Add newModelsList to modelOptions and remove duplicates
const combinedModelOptions = [...modelOptions, ...newModelOptions];
const uniqueModelOptions = combinedModelOptions.filter(
// Check if any model in the array appears more than once
(model, index, array) =>
array.findIndex((t) => t.value === model.value) === index,
);
setModelOptions(uniqueModelOptions);
},
);
2023-04-09 11:18:53 +05:30
}, []);
2023-11-23 14:23:09 +05:30
// FETCH CUSTOM MODELS FROM CUSTOM MODELS PATH
2023-04-09 11:18:53 +05:30
useEffect(() => {
const customModelsPath = JSON.parse(
2024-02-07 06:53:19 +05:30
localStorage.getItem("customModelsPath"),
2023-04-09 11:18:53 +05:30
);
if (customModelsPath !== null) {
2024-09-24 20:05:33 +05:30
window.electron.send(ELECTRON_COMMANDS.GET_MODELS_LIST, customModelsPath);
logit("🎯 GET_MODELS_LIST: ", customModelsPath);
2023-04-09 11:18:53 +05:30
}
2022-11-12 02:09:28 +05:30
}, []);
2023-11-23 14:23:09 +05:30
// FETCH NEWS
2023-11-23 11:28:29 +05:30
useEffect(() => {
// TODO: ADD AN ABOUT TAB
if (window && window.navigator.onLine === false) return;
2023-12-03 12:06:00 +05:30
try {
fetch("https://raw.githubusercontent.com/upscayl/upscayl/main/news.md", {
cache: "no-cache",
2023-11-23 14:23:09 +05:30
})
2023-12-03 12:06:00 +05:30
.then((res) => {
return res.text();
})
.then((result) => {
const newsData = result;
if (!newsData) {
console.log("📰 Could not fetch news data");
return;
2023-11-26 13:34:03 +05:30
}
2023-12-03 12:06:00 +05:30
const markdownData = matter(newsData);
if (!markdownData) return;
if (markdownData && markdownData.data.dontShow) {
2023-12-03 12:06:00 +05:30
return;
}
if (
markdownData &&
news &&
markdownData?.data?.version === news?.data?.version
) {
console.log("📰 News is up to date");
if (showNewsModal === false) {
setShowNewsModal(false);
}
} else if (markdownData) {
setNews(matter(newsData));
setShowNewsModal(true);
}
});
} catch (error) {
console.log("Could not fetch Upscayl News");
}
2023-11-26 13:34:03 +05:30
}, [news]);
2023-11-23 11:28:29 +05:30
2023-11-23 14:23:09 +05:30
// LOADING STATE
2023-10-15 09:27:11 +05:30
useEffect(() => {
setIsLoading(false);
}, []);
// HANDLERS
2022-12-16 21:50:46 +05:30
const resetImagePaths = () => {
logit("🔄 Resetting image paths");
2022-12-24 12:47:54 +05:30
setDimensions({
width: null,
height: null,
});
2022-12-16 21:50:46 +05:30
setProgress("");
2023-11-23 14:23:09 +05:30
setImagePath("");
2022-12-16 21:50:46 +05:30
setUpscaledImagePath("");
setBatchFolderPath("");
setUpscaledBatchFolderPath("");
};
2023-11-23 14:23:09 +05:30
// UTILS
2022-12-16 21:50:46 +05:30
// HANDLERS
2023-10-15 09:27:11 +05:30
if (isLoading) {
2023-08-30 10:24:16 +05:30
return (
2024-04-24 16:38:27 +05:30
<Logo className="absolute left-1/2 top-1/2 w-36 -translate-x-1/2 -translate-y-1/2 animate-pulse" />
2023-08-30 10:24:16 +05:30
);
}
2022-11-12 02:09:28 +05:30
return (
2022-11-12 03:02:24 +05:30
<div className="flex h-screen w-screen flex-row overflow-hidden bg-base-300">
2024-09-24 20:05:33 +05:30
<Sidebar
imagePath={imagePath}
dimensions={dimensions}
upscaledImagePath={upscaledImagePath}
setUpscaledImagePath={setUpscaledImagePath}
batchFolderPath={batchFolderPath}
setUpscaledBatchFolderPath={setUpscaledBatchFolderPath}
selectImageHandler={selectImageHandler}
selectFolderHandler={selectFolderHandler}
/>
<MainContent
imagePath={imagePath}
resetImagePaths={resetImagePaths}
upscaledBatchFolderPath={upscaledBatchFolderPath}
setImagePath={setImagePath}
validateImagePath={validateImagePath}
selectFolderHandler={selectFolderHandler}
selectImageHandler={selectImageHandler}
batchFolderPath={batchFolderPath}
upscaledImagePath={upscaledImagePath}
doubleUpscaylCounter={doubleUpscaylCounter}
setDimensions={setDimensions}
/>
2022-11-12 02:09:28 +05:30
</div>
);
};
export default Home;