/* eslint-disable no-loop-func */
import React, { useState, useEffect, memo } from 'react';
import { Button, Progress, Input } from 'antd';
import { Transition } from 'react-transition-group';
import styled, { useTheme } from 'styled-components';
import { ipcRenderer } from 'electron';
import fse from 'fs-extra';
import { useSelector, useDispatch } from 'react-redux';
import path from 'path';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faFolder } from '@fortawesome/free-solid-svg-icons';
import { exec } from 'child_process';
import { promisify } from 'util';
import Modal from '../components/Modal';
import { downloadFile } from '../../app/desktop/utils/downloader';
import {
convertOSToJavaFormat,
convertArchToJavaFormat,
extractAll,
isLatestJavaDownloaded
} from '../../app/desktop/utils';
import { _getTempPath } from '../utils/selectors';
import { closeModal } from '../reducers/modals/actions';
import {
updateJavaLatestPath,
updateJavaPath
} from '../reducers/settings/actions';
import { UPDATE_MODAL } from '../reducers/modals/actionTypes';
import { LATEST_JAVA_VERSION } from '../utils/constants';
const JavaSetup = () => {
const [step, setStep] = useState(0);
const [choice, setChoice] = useState(null);
const [isJava8Downloaded, setIsJava8Downloaded] = useState(null);
const [isJavaLatestDownloaded, setIsJavaLatestDownloaded] = useState(null);
const [java8Log, setJava8Log] = useState(null);
const [javaLatestLog, setJavaLatestLog] = useState(null);
const javaManifest = useSelector(state => state.app.javaManifest);
const javaLatestManifest = useSelector(state => state.app.javaLatestManifest);
const userData = useSelector(state => state.userData);
const manifests = {
javaLatest: javaLatestManifest,
java: javaManifest
};
useEffect(() => {
isLatestJavaDownloaded(manifests, userData, true, 8)
.then(e => {
setIsJava8Downloaded(e?.isValid);
return setJava8Log(e?.log);
})
.catch(err => console.error(err));
isLatestJavaDownloaded(manifests, userData, true, LATEST_JAVA_VERSION)
.then(e => {
setIsJavaLatestDownloaded(e?.isValid);
return setJavaLatestLog(e?.log);
})
.catch(err => console.error(err));
}, []);
return (
{state => (
Java Setup
For an optimal experience, we suggest letting us take care of java
for you. Only manually manage java if you know what you're
doing, it may result in GDLauncher not working!
h3 {
border-radius: 5px;
padding: 2px 4px;
background: ${props => props.theme.palette.colors.red};
}
`}
>
Missing Versions:
{!isJava8Downloaded && isJava8Downloaded !== null && (
Java 8
)}
{!isJavaLatestDownloaded && isJavaLatestDownloaded !== null && (
Java {LATEST_JAVA_VERSION}
)}
div {
display: flex;
justify-content: center;
margin-top: 20px;
}
`}
>
{
setStep(1);
setChoice(0);
}}
>
Automatic Setup
{
setStep(1);
setChoice(1);
}}
>
Manual Setup
)}
{state => (
{choice === 0 ? 'Automatic' : 'Manual'} Setup
{choice === 0 ? (
) : (
)}
)}
);
};
const ManualSetup = ({ setStep }) => {
const [javaPath, setJavaPath] = useState('');
const [javaLatestPath, setJavaLatestPath] = useState('');
const dispatch = useDispatch();
const selectFolder = async version => {
const { filePaths, canceled } = await ipcRenderer.invoke('openFileDialog');
if (!canceled) {
if (version === LATEST_JAVA_VERSION) {
setJavaLatestPath(filePaths[0]);
} else setJavaPath(filePaths[0]);
}
};
return (
);
};
const AutomaticSetup = ({
isJava8Downloaded,
isJavaLatestDownloaded,
java8Log,
javaLatestLog
}) => {
const [downloadPercentage, setDownloadPercentage] = useState(0);
const [currentSubStep, setCurrentSubStep] = useState('Downloading Java');
const [currentStepPercentage, setCurrentStepPercentage] = useState(0);
const javaManifest = useSelector(state => state.app.javaManifest);
const javaLatestManifest = useSelector(state => state.app.javaLatestManifest);
const userData = useSelector(state => state.userData);
const tempFolder = useSelector(_getTempPath);
const modals = useSelector(state => state.modals);
const dispatch = useDispatch();
const theme = useTheme();
const javaToInstall = [];
useEffect(() => {
if (javaToInstall.length > 0) {
const instanceManagerModalIndex = modals.findIndex(
x => x.modalType === 'JavaSetup'
);
dispatch({
type: UPDATE_MODAL,
modals: [
...modals.slice(0, instanceManagerModalIndex),
{
modalType: 'JavaSetup',
modalProps: { preventClose: true }
},
...modals.slice(instanceManagerModalIndex + 1)
]
});
}
}, []);
if (!isJava8Downloaded) javaToInstall.push(8);
if (!isJavaLatestDownloaded) javaToInstall.push(LATEST_JAVA_VERSION);
const installJava = async () => {
const javaOs = convertOSToJavaFormat(process.platform);
const javaArch = convertArchToJavaFormat(process.arch);
const java8Meta = javaManifest.find(
v =>
v.os === javaOs &&
v.architecture === javaArch &&
(v.binary_type === 'jre' || v.binary_type === 'jdk')
);
const javaLatestMeta = javaLatestManifest.find(
v =>
v.os === javaOs &&
v.architecture === javaArch &&
(v.binary_type === 'jre' || v.binary_type === 'jdk')
);
const totalExtractionSteps = process.platform !== 'win32' ? 2 : 1;
const totalSteps = (totalExtractionSteps + 1) * javaToInstall.length;
const setStepPercentage = (stepNumber, percentage) => {
setCurrentStepPercentage(
parseInt(percentage / totalSteps + (stepNumber * 100) / totalSteps, 10)
);
};
let index = 0;
for (const javaVersion of javaToInstall) {
const {
version_data: { openjdk_version: version },
binary_link: url
} = javaVersion === 8 ? java8Meta : javaLatestMeta;
const javaBaseFolder = path.join(userData, 'java');
await fse.remove(path.join(javaBaseFolder, version));
const downloadLocation = path.join(tempFolder, path.basename(url));
setCurrentSubStep(`Java ${javaVersion} - Downloading`);
await downloadFile(downloadLocation, url, p => {
ipcRenderer.invoke('update-progress-bar', p);
setDownloadPercentage(p);
setStepPercentage(index, p);
});
ipcRenderer.invoke('update-progress-bar', -1);
index += 1;
setDownloadPercentage(0);
setStepPercentage(index, 0);
await new Promise(resolve => setTimeout(resolve, 500));
setCurrentSubStep(
`Java ${javaVersion} - Extracting 1 / ${totalExtractionSteps}`
);
let { extractedParentDir } = await extractAll(
downloadLocation,
tempFolder,
{
$progress: true
},
{
update: percent => {
ipcRenderer.invoke('update-progress-bar', percent);
setDownloadPercentage(percent);
setStepPercentage(index, percent);
}
}
);
index += 1;
setDownloadPercentage(0);
setStepPercentage(index, 0);
await fse.remove(downloadLocation);
// If NOT windows then tar.gz instead of zip, so we need to extract 2 times.
if (process.platform !== 'win32') {
ipcRenderer.invoke('update-progress-bar', -1);
await new Promise(resolve => setTimeout(resolve, 500));
setCurrentSubStep(
`Java ${javaVersion} - Extracting 2 / ${totalExtractionSteps}`
);
const tempTarName = path.join(
tempFolder,
path.basename(url).replace('.tar.gz', '.tar')
);
({ extractedParentDir } = await extractAll(
tempTarName,
tempFolder,
{
$progress: true
},
{
update: percent => {
ipcRenderer.invoke('update-progress-bar', percent);
setDownloadPercentage(percent);
setStepPercentage(index, percent);
}
}
));
await fse.remove(tempTarName);
index += 1;
setDownloadPercentage(0);
setStepPercentage(index, 0);
}
const directoryToMove =
process.platform === 'darwin'
? path.join(tempFolder, extractedParentDir, 'Contents', 'Home')
: path.join(tempFolder, extractedParentDir);
await fse.move(directoryToMove, path.join(javaBaseFolder, version));
await fse.remove(path.join(tempFolder, extractedParentDir));
const ext = process.platform === 'win32' ? '.exe' : '';
if (process.platform !== 'win32') {
const execPath = path.join(
javaBaseFolder,
version,
'bin',
`java${ext}`
);
await promisify(exec)(`chmod +x "${execPath}"`);
await promisify(exec)(`chmod 755 "${execPath}"`);
}
}
dispatch(updateJavaPath(null));
dispatch(updateJavaLatestPath(null));
setCurrentSubStep(`Java is ready!`);
ipcRenderer.invoke('update-progress-bar', -1);
setDownloadPercentage(100);
setCurrentStepPercentage(100);
await new Promise(resolve => setTimeout(resolve, 2000));
if (!javaLatestLog || !java8Log) dispatch(closeModal());
};
useEffect(() => {
installJava();
}, []);
return (
{javaToInstall.length > 0 ? (
<>
{currentSubStep}
{downloadPercentage ? (
) : null}
>
) : (
Java is already installed!
Java 8 details:
{java8Log}
Java {LATEST_JAVA_VERSION} details:
{javaLatestLog}
)}
{javaLatestLog && java8Log && (
dispatch(closeModal())}
>
Close
)}
);
};
export default memo(JavaSetup);
const FirstStep = styled.div`
transition: 0.2s ease-in-out;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
will-change: transform;
transform: translateX(
${({ state }) => (state === 'exiting' || state === 'exited' ? -100 : 0)}%
);
`;
const SecondStep = styled.div`
transition: 0.2s ease-in-out;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
will-change: transform;
transform: translateX(
${({ state }) => (state === 'entering' || state === 'entered' ? 0 : 101)}%
);
`;