/** * @fileOverview Define the menu displayed with the tree of worlds on the welcome page */ import * as React from 'react' import { useStore, useSelector } from 'react-redux'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import { faDownload, faUpload, faEraser } from '@fortawesome/free-solid-svg-icons' import './world_selection_menu.css' import { Button } from './button' import { GameIdContext } from '../app'; import { useAppDispatch, useAppSelector } from '../hooks'; import { deleteProgress, selectProgress, loadProgress, GameProgressState } from '../state/progress'; /** Only to specify the types for `downloadFile` */ interface downloadFileParam { data: string fileName: string fileType: string } /** Download a file containing `data` */ const downloadFile = ({ data, fileName, fileType } : downloadFileParam) => { const blob = new Blob([data], { type: fileType }) const a = document.createElement('a') a.download = fileName a.href = window.URL.createObjectURL(blob) const clickEvt = new MouseEvent('click', { view: window, bubbles: true, cancelable: true, }) a.dispatchEvent(clickEvt) a.remove() } /** The menu that is shown next to the world selection graph */ function WorldSelectionMenu() { const [file, setFile] = React.useState(); const gameId = React.useContext(GameIdContext) const store = useStore() /* 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), 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() } return } export default WorldSelectionMenu