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}
}
}
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 }
}