Application.tsx 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. import { hot } from 'react-hot-loader/root'
  2. import * as React from 'react'
  3. import Frame from './frame/Frame'
  4. import Welcome from './welcome/Welcome'
  5. import { connect } from 'react-redux'
  6. import { View } from '../meta/Views'
  7. import Landing from './landing/Landing'
  8. import Login from './login/Login'
  9. import Loader from './loader/Loader'
  10. import Settings from './settings/Settings'
  11. import { StoreType } from '../redux/store'
  12. import { CSSTransition } from 'react-transition-group'
  13. import { ViewActionDispatch } from '../redux/actions/viewActions'
  14. import { throttle } from 'lodash'
  15. import { readdir } from 'fs-extra'
  16. import { join } from 'path'
  17. import Overlay from './overlay/Overlay'
  18. import { OverlayPushAction, OverlayActionDispatch } from '../redux/actions/overlayActions'
  19. import { DistributionAPI } from 'common/distribution/distribution'
  20. import { getServerStatus } from 'common/util/ServerStatusUtil'
  21. import './Application.css'
  22. declare const __static: string
  23. function setBackground(id: number) {
  24. import(`../../../static/images/backgrounds/${id}.jpg`).then(mdl => {
  25. document.body.style.backgroundImage = `url('${mdl.default}')`
  26. })
  27. }
  28. interface ApplicationProps {
  29. currentView: View
  30. overlayQueue: OverlayPushAction<unknown>[]
  31. }
  32. interface ApplicationState {
  33. loading: boolean
  34. showMain: boolean
  35. renderMain: boolean
  36. workingView: View
  37. }
  38. const mapState = (state: StoreType): Partial<ApplicationProps> => {
  39. return {
  40. currentView: state.currentView,
  41. overlayQueue: state.overlayQueue
  42. }
  43. }
  44. const mapDispatch = {
  45. ...ViewActionDispatch,
  46. ...OverlayActionDispatch
  47. }
  48. class Application extends React.Component<ApplicationProps & typeof mapDispatch, ApplicationState> {
  49. private bkid!: number
  50. constructor(props: ApplicationProps & typeof mapDispatch) {
  51. super(props)
  52. this.state = {
  53. loading: true,
  54. showMain: false,
  55. renderMain: false,
  56. workingView: props.currentView
  57. }
  58. }
  59. getViewElement(): JSX.Element {
  60. switch(this.state.workingView) {
  61. case View.WELCOME:
  62. return <>
  63. <Welcome />
  64. </>
  65. case View.LANDING:
  66. return <>
  67. <Landing />
  68. </>
  69. case View.LOGIN:
  70. return <>
  71. <Login cancelable={false} />
  72. </>
  73. case View.SETTINGS:
  74. return <>
  75. <Settings />
  76. </>
  77. }
  78. }
  79. private hasOverlay = (): boolean => {
  80. return this.props.overlayQueue.length > 0
  81. }
  82. private updateWorkingView = throttle(() => {
  83. this.setState({
  84. ...this.state,
  85. workingView: this.props.currentView
  86. })
  87. }, 200)
  88. private showMain = (): void => {
  89. setBackground(this.bkid)
  90. this.setState({
  91. ...this.state,
  92. showMain: true
  93. })
  94. }
  95. private initLoad = async (): Promise<void> => {
  96. if(this.state.loading) {
  97. const MIN_LOAD = 800
  98. const start = Date.now()
  99. this.bkid = Math.floor((Math.random() * (await readdir(join(__static, 'images', 'backgrounds'))).length))
  100. const endLoad = () => {
  101. this.setState({
  102. ...this.state,
  103. loading: false
  104. })
  105. // TODO temp
  106. setTimeout(() => {
  107. //this.props.setView(View.WELCOME)
  108. this.props.pushGenericOverlay({
  109. title: 'Load Distribution',
  110. description: 'This is a test. Will load the distribution.',
  111. dismissible: false,
  112. acknowledgeCallback: async () => {
  113. const distro = new DistributionAPI('C:\\Users\\user\\AppData\\Roaming\\Helios Launcher')
  114. const x = await distro.testLoad()
  115. console.log(x)
  116. const serverStatus = await getServerStatus(47, 'mc.westeroscraft.com', 25565)
  117. console.log(serverStatus)
  118. }
  119. })
  120. this.props.pushGenericOverlay({
  121. title: 'Test Title 2',
  122. description: 'Test Description',
  123. dismissible: true
  124. })
  125. this.props.pushGenericOverlay({
  126. title: 'Test Title 3',
  127. description: 'Test Description',
  128. dismissible: true
  129. })
  130. this.props.pushGenericOverlay({
  131. title: 'Test Title 4',
  132. description: 'Test Description',
  133. dismissible: true
  134. })
  135. this.props.pushGenericOverlay({
  136. title: 'Test Title IMPORTANT',
  137. description: 'Test Description',
  138. dismissible: true
  139. }, true)
  140. }, 5000)
  141. }
  142. const diff = Date.now() - start
  143. if(diff < MIN_LOAD) {
  144. setTimeout(endLoad, MIN_LOAD-diff)
  145. } else {
  146. endLoad()
  147. }
  148. }
  149. }
  150. render(): JSX.Element {
  151. return (
  152. <>
  153. <Frame />
  154. <CSSTransition
  155. in={this.state.showMain}
  156. appear={true}
  157. timeout={500}
  158. classNames="appWrapper"
  159. unmountOnExit
  160. >
  161. <div className="appWrapper" {...(this.hasOverlay() ? {overlay: 'true'} : {})}>
  162. <CSSTransition
  163. in={this.props.currentView == this.state.workingView}
  164. appear={true}
  165. timeout={500}
  166. classNames="appWrapper"
  167. unmountOnExit
  168. onExited={this.updateWorkingView}
  169. >
  170. {this.getViewElement()}
  171. </CSSTransition>
  172. </div>
  173. </CSSTransition>
  174. <CSSTransition
  175. in={this.hasOverlay()}
  176. appear={true}
  177. timeout={500}
  178. classNames="appWrapper"
  179. unmountOnExit
  180. >
  181. <Overlay overlayQueue={this.props.overlayQueue} />
  182. </CSSTransition>
  183. <CSSTransition
  184. in={this.state.loading}
  185. appear={true}
  186. timeout={300}
  187. classNames="loader"
  188. unmountOnExit
  189. onEnter={this.initLoad}
  190. onExited={this.showMain}
  191. >
  192. <Loader />
  193. </CSSTransition>
  194. </>
  195. )
  196. }
  197. }
  198. export default hot(connect<unknown, typeof mapDispatch>(mapState, mapDispatch)(Application))