diff --git a/common/models-list.ts b/common/models-list.ts index dc1a8f9..b90583d 100644 --- a/common/models-list.ts +++ b/common/models-list.ts @@ -1,13 +1,32 @@ -export const defaultModelsList = [ - { label: "General Photo (Real-ESRGAN)", value: "realesrgan-x4plus" }, - { - label: "General Photo (Fast Real-ESRGAN)", - value: "realesrgan-x4fast", +export const MODELS = { + "realesrgan-x4plus": { + id: "realesrgan-x4plus", + name: "Upscayl Standard", }, - { label: "General Photo (Remacri)", value: "remacri" }, - { label: "General Photo (Ultramix Balanced)", value: "ultramix_balanced" }, - { label: "General Photo (Ultrasharp)", value: "ultrasharp" }, - { label: "Digital Art", value: "realesrgan-x4plus-anime" }, -]; + "realesrgan-x4fast": { + id: "realesrgan-x4fast", + name: "Upscayl Lite", + }, + remacri: { + id: "remacri", + name: "Remacri (Non-Commercial)", + }, + ultramix_balanced: { + id: "ultramix_balanced", + name: "Ultramix (Non-Commercial)", + }, + ultrasharp: { + id: "ultrasharp", + name: "Ultrasharp (Non-Commercial)", + }, + "realesrgan-x4plus-anime": { + id: "realesrgan-x4plus-anime", + name: "Digital Art", + }, +}; -export const DEFAULT_MODELS = defaultModelsList.map((model) => model.value); +export type ModelId = keyof typeof MODELS; + +export const DEFAULT_MODELS_ID_LIST = Object.keys(MODELS).map( + (modelId) => modelId, +); diff --git a/electron/commands/batch-upscayl.ts b/electron/commands/batch-upscayl.ts index 584552f..38bdd1a 100644 --- a/electron/commands/batch-upscayl.ts +++ b/electron/commands/batch-upscayl.ts @@ -11,10 +11,10 @@ import { spawnUpscayl } from "../utils/spawn-upscayl"; import { getBatchArguments } from "../utils/get-arguments"; import slash from "../utils/slash"; import { modelsPath } from "../utils/get-resource-paths"; -import { ELECTRON_COMMANDS } from "@common/electron-commands"; +import { ELECTRON_COMMANDS } from "../../common/electron-commands"; import { BatchUpscaylPayload } from "../../common/types/types"; import showNotification from "../utils/show-notification"; -import { DEFAULT_MODELS } from "../../common/models-list"; +import { DEFAULT_MODELS_ID_LIST } from "../../common/models-list"; const batchUpscayl = async (event, payload: BatchUpscaylPayload) => { const mainWindow = getMainWindow(); @@ -41,7 +41,7 @@ const batchUpscayl = async (event, payload: BatchUpscaylPayload) => { fs.mkdirSync(outputFolderPath, { recursive: true }); } - const isDefaultModel = DEFAULT_MODELS.includes(model); + const isDefaultModel = DEFAULT_MODELS_ID_LIST.includes(model); // UPSCALE const upscayl = spawnUpscayl( diff --git a/electron/commands/custom-models-select.ts b/electron/commands/custom-models-select.ts index a0ab7d0..ae0ef0e 100644 --- a/electron/commands/custom-models-select.ts +++ b/electron/commands/custom-models-select.ts @@ -5,7 +5,7 @@ import { } from "../utils/config-variables"; import logit from "../utils/logit"; import slash from "../utils/slash"; -import { ELECTRON_COMMANDS } from "@common/electron-commands"; +import { ELECTRON_COMMANDS } from "../../common/electron-commands"; import getModels from "../utils/get-models"; import { getMainWindow } from "../main-window"; import settings from "electron-settings"; diff --git a/electron/commands/double-upscayl.ts b/electron/commands/double-upscayl.ts index 34a81e3..b8fdb4c 100644 --- a/electron/commands/double-upscayl.ts +++ b/electron/commands/double-upscayl.ts @@ -14,11 +14,11 @@ import { } from "../utils/get-arguments"; import { modelsPath } from "../utils/get-resource-paths"; import logit from "../utils/logit"; -import { ELECTRON_COMMANDS } from "@common/electron-commands"; +import { ELECTRON_COMMANDS } from "../../common/electron-commands"; import { DoubleUpscaylPayload } from "../../common/types/types"; import { ImageFormat } from "../types/types"; import showNotification from "../utils/show-notification"; -import { DEFAULT_MODELS } from "../../common/models-list"; +import { DEFAULT_MODELS_ID_LIST } from "../../common/models-list"; import getFilenameFromPath from "../../common/get-file-name"; import decodePath from "../../common/decode-path"; import getDirectoryFromPath from "../../common/get-directory-from-path"; @@ -41,7 +41,7 @@ const doubleUpscayl = async (event, payload: DoubleUpscaylPayload) => { const fullfileName = getFilenameFromPath(imagePath); const fileName = parse(fullfileName).name; - const isDefaultModel = DEFAULT_MODELS.includes(model); + const isDefaultModel = DEFAULT_MODELS_ID_LIST.includes(model); // COPY IMAGE TO TMP FOLDER diff --git a/electron/commands/get-models-list.ts b/electron/commands/get-models-list.ts index cce3e37..29499e9 100644 --- a/electron/commands/get-models-list.ts +++ b/electron/commands/get-models-list.ts @@ -1,4 +1,4 @@ -import { ELECTRON_COMMANDS } from "@common/electron-commands"; +import { ELECTRON_COMMANDS } from "../../common/electron-commands"; import { getMainWindow } from "../main-window"; import { savedCustomModelsPath, diff --git a/electron/commands/image-upscayl.ts b/electron/commands/image-upscayl.ts index 9a7ce50..38dce67 100644 --- a/electron/commands/image-upscayl.ts +++ b/electron/commands/image-upscayl.ts @@ -1,6 +1,6 @@ import fs from "fs"; import { modelsPath } from "../utils/get-resource-paths"; -import { ELECTRON_COMMANDS } from "@common/electron-commands"; +import { ELECTRON_COMMANDS } from "../../common/electron-commands"; import { savedCustomModelsPath, setChildProcesses, @@ -16,7 +16,7 @@ import { getMainWindow } from "../main-window"; import { ImageUpscaylPayload } from "../../common/types/types"; import { ImageFormat } from "../types/types"; import showNotification from "../utils/show-notification"; -import { DEFAULT_MODELS } from "../../common/models-list"; +import { DEFAULT_MODELS_ID_LIST } from "../../common/models-list"; import getFilenameFromPath from "../../common/get-file-name"; import decodePath from "../../common/decode-path"; import getDirectoryFromPath from "../../common/get-directory-from-path"; @@ -55,7 +55,7 @@ const imageUpscayl = async (event, payload: ImageUpscaylPayload) => { "." + saveImageAs; - const isDefaultModel = DEFAULT_MODELS.includes(model); + const isDefaultModel = DEFAULT_MODELS_ID_LIST.includes(model); // Check if windows can write the new filename to the file system if (outFile.length >= 255) { diff --git a/electron/utils/logit.ts b/electron/utils/logit.ts index b80a8f7..0c4d74e 100644 --- a/electron/utils/logit.ts +++ b/electron/utils/logit.ts @@ -1,6 +1,6 @@ import log from "electron-log"; -import { ELECTRON_COMMANDS } from "@common/electron-commands"; import { getMainWindow } from "../main-window"; +import { ELECTRON_COMMANDS } from "../../common/electron-commands"; const logit = (...args: any) => { const mainWindow = getMainWindow(); diff --git a/org.upscayl.Upscayl.desktop b/org.upscayl.Upscayl.desktop deleted file mode 100644 index 8134aa8..0000000 --- a/org.upscayl.Upscayl.desktop +++ /dev/null @@ -1,8 +0,0 @@ -[Desktop Entry] -X-Desktop-File-Install-Version=0.26 -Exec=upscayl %U --ozone-platform-hint=auto --enable-features=WaylandWindowDecorations -Comment=Upscale Images with AI -Name=Upscayl -StartupNotify=false -Categories=ImageProcessing;RasterGraphics;Graphics; -Type=Application diff --git a/package-lock.json b/package-lock.json index 5df6988..afd3879 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,7 @@ "dependencies": { "@radix-ui/react-dialog": "^1.0.5", "@radix-ui/react-popover": "^1.0.7", + "@radix-ui/react-scroll-area": "^1.2.0", "@radix-ui/react-slot": "^1.0.2", "@radix-ui/react-toast": "^1.1.5", "class-variance-authority": "^0.7.0", @@ -1739,6 +1740,11 @@ "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" }, + "node_modules/@radix-ui/number": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.1.0.tgz", + "integrity": "sha512-V3gRzhVNU1ldS5XhAPTom1fOIo4ccrjjJgmE+LI2h/WaFpHmx0MQApT+KZHnx8abG6Avtfcz4WoEciMnpFT3HQ==" + }, "node_modules/@radix-ui/primitive": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.0.1.tgz", @@ -1866,6 +1872,20 @@ } } }, + "node_modules/@radix-ui/react-direction": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.0.tgz", + "integrity": "sha512-BUuBvgThEiAXh2DWu93XsT+a3aWrGqolGlqqw5VU1kG7p/ZH2cuDlM1sRLNnY3QcBS69UIz2mcKhMxDsdewhjg==", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-dismissable-layer": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.0.5.tgz", @@ -2092,6 +2112,159 @@ } } }, + "node_modules/@radix-ui/react-scroll-area": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-scroll-area/-/react-scroll-area-1.2.0.tgz", + "integrity": "sha512-q2jMBdsJ9zB7QG6ngQNzNwlvxLQqONyL58QbEGwuyRZZb/ARQwk3uQVbCF7GvQVOtV6EU/pDxAw3zRzJZI3rpQ==", + "dependencies": { + "@radix-ui/number": "1.1.0", + "@radix-ui/primitive": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-direction": "1.1.0", + "@radix-ui/react-presence": "1.1.1", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-use-callback-ref": "1.1.0", + "@radix-ui/react-use-layout-effect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-scroll-area/node_modules/@radix-ui/primitive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.0.tgz", + "integrity": "sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA==" + }, + "node_modules/@radix-ui/react-scroll-area/node_modules/@radix-ui/react-compose-refs": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.0.tgz", + "integrity": "sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw==", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-scroll-area/node_modules/@radix-ui/react-context": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.1.tgz", + "integrity": "sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q==", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-scroll-area/node_modules/@radix-ui/react-presence": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.1.tgz", + "integrity": "sha512-IeFXVi4YS1K0wVZzXNrbaaUvIJ3qdY+/Ih4eHFhWA9SwGR9UDX7Ck8abvL57C4cv3wwMvUE0OG69Qc3NCcTe/A==", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-use-layout-effect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-scroll-area/node_modules/@radix-ui/react-primitive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.0.tgz", + "integrity": "sha512-ZSpFm0/uHa8zTvKBDjLFWLo8dkr4MBsiDLz0g3gMUwqgLHz9rTaRRGYDgvZPtBJgYCBKXkS9fzmoySgr8CO6Cw==", + "dependencies": { + "@radix-ui/react-slot": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-scroll-area/node_modules/@radix-ui/react-slot": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.0.tgz", + "integrity": "sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw==", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-scroll-area/node_modules/@radix-ui/react-use-callback-ref": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.0.tgz", + "integrity": "sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-scroll-area/node_modules/@radix-ui/react-use-layout-effect": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.0.tgz", + "integrity": "sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-slot": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.0.2.tgz", diff --git a/package.json b/package.json index 1e2ef30..abad0fb 100644 --- a/package.json +++ b/package.json @@ -225,6 +225,7 @@ "dependencies": { "@radix-ui/react-dialog": "^1.0.5", "@radix-ui/react-popover": "^1.0.7", + "@radix-ui/react-scroll-area": "^1.2.0", "@radix-ui/react-slot": "^1.0.2", "@radix-ui/react-toast": "^1.1.5", "class-variance-authority": "^0.7.0", diff --git a/renderer/atoms/models-list-atom.ts b/renderer/atoms/models-list-atom.ts index df79de0..0f1ab96 100644 --- a/renderer/atoms/models-list-atom.ts +++ b/renderer/atoms/models-list-atom.ts @@ -1,9 +1,3 @@ -import { defaultModelsList } from "@common/models-list"; import { atom } from "jotai"; -export type TModelsList = { - label: string; - value: string; -}[]; - -export const modelsListAtom = atom(defaultModelsList); +export const customModelIdsAtom = atom([] as string[]); diff --git a/renderer/atoms/user-settings-atom.ts b/renderer/atoms/user-settings-atom.ts index a4f1e60..904edc8 100644 --- a/renderer/atoms/user-settings-atom.ts +++ b/renderer/atoms/user-settings-atom.ts @@ -1,3 +1,5 @@ +import { ImageFormat } from "@/lib/valid-formats"; +import { ModelId } from "@common/models-list"; import { atom } from "jotai"; import { atomWithStorage } from "jotai/utils"; @@ -6,6 +8,17 @@ export const customModelsPathAtom = atomWithStorage( null, ); +export const selectedModelIdAtom = atomWithStorage( + "selectedModelId", + "realesrgan-x4plus", +); +export const doubleUpscaylAtom = atomWithStorage("selectedModelId", false); +export const gpuIdAtom = atomWithStorage("gpuId", ""); +export const saveImageAsAtom = atomWithStorage( + "saveImageAs", + "png", +); + export const scaleAtom = atomWithStorage("scale", "4"); export const batchModeAtom = atom(false); diff --git a/renderer/components/main-content/index.tsx b/renderer/components/main-content/index.tsx index 44298b9..0b89aa5 100644 --- a/renderer/components/main-content/index.tsx +++ b/renderer/components/main-content/index.tsx @@ -15,7 +15,7 @@ import { useToast } from "@/components/ui/use-toast"; import { sanitizePath } from "@common/sanitize-path"; import getDirectoryFromPath from "@common/get-directory-from-path"; import { FEATURE_FLAGS } from "@common/feature-flags"; -import { VALID_IMAGE_FORMATS } from "@/lib/valid-formats"; +import { ImageFormat, VALID_IMAGE_FORMATS } from "@/lib/valid-formats"; import ProgressBar from "./progress-bar"; import InstructionsCard from "./instructions-card"; import ImageViewSettings from "./image-view-settings"; @@ -176,12 +176,12 @@ const MainContent = ({ } const type = items[0].type; const filePath = files[0].path; - const extension = files[0].name.split(".").at(-1); + const extension = files[0].name + .split(".") + .at(-1) + .toLowerCase() as ImageFormat; logit("📋 Pasted file: ", JSON.stringify({ type, filePath, extension })); - if ( - !type.includes("image") && - !VALID_IMAGE_FORMATS.includes(extension.toLowerCase()) - ) { + if (!type.includes("image") && !VALID_IMAGE_FORMATS.includes(extension)) { toast({ title: t("ERRORS.INVALID_IMAGE_ERROR.TITLE"), description: t("ERRORS.INVALID_IMAGE_ERROR.ADDITIONAL_DESCRIPTION"), diff --git a/renderer/components/sidebar/index.tsx b/renderer/components/sidebar/index.tsx index ecd62a3..647ceca 100644 --- a/renderer/components/sidebar/index.tsx +++ b/renderer/components/sidebar/index.tsx @@ -14,6 +14,10 @@ import { useCustomWidthAtom, tileSizeAtom, showSidebarAtom, + selectedModelIdAtom, + doubleUpscaylAtom, + gpuIdAtom, + saveImageAsAtom, } from "../../atoms/user-settings-atom"; import useLogger from "../hooks/use-logger"; import { @@ -63,16 +67,16 @@ const Sidebar = ({ // LOCAL STATES // TODO: Add electron handler for os - const [model, setModel] = useState("realesrgan-x4plus"); - const [doubleUpscayl, setDoubleUpscayl] = useState(false); - const overwrite = useAtomValue(overwriteAtom); - const [gpuId, setGpuId] = useState(""); - const [saveImageAs, setSaveImageAs] = useState("png"); + const [selectedModelId, setSelectedModelId] = useAtom(selectedModelIdAtom); + const [doubleUpscayl, setDoubleUpscayl] = useAtom(doubleUpscaylAtom); + const [gpuId, setGpuId] = useAtom(gpuIdAtom); + const [saveImageAs, setSaveImageAs] = useAtom(saveImageAsAtom); const [selectedTab, setSelectedTab] = useState(0); const [showCloudModal, setShowCloudModal] = useState(false); // ATOMIC STATES + const overwrite = useAtomValue(overwriteAtom); const outputPath = useAtomValue(savedOutputPathAtom); const [compression, setCompression] = useAtom(compressionAtom); const setProgress = useSetAtom(progressAtom); @@ -87,7 +91,7 @@ const Sidebar = ({ const [showSidebar, setShowSidebar] = useAtom(showSidebarAtom); const handleModelChange = (e: any) => { - setModel(e.value); + setSelectedModelId(e.value); logit("🔀 Model changed: ", e.value); localStorage.setItem( "model", @@ -108,7 +112,7 @@ const Sidebar = ({ { imagePath, outputPath, - model, + model: selectedModelId, gpuId: gpuId.length === 0 ? null : gpuId, saveImageAs, scale, @@ -128,7 +132,7 @@ const Sidebar = ({ { batchFolderPath, outputPath, - model, + model: selectedModelId, gpuId: gpuId.length === 0 ? null : gpuId, saveImageAs, scale, @@ -145,7 +149,7 @@ const Sidebar = ({ window.electron.send(ELECTRON_COMMANDS.UPSCAYL, { imagePath, outputPath, - model, + model: selectedModelId, gpuId: gpuId.length === 0 ? null : gpuId, saveImageAs, scale, @@ -181,7 +185,7 @@ const Sidebar = ({ className={`relative flex h-screen min-w-[350px] max-w-[350px] flex-col bg-base-100 ${showSidebar ? "" : "hidden"}`} > + + + + Select AI Model + + +
+ {Object.entries(MODELS).map((modelData) => { + const modelId = modelData[0] as ModelId; + const model = modelData[1]; + return ( + +
+ + ); + })} + {customModelIds.map((customModel) => { + return ( + + ); + })} + +
+
+ + + !open && setZoomedModel(null)} + > + +
+
+
+ {`${MODELS[zoomedModel]?.name} +
+ Before +
+
+
+ {`${MODELS[zoomedModel]?.name} +
+ After +
+
+
+ +
+
+
+ + ); +} diff --git a/renderer/components/sidebar/upscayl-tab/upscayl-steps.tsx b/renderer/components/sidebar/upscayl-tab/upscayl-steps.tsx index 016e5c1..c2ca2ea 100644 --- a/renderer/components/sidebar/upscayl-tab/upscayl-steps.tsx +++ b/renderer/components/sidebar/upscayl-tab/upscayl-steps.tsx @@ -1,8 +1,7 @@ import { useAtom, useAtomValue } from "jotai"; -import React, { useEffect, useMemo, useState } from "react"; +import React, { useEffect, useMemo } from "react"; import { Tooltip } from "react-tooltip"; import { themeChange } from "theme-change"; -import { TModelsList, modelsListAtom } from "../../../atoms/models-list-atom"; import useLogger from "../../hooks/use-logger"; import { savedOutputPathAtom, @@ -14,16 +13,15 @@ import { } from "../../../atoms/user-settings-atom"; import { FEATURE_FLAGS } from "@common/feature-flags"; import { ELECTRON_COMMANDS } from "@common/electron-commands"; -import Select from "react-select"; -import { cn } from "@/lib/utils"; import { useToast } from "@/components/ui/use-toast"; import { translationAtom } from "@/atoms/translations-atom"; import { SelectImageScale } from "../settings-tab/select-image-scale"; +import SelectModel from "./select-model"; +import { ImageFormat } from "@/lib/valid-formats"; interface IProps { selectImageHandler: () => Promise; selectFolderHandler: () => Promise; - handleModelChange: (e: any) => void; upscaylHandler: () => Promise; batchMode: boolean; setBatchMode: React.Dispatch>; @@ -34,16 +32,13 @@ interface IProps { width: number | null; height: number | null; }; - setSaveImageAs: React.Dispatch>; - model: string; - setModel: React.Dispatch>; + setSaveImageAs: React.Dispatch>; setGpuId: React.Dispatch>; } function UpscaylSteps({ selectImageHandler, selectFolderHandler, - handleModelChange, upscaylHandler, batchMode, setBatchMode, @@ -51,22 +46,11 @@ function UpscaylSteps({ doubleUpscayl, setDoubleUpscayl, dimensions, - setSaveImageAs, - model, - setModel, - setGpuId, }: IProps) { - const [currentModel, setCurrentModel] = useState({ - label: null, - value: null, - }); - - const modelOptions = useAtomValue(modelsListAtom); const [scale, setScale] = useAtom(scaleAtom); const [outputPath, setOutputPath] = useAtom(savedOutputPathAtom); const [progress, setProgress] = useAtom(progressAtom); const rememberOutputFolder = useAtomValue(rememberOutputFolderAtom); - const [open, setOpen] = React.useState(false); const customWidth = useAtomValue(customWidthAtom); const useCustomWidth = useAtomValue(useCustomWidthAtom); @@ -86,50 +70,8 @@ function UpscaylSteps({ useEffect(() => { themeChange(false); - - if (!localStorage.getItem("saveImageAs")) { - logit("⚙️ Setting saveImageAs to png"); - localStorage.setItem("saveImageAs", "png"); - } else { - const currentlySavedImageFormat = localStorage.getItem("saveImageAs"); - logit( - "⚙️ Getting saveImageAs from localStorage: ", - currentlySavedImageFormat, - ); - setSaveImageAs(currentlySavedImageFormat); - } - - if (!localStorage.getItem("model")) { - setCurrentModel(modelOptions[0]); - setModel(modelOptions[0].value); - localStorage.setItem("model", JSON.stringify(modelOptions[0])); - logit("🔀 Setting model to", modelOptions[0].value); - } else { - const currentlySavedModel = JSON.parse( - localStorage.getItem("model"), - ) as (typeof modelOptions)[0]; - setCurrentModel(currentlySavedModel); - setModel(currentlySavedModel.value); - logit( - "⚙️ Getting model from localStorage: ", - JSON.stringify(currentlySavedModel), - ); - } - - if (!localStorage.getItem("gpuId")) { - localStorage.setItem("gpuId", ""); - logit("⚙️ Setting gpuId to empty string"); - } else { - const currentlySavedGpuId = localStorage.getItem("gpuId"); - setGpuId(currentlySavedGpuId); - logit("⚙️ Getting gpuId from localStorage: ", currentlySavedGpuId); - } }, []); - useEffect(() => { - logit("🔀 Setting model to", currentModel.value); - }, [currentModel]); - const upscaylResolution = useMemo(() => { const newDimensions = { width: dimensions.width, @@ -214,25 +156,7 @@ function UpscaylSteps({

{t("APP.MODEL_SELECTION.TITLE")}

{t("APP.MODEL_SELECTION.DESCRIPTION")}

-