151 lines
4.8 KiB
TypeScript
151 lines
4.8 KiB
TypeScript
import React, { useEffect, useState } from 'react'
|
|
import { openURL } from 'prismarine-viewer/viewer/lib/simpleUtils'
|
|
import { haveDirectoryPicker } from '../utils'
|
|
import styles from './mainMenu.module.css'
|
|
import Button from './Button'
|
|
import ButtonWithTooltip from './ButtonWithTooltip'
|
|
|
|
type Action = (e: React.MouseEvent<HTMLButtonElement>) => void
|
|
|
|
interface Props {
|
|
connectToServerAction?: Action
|
|
singleplayerAction?: Action
|
|
optionsAction?: Action
|
|
githubAction?: Action
|
|
discordAction?: Action
|
|
openFileAction?: Action
|
|
mapsProvider?: string
|
|
}
|
|
|
|
const refreshApp = async () => {
|
|
const registration = await navigator.serviceWorker.getRegistration()
|
|
await registration?.unregister()
|
|
window.justReloaded = true
|
|
sessionStorage.justReloaded = true
|
|
window.location.reload()
|
|
}
|
|
|
|
const httpsRegex = /^https?:\/\//
|
|
|
|
export default ({ connectToServerAction, mapsProvider, singleplayerAction, optionsAction, githubAction, discordAction, openFileAction }: Props) => {
|
|
const [versionStatus, setVersionStatus] = useState('')
|
|
const [versionTitle, setVersionTitle] = useState('')
|
|
|
|
useEffect(() => {
|
|
if (process.env.NODE_ENV === 'development') {
|
|
setVersionStatus('(dev)')
|
|
} else {
|
|
fetch('./version.txt').then(async (f) => {
|
|
if (f.status === 404) return
|
|
const contents = await f.text()
|
|
const isLatest = contents === process.env.BUILD_VERSION
|
|
if (!isLatest && sessionStorage.justReloaded) {
|
|
// try to force bypass cache
|
|
location.search = '?update=true'
|
|
}
|
|
sessionStorage.justReloaded = false
|
|
setVersionStatus(`(${isLatest ? 'latest' : 'new version available'})`)
|
|
setVersionTitle(`Loaded: ${process.env.BUILD_VERSION}. Remote: ${contents}`)
|
|
}, () => { })
|
|
}
|
|
}, [])
|
|
|
|
|
|
return (
|
|
<div className={styles.root}>
|
|
<div className={styles['game-title']}>
|
|
<div className={styles.minec}></div>
|
|
<div className={styles.raft}></div>
|
|
<div className={styles.edition}></div>
|
|
<span className={styles.splash}>Prismarine is a beautiful block</span>
|
|
</div>
|
|
|
|
<div className={styles.menu}>
|
|
<ButtonWithTooltip
|
|
initialTooltip={{
|
|
content: 'Connect to Java servers!',
|
|
placement: 'top',
|
|
}}
|
|
onClick={connectToServerAction}
|
|
data-test-id='servers-screen-button'
|
|
>
|
|
Connect to server
|
|
</ButtonWithTooltip>
|
|
<div style={{ display: 'flex', justifyContent: 'space-between' }}>
|
|
<ButtonWithTooltip
|
|
style={{ width: 170 }}
|
|
onClick={singleplayerAction}
|
|
data-test-id='singleplayer-button'
|
|
initialTooltip={{
|
|
content: 'Create worlds and play offline',
|
|
placement: 'left',
|
|
offset: -40
|
|
}}
|
|
>
|
|
Singleplayer
|
|
</ButtonWithTooltip>
|
|
|
|
<ButtonWithTooltip
|
|
data-test-id='select-file-folder'
|
|
icon='pixelarticons:folder'
|
|
onClick={openFileAction}
|
|
initialTooltip={{
|
|
content: 'Load any 1.8-1.16 Java world' + (haveDirectoryPicker() ? '' : ' (zip)'),
|
|
placement: 'bottom-start',
|
|
}}
|
|
/>
|
|
</div>
|
|
<Button
|
|
onClick={optionsAction}
|
|
>
|
|
Options
|
|
</Button>
|
|
<div className={styles['menu-row']}>
|
|
<ButtonWithTooltip
|
|
initialTooltip={{
|
|
content: 'Report bugs or request features!',
|
|
}}
|
|
style={{ width: '98px' }}
|
|
onClick={githubAction}
|
|
>
|
|
GitHub
|
|
</ButtonWithTooltip>
|
|
<Button
|
|
style={{ width: '98px' }}
|
|
onClick={discordAction}
|
|
>
|
|
Discord
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
|
|
<div className={styles['bottom-info']}>
|
|
<span
|
|
title={`${versionTitle} (click to reload)`}
|
|
onClick={async () => {
|
|
setVersionStatus('(reloading)')
|
|
await refreshApp()
|
|
}}
|
|
className={styles['product-info']}
|
|
>
|
|
Prismarine Web Client {versionStatus}
|
|
</span>
|
|
<span className={styles['product-description']}>
|
|
<a style={{
|
|
color: 'lightgray',
|
|
fontSize: 9,
|
|
}} href='https://privacy.mcraft.fun'>Privacy Policy</a>
|
|
<span>A Minecraft client in the browser!</span>
|
|
</span>
|
|
</div>
|
|
|
|
{mapsProvider &&
|
|
<ButtonWithTooltip
|
|
className={styles['maps-provider']}
|
|
icon='pixelarticons:map'
|
|
initialTooltip={{ content: 'Explore maps to play from provider!', placement: 'right' }}
|
|
onClick={() => openURL(httpsRegex.test(mapsProvider) ? mapsProvider : 'https://' + mapsProvider, false)}
|
|
/>}
|
|
</div>
|
|
)
|
|
}
|