new design for welcome page #96

This commit is contained in:
Jon Eugster
2023-08-31 18:15:15 +02:00
parent 42eaedda70
commit db5cfbc433
12 changed files with 670 additions and 409 deletions
+6 -109
View File
@@ -169,7 +169,7 @@ export function WorldPath({source, target, unlocked} : {source: any, target: any
}
/** Download a file containing `data` */
const downloadFile = ({ data, fileName, fileType } :
export const downloadFile = ({ data, fileName, fileType } :
{ data: string
fileName: string
fileType: string}) => {
@@ -186,88 +186,21 @@ const downloadFile = ({ data, fileName, fileType } :
a.remove()
}
// TODO: I think this should be removed and that single button incorporated differently
/** Menu on desktop to go back to game server */
export function WelcomeMenu() {
return <nav className="world-selection-menu">
<Button inverted="false" title="back to games selection" to="/">
<FontAwesomeIcon icon={faArrowLeft} />&nbsp;<FontAwesomeIcon icon={faGlobe} />
</Button>
</nav>
}
/** The menu that is shown next to the world selection graph */
function WorldSelectionMenu() {
const [file, setFile] = React.useState<File>();
export function WorldSelectionMenu() {
const gameId = React.useContext(GameIdContext)
const store = useStore()
const difficulty = useSelector(selectDifficulty(gameId))
/* state variables to toggle the pop-up menus */
const [eraseMenu, setEraseMenu] = React.useState(false);
const openEraseMenu = () => setEraseMenu(true);
const closeEraseMenu = () => setEraseMenu(false);
const [uploadMenu, setUploadMenu] = React.useState(false);
const openUploadMenu = () => setUploadMenu(true);
const closeUploadMenu = () => setUploadMenu(false);
const gameProgress = useSelector(selectProgress(gameId))
const dispatch = useAppDispatch()
/** Download the current progress (i.e. what's saved in the browser store) */
const downloadProgress = (e) => {
e.preventDefault()
downloadFile({
data: JSON.stringify(gameProgress, null, 2),
fileName: `lean4game-${gameId}-${new Date().toLocaleDateString()}.json`,
fileType: 'text/json',
})
}
const handleFileChange = (e) => {
if (e.target.files) {
setFile(e.target.files[0])
}
}
/** Upload progress from a */
const uploadProgress = (e) => {
if (!file) {return}
const fileReader = new FileReader()
fileReader.readAsText(file, "UTF-8")
fileReader.onload = (e) => {
const data = JSON.parse(e.target.result.toString()) as GameProgressState
console.debug("Json Data", data)
dispatch(loadProgress({game: gameId, data: data}))
}
closeUploadMenu()
}
const eraseProgress = () => {
dispatch(deleteProgress({game: gameId}))
closeEraseMenu()
}
const downloadAndErase = (e) => {
downloadProgress(e)
eraseProgress()
}
function label(x : number) {
return x == 0 ? 'none' : x == 1 ? 'lax' : 'regular'
}
return <nav className="world-selection-menu">
<Button onClick={downloadProgress} title="Download game progress" to=""><FontAwesomeIcon icon={faDownload} /></Button>
<Button title="Load game progress from JSON" onClick={openUploadMenu} to=""><FontAwesomeIcon icon={faUpload} /></Button>
<Button title="Clear game progress" to="" onClick={openEraseMenu}><FontAwesomeIcon icon={faEraser} /></Button>
<div className="slider-wrap">
<span className="difficulty-label">Game Rules:</span>
<span className="difficulty-label">Game Rules</span>
<Slider
orientation="vertical"
title="Game Rules:&#10;- regular: 🔐 levels, 🔐 tactics&#10;- lax: 🔓 levels, 🔐 tactics&#10;- none: 🔓 levels, 🔓 tactics"
min={0} max={2}
aria-label="Game Rules"
@@ -279,48 +212,12 @@ function WorldSelectionMenu() {
]}
valueLabelFormat={label}
getAriaValueText={label}
valueLabelDisplay="auto"
valueLabelDisplay="off"
onChange={(ev, val: number) => {
dispatch(changedDifficulty({game: gameId, difficulty: val}))
}}
></Slider>
</div>
{eraseMenu?
<div className="modal-wrapper">
<div className="modal-backdrop" onClick={closeEraseMenu} />
<div className="modal">
<div className="codicon codicon-close modal-close" onClick={closeEraseMenu}></div>
<h2>Delete Progress?</h2>
<p>Do you want to delete your saved progress irreversibly?</p>
<p>
(This deletes your proofs and your collected inventory.
Saves from other games are not deleted.)
</p>
<Button onClick={eraseProgress} to="">Delete</Button>
<Button onClick={downloadAndErase} to="">Download & Delete</Button>
<Button onClick={closeEraseMenu} to="">Cancel</Button>
</div>
</div> : null}
{uploadMenu ?
<div className="modal-wrapper">
<div className="modal-backdrop" onClick={closeUploadMenu} />
<div className="modal">
<div className="codicon codicon-close modal-close" onClick={closeUploadMenu}></div>
<h2>Upload Saved Progress</h2>
<p>Select a JSON file with the saved game progress to load your progress.</p>
<p><b>Warning:</b> This will delete your current game progress!
Consider <a className="download-link" onClick={downloadProgress} >downloading your current progress</a> first!</p>
<input type="file" onChange={handleFileChange}/>
<Button to="" onClick={uploadProgress}>Load selected file</Button>
</div>
</div> : null}
</nav>
}
@@ -444,7 +341,7 @@ export function WorldTreePanel({worlds, worldSize}:
let dx = bounds ? s*(bounds.x2 - bounds.x1) + 2*padding : null
return <div className="column">
<WorldSelectionMenu />
<WorldSelectionMenu />
<svg xmlns="http://www.w3.org/2000/svg" xmlnsXlink="http://www.w3.org/1999/xlink"
width={bounds ? `${ds * dx}` : ''}
viewBox={bounds ? `${s*bounds.x1 - padding} ${s*bounds.y1 - padding} ${dx} ${s*(bounds.y2 - bounds.y1) + 2 * padding}` : ''}