import { hot } from 'react-hot-loader/root' import * as React from 'react' import Frame from './frame/Frame' import Welcome from './welcome/Welcome' import { connect } from 'react-redux' import { View } from '../meta/Views' import Landing from './landing/Landing' import Login from './login/Login' import Loader from './loader/Loader' import Settings from './settings/Settings' import Overlay from './overlay/Overlay' import Fatal from './fatal/Fatal' import { StoreType } from '../redux/store' import { CSSTransition } from 'react-transition-group' import { ViewActionDispatch } from '../redux/actions/viewActions' import { throttle } from 'lodash' import { readdir } from 'fs-extra' import { join } from 'path' import { AppActionDispatch } from '../redux/actions/appActions' import { OverlayPushAction, OverlayActionDispatch } from '../redux/actions/overlayActions' import { LoggerUtil } from 'common/logging/loggerutil' import { DistributionAPI } from 'common/distribution/DistributionAPI' import { getServerStatus, ServerStatus } from 'common/mojang/net/ServerStatusAPI' import { Distribution } from 'helios-distribution-types' import { HeliosDistribution, HeliosServer } from 'common/distribution/DistributionFactory' import './Application.css' declare const __static: string function setBackground(id: number) { import(`../../../static/images/backgrounds/${id}.jpg`).then(mdl => { document.body.style.backgroundImage = `url('${mdl.default}')` }) } interface ApplicationProps { currentView: View overlayQueue: OverlayPushAction[] distribution: HeliosDistribution selectedServer: HeliosServer selectedServerStatus: ServerStatus } interface ApplicationState { loading: boolean showMain: boolean renderMain: boolean workingView: View } const mapState = (state: StoreType): Partial => { return { currentView: state.currentView, overlayQueue: state.overlayQueue, distribution: state.app.distribution!, selectedServer: state.app.selectedServer! } } const mapDispatch = { ...AppActionDispatch, ...ViewActionDispatch, ...OverlayActionDispatch } class Application extends React.Component { private static readonly logger = LoggerUtil.getLogger('ApplicationTSX') private bkid!: number constructor(props: ApplicationProps & typeof mapDispatch) { super(props) this.state = { loading: true, showMain: false, renderMain: false, workingView: props.currentView } } private getViewElement = (): JSX.Element => { // TODO debug remove console.log('loading', this.props.currentView, this.state.workingView) switch(this.state.workingView) { case View.WELCOME: return <> case View.LANDING: return <> case View.LOGIN: return <> case View.SETTINGS: return <> case View.FATAL: return <> case View.NONE: return <> } } private hasOverlay = (): boolean => { return this.props.overlayQueue.length > 0 } private updateWorkingView = throttle(() => { // TODO debug remove console.log('Setting to', this.props.currentView) this.setState({ ...this.state, workingView: this.props.currentView }) }, 200) private finishLoad = (): void => { if(this.props.currentView !== View.FATAL) { setBackground(this.bkid) } this.showMain() } private showMain = (): void => { this.setState({ ...this.state, showMain: true }) } private initLoad = async (): Promise => { if(this.state.loading) { const MIN_LOAD = 800 const start = Date.now() // Initial distribution load. const distroAPI = new DistributionAPI('C:\\Users\\user\\AppData\\Roaming\\Helios Launcher') let rawDisto: Distribution try { rawDisto = await distroAPI.testLoad() console.log('distro', distroAPI) } catch(err) { console.log('EXCEPTION IN DISTRO LOAD TODO TODO TODO', err) rawDisto = null! } // Fatal error if(rawDisto == null) { this.props.setView(View.FATAL) this.setState({ ...this.state, loading: false, workingView: View.FATAL }) return } else { const distro = new HeliosDistribution(rawDisto) // TODO TEMP USE CONFIG // TODO TODO TODO TODO const selectedServer: HeliosServer = distro.servers[0] const { hostname, port } = selectedServer let selectedServerStatus try { selectedServerStatus = await getServerStatus(47, hostname, port) } catch(err) { Application.logger.error('Failed to refresh server status', selectedServerStatus) } this.props.setDistribution(distro) this.props.setSelectedServer(selectedServer) this.props.setSelectedServerStatus(selectedServerStatus) } // TODO Setup hook for distro refresh every ~ 5 mins. // Pick a background id. this.bkid = Math.floor((Math.random() * (await readdir(join(__static, 'images', 'backgrounds'))).length)) const endLoad = () => { // TODO determine correct view // either welcome, landing, or login this.props.setView(View.LANDING) this.setState({ ...this.state, loading: false, workingView: View.LANDING }) // TODO temp setTimeout(() => { // this.props.setView(View.WELCOME) // this.props.pushGenericOverlay({ // title: 'Load Distribution', // description: 'This is a test.', // dismissible: false, // acknowledgeCallback: async () => { // const serverStatus = await getServerStatus(47, 'play.hypixel.net', 25565) // console.log(serverStatus) // } // }) // this.props.pushGenericOverlay({ // title: 'Test Title 2', // description: 'Test Description', // dismissible: true // }) // this.props.pushGenericOverlay({ // title: 'Test Title IMPORTANT', // description: 'Test Description', // dismissible: true // }, true) }, 5000) } const diff = Date.now() - start if(diff < MIN_LOAD) { setTimeout(endLoad, MIN_LOAD-diff) } else { endLoad() } } } render(): JSX.Element { return ( <>
{this.getViewElement()}
) } } export default hot(connect(mapState, mapDispatch)(Application))