import * as React from 'react'; import { useState, useEffect, useRef } from 'react'; import './welcome.css' import cytoscape, { LayoutOptions } from 'cytoscape' import klay from 'cytoscape-klay'; import { useNavigate } from 'react-router-dom'; import { useSelector } from 'react-redux'; cytoscape.use( klay ); import { Box, Typography, CircularProgress } from '@mui/material'; import { useGetGameInfoQuery } from '../state/api'; import { Link } from 'react-router-dom'; import Markdown from './Markdown'; import { selectCompleted } from '../state/progress'; import { SetTitleContext } from '../App'; function LevelIcon({ worldId, levelId, position }) { const completed = useSelector(selectCompleted(worldId,levelId)) // TODO: relative positioning? return ( ) } function Welcome() { const navigate = useNavigate(); const gameInfo = useGetGameInfoQuery() const { nodes, bounds }: any = gameInfo.data ? computeWorldLayout(gameInfo.data?.worlds) : {nodes: []} const {setTitle, setSubtitle} = React.useContext(SetTitleContext); useEffect(() => { if (gameInfo.data?.title) { window.document.title = gameInfo.data.title setTitle(gameInfo.data.title) } }, [gameInfo.data?.title]) const padding = 20 const svgElements = [] if (gameInfo.data) { for (let i in gameInfo.data.worlds.edges) { const edge = gameInfo.data.worlds.edges[i] svgElements.push( ) } for (let id in nodes) { let position: cytoscape.Position = nodes[id].position svgElements.push( {nodes[id].data.title ? nodes[id].data.title : id} ) for (let i = 1; i <= gameInfo.data.worldSize[id]; i++) { svgElements.push( ) } } } return
{ gameInfo.isLoading? :
{gameInfo.data?.introduction} {svgElements}
}
} export default Welcome function computeWorldLayout(worlds) { let elements = [] for (let id in worlds.nodes) { elements.push({ data: { id: id, title: worlds.nodes[id].title } }) } for (let edge of worlds.edges) { elements.push({ data: { id: edge[0] + " --edge-to--> " + edge[1], source: edge[0], target: edge[1] } }) } const cy = cytoscape({ container: null, elements, headless: true, styleEnabled: false }) const layout = cy.layout({name: "klay", klay: {direction: "DOWN"}} as LayoutOptions).run() let nodes = {} cy.nodes().forEach((node, id) => { nodes[node.id()] = { position: node.position(), data: node.data() } }) const bounds = cy.nodes().boundingBox() return { nodes, bounds } }