2023-05-01 13:14:12 +05:30
import { useAtom , useAtomValue } from "jotai" ;
2022-12-11 11:17:00 +05:30
import React , { useEffect , useState } from "react" ;
2022-11-12 02:09:28 +05:30
import Select from "react-select" ;
import ReactTooltip from "react-tooltip" ;
2022-12-08 08:55:26 +05:30
import { themeChange } from "theme-change" ;
2023-04-09 10:46:15 +05:30
import { modelsListAtom } from "../atoms/modelsListAtom" ;
2023-05-01 12:51:47 +05:30
import useLog from "./hooks/useLog" ;
2022-11-12 02:09:28 +05:30
2022-11-15 20:24:06 +05:30
interface IProps {
progress : string ;
selectImageHandler : ( ) = > Promise < void > ;
selectFolderHandler : ( ) = > Promise < void > ;
handleModelChange : ( e : any ) = > void ;
outputHandler : ( ) = > Promise < void > ;
upscaylHandler : ( ) = > Promise < void > ;
batchMode : boolean ;
2023-03-12 13:11:43 +05:30
setBatchMode : React.Dispatch < React.SetStateAction < boolean > > ;
2022-11-15 20:24:06 +05:30
imagePath : string ;
outputPath : string ;
doubleUpscayl : boolean ;
2023-03-12 13:11:43 +05:30
setDoubleUpscayl : React.Dispatch < React.SetStateAction < boolean > > ;
2022-12-24 12:47:54 +05:30
dimensions : {
width : number | null ;
height : number | null ;
} ;
2023-05-01 14:53:11 +05:30
setSaveImageAs : React.Dispatch < React.SetStateAction < string > > ;
setModel : React.Dispatch < React.SetStateAction < string > > ;
setGpuId : React.Dispatch < React.SetStateAction < string > > ;
2022-11-15 20:24:06 +05:30
}
2022-11-23 23:54:30 +05:30
function LeftPaneImageSteps ( {
2022-11-15 20:24:06 +05:30
progress ,
selectImageHandler ,
selectFolderHandler ,
handleModelChange ,
outputHandler ,
upscaylHandler ,
batchMode ,
setBatchMode ,
imagePath ,
outputPath ,
doubleUpscayl ,
setDoubleUpscayl ,
2022-12-24 12:47:54 +05:30
dimensions ,
2023-05-01 14:53:11 +05:30
setSaveImageAs ,
setModel ,
setGpuId ,
2022-11-15 20:24:06 +05:30
} : IProps ) {
2022-12-24 14:15:15 +05:30
const [ currentModel , setCurrentModel ] = useState < {
label : string ;
value : string ;
} > ( {
label : null ,
value : null ,
} ) ;
2023-05-01 13:14:12 +05:30
const modelOptions = useAtomValue ( modelsListAtom ) ;
2023-03-12 13:11:43 +05:30
2023-05-01 14:53:11 +05:30
const { logit } = useLog ( ) ;
useEffect ( ( ) = > {
themeChange ( false ) ;
if ( ! localStorage . getItem ( "saveImageAs" ) ) {
2023-05-06 10:47:35 +05:30
logit ( "⚙️ Setting saveImageAs to png" ) ;
2023-05-01 14:53:11 +05:30
localStorage . setItem ( "saveImageAs" , "png" ) ;
} else {
const currentlySavedImageFormat = localStorage . getItem ( "saveImageAs" ) ;
logit (
2023-05-06 10:47:35 +05:30
"⚙️ Getting saveImageAs from localStorage" ,
2023-05-01 14:53:11 +05:30
currentlySavedImageFormat
) ;
setSaveImageAs ( currentlySavedImageFormat ) ;
}
if ( ! localStorage . getItem ( "model" ) ) {
setCurrentModel ( modelOptions [ 0 ] ) ;
setModel ( modelOptions [ 0 ] . value ) ;
localStorage . setItem ( "model" , JSON . stringify ( modelOptions [ 0 ] ) ) ;
2023-05-06 10:47:35 +05:30
logit ( "🔀 Setting model to" , modelOptions [ 0 ] . value ) ;
2023-05-01 14:53:11 +05:30
} else {
const currentlySavedModel = JSON . parse (
localStorage . getItem ( "model" )
) as ( typeof modelOptions ) [ 0 ] ;
setCurrentModel ( currentlySavedModel ) ;
setModel ( currentlySavedModel . value ) ;
logit (
2023-05-06 10:47:35 +05:30
"⚙️ Getting model from localStorage" ,
2023-05-01 14:53:11 +05:30
JSON . stringify ( currentlySavedModel )
) ;
}
if ( ! localStorage . getItem ( "gpuId" ) ) {
localStorage . setItem ( "gpuId" , "" ) ;
2023-05-06 10:47:35 +05:30
logit ( "⚙️ Setting gpuId to empty string" ) ;
2023-05-01 14:53:11 +05:30
} else {
const currentlySavedGpuId = localStorage . getItem ( "gpuId" ) ;
setGpuId ( currentlySavedGpuId ) ;
2023-05-06 10:47:35 +05:30
logit ( "⚙️ Getting gpuId from localStorage" , currentlySavedGpuId ) ;
2023-05-01 14:53:11 +05:30
}
} , [ ] ) ;
useEffect ( ( ) = > {
2023-05-06 10:47:35 +05:30
logit ( "🔀 Setting model to" , currentModel . value ) ;
2023-05-01 14:53:11 +05:30
} , [ currentModel ] ) ;
2023-06-03 06:19:13 +05:30
const getUpscaleResolution = ( ) = > {
const newDimensions = {
width : dimensions.width ,
height : dimensions.height ,
} ;
if ( doubleUpscayl ) {
newDimensions . width = dimensions . width * 16 ;
newDimensions . height = dimensions . height * 16 ;
} else {
newDimensions . width = dimensions . width * 4 ;
newDimensions . height = dimensions . height * 4 ;
}
if ( newDimensions . width > 32768 ) {
logit ( "🚫 Upscale width is too large, setting to a maximum of 32768px" ) ;
newDimensions . width = 32384 ;
}
if ( newDimensions . height > 32768 ) {
logit ( "🚫 Upscale height is too large, setting to a maximum of 32768px" ) ;
newDimensions . height = 32384 ;
}
return newDimensions ;
} ;
2022-11-12 02:09:28 +05:30
return (
2022-11-15 20:12:20 +05:30
< div className = "animate-step-in animate flex h-screen flex-col gap-7 overflow-y-auto p-5 overflow-x-hidden" >
2022-11-12 02:09:28 +05:30
{ /* BATCH OPTION */ }
2022-11-12 03:02:24 +05:30
< div className = "flex flex-row items-center gap-2" >
< input
type = "checkbox"
2022-11-15 20:12:20 +05:30
className = "toggle"
2023-04-15 10:30:19 +05:30
defaultChecked = { batchMode }
2023-04-28 07:30:59 +05:30
onClick = { ( ) = > setBatchMode ( ( oldValue ) = > ! oldValue ) } > < / input >
2022-11-23 23:54:30 +05:30
< p
className = "mr-1 inline-block cursor-help text-sm"
2023-06-18 11:47:45 -04:00
data - tip = "This will let you Upscayl all files in a folder at once" >
Batch Upscayl
2022-11-23 23:54:30 +05:30
< / p >
2022-11-12 02:09:28 +05:30
< / div >
{ /* STEP 1 */ }
2022-11-15 20:24:06 +05:30
< div data-tip = { imagePath } >
2022-11-12 02:09:28 +05:30
< p className = "step-heading" > Step 1 < / p >
< button
2022-11-12 03:02:24 +05:30
className = "btn-primary btn"
2022-11-23 23:54:30 +05:30
onClick = { ! batchMode ? selectImageHandler : selectFolderHandler } >
2022-11-15 20:24:06 +05:30
Select { batchMode ? "Folder" : "Image" }
2022-11-12 02:09:28 +05:30
< / button >
< / div >
{ /* STEP 2 */ }
< div className = "animate-step-in" >
< p className = "step-heading" > Step 2 < / p >
2023-06-18 11:47:45 -04:00
< p className = "mb-2 text-sm" > Select Upscayling Type < / p >
2022-11-12 02:09:28 +05:30
< Select
options = { modelOptions }
components = { {
IndicatorSeparator : ( ) = > null ,
DropdownIndicator : ( ) = > null ,
} }
2022-12-27 12:15:16 +05:30
onChange = { ( e ) = > {
handleModelChange ( e ) ;
setCurrentModel ( { label : e.label , value : e.value } ) ;
} }
2022-11-14 21:37:39 +05:30
className = "react-select-container"
2022-11-12 02:09:28 +05:30
classNamePrefix = "react-select"
2022-12-24 14:15:15 +05:30
value = { currentModel }
2022-11-12 02:09:28 +05:30
/ >
2023-03-18 18:03:17 +05:30
{ ! batchMode && (
2022-11-23 23:54:30 +05:30
< div className = "mt-4 flex items-center gap-1" >
2022-11-12 02:09:28 +05:30
< input
type = "checkbox"
2022-11-12 03:02:24 +05:30
className = "checkbox"
2022-11-15 20:24:06 +05:30
checked = { doubleUpscayl }
2022-11-12 02:09:28 +05:30
onChange = { ( e ) = > {
if ( e . target . checked ) {
2022-11-15 20:24:06 +05:30
setDoubleUpscayl ( true ) ;
2022-11-12 02:09:28 +05:30
} else {
2022-11-15 20:24:06 +05:30
setDoubleUpscayl ( false ) ;
2022-11-12 02:09:28 +05:30
}
} }
/ >
< p
2022-11-12 03:02:24 +05:30
className = "cursor-pointer text-sm"
2022-11-12 02:09:28 +05:30
onClick = { ( e ) = > {
2022-11-15 20:24:06 +05:30
setDoubleUpscayl ( ! doubleUpscayl ) ;
2022-11-23 23:54:30 +05:30
} } >
2022-11-12 02:09:28 +05:30
Double Upscayl
< / p >
2022-11-23 23:54:30 +05:30
< button
className = "badge-info badge cursor-help"
2023-03-18 17:28:38 +05:30
data - tip = "Enable this option to get a 16x upscayl (we just run upscayl twice). Note that this may not always work properly with all images, for example, images with really large resolutions." >
2022-11-23 23:54:30 +05:30
i
< / button >
2022-11-12 02:09:28 +05:30
< / div >
) }
< / div >
{ /* STEP 3 */ }
2022-11-15 20:24:06 +05:30
< div className = "animate-step-in" data-tip = { outputPath } >
2022-11-12 02:09:28 +05:30
< p className = "step-heading" > Step 3 < / p >
2022-12-24 13:13:38 +05:30
< p className = "mb-2 text-sm" >
Defaults to { ! batchMode ? "Image's" : "Folder's" } path
< / p >
2022-11-15 20:24:06 +05:30
< button className = "btn-primary btn" onClick = { outputHandler } >
2022-11-12 02:09:28 +05:30
Set Output Folder
< / button >
< / div >
{ /* STEP 4 */ }
< div className = "animate-step-in" >
< p className = "step-heading" > Step 4 < / p >
2022-12-24 12:47:54 +05:30
{ dimensions . width && dimensions . height && (
< p className = "mb-2 text-sm" >
2023-06-18 11:47:45 -04:00
Upscayl from { " " }
2022-12-24 12:47:54 +05:30
< span className = "font-bold" >
{ dimensions . width } x { dimensions . height }
< / span > { " " }
to { " " }
< span className = "font-bold" >
2023-06-03 06:19:50 +05:30
{ getUpscaleResolution ( ) . width } x { getUpscaleResolution ( ) . height }
2022-12-24 12:47:54 +05:30
< / span >
< / p >
) }
2022-11-12 02:09:28 +05:30
< button
2022-11-12 03:02:24 +05:30
className = "btn-accent btn"
2022-11-15 20:24:06 +05:30
onClick = { upscaylHandler }
2022-11-23 23:54:30 +05:30
disabled = { progress . length > 0 } >
2022-11-15 20:24:06 +05:30
{ progress . length > 0 ? "Upscayling⏳" : "Upscayl" }
2022-11-12 02:09:28 +05:30
< / button >
< / div >
2022-11-23 23:54:30 +05:30
< ReactTooltip class = "max-w-sm" / >
2022-11-12 02:09:28 +05:30
< / div >
) ;
}
2022-11-23 23:54:30 +05:30
export default LeftPaneImageSteps ;