diff --git a/client/src/components/LeftPanel.tsx b/client/src/components/LeftPanel.tsx index 1e2fc88..0e75963 100644 --- a/client/src/components/LeftPanel.tsx +++ b/client/src/components/LeftPanel.tsx @@ -1,110 +1,25 @@ import * as React from 'react'; import { useState, useEffect } from 'react'; -import ReactMarkdown from 'react-markdown'; import './inventory.css' - -import { Paper, Box, Typography, Accordion, AccordionSummary, AccordionDetails, Tabs, Tab, Divider, Button, List, ListItem, ListItemButton, ListItemIcon, ListItemText } from '@mui/material'; -import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; - import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import { faLock, faLockOpen, faBook, faHammer, faBan } from '@fortawesome/free-solid-svg-icons' import Markdown from './Markdown'; -function TacticDoc(props) { - return ( - - }> - {props.tactic.name} - - - {props.tactic.content} - - ) -} - -function LemmaDoc({ lemma }) { - return ( - - }> - {lemma.userName} - - - {lemma.content} - - ) -} - -function LemmaDocs({ lemmas }) { - const [categories, setCategories] = useState(new Map()) - const [curCategory, setCurCategory] = useState("") - - const changeTab = (event: React.SyntheticEvent, newValue : string) => { - setCurCategory(newValue); - }; - - useEffect(() => { - const cats = new Map() - lemmas.forEach(function (item) { - const category = item.category - cats.set(category, (cats.get(category) || []).concat([item])) - }); - setCategories(cats) - setCurCategory(cats.keys().next().value) - }, [lemmas]); - - return ( -
- - - {(Array.from(categories)).map(([category, _]) => )} - - - {curCategory && categories.get(curCategory).map((lemma) => )} -
) -} -function LeftPanel({ spells, inventory, showSidePanel, setShowSidePanel }) { +function LeftPanel({ tactics, inventory, showSidePanel, setShowSidePanel }) { return ( <>
- { ["rfl", "tauto", "trivial", "simp", "left", "right", "assumption", "constructor"].map ((tac) => { - const locked = Math.random() > 0.5 - const disabled = Math.random() > 0.5 - const icon = locked ? faLock : disabled ? faBan : faLockOpen + { tactics.map (({name, locked, disabled}) => { + const icon = locked ? : + disabled ? : "" const className = locked ? "locked" : disabled ? "disabled" : "" - return
 {tac}
+ return
{icon} {name}
})} + {/* TODO: Click on Tactic: show info + TODO: click on paste icon -> paste into command line */}
- - - setShowSidePanel(true)}> - - - - - - {spells && spells.length > 0 && - - {spells.map((spell) => )} - } - - - - - - - - - {inventory && inventory.length > 0 && - - - } - - ) } diff --git a/client/src/components/Level.tsx b/client/src/components/Level.tsx index 8743d72..77134bc 100644 --- a/client/src/components/Level.tsx +++ b/client/src/components/Level.tsx @@ -184,8 +184,8 @@ function Level() {
- + {!level.isLoading && }
diff --git a/client/src/components/inventory.css b/client/src/components/inventory.css index 5b04633..40f98c1 100644 --- a/client/src/components/inventory.css +++ b/client/src/components/inventory.css @@ -2,6 +2,7 @@ display: flex; gap: .5em; flex-wrap : wrap; + padding: 1em } .tactic-inventory .tactic { diff --git a/client/src/state/api.ts b/client/src/state/api.ts index 082fe53..23e3de1 100644 --- a/client/src/state/api.ts +++ b/client/src/state/api.ts @@ -14,7 +14,7 @@ interface LevelInfo { title: null|string, introduction: null|string, index: number, - tactics: any[], + tactics: {name: string, disabled: boolean, locked: boolean}[], lemmas: any[], descrText: null|string, descrFormat: null|string, diff --git a/server/leanserver/GameServer/Commands.lean b/server/leanserver/GameServer/Commands.lean index 231a9a9..d0174dc 100644 --- a/server/leanserver/GameServer/Commands.lean +++ b/server/leanserver/GameServer/Commands.lean @@ -266,28 +266,41 @@ elab "MakeGame" : command => do -- Compute which tactics are available in which level: let mut newTacticsInWorld : HashMap Name (HashSet Name) := {} + let mut allTactics : HashSet Name := {} for (worldId, world) in game.worlds.nodes.toArray do let mut newTactics : HashSet Name:= {} for (_, level) in world.levels.toArray do newTactics := newTactics.insertMany level.newTactics + allTactics := allTactics.insertMany level.newTactics newTacticsInWorld := newTacticsInWorld.insert worldId newTactics - let mut tacticsInWorld : HashMap Name (HashSet Name) := {} + let tacticAvailability₀ : HashMap Name TacticAvailability := + HashMap.ofList $ + allTactics.toList.map fun name => + (name, {name, locked := true, disabled := false}) + + let mut tacticsInWorld : HashMap Name (HashMap Name TacticAvailability) := {} for (worldId, _) in game.worlds.nodes.toArray do - let mut tactics : HashSet Name:= {} + let mut tactics : HashMap Name TacticAvailability := tacticAvailability₀ let predecessors := game.worlds.predecessors worldId for predWorldId in predecessors do - tactics := tactics.insertMany (newTacticsInWorld.find! predWorldId) + for tac in newTacticsInWorld.find! predWorldId do + tactics := tactics.insert tac {name := tac, locked := false, disabled := false} tacticsInWorld := tacticsInWorld.insert worldId tactics for (worldId, world) in game.worlds.nodes.toArray do let mut tactics := tacticsInWorld.find! worldId - logInfo m!"{tactics.toArray}" let levels := world.levels.toArray.insertionSort fun a b => a.1 < b.1 for (levelId, level) in levels do - tactics := tactics.insertMany level.newTactics - + for tac in level.newTactics do + tactics := tactics.insert tac {name := tac, locked := false, disabled := false} + for tac in level.disabledTactics do + tactics := tactics.insert tac {name := tac, locked := false, disabled := true} + + let tacticArray := tactics.toArray + |>.insertionSort (fun a b => a.1.toString < b.1.toString) + |>.map (·.2) modifyLevel ⟨← getCurGameId, worldId, levelId⟩ fun level => do - return {level with tactics := ← tactics.toArray.mapM getTacticDoc!} + return {level with tactics := tacticArray} diff --git a/server/leanserver/GameServer/EnvExtensions.lean b/server/leanserver/GameServer/EnvExtensions.lean index 6e726f5..9b5aa67 100644 --- a/server/leanserver/GameServer/EnvExtensions.lean +++ b/server/leanserver/GameServer/EnvExtensions.lean @@ -144,6 +144,12 @@ structure LevelId where level : Nat deriving Inhabited +structure TacticAvailability where + name : Name + locked : Bool + disabled : Bool +deriving ToJson, FromJson, Repr + def getCurLevelId [MonadError m] : m LevelId := do return { game := ← getCurGameId, world := ← getCurWorldId, level := ← getCurLevelIdx} @@ -170,7 +176,7 @@ structure GameLevel where -- only these tactics are allowed in this level (ignore if empty): onlyTactics: Array Name := default -- tactics in this level (computed by `MakeGame`): - tactics: Array TacticDocEntry := default + tactics: Array TacticAvailability := default -- new lemmas introduces by this level: newLemmas: Array Name := default -- lemmas exceptionally forbidden in this level: diff --git a/server/leanserver/GameServer/Game.lean b/server/leanserver/GameServer/Game.lean index cea1e91..9959d48 100644 --- a/server/leanserver/GameServer/Game.lean +++ b/server/leanserver/GameServer/Game.lean @@ -41,7 +41,7 @@ Fields: structure LevelInfo where index : Nat title : String - tactics: Array TacticDocEntry + tactics: Array TacticAvailability lemmas: Array LemmaDocEntry introduction : String descrText : String := ""