1
0
mirror of https://github.com/upscayl/upscayl.git synced 2024-09-24 03:18:28 +02:00

Added tabs and logs

This commit is contained in:
Nayam Amarshe 2023-03-18 22:38:50 +05:30
parent 20ad827a8e
commit 9d9aed3dd9
6 changed files with 356 additions and 93 deletions

18
package-lock.json generated
View File

@ -10,7 +10,7 @@
"license": "AGPL-3.0",
"dependencies": {
"app-root-dir": "^1.0.2",
"daisyui": "^2.39.1",
"daisyui": "^2.51.4",
"electron-is-dev": "^2.0.0",
"electron-is-packaged": "^1.0.2",
"electron-next": "^3.1.5",
@ -2890,15 +2890,19 @@
"integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw=="
},
"node_modules/daisyui": {
"version": "2.39.1",
"resolved": "https://registry.npmjs.org/daisyui/-/daisyui-2.39.1.tgz",
"integrity": "sha512-J7goHjiQ6zk7irpKJ0HyElAuWF+x8iGoebQ1IfHM6BuvKoGSOcfZC/bedTultsX2Co5XARsE+qvE7BI1amUtsQ==",
"version": "2.51.4",
"resolved": "https://registry.npmjs.org/daisyui/-/daisyui-2.51.4.tgz",
"integrity": "sha512-TGYD2BQCduxkKbDALlaWWaUdi33tryUuO/MxxBtAmLJ9zKn04gF6xduMxbrAUesR4AFr6LZW187TqF2H5c1AoA==",
"dependencies": {
"color": "^4.2",
"css-selector-tokenizer": "^0.8.0",
"postcss-js": "^4.0.0",
"tailwindcss": "^3"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/daisyui"
},
"peerDependencies": {
"autoprefixer": "^10.0.2",
"postcss": "^8.1.6"
@ -9772,9 +9776,9 @@
"integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw=="
},
"daisyui": {
"version": "2.39.1",
"resolved": "https://registry.npmjs.org/daisyui/-/daisyui-2.39.1.tgz",
"integrity": "sha512-J7goHjiQ6zk7irpKJ0HyElAuWF+x8iGoebQ1IfHM6BuvKoGSOcfZC/bedTultsX2Co5XARsE+qvE7BI1amUtsQ==",
"version": "2.51.4",
"resolved": "https://registry.npmjs.org/daisyui/-/daisyui-2.51.4.tgz",
"integrity": "sha512-TGYD2BQCduxkKbDALlaWWaUdi33tryUuO/MxxBtAmLJ9zKn04gF6xduMxbrAUesR4AFr6LZW187TqF2H5c1AoA==",
"requires": {
"color": "^4.2",
"css-selector-tokenizer": "^0.8.0",

View File

@ -156,7 +156,7 @@
},
"dependencies": {
"app-root-dir": "^1.0.2",
"daisyui": "^2.39.1",
"daisyui": "^2.51.4",
"electron-is-dev": "^2.0.0",
"electron-is-packaged": "^1.0.2",
"electron-next": "^3.1.5",

View File

@ -280,87 +280,6 @@ function LeftPaneImageSteps({
disabled={progress.length > 0}>
{progress.length > 0 ? "Upscayling⏳" : "Upscayl"}
</button>
{/* ADVANCED OPTIONS */}
<div className="rounded-btn collapse mt-5">
<input type="checkbox" className="peer" />
{/* HEADER */}
<div className="collapse-title bg-neutral text-neutral-content peer-checked:bg-primary peer-checked:text-primary-content">
Advanced Options
</div>
{/* CONTENT */}
<div className="collapse-content flex flex-col gap-4 bg-neutral text-neutral-content peer-checked:bg-base-300 peer-checked:py-4 peer-checked:text-base-content">
{/* IMAGE FORMAT BUTTONS */}
<div className="flex flex-col gap-2">
<p>Save Image As:</p>
<div className="flex flex-wrap gap-2">
{batchMode && (
<p className="text-sm text-base-content/70">
Only PNG is supported in Batch Upscale
</p>
)}
{/* PNG */}
<button
className={`btn-primary btn ${
saveImageAs === "png" && "btn-accent"
}`}
onClick={() => setExportType("png")}>
PNG
</button>
{/* JPG */}
<button
className={`btn-primary btn ${
saveImageAs === "jpg" && "btn-accent"
}`}
onClick={() => setExportType("jpg")}>
JPG
</button>
{/* WEBP */}
<button
className={`btn-primary btn ${
saveImageAs === "webp" && "btn-accent"
}`}
onClick={() => setExportType("webp")}>
WEBP
</button>
</div>
</div>
{/* THEME SELECTOR */}
<div className="flex flex-col gap-2">
<p>Upscayl Theme:</p>
<select data-choose-theme className="select-primary select">
<option value="dark">Default</option>
{availableThemes.map((theme) => {
return (
<option value={theme.value} key={theme.value}>
{theme.label.toLocaleUpperCase()}
</option>
);
})}
</select>
</div>
{/* GPU ID INPUT */}
<div className="flex flex-col gap-2">
<p>GPU ID:</p>
<input
type="text"
placeholder="Type here"
className="input w-full max-w-xs"
value={gpuId}
onChange={handleGpuIdChange}
/>
</div>
{/* DONATE BUTTON */}
<div className="flex flex-col gap-2">
<p>If you like what we do :)</p>
<a
href="https://buymeacoffee.com/fossisthefuture"
target="_blank">
<button className="btn-primary btn">Donate</button>
</a>
</div>
</div>
</div>
</div>
<ReactTooltip class="max-w-sm" />

View File

@ -0,0 +1,277 @@
import React, { useEffect, useState } from "react";
import Select from "react-select";
import ReactTooltip from "react-tooltip";
import { themeChange } from "theme-change";
interface IProps {
progress: string;
selectImageHandler: () => Promise<void>;
selectFolderHandler: () => Promise<void>;
handleModelChange: (e: any) => void;
handleDrop: (e: any) => void;
outputHandler: () => Promise<void>;
upscaylHandler: () => Promise<void>;
batchMode: boolean;
setBatchMode: React.Dispatch<React.SetStateAction<boolean>>;
imagePath: string;
outputPath: string;
doubleUpscayl: boolean;
setDoubleUpscayl: React.Dispatch<React.SetStateAction<boolean>>;
model: string;
setModel: React.Dispatch<React.SetStateAction<string>>;
isVideo: boolean;
setIsVideo: React.Dispatch<React.SetStateAction<boolean>>;
saveImageAs: string;
setSaveImageAs: React.Dispatch<React.SetStateAction<string>>;
gpuId: string;
setGpuId: React.Dispatch<React.SetStateAction<string>>;
dimensions: {
width: number | null;
height: number | null;
};
}
function SettingsTab({
progress,
selectImageHandler,
selectFolderHandler,
handleModelChange,
handleDrop,
outputHandler,
upscaylHandler,
batchMode,
setBatchMode,
imagePath,
outputPath,
doubleUpscayl,
setDoubleUpscayl,
model,
setModel,
isVideo,
setIsVideo,
gpuId,
setGpuId,
saveImageAs,
setSaveImageAs,
dimensions,
}: IProps) {
const [currentModel, setCurrentModel] = useState<{
label: string;
value: string;
}>({
label: null,
value: null,
});
useEffect(() => {
themeChange(false);
if (!localStorage.getItem("saveImageAs")) {
localStorage.setItem("saveImageAs", "png");
} else {
const currentlySavedImageFormat = localStorage.getItem("saveImageAs");
setSaveImageAs(currentlySavedImageFormat);
}
if (!localStorage.getItem("model")) {
setCurrentModel(modelOptions[0]);
setModel(modelOptions[0].value);
localStorage.setItem("model", JSON.stringify(modelOptions[0]));
} else {
const currentlySavedModel = JSON.parse(
localStorage.getItem("model")
) as typeof modelOptions[0];
setCurrentModel(currentlySavedModel);
setModel(currentlySavedModel.value);
}
if (!localStorage.getItem("gpuId")) {
localStorage.setItem("gpuId", "");
} else {
const currentlySavedGpuId = localStorage.getItem("gpuId");
setGpuId(currentlySavedGpuId);
}
}, []);
useEffect(() => {
console.log("Current Model: ", currentModel);
}, [currentModel]);
const setExportType = (format: string) => {
setSaveImageAs(format);
localStorage.setItem("saveImageAs", format);
};
const handleBatchMode = () => {
setBatchMode((oldValue) => !oldValue);
};
const handleGpuIdChange = (e) => {
setGpuId(e.target.value);
localStorage.setItem("gpuId", e.target.value);
};
const customStyles = {
option: (provided, state) => ({
...provided,
borderBottom: "1px dotted pink",
color: state.isSelected ? "red" : "blue",
padding: 20,
}),
control: () => ({
// none of react-select's styles are passed to <Control />
width: 200,
}),
singleValue: (provided, state) => {
const opacity = state.isDisabled ? 0.5 : 1;
const transition = "opacity 300ms";
return { ...provided, opacity, transition };
},
};
const modelOptions = [
{ label: "General Photo (Real-ESRGAN)", value: "realesrgan-x4plus" },
{ 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" },
];
const availableThemes = [
{ label: "light", value: "light" },
{ label: "dark", value: "dark" },
{ label: "cupcake", value: "cupcake" },
{ label: "bumblebee", value: "bumblebee" },
{ label: "emerald", value: "emerald" },
{ label: "corporate", value: "corporate" },
{ label: "synthwave", value: "synthwave" },
{ label: "retro", value: "retro" },
{ label: "cyberpunk", value: "cyberpunk" },
{ label: "valentine", value: "valentine" },
{ label: "halloween", value: "halloween" },
{ label: "garden", value: "garden" },
{ label: "forest", value: "forest" },
{ label: "aqua", value: "aqua" },
{ label: "lofi", value: "lofi" },
{ label: "pastel", value: "pastel" },
{ label: "fantasy", value: "fantasy" },
{ label: "wireframe", value: "wireframe" },
{ label: "black", value: "black" },
{ label: "luxury", value: "luxury" },
{ label: "dracula", value: "dracula" },
{ label: "cmyk", value: "cmyk" },
{ label: "autumn", value: "autumn" },
{ label: "business", value: "business" },
{ label: "acid", value: "acid" },
{ label: "lemonade", value: "lemonade" },
{ label: "night", value: "night" },
{ label: "coffee", value: "coffee" },
{ label: "winter", value: "winter" },
];
useEffect(() => {}, [imagePath]);
return (
<div className="animate-step-in animate flex h-screen flex-col gap-7 overflow-y-auto p-5 overflow-x-hidden">
{/* IMAGE FORMAT BUTTONS */}
<div className="flex flex-col gap-2">
<p className="text-sm font-medium">Save Image As:</p>
<div className="flex flex-col gap-2">
{batchMode && (
<p className="text-xs text-base-content/70">
Only PNG is supported in Batch Upscale
</p>
)}
<div className="flex flex-wrap gap-2">
{/* PNG */}
<button
className={`btn-primary btn ${
saveImageAs === "png" && "btn-accent"
}`}
onClick={() => setExportType("png")}>
PNG
</button>
{/* JPG */}
<button
className={`btn-primary btn ${
saveImageAs === "jpg" && "btn-accent"
}`}
onClick={() => setExportType("jpg")}>
JPG
</button>
{/* WEBP */}
<button
className={`btn-primary btn ${
saveImageAs === "webp" && "btn-accent"
}`}
onClick={() => setExportType("webp")}>
WEBP
</button>
</div>
</div>
</div>
{/* THEME SELECTOR */}
<div className="flex flex-col gap-2">
<p className="text-sm font-medium">Upscayl Theme:</p>
<select data-choose-theme className="select-primary select">
<option value="dark">Default</option>
{availableThemes.map((theme) => {
return (
<option value={theme.value} key={theme.value}>
{theme.label.toLocaleUpperCase()}
</option>
);
})}
</select>
</div>
{/* GPU ID INPUT */}
<div className="flex flex-col gap-2">
<p className="text-sm font-medium">GPU ID:</p>
<input
type="text"
placeholder="Type here"
className="input-bordered input w-full max-w-xs"
value={gpuId}
onChange={handleGpuIdChange}
/>
</div>
<div className="relative flex flex-col gap-2">
<button
className="btn-primary btn-xs btn absolute top-10 right-5 z-10"
onClick={() => {
navigator.clipboard.writeText("Hello World!");
}}>
Copy 📋
</button>
<p className="text-sm font-medium">Logs</p>
<code className="rounded-btn min-h-16 relative h-full max-h-64 overflow-y-auto bg-base-200 p-4">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Corrupti,
odit autem eos eius explicabo optio minima ducimus est id similique
distinctio, sit natus! Harum, tempora saepe ipsam ipsa at, tenetur
tempore dolorem dolore officiis, soluta voluptate! Officia
repellendus, eligendi sunt voluptates inventore maxime expedita autem
fuga dignissimos atque aliquid amet, sequi in cupiditate? Nulla
reprehenderit labore quas quis natus dolor quos qui repellendus rerum
ducimus, unde, porro placeat deserunt maiores ex aliquam. Assumenda
laborum atque iure, nulla unde repudiandae cum odit libero magni vero
veritatis voluptates quaerat tempore quod ex sint iusto. Illum,
repudiandae id consequatur facere molestiae itaque asperiores.
</code>
</div>
{/* DONATE BUTTON */}
<div className="mt-auto flex flex-col items-center justify-center gap-2 text-sm font-medium">
<p>If you like what we do :)</p>
<a href="https://buymeacoffee.com/fossisthefuture" target="_blank">
<button className="btn-primary btn">Donate</button>
</a>
</div>
</div>
);
}
export default SettingsTab;

View File

@ -0,0 +1,29 @@
import React from "react";
type TabsProps = {
selectedTab: number;
setSelectedTab: (tab: number) => void;
};
const Tabs = ({ selectedTab, setSelectedTab }: TabsProps) => {
return (
<div className="tabs tabs-boxed mx-auto">
<a
className={`tab ${selectedTab === 0 && "tab-active"}`}
onClick={() => {
setSelectedTab(0);
}}>
Upscayl
</a>
<a
className={`tab ${selectedTab === 1 && "tab-active"}`}
onClick={() => {
setSelectedTab(1);
}}>
Settings
</a>
</div>
);
};
export default Tabs;

View File

@ -8,6 +8,8 @@ import RightPaneInfo from "../components/RightPaneInfo";
import ImageOptions from "../components/ImageOptions";
import LeftPaneVideoSteps from "../components/LeftPaneVideoSteps";
import LeftPaneImageSteps from "../components/LeftPaneImageSteps";
import Tabs from "../components/Tabs";
import SettingsTab from "../components/SettingsTab";
const Home = () => {
// STATES
@ -35,6 +37,7 @@ const Home = () => {
width: null,
height: null,
});
const [selectedTab, setSelectedTab] = useState(0);
// EFFECTS
useEffect(() => {
@ -383,6 +386,8 @@ const Home = () => {
<div className="flex h-screen w-128 flex-col rounded-r-3xl bg-base-100">
{/* HEADER */}
<Header version={version} />
<Tabs selectedTab={selectedTab} setSelectedTab={setSelectedTab} />
{/* <div className="flex items-center justify-center gap-2 pb-4 font-medium">
<p>Image</p>
<input
@ -408,7 +413,7 @@ const Home = () => {
<p>Video</p>
</div> */}
{/* LEFT PANE */}
{isVideo ? (
{/* {isVideo ? (
<LeftPaneVideoSteps
progress={progress}
selectVideoHandler={selectVideoHandler}
@ -422,7 +427,8 @@ const Home = () => {
isVideo={isVideo}
setIsVideo={setIsVideo}
/>
) : (
) : ( */}
{selectedTab === 0 && (
<LeftPaneImageSteps
progress={progress}
selectImageHandler={selectImageHandler}
@ -448,6 +454,34 @@ const Home = () => {
dimensions={dimensions}
/>
)}
{selectedTab === 1 && (
<SettingsTab
progress={progress}
selectImageHandler={selectImageHandler}
selectFolderHandler={selectFolderHandler}
handleModelChange={handleModelChange}
handleDrop={handleDrop}
outputHandler={outputHandler}
upscaylHandler={upscaylHandler}
batchMode={batchMode}
setBatchMode={setBatchMode}
imagePath={imagePath}
outputPath={outputPath}
doubleUpscayl={doubleUpscayl}
setDoubleUpscayl={setDoubleUpscayl}
model={model}
setModel={setModel}
isVideo={isVideo}
setIsVideo={setIsVideo}
gpuId={gpuId}
setGpuId={setGpuId}
saveImageAs={saveImageAs}
setSaveImageAs={setSaveImageAs}
dimensions={dimensions}
/>
)}
{/* )} */}
<Footer />
</div>
@ -522,7 +556,7 @@ const Home = () => {
{batchMode &&
upscaledBatchFolderPath.length === 0 &&
batchFolderPath.length > 0 && (
<p className="text-neutral-50 select-none font-bold">
<p className="select-none font-bold text-neutral-50">
Selected folder: {batchFolderPath}
</p>
)}
@ -530,7 +564,7 @@ const Home = () => {
{/* BATCH UPSCALE DONE INFO */}
{batchMode && upscaledBatchFolderPath.length > 0 && (
<>
<p className="text-neutral-50 select-none py-4 font-bold">
<p className="select-none py-4 font-bold text-neutral-50">
All done!
</p>
<button