add menu to delete game progress
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
import * as React from 'react'
|
||||
import { Button } from './Button'
|
||||
import { GameIdContext } from '../App';
|
||||
import { useStore } from 'react-redux';
|
||||
import { useAppDispatch, useAppSelector } from '../hooks';
|
||||
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
||||
import { faDownload, faUpload, faEraser } from '@fortawesome/free-solid-svg-icons'
|
||||
|
||||
import { deleteProgress } from '../state/progress';
|
||||
|
||||
function GameMenu() {
|
||||
|
||||
const gameId = React.useContext(GameIdContext)
|
||||
const store = useStore()
|
||||
|
||||
const [eraseMenu, setEraseMenu] = React.useState(false);
|
||||
const openEraseMenu = () => setEraseMenu(true);
|
||||
const closeEraseMenu = () => setEraseMenu(false);
|
||||
|
||||
const dispatch = useAppDispatch()
|
||||
|
||||
const downloadProgress = () => {};
|
||||
// const uploadProgress = () => {};
|
||||
|
||||
const eraseProgress = () => {
|
||||
dispatch(deleteProgress({game: gameId}))
|
||||
closeEraseMenu()
|
||||
}
|
||||
|
||||
const downloadAndErase = () => {
|
||||
downloadProgress ()
|
||||
eraseProgress()
|
||||
}
|
||||
|
||||
return <nav className="game-menu">
|
||||
<Button disabled={true} onClick={downloadProgress} title="Download game progress" to=""><FontAwesomeIcon icon={faDownload} /></Button>
|
||||
<Button disabled={true} title="Load game progress from JSON" to=""><FontAwesomeIcon icon={faUpload} /></Button>
|
||||
<Button title="Clear game progress" to="" onClick={openEraseMenu}><FontAwesomeIcon icon={faEraser} /></Button>
|
||||
|
||||
{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 state irreversibly?</p>
|
||||
<p>(This only affects your saved proofs, no levels are ever locked.
|
||||
Saves from other games are not deleted.)</p>
|
||||
|
||||
<Button onClick={eraseProgress} to="">Delete</Button>
|
||||
<Button disabled={true} onClick={downloadAndErase} to="">Download & Delete</Button>
|
||||
<Button onClick={closeEraseMenu} to="">Cancel</Button>
|
||||
</div>
|
||||
</div> : null}
|
||||
</nav>
|
||||
}
|
||||
|
||||
export default GameMenu
|
||||
@@ -7,6 +7,7 @@ import { useNavigate } from 'react-router-dom';
|
||||
import { useSelector } from 'react-redux';
|
||||
import Split from 'react-split'
|
||||
|
||||
import GameMenu from './GameMenu';
|
||||
import {PrivacyPolicy} from './PrivacyPolicy';
|
||||
|
||||
cytoscape.use( klay );
|
||||
@@ -17,6 +18,11 @@ import { Link } from 'react-router-dom';
|
||||
import Markdown from './Markdown';
|
||||
import { selectCompleted } from '../state/progress';
|
||||
import { GameIdContext } from '../App';
|
||||
import { Button } from './Button';
|
||||
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
||||
import { faDownload, faUpload, faEraser } from '@fortawesome/free-solid-svg-icons'
|
||||
|
||||
|
||||
const N = 24 // max number of levels per world
|
||||
const R = 800 // radius of a world
|
||||
@@ -33,7 +39,7 @@ function LevelIcon({ worldId, levelId, position }) {
|
||||
|
||||
// TODO: relative positioning?
|
||||
return (
|
||||
<Link to={`/game/${gameId}/world/${worldId}/level/${levelId}`} key={`/game/${gameId}/world/${worldId}/level/${levelId}`}>
|
||||
<Link to={`/game/${gameId}/world/${worldId}/level/${levelId}`}>
|
||||
<circle fill={completed ? "green" :"#999"} cx={x} cy={y} r={r} />
|
||||
</Link>
|
||||
)
|
||||
@@ -69,7 +75,9 @@ function Welcome() {
|
||||
|
||||
for (let i = 1; i <= gameInfo.data.worldSize[id]; i++) {
|
||||
svgElements.push(
|
||||
<LevelIcon position={position} worldId={id} levelId={i} />
|
||||
<LevelIcon
|
||||
key={`/game/${gameId}/world/${id}/level/${i}`}
|
||||
position={position} worldId={id} levelId={i} />
|
||||
)
|
||||
}
|
||||
|
||||
@@ -103,6 +111,7 @@ function Welcome() {
|
||||
</Typography>
|
||||
</div>
|
||||
<div className="column">
|
||||
<GameMenu />
|
||||
<Box textAlign='center' sx={{ m: 5 }}>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlnsXlink="http://www.w3.org/1999/xlink"
|
||||
viewBox={bounds ? `${s*bounds.x1 - padding} ${s*bounds.y1 - padding} ${s*bounds.x2 - s*bounds.x1 + 2 * padding} ${s*bounds.y2 - s*bounds.y1 + 2 * padding}` : ''}>
|
||||
@@ -112,7 +121,7 @@ function Welcome() {
|
||||
</div>
|
||||
</Split>
|
||||
}
|
||||
<PrivacyPolicy/>
|
||||
<PrivacyPolicy />
|
||||
</div>
|
||||
}
|
||||
|
||||
|
||||
@@ -191,3 +191,15 @@ svg .world-title {
|
||||
.modal table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.game-menu {
|
||||
padding: .5em;
|
||||
}
|
||||
|
||||
.game-menu .btn {
|
||||
min-width: 5em;
|
||||
text-align: center;
|
||||
margin-left: .4em;
|
||||
margin-right: .4em;
|
||||
margin-bottom: .2em;
|
||||
}
|
||||
|
||||
@@ -49,6 +49,9 @@ export const progressSlice = createSlice({
|
||||
addLevelProgress(state, action)
|
||||
state.level[action.payload.game][action.payload.world][action.payload.level].completed = true
|
||||
},
|
||||
deleteProgress(state, action: PayloadAction<{game: string}>) {
|
||||
state.level[action.payload.game] = {}
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
@@ -85,4 +88,4 @@ export function selectProgress() {
|
||||
}
|
||||
}
|
||||
|
||||
export const { changedSelection, codeEdited, levelCompleted } = progressSlice.actions
|
||||
export const { changedSelection, codeEdited, levelCompleted, deleteProgress } = progressSlice.actions
|
||||
|
||||
Reference in New Issue
Block a user