mirror of
https://github.com/upscayl/upscayl.git
synced 2024-11-23 23:21:05 +01:00
New models selection menu
This commit is contained in:
parent
a0af4fe02a
commit
a6f344f3b8
@ -1,13 +1,32 @@
|
|||||||
export const defaultModelsList = [
|
export const MODELS = {
|
||||||
{ label: "General Photo (Real-ESRGAN)", value: "realesrgan-x4plus" },
|
"realesrgan-x4plus": {
|
||||||
{
|
id: "realesrgan-x4plus",
|
||||||
label: "General Photo (Fast Real-ESRGAN)",
|
name: "Upscayl Standard",
|
||||||
value: "realesrgan-x4fast",
|
|
||||||
},
|
},
|
||||||
{ label: "General Photo (Remacri)", value: "remacri" },
|
"realesrgan-x4fast": {
|
||||||
{ label: "General Photo (Ultramix Balanced)", value: "ultramix_balanced" },
|
id: "realesrgan-x4fast",
|
||||||
{ label: "General Photo (Ultrasharp)", value: "ultrasharp" },
|
name: "Upscayl Lite",
|
||||||
{ label: "Digital Art", value: "realesrgan-x4plus-anime" },
|
},
|
||||||
];
|
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,
|
||||||
|
);
|
||||||
|
@ -11,10 +11,10 @@ import { spawnUpscayl } from "../utils/spawn-upscayl";
|
|||||||
import { getBatchArguments } from "../utils/get-arguments";
|
import { getBatchArguments } from "../utils/get-arguments";
|
||||||
import slash from "../utils/slash";
|
import slash from "../utils/slash";
|
||||||
import { modelsPath } from "../utils/get-resource-paths";
|
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 { BatchUpscaylPayload } from "../../common/types/types";
|
||||||
import showNotification from "../utils/show-notification";
|
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 batchUpscayl = async (event, payload: BatchUpscaylPayload) => {
|
||||||
const mainWindow = getMainWindow();
|
const mainWindow = getMainWindow();
|
||||||
@ -41,7 +41,7 @@ const batchUpscayl = async (event, payload: BatchUpscaylPayload) => {
|
|||||||
fs.mkdirSync(outputFolderPath, { recursive: true });
|
fs.mkdirSync(outputFolderPath, { recursive: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
const isDefaultModel = DEFAULT_MODELS.includes(model);
|
const isDefaultModel = DEFAULT_MODELS_ID_LIST.includes(model);
|
||||||
|
|
||||||
// UPSCALE
|
// UPSCALE
|
||||||
const upscayl = spawnUpscayl(
|
const upscayl = spawnUpscayl(
|
||||||
|
@ -5,7 +5,7 @@ import {
|
|||||||
} from "../utils/config-variables";
|
} from "../utils/config-variables";
|
||||||
import logit from "../utils/logit";
|
import logit from "../utils/logit";
|
||||||
import slash from "../utils/slash";
|
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 getModels from "../utils/get-models";
|
||||||
import { getMainWindow } from "../main-window";
|
import { getMainWindow } from "../main-window";
|
||||||
import settings from "electron-settings";
|
import settings from "electron-settings";
|
||||||
|
@ -14,11 +14,11 @@ import {
|
|||||||
} from "../utils/get-arguments";
|
} from "../utils/get-arguments";
|
||||||
import { modelsPath } from "../utils/get-resource-paths";
|
import { modelsPath } from "../utils/get-resource-paths";
|
||||||
import logit from "../utils/logit";
|
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 { DoubleUpscaylPayload } from "../../common/types/types";
|
||||||
import { ImageFormat } from "../types/types";
|
import { ImageFormat } from "../types/types";
|
||||||
import showNotification from "../utils/show-notification";
|
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 getFilenameFromPath from "../../common/get-file-name";
|
||||||
import decodePath from "../../common/decode-path";
|
import decodePath from "../../common/decode-path";
|
||||||
import getDirectoryFromPath from "../../common/get-directory-from-path";
|
import getDirectoryFromPath from "../../common/get-directory-from-path";
|
||||||
@ -41,7 +41,7 @@ const doubleUpscayl = async (event, payload: DoubleUpscaylPayload) => {
|
|||||||
const fullfileName = getFilenameFromPath(imagePath);
|
const fullfileName = getFilenameFromPath(imagePath);
|
||||||
const fileName = parse(fullfileName).name;
|
const fileName = parse(fullfileName).name;
|
||||||
|
|
||||||
const isDefaultModel = DEFAULT_MODELS.includes(model);
|
const isDefaultModel = DEFAULT_MODELS_ID_LIST.includes(model);
|
||||||
|
|
||||||
// COPY IMAGE TO TMP FOLDER
|
// COPY IMAGE TO TMP FOLDER
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { ELECTRON_COMMANDS } from "@common/electron-commands";
|
import { ELECTRON_COMMANDS } from "../../common/electron-commands";
|
||||||
import { getMainWindow } from "../main-window";
|
import { getMainWindow } from "../main-window";
|
||||||
import {
|
import {
|
||||||
savedCustomModelsPath,
|
savedCustomModelsPath,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import fs from "fs";
|
import fs from "fs";
|
||||||
import { modelsPath } from "../utils/get-resource-paths";
|
import { modelsPath } from "../utils/get-resource-paths";
|
||||||
import { ELECTRON_COMMANDS } from "@common/electron-commands";
|
import { ELECTRON_COMMANDS } from "../../common/electron-commands";
|
||||||
import {
|
import {
|
||||||
savedCustomModelsPath,
|
savedCustomModelsPath,
|
||||||
setChildProcesses,
|
setChildProcesses,
|
||||||
@ -16,7 +16,7 @@ import { getMainWindow } from "../main-window";
|
|||||||
import { ImageUpscaylPayload } from "../../common/types/types";
|
import { ImageUpscaylPayload } from "../../common/types/types";
|
||||||
import { ImageFormat } from "../types/types";
|
import { ImageFormat } from "../types/types";
|
||||||
import showNotification from "../utils/show-notification";
|
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 getFilenameFromPath from "../../common/get-file-name";
|
||||||
import decodePath from "../../common/decode-path";
|
import decodePath from "../../common/decode-path";
|
||||||
import getDirectoryFromPath from "../../common/get-directory-from-path";
|
import getDirectoryFromPath from "../../common/get-directory-from-path";
|
||||||
@ -55,7 +55,7 @@ const imageUpscayl = async (event, payload: ImageUpscaylPayload) => {
|
|||||||
"." +
|
"." +
|
||||||
saveImageAs;
|
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
|
// Check if windows can write the new filename to the file system
|
||||||
if (outFile.length >= 255) {
|
if (outFile.length >= 255) {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import log from "electron-log";
|
import log from "electron-log";
|
||||||
import { ELECTRON_COMMANDS } from "@common/electron-commands";
|
|
||||||
import { getMainWindow } from "../main-window";
|
import { getMainWindow } from "../main-window";
|
||||||
|
import { ELECTRON_COMMANDS } from "../../common/electron-commands";
|
||||||
|
|
||||||
const logit = (...args: any) => {
|
const logit = (...args: any) => {
|
||||||
const mainWindow = getMainWindow();
|
const mainWindow = getMainWindow();
|
||||||
|
@ -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
|
|
173
package-lock.json
generated
173
package-lock.json
generated
@ -11,6 +11,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@radix-ui/react-dialog": "^1.0.5",
|
"@radix-ui/react-dialog": "^1.0.5",
|
||||||
"@radix-ui/react-popover": "^1.0.7",
|
"@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-slot": "^1.0.2",
|
||||||
"@radix-ui/react-toast": "^1.1.5",
|
"@radix-ui/react-toast": "^1.1.5",
|
||||||
"class-variance-authority": "^0.7.0",
|
"class-variance-authority": "^0.7.0",
|
||||||
@ -1739,6 +1740,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz",
|
||||||
"integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw=="
|
"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": {
|
"node_modules/@radix-ui/primitive": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.0.1.tgz",
|
"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": {
|
"node_modules/@radix-ui/react-dismissable-layer": {
|
||||||
"version": "1.0.5",
|
"version": "1.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.0.5.tgz",
|
"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": {
|
"node_modules/@radix-ui/react-slot": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.0.2.tgz",
|
||||||
|
@ -225,6 +225,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@radix-ui/react-dialog": "^1.0.5",
|
"@radix-ui/react-dialog": "^1.0.5",
|
||||||
"@radix-ui/react-popover": "^1.0.7",
|
"@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-slot": "^1.0.2",
|
||||||
"@radix-ui/react-toast": "^1.1.5",
|
"@radix-ui/react-toast": "^1.1.5",
|
||||||
"class-variance-authority": "^0.7.0",
|
"class-variance-authority": "^0.7.0",
|
||||||
|
@ -1,9 +1,3 @@
|
|||||||
import { defaultModelsList } from "@common/models-list";
|
|
||||||
import { atom } from "jotai";
|
import { atom } from "jotai";
|
||||||
|
|
||||||
export type TModelsList = {
|
export const customModelIdsAtom = atom([] as string[]);
|
||||||
label: string;
|
|
||||||
value: string;
|
|
||||||
}[];
|
|
||||||
|
|
||||||
export const modelsListAtom = atom<TModelsList>(defaultModelsList);
|
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import { ImageFormat } from "@/lib/valid-formats";
|
||||||
|
import { ModelId } from "@common/models-list";
|
||||||
import { atom } from "jotai";
|
import { atom } from "jotai";
|
||||||
import { atomWithStorage } from "jotai/utils";
|
import { atomWithStorage } from "jotai/utils";
|
||||||
|
|
||||||
@ -6,6 +8,17 @@ export const customModelsPathAtom = atomWithStorage<string | null>(
|
|||||||
null,
|
null,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export const selectedModelIdAtom = atomWithStorage<ModelId | string>(
|
||||||
|
"selectedModelId",
|
||||||
|
"realesrgan-x4plus",
|
||||||
|
);
|
||||||
|
export const doubleUpscaylAtom = atomWithStorage("selectedModelId", false);
|
||||||
|
export const gpuIdAtom = atomWithStorage("gpuId", "");
|
||||||
|
export const saveImageAsAtom = atomWithStorage<ImageFormat>(
|
||||||
|
"saveImageAs",
|
||||||
|
"png",
|
||||||
|
);
|
||||||
|
|
||||||
export const scaleAtom = atomWithStorage<string>("scale", "4");
|
export const scaleAtom = atomWithStorage<string>("scale", "4");
|
||||||
|
|
||||||
export const batchModeAtom = atom<boolean>(false);
|
export const batchModeAtom = atom<boolean>(false);
|
||||||
|
@ -15,7 +15,7 @@ import { useToast } from "@/components/ui/use-toast";
|
|||||||
import { sanitizePath } from "@common/sanitize-path";
|
import { sanitizePath } from "@common/sanitize-path";
|
||||||
import getDirectoryFromPath from "@common/get-directory-from-path";
|
import getDirectoryFromPath from "@common/get-directory-from-path";
|
||||||
import { FEATURE_FLAGS } from "@common/feature-flags";
|
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 ProgressBar from "./progress-bar";
|
||||||
import InstructionsCard from "./instructions-card";
|
import InstructionsCard from "./instructions-card";
|
||||||
import ImageViewSettings from "./image-view-settings";
|
import ImageViewSettings from "./image-view-settings";
|
||||||
@ -176,12 +176,12 @@ const MainContent = ({
|
|||||||
}
|
}
|
||||||
const type = items[0].type;
|
const type = items[0].type;
|
||||||
const filePath = files[0].path;
|
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 }));
|
logit("📋 Pasted file: ", JSON.stringify({ type, filePath, extension }));
|
||||||
if (
|
if (!type.includes("image") && !VALID_IMAGE_FORMATS.includes(extension)) {
|
||||||
!type.includes("image") &&
|
|
||||||
!VALID_IMAGE_FORMATS.includes(extension.toLowerCase())
|
|
||||||
) {
|
|
||||||
toast({
|
toast({
|
||||||
title: t("ERRORS.INVALID_IMAGE_ERROR.TITLE"),
|
title: t("ERRORS.INVALID_IMAGE_ERROR.TITLE"),
|
||||||
description: t("ERRORS.INVALID_IMAGE_ERROR.ADDITIONAL_DESCRIPTION"),
|
description: t("ERRORS.INVALID_IMAGE_ERROR.ADDITIONAL_DESCRIPTION"),
|
||||||
|
@ -14,6 +14,10 @@ import {
|
|||||||
useCustomWidthAtom,
|
useCustomWidthAtom,
|
||||||
tileSizeAtom,
|
tileSizeAtom,
|
||||||
showSidebarAtom,
|
showSidebarAtom,
|
||||||
|
selectedModelIdAtom,
|
||||||
|
doubleUpscaylAtom,
|
||||||
|
gpuIdAtom,
|
||||||
|
saveImageAsAtom,
|
||||||
} from "../../atoms/user-settings-atom";
|
} from "../../atoms/user-settings-atom";
|
||||||
import useLogger from "../hooks/use-logger";
|
import useLogger from "../hooks/use-logger";
|
||||||
import {
|
import {
|
||||||
@ -63,16 +67,16 @@ const Sidebar = ({
|
|||||||
|
|
||||||
// LOCAL STATES
|
// LOCAL STATES
|
||||||
// TODO: Add electron handler for os
|
// TODO: Add electron handler for os
|
||||||
const [model, setModel] = useState("realesrgan-x4plus");
|
const [selectedModelId, setSelectedModelId] = useAtom(selectedModelIdAtom);
|
||||||
const [doubleUpscayl, setDoubleUpscayl] = useState(false);
|
const [doubleUpscayl, setDoubleUpscayl] = useAtom(doubleUpscaylAtom);
|
||||||
const overwrite = useAtomValue(overwriteAtom);
|
const [gpuId, setGpuId] = useAtom(gpuIdAtom);
|
||||||
const [gpuId, setGpuId] = useState("");
|
const [saveImageAs, setSaveImageAs] = useAtom(saveImageAsAtom);
|
||||||
const [saveImageAs, setSaveImageAs] = useState("png");
|
|
||||||
|
|
||||||
const [selectedTab, setSelectedTab] = useState(0);
|
const [selectedTab, setSelectedTab] = useState(0);
|
||||||
const [showCloudModal, setShowCloudModal] = useState(false);
|
const [showCloudModal, setShowCloudModal] = useState(false);
|
||||||
|
|
||||||
// ATOMIC STATES
|
// ATOMIC STATES
|
||||||
|
const overwrite = useAtomValue(overwriteAtom);
|
||||||
const outputPath = useAtomValue(savedOutputPathAtom);
|
const outputPath = useAtomValue(savedOutputPathAtom);
|
||||||
const [compression, setCompression] = useAtom(compressionAtom);
|
const [compression, setCompression] = useAtom(compressionAtom);
|
||||||
const setProgress = useSetAtom(progressAtom);
|
const setProgress = useSetAtom(progressAtom);
|
||||||
@ -87,7 +91,7 @@ const Sidebar = ({
|
|||||||
const [showSidebar, setShowSidebar] = useAtom(showSidebarAtom);
|
const [showSidebar, setShowSidebar] = useAtom(showSidebarAtom);
|
||||||
|
|
||||||
const handleModelChange = (e: any) => {
|
const handleModelChange = (e: any) => {
|
||||||
setModel(e.value);
|
setSelectedModelId(e.value);
|
||||||
logit("🔀 Model changed: ", e.value);
|
logit("🔀 Model changed: ", e.value);
|
||||||
localStorage.setItem(
|
localStorage.setItem(
|
||||||
"model",
|
"model",
|
||||||
@ -108,7 +112,7 @@ const Sidebar = ({
|
|||||||
{
|
{
|
||||||
imagePath,
|
imagePath,
|
||||||
outputPath,
|
outputPath,
|
||||||
model,
|
model: selectedModelId,
|
||||||
gpuId: gpuId.length === 0 ? null : gpuId,
|
gpuId: gpuId.length === 0 ? null : gpuId,
|
||||||
saveImageAs,
|
saveImageAs,
|
||||||
scale,
|
scale,
|
||||||
@ -128,7 +132,7 @@ const Sidebar = ({
|
|||||||
{
|
{
|
||||||
batchFolderPath,
|
batchFolderPath,
|
||||||
outputPath,
|
outputPath,
|
||||||
model,
|
model: selectedModelId,
|
||||||
gpuId: gpuId.length === 0 ? null : gpuId,
|
gpuId: gpuId.length === 0 ? null : gpuId,
|
||||||
saveImageAs,
|
saveImageAs,
|
||||||
scale,
|
scale,
|
||||||
@ -145,7 +149,7 @@ const Sidebar = ({
|
|||||||
window.electron.send<ImageUpscaylPayload>(ELECTRON_COMMANDS.UPSCAYL, {
|
window.electron.send<ImageUpscaylPayload>(ELECTRON_COMMANDS.UPSCAYL, {
|
||||||
imagePath,
|
imagePath,
|
||||||
outputPath,
|
outputPath,
|
||||||
model,
|
model: selectedModelId,
|
||||||
gpuId: gpuId.length === 0 ? null : gpuId,
|
gpuId: gpuId.length === 0 ? null : gpuId,
|
||||||
saveImageAs,
|
saveImageAs,
|
||||||
scale,
|
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"}`}
|
className={`relative flex h-screen min-w-[350px] max-w-[350px] flex-col bg-base-100 ${showSidebar ? "" : "hidden"}`}
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
className="absolute -right-0 top-1/2 z-[999] -translate-y-1/2 translate-x-1/2 rounded-full bg-base-100 p-4"
|
className="absolute -right-0 top-1/2 z-50 -translate-y-1/2 translate-x-1/2 rounded-full bg-base-100 p-4"
|
||||||
onClick={() => setShowSidebar((prev) => !prev)}
|
onClick={() => setShowSidebar((prev) => !prev)}
|
||||||
>
|
>
|
||||||
<ChevronLeftIcon />
|
<ChevronLeftIcon />
|
||||||
@ -201,7 +205,6 @@ const Sidebar = ({
|
|||||||
<UpscaylSteps
|
<UpscaylSteps
|
||||||
selectImageHandler={selectImageHandler}
|
selectImageHandler={selectImageHandler}
|
||||||
selectFolderHandler={selectFolderHandler}
|
selectFolderHandler={selectFolderHandler}
|
||||||
handleModelChange={handleModelChange}
|
|
||||||
upscaylHandler={upscaylHandler}
|
upscaylHandler={upscaylHandler}
|
||||||
batchMode={batchMode}
|
batchMode={batchMode}
|
||||||
setBatchMode={setBatchMode}
|
setBatchMode={setBatchMode}
|
||||||
@ -210,8 +213,6 @@ const Sidebar = ({
|
|||||||
setDoubleUpscayl={setDoubleUpscayl}
|
setDoubleUpscayl={setDoubleUpscayl}
|
||||||
dimensions={dimensions}
|
dimensions={dimensions}
|
||||||
setGpuId={setGpuId}
|
setGpuId={setGpuId}
|
||||||
model={model}
|
|
||||||
setModel={setModel}
|
|
||||||
setSaveImageAs={setSaveImageAs}
|
setSaveImageAs={setSaveImageAs}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
@ -219,7 +220,6 @@ const Sidebar = ({
|
|||||||
{selectedTab === 1 && (
|
{selectedTab === 1 && (
|
||||||
<SettingsTab
|
<SettingsTab
|
||||||
batchMode={batchMode}
|
batchMode={batchMode}
|
||||||
setModel={setModel}
|
|
||||||
compression={compression}
|
compression={compression}
|
||||||
setCompression={setCompression}
|
setCompression={setCompression}
|
||||||
gpuId={gpuId}
|
gpuId={gpuId}
|
||||||
|
@ -10,7 +10,7 @@ import React, { useEffect, useState } from "react";
|
|||||||
import { themeChange } from "theme-change";
|
import { themeChange } from "theme-change";
|
||||||
import { useAtom, useAtomValue } from "jotai";
|
import { useAtom, useAtomValue } from "jotai";
|
||||||
import { customModelsPathAtom, scaleAtom } from "@/atoms/user-settings-atom";
|
import { customModelsPathAtom, scaleAtom } from "@/atoms/user-settings-atom";
|
||||||
import { modelsListAtom } from "@/atoms/models-list-atom";
|
import { customModelIdsAtom } from "@/atoms/models-list-atom";
|
||||||
import useLogger from "@/components/hooks/use-logger";
|
import useLogger from "@/components/hooks/use-logger";
|
||||||
import { InputCompression } from "./input-compression";
|
import { InputCompression } from "./input-compression";
|
||||||
import OverwriteToggle from "./overwrite-toggle";
|
import OverwriteToggle from "./overwrite-toggle";
|
||||||
@ -23,12 +23,12 @@ import { InputCustomResolution } from "./input-custom-resolution";
|
|||||||
import { InputTileSize } from "./input-tile-size";
|
import { InputTileSize } from "./input-tile-size";
|
||||||
import LanguageSwitcher from "./language-switcher";
|
import LanguageSwitcher from "./language-switcher";
|
||||||
import { translationAtom } from "@/atoms/translations-atom";
|
import { translationAtom } from "@/atoms/translations-atom";
|
||||||
|
import { ImageFormat } from "@/lib/valid-formats";
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
batchMode: boolean;
|
batchMode: boolean;
|
||||||
setModel: React.Dispatch<React.SetStateAction<string>>;
|
saveImageAs: ImageFormat;
|
||||||
saveImageAs: string;
|
setSaveImageAs: React.Dispatch<React.SetStateAction<ImageFormat>>;
|
||||||
setSaveImageAs: React.Dispatch<React.SetStateAction<string>>;
|
|
||||||
compression: number;
|
compression: number;
|
||||||
setCompression: React.Dispatch<React.SetStateAction<number>>;
|
setCompression: React.Dispatch<React.SetStateAction<number>>;
|
||||||
gpuId: string;
|
gpuId: string;
|
||||||
@ -41,7 +41,6 @@ interface IProps {
|
|||||||
|
|
||||||
function SettingsTab({
|
function SettingsTab({
|
||||||
batchMode,
|
batchMode,
|
||||||
setModel,
|
|
||||||
compression,
|
compression,
|
||||||
setCompression,
|
setCompression,
|
||||||
gpuId,
|
gpuId,
|
||||||
@ -49,7 +48,6 @@ function SettingsTab({
|
|||||||
saveImageAs,
|
saveImageAs,
|
||||||
setSaveImageAs,
|
setSaveImageAs,
|
||||||
logData,
|
logData,
|
||||||
|
|
||||||
show,
|
show,
|
||||||
setShow,
|
setShow,
|
||||||
setDontShowCloudModal,
|
setDontShowCloudModal,
|
||||||
@ -57,65 +55,17 @@ function SettingsTab({
|
|||||||
const [isCopied, setIsCopied] = useState(false);
|
const [isCopied, setIsCopied] = useState(false);
|
||||||
|
|
||||||
const [customModelsPath, setCustomModelsPath] = useAtom(customModelsPathAtom);
|
const [customModelsPath, setCustomModelsPath] = useAtom(customModelsPathAtom);
|
||||||
const modelOptions = useAtomValue(modelsListAtom);
|
|
||||||
const [scale, setScale] = useAtom(scaleAtom);
|
const [scale, setScale] = useAtom(scaleAtom);
|
||||||
const [enableScrollbar, setEnableScrollbar] = useState(true);
|
const [enableScrollbar, setEnableScrollbar] = useState(true);
|
||||||
const [timeoutId, setTimeoutId] = useState(null);
|
const [timeoutId, setTimeoutId] = useState(null);
|
||||||
const t = useAtomValue(translationAtom);
|
const t = useAtomValue(translationAtom);
|
||||||
|
|
||||||
const logit = useLogger();
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
themeChange(false);
|
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")) {
|
|
||||||
setModel(modelOptions[0].value);
|
|
||||||
localStorage.setItem("model", JSON.stringify(modelOptions[0]));
|
|
||||||
logit("🔀 Setting model to", modelOptions[0].value);
|
|
||||||
} else {
|
|
||||||
let currentlySavedModel = JSON.parse(
|
|
||||||
localStorage.getItem("model"),
|
|
||||||
) as (typeof modelOptions)[0];
|
|
||||||
if (
|
|
||||||
modelOptions.find(
|
|
||||||
(model) => model.value === currentlySavedModel.value,
|
|
||||||
) === undefined
|
|
||||||
) {
|
|
||||||
localStorage.setItem("model", JSON.stringify(modelOptions[0]));
|
|
||||||
logit("🔀 Setting model to", modelOptions[0].value);
|
|
||||||
currentlySavedModel = modelOptions[0];
|
|
||||||
}
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
// HANDLERS
|
// HANDLERS
|
||||||
const setExportType = (format: string) => {
|
const setExportType = (format: ImageFormat) => {
|
||||||
setSaveImageAs(format);
|
setSaveImageAs(format);
|
||||||
localStorage.setItem("saveImageAs", format);
|
localStorage.setItem("saveImageAs", format);
|
||||||
};
|
};
|
||||||
|
@ -12,7 +12,7 @@ const SidebarToggleButton = ({
|
|||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
className={cn(
|
className={cn(
|
||||||
"fixed left-0 top-1/2 z-[999] -translate-y-1/2 rounded-r-full bg-base-100 p-4 ",
|
"fixed left-0 top-1/2 z-50 -translate-y-1/2 rounded-r-full bg-base-100 p-4 ",
|
||||||
showSidebar ? "hidden" : "",
|
showSidebar ? "hidden" : "",
|
||||||
)}
|
)}
|
||||||
onClick={() => setShowSidebar((prev) => !prev)}
|
onClick={() => setShowSidebar((prev) => !prev)}
|
||||||
|
158
renderer/components/sidebar/upscayl-tab/select-model.tsx
Normal file
158
renderer/components/sidebar/upscayl-tab/select-model.tsx
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
"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";
|
||||||
|
|
||||||
|
export default function SelectModel() {
|
||||||
|
const [selectedModelId, setSelectedModelId] = useAtom(selectedModelIdAtom);
|
||||||
|
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);
|
||||||
|
};
|
||||||
|
|
||||||
|
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" />
|
||||||
|
{MODELS[selectedModelId]?.name || selectedModelId}
|
||||||
|
</button>
|
||||||
|
</DialogTrigger>
|
||||||
|
<DialogContent className="z-50 sm:max-w-lg">
|
||||||
|
<DialogHeader>
|
||||||
|
<DialogTitle>Select AI Model</DialogTitle>
|
||||||
|
</DialogHeader>
|
||||||
|
<ScrollArea className="max-h-[600px] pr-4">
|
||||||
|
<div className="grid gap-4">
|
||||||
|
{Object.entries(MODELS).map((modelData) => {
|
||||||
|
const modelId = modelData[0] as ModelId;
|
||||||
|
const model = modelData[1];
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
key={modelId}
|
||||||
|
variant="outline"
|
||||||
|
className="h-auto w-full flex-col items-start p-4"
|
||||||
|
onClick={() => handleModelSelect(modelId)}
|
||||||
|
>
|
||||||
|
<div className="mb-2 font-semibold">{model.name}</div>
|
||||||
|
<div className="relative h-52 w-full overflow-hidden rounded-md">
|
||||||
|
<div className="flex h-full w-full">
|
||||||
|
<img
|
||||||
|
src={`/model-comparison/${model.name}/before.webp`}
|
||||||
|
alt={`${model.name} Before`}
|
||||||
|
className="h-full w-1/2 object-cover"
|
||||||
|
/>
|
||||||
|
<img
|
||||||
|
src={`/model-comparison/${model.id}/after.webp`}
|
||||||
|
alt={`${model.name} After`}
|
||||||
|
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">
|
||||||
|
Before
|
||||||
|
</div>
|
||||||
|
<div className="absolute bottom-2 right-2 rounded bg-black bg-opacity-50 px-1 text-xs text-white">
|
||||||
|
After
|
||||||
|
</div>
|
||||||
|
<Button
|
||||||
|
variant="secondary"
|
||||||
|
size="icon"
|
||||||
|
className="absolute right-2 top-2"
|
||||||
|
onClick={(e) => handleZoom(e, modelId)}
|
||||||
|
>
|
||||||
|
<Maximize2 className="h-4 w-4" />
|
||||||
|
<span className="sr-only">Zoom</span>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
{customModelIds.map((customModel) => {
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
key={customModel}
|
||||||
|
variant="outline"
|
||||||
|
className="h-auto w-full flex-col items-start p-4"
|
||||||
|
onClick={() => handleModelSelect(customModel)}
|
||||||
|
>
|
||||||
|
{customModel}
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</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
|
||||||
|
src={`/model-comparison/${MODELS[zoomedModel]?.id}/before.webp`}
|
||||||
|
alt={`${MODELS[zoomedModel]?.name} Before`}
|
||||||
|
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
|
||||||
|
src={`/model-comparison/${MODELS[zoomedModel]?.id}/after.webp`}
|
||||||
|
alt={`${MODELS[zoomedModel]?.name} After`}
|
||||||
|
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>
|
||||||
|
<Button
|
||||||
|
variant="secondary"
|
||||||
|
size="icon"
|
||||||
|
className="absolute right-4 top-4"
|
||||||
|
onClick={() => setZoomedModel(null)}
|
||||||
|
>
|
||||||
|
<X className="h-4 w-4" />
|
||||||
|
<span className="sr-only">Close</span>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</DialogContent>
|
||||||
|
</Dialog>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
@ -1,8 +1,7 @@
|
|||||||
import { useAtom, useAtomValue } from "jotai";
|
import { useAtom, useAtomValue } from "jotai";
|
||||||
import React, { useEffect, useMemo, useState } from "react";
|
import React, { useEffect, useMemo } from "react";
|
||||||
import { Tooltip } from "react-tooltip";
|
import { Tooltip } from "react-tooltip";
|
||||||
import { themeChange } from "theme-change";
|
import { themeChange } from "theme-change";
|
||||||
import { TModelsList, modelsListAtom } from "../../../atoms/models-list-atom";
|
|
||||||
import useLogger from "../../hooks/use-logger";
|
import useLogger from "../../hooks/use-logger";
|
||||||
import {
|
import {
|
||||||
savedOutputPathAtom,
|
savedOutputPathAtom,
|
||||||
@ -14,16 +13,15 @@ import {
|
|||||||
} from "../../../atoms/user-settings-atom";
|
} from "../../../atoms/user-settings-atom";
|
||||||
import { FEATURE_FLAGS } from "@common/feature-flags";
|
import { FEATURE_FLAGS } from "@common/feature-flags";
|
||||||
import { ELECTRON_COMMANDS } from "@common/electron-commands";
|
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 { useToast } from "@/components/ui/use-toast";
|
||||||
import { translationAtom } from "@/atoms/translations-atom";
|
import { translationAtom } from "@/atoms/translations-atom";
|
||||||
import { SelectImageScale } from "../settings-tab/select-image-scale";
|
import { SelectImageScale } from "../settings-tab/select-image-scale";
|
||||||
|
import SelectModel from "./select-model";
|
||||||
|
import { ImageFormat } from "@/lib/valid-formats";
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
selectImageHandler: () => Promise<void>;
|
selectImageHandler: () => Promise<void>;
|
||||||
selectFolderHandler: () => Promise<void>;
|
selectFolderHandler: () => Promise<void>;
|
||||||
handleModelChange: (e: any) => void;
|
|
||||||
upscaylHandler: () => Promise<void>;
|
upscaylHandler: () => Promise<void>;
|
||||||
batchMode: boolean;
|
batchMode: boolean;
|
||||||
setBatchMode: React.Dispatch<React.SetStateAction<boolean>>;
|
setBatchMode: React.Dispatch<React.SetStateAction<boolean>>;
|
||||||
@ -34,16 +32,13 @@ interface IProps {
|
|||||||
width: number | null;
|
width: number | null;
|
||||||
height: number | null;
|
height: number | null;
|
||||||
};
|
};
|
||||||
setSaveImageAs: React.Dispatch<React.SetStateAction<string>>;
|
setSaveImageAs: React.Dispatch<React.SetStateAction<ImageFormat>>;
|
||||||
model: string;
|
|
||||||
setModel: React.Dispatch<React.SetStateAction<string>>;
|
|
||||||
setGpuId: React.Dispatch<React.SetStateAction<string>>;
|
setGpuId: React.Dispatch<React.SetStateAction<string>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
function UpscaylSteps({
|
function UpscaylSteps({
|
||||||
selectImageHandler,
|
selectImageHandler,
|
||||||
selectFolderHandler,
|
selectFolderHandler,
|
||||||
handleModelChange,
|
|
||||||
upscaylHandler,
|
upscaylHandler,
|
||||||
batchMode,
|
batchMode,
|
||||||
setBatchMode,
|
setBatchMode,
|
||||||
@ -51,22 +46,11 @@ function UpscaylSteps({
|
|||||||
doubleUpscayl,
|
doubleUpscayl,
|
||||||
setDoubleUpscayl,
|
setDoubleUpscayl,
|
||||||
dimensions,
|
dimensions,
|
||||||
setSaveImageAs,
|
|
||||||
model,
|
|
||||||
setModel,
|
|
||||||
setGpuId,
|
|
||||||
}: IProps) {
|
}: IProps) {
|
||||||
const [currentModel, setCurrentModel] = useState<TModelsList[0]>({
|
|
||||||
label: null,
|
|
||||||
value: null,
|
|
||||||
});
|
|
||||||
|
|
||||||
const modelOptions = useAtomValue(modelsListAtom);
|
|
||||||
const [scale, setScale] = useAtom(scaleAtom);
|
const [scale, setScale] = useAtom(scaleAtom);
|
||||||
const [outputPath, setOutputPath] = useAtom(savedOutputPathAtom);
|
const [outputPath, setOutputPath] = useAtom(savedOutputPathAtom);
|
||||||
const [progress, setProgress] = useAtom(progressAtom);
|
const [progress, setProgress] = useAtom(progressAtom);
|
||||||
const rememberOutputFolder = useAtomValue(rememberOutputFolderAtom);
|
const rememberOutputFolder = useAtomValue(rememberOutputFolderAtom);
|
||||||
const [open, setOpen] = React.useState(false);
|
|
||||||
const customWidth = useAtomValue(customWidthAtom);
|
const customWidth = useAtomValue(customWidthAtom);
|
||||||
const useCustomWidth = useAtomValue(useCustomWidthAtom);
|
const useCustomWidth = useAtomValue(useCustomWidthAtom);
|
||||||
|
|
||||||
@ -86,50 +70,8 @@ function UpscaylSteps({
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
themeChange(false);
|
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 upscaylResolution = useMemo(() => {
|
||||||
const newDimensions = {
|
const newDimensions = {
|
||||||
width: dimensions.width,
|
width: dimensions.width,
|
||||||
@ -214,25 +156,7 @@ function UpscaylSteps({
|
|||||||
<p className="step-heading">{t("APP.MODEL_SELECTION.TITLE")}</p>
|
<p className="step-heading">{t("APP.MODEL_SELECTION.TITLE")}</p>
|
||||||
<p className="mb-2 text-sm">{t("APP.MODEL_SELECTION.DESCRIPTION")}</p>
|
<p className="mb-2 text-sm">{t("APP.MODEL_SELECTION.DESCRIPTION")}</p>
|
||||||
|
|
||||||
<Select
|
<SelectModel />
|
||||||
onMenuOpen={() => setOpen(true)}
|
|
||||||
onMenuClose={() => setOpen(false)}
|
|
||||||
options={modelOptions}
|
|
||||||
components={{
|
|
||||||
IndicatorSeparator: () => null,
|
|
||||||
DropdownIndicator: () => null,
|
|
||||||
}}
|
|
||||||
onChange={(e) => {
|
|
||||||
handleModelChange(e);
|
|
||||||
setCurrentModel({ label: e.label, value: e.value });
|
|
||||||
}}
|
|
||||||
className={cn(
|
|
||||||
"react-select-container transition-all group-hover:w-full group-active:w-full focus:w-full",
|
|
||||||
open && "!w-full",
|
|
||||||
)}
|
|
||||||
classNamePrefix="react-select"
|
|
||||||
value={currentModel}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{!batchMode && (
|
{!batchMode && (
|
||||||
|
@ -4,8 +4,7 @@ import { X } from "lucide-react";
|
|||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
import { useAtomValue } from "jotai";
|
import { useAtomValue } from "jotai";
|
||||||
import { translationAtom } from "@/atoms/translations-atom";
|
import { translationAtom } from "@/atoms/translations-atom";
|
||||||
|
import useTranslation from "../hooks/use-translation";
|
||||||
const t = useAtomValue(translationAtom);
|
|
||||||
|
|
||||||
const Dialog = DialogPrimitive.Root;
|
const Dialog = DialogPrimitive.Root;
|
||||||
|
|
||||||
@ -32,26 +31,32 @@ DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
|
|||||||
|
|
||||||
const DialogContent = React.forwardRef<
|
const DialogContent = React.forwardRef<
|
||||||
React.ElementRef<typeof DialogPrimitive.Content>,
|
React.ElementRef<typeof DialogPrimitive.Content>,
|
||||||
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>
|
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content> & {
|
||||||
>(({ className, children, ...props }, ref) => (
|
hideCloseButton?: boolean;
|
||||||
<DialogPortal>
|
}
|
||||||
<DialogOverlay />
|
>(({ className, children, ...props }, ref) => {
|
||||||
<DialogPrimitive.Content
|
const t = useTranslation();
|
||||||
ref={ref}
|
|
||||||
className={cn(
|
return (
|
||||||
"fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",
|
<DialogPortal>
|
||||||
className,
|
<DialogOverlay />
|
||||||
)}
|
<DialogPrimitive.Content
|
||||||
{...props}
|
ref={ref}
|
||||||
>
|
className={cn(
|
||||||
{children}
|
"fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",
|
||||||
<DialogPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity data-[state=open]:bg-accent data-[state=open]:text-muted-foreground hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none">
|
className,
|
||||||
<X className="h-4 w-4" />
|
)}
|
||||||
<span className="sr-only">{t("APP.DIALOG_BOX.CLOSE")}</span>
|
{...props}
|
||||||
</DialogPrimitive.Close>
|
>
|
||||||
</DialogPrimitive.Content>
|
{children}
|
||||||
</DialogPortal>
|
<DialogPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity data-[state=open]:bg-accent data-[state=open]:text-muted-foreground hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none">
|
||||||
));
|
<X className="h-4 w-4" />
|
||||||
|
<span className="sr-only">{t("APP.DIALOG_BOX.CLOSE")}</span>
|
||||||
|
</DialogPrimitive.Close>
|
||||||
|
</DialogPrimitive.Content>
|
||||||
|
</DialogPortal>
|
||||||
|
);
|
||||||
|
});
|
||||||
DialogContent.displayName = DialogPrimitive.Content.displayName;
|
DialogContent.displayName = DialogPrimitive.Content.displayName;
|
||||||
|
|
||||||
const DialogHeader = ({
|
const DialogHeader = ({
|
||||||
|
46
renderer/components/ui/scroll-area.tsx
Normal file
46
renderer/components/ui/scroll-area.tsx
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
import * as React from "react"
|
||||||
|
import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area"
|
||||||
|
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
const ScrollArea = React.forwardRef<
|
||||||
|
React.ElementRef<typeof ScrollAreaPrimitive.Root>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.Root>
|
||||||
|
>(({ className, children, ...props }, ref) => (
|
||||||
|
<ScrollAreaPrimitive.Root
|
||||||
|
ref={ref}
|
||||||
|
className={cn("relative overflow-hidden", className)}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<ScrollAreaPrimitive.Viewport className="h-full w-full rounded-[inherit]">
|
||||||
|
{children}
|
||||||
|
</ScrollAreaPrimitive.Viewport>
|
||||||
|
<ScrollBar />
|
||||||
|
<ScrollAreaPrimitive.Corner />
|
||||||
|
</ScrollAreaPrimitive.Root>
|
||||||
|
))
|
||||||
|
ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName
|
||||||
|
|
||||||
|
const ScrollBar = React.forwardRef<
|
||||||
|
React.ElementRef<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>
|
||||||
|
>(({ className, orientation = "vertical", ...props }, ref) => (
|
||||||
|
<ScrollAreaPrimitive.ScrollAreaScrollbar
|
||||||
|
ref={ref}
|
||||||
|
orientation={orientation}
|
||||||
|
className={cn(
|
||||||
|
"flex touch-none select-none transition-colors",
|
||||||
|
orientation === "vertical" &&
|
||||||
|
"h-full w-2.5 border-l border-l-transparent p-[1px]",
|
||||||
|
orientation === "horizontal" &&
|
||||||
|
"h-2.5 flex-col border-t border-t-transparent p-[1px]",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<ScrollAreaPrimitive.ScrollAreaThumb className="relative flex-1 rounded-full bg-border" />
|
||||||
|
</ScrollAreaPrimitive.ScrollAreaScrollbar>
|
||||||
|
))
|
||||||
|
ScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName
|
||||||
|
|
||||||
|
export { ScrollArea, ScrollBar }
|
@ -1 +1,9 @@
|
|||||||
export const VALID_IMAGE_FORMATS = ["png", "jpg", "jpeg", "jfif", "webp"];
|
export const VALID_IMAGE_FORMATS = [
|
||||||
|
"png",
|
||||||
|
"jpg",
|
||||||
|
"jpeg",
|
||||||
|
"jfif",
|
||||||
|
"webp",
|
||||||
|
] as const;
|
||||||
|
|
||||||
|
export type ImageFormat = (typeof VALID_IMAGE_FORMATS)[number];
|
||||||
|
2
renderer/next-env.d.ts
vendored
2
renderer/next-env.d.ts
vendored
@ -2,4 +2,4 @@
|
|||||||
/// <reference types="next/image-types/global" />
|
/// <reference types="next/image-types/global" />
|
||||||
|
|
||||||
// NOTE: This file should not be edited
|
// NOTE: This file should not be edited
|
||||||
// see https://nextjs.org/docs/basic-features/typescript for more information.
|
// see https://nextjs.org/docs/pages/building-your-application/configuring/typescript for more information.
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
"use client";
|
"use client";
|
||||||
import { useState, useEffect } from "react";
|
import { useState, useEffect } from "react";
|
||||||
import { ELECTRON_COMMANDS } from "@common/electron-commands";
|
import { ELECTRON_COMMANDS } from "@common/electron-commands";
|
||||||
import { useAtom, useAtomValue, useSetAtom } from "jotai";
|
import { useAtomValue, useSetAtom } from "jotai";
|
||||||
import { modelsListAtom } from "../atoms/models-list-atom";
|
import { customModelIdsAtom } from "../atoms/models-list-atom";
|
||||||
import {
|
import {
|
||||||
batchModeAtom,
|
batchModeAtom,
|
||||||
savedOutputPathAtom,
|
savedOutputPathAtom,
|
||||||
@ -10,7 +10,6 @@ import {
|
|||||||
rememberOutputFolderAtom,
|
rememberOutputFolderAtom,
|
||||||
} from "../atoms/user-settings-atom";
|
} from "../atoms/user-settings-atom";
|
||||||
import useLogger from "../components/hooks/use-logger";
|
import useLogger from "../components/hooks/use-logger";
|
||||||
import { newsAtom, showNewsModalAtom } from "@/atoms/news-atom";
|
|
||||||
import { useToast } from "@/components/ui/use-toast";
|
import { useToast } from "@/components/ui/use-toast";
|
||||||
import { ToastAction } from "@/components/ui/toast";
|
import { ToastAction } from "@/components/ui/toast";
|
||||||
import UpscaylSVGLogo from "@/components/icons/upscayl-logo-svg";
|
import UpscaylSVGLogo from "@/components/icons/upscayl-logo-svg";
|
||||||
@ -19,7 +18,7 @@ import Sidebar from "@/components/sidebar";
|
|||||||
import MainContent from "@/components/main-content";
|
import MainContent from "@/components/main-content";
|
||||||
import getDirectoryFromPath from "@common/get-directory-from-path";
|
import getDirectoryFromPath from "@common/get-directory-from-path";
|
||||||
import { FEATURE_FLAGS } from "@common/feature-flags";
|
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 { initCustomModels } from "@/components/hooks/use-custom-models";
|
import { initCustomModels } from "@/components/hooks/use-custom-models";
|
||||||
|
|
||||||
const Home = () => {
|
const Home = () => {
|
||||||
@ -30,7 +29,6 @@ const Home = () => {
|
|||||||
initCustomModels();
|
initCustomModels();
|
||||||
|
|
||||||
const [isLoading, setIsLoading] = useState(true);
|
const [isLoading, setIsLoading] = useState(true);
|
||||||
|
|
||||||
const [imagePath, setImagePath] = useState("");
|
const [imagePath, setImagePath] = useState("");
|
||||||
const [upscaledImagePath, setUpscaledImagePath] = useState("");
|
const [upscaledImagePath, setUpscaledImagePath] = useState("");
|
||||||
const [dimensions, setDimensions] = useState({
|
const [dimensions, setDimensions] = useState({
|
||||||
@ -39,18 +37,12 @@ const Home = () => {
|
|||||||
});
|
});
|
||||||
const setOutputPath = useSetAtom(savedOutputPathAtom);
|
const setOutputPath = useSetAtom(savedOutputPathAtom);
|
||||||
const rememberOutputFolder = useAtomValue(rememberOutputFolderAtom);
|
const rememberOutputFolder = useAtomValue(rememberOutputFolderAtom);
|
||||||
|
|
||||||
const batchMode = useAtomValue(batchModeAtom);
|
const batchMode = useAtomValue(batchModeAtom);
|
||||||
const [batchFolderPath, setBatchFolderPath] = useState("");
|
const [batchFolderPath, setBatchFolderPath] = useState("");
|
||||||
const [upscaledBatchFolderPath, setUpscaledBatchFolderPath] = useState("");
|
const [upscaledBatchFolderPath, setUpscaledBatchFolderPath] = useState("");
|
||||||
|
|
||||||
const setProgress = useSetAtom(progressAtom);
|
const setProgress = useSetAtom(progressAtom);
|
||||||
const [doubleUpscaylCounter, setDoubleUpscaylCounter] = useState(0);
|
const [doubleUpscaylCounter, setDoubleUpscaylCounter] = useState(0);
|
||||||
|
const setModelIds = useSetAtom(customModelIdsAtom);
|
||||||
const [modelOptions, setModelOptions] = useAtom(modelsListAtom);
|
|
||||||
|
|
||||||
const [news, setNews] = useAtom(newsAtom);
|
|
||||||
const [showNewsModal, setShowNewsModal] = useAtom(showNewsModalAtom);
|
|
||||||
|
|
||||||
const selectImageHandler = async () => {
|
const selectImageHandler = async () => {
|
||||||
resetImagePaths();
|
resetImagePaths();
|
||||||
@ -89,7 +81,7 @@ const Home = () => {
|
|||||||
const validateImagePath = (path: string) => {
|
const validateImagePath = (path: string) => {
|
||||||
if (path.length > 0) {
|
if (path.length > 0) {
|
||||||
logit("🖼 imagePath: ", path);
|
logit("🖼 imagePath: ", path);
|
||||||
const extension = path.split(".").pop().toLowerCase();
|
const extension = path.split(".").pop().toLowerCase() as ImageFormat;
|
||||||
logit("🔤 Extension: ", extension);
|
logit("🔤 Extension: ", extension);
|
||||||
if (!VALID_IMAGE_FORMATS.includes(extension)) {
|
if (!VALID_IMAGE_FORMATS.includes(extension)) {
|
||||||
toast({
|
toast({
|
||||||
@ -260,19 +252,8 @@ const Home = () => {
|
|||||||
ELECTRON_COMMANDS.CUSTOM_MODEL_FILES_LIST,
|
ELECTRON_COMMANDS.CUSTOM_MODEL_FILES_LIST,
|
||||||
(_, data: string[]) => {
|
(_, data: string[]) => {
|
||||||
logit(`📜 CUSTOM_MODEL_FILES_LIST: `, data);
|
logit(`📜 CUSTOM_MODEL_FILES_LIST: `, data);
|
||||||
const newModelOptions = data.map((model) => {
|
console.log("🚀 => data:", data);
|
||||||
return {
|
setModelIds(data);
|
||||||
value: model,
|
|
||||||
label: model,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
// Add newModelsList to modelOptions and remove duplicates
|
|
||||||
const modelMap = new Map();
|
|
||||||
[...modelOptions, ...newModelOptions].forEach((model) => {
|
|
||||||
modelMap.set(model.value, model);
|
|
||||||
});
|
|
||||||
const uniqueModelOptions = Array.from(modelMap.values());
|
|
||||||
setModelOptions(uniqueModelOptions);
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}, []);
|
}, []);
|
||||||
|
Loading…
Reference in New Issue
Block a user