show lemma and tactic docs

This commit is contained in:
Alexander Bentkamp
2023-02-09 15:34:37 +01:00
parent 891d51829c
commit 116026428f
6 changed files with 119 additions and 20 deletions
+41 -11
View File
@@ -4,31 +4,61 @@ import './inventory.css'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faLock, faLockOpen, faBook, faHammer, faBan } from '@fortawesome/free-solid-svg-icons'
import Markdown from './Markdown';
import { useLoadDocQuery } from '../state/api';
function Inventory({ tactics, lemmas } :
{lemmas: {name: string, locked: boolean, disabled: boolean}[],
tactics: {name: string, locked: boolean, disabled: boolean}[]}) {
return (
<>
<div className="inventory">
{ tactics.map(tac => <InventoryItem name={tac.name} locked={tac.locked} disabled={tac.disabled} />) }
{/* TODO: Click on Tactic: show info
TODO: click on paste icon -> paste into command line */}
</div>
const [docName, setDocName] = useState(null)
const [docType, setDocType] = useState(null)
return (
<div className="inventory">
{ lemmas.map(lem => <InventoryItem name={lem.name} locked={lem.locked} disabled={lem.disabled} />) }
<h2>Tactics</h2>
<div className="inventory-list">
{ tactics.map(tac =>
<InventoryItem key={tac.name} showDoc={() => {setDocName(tac.name); setDocType("tactic")}}
name={tac.name} locked={tac.locked} disabled={tac.disabled} />) }
{/* TODO: Click on Tactic: show info
TODO: click on paste icon -> paste into command line */}
</div>
<h2>Lemmas</h2>
<div className="inventory-list">
{ lemmas.map(lem =>
<InventoryItem key={lem.name} showDoc={() => {setDocName(lem.name); setDocType("lemma")}}
name={lem.name} locked={lem.locked} disabled={lem.disabled} />) }
</div>
{docName && <Documentation name={docName} type={docType} />}
</div>
</>
)
}
function InventoryItem({name, locked, disabled}) {
function InventoryItem({name, locked, disabled, showDoc}) {
const icon = locked ? <FontAwesomeIcon icon={faLock} /> :
disabled ? <FontAwesomeIcon icon={faBan} /> : ""
const className = locked ? "locked" : disabled ? "disabled" : ""
return <div className={`item ${className}`}>{icon} {name}</div>
const handleClick = () => {
if (!locked && !disabled) {
showDoc()
}
}
return <div className={`item ${className}`} onClick={handleClick}>{icon} {name}</div>
}
function Documentation({name, type}) {
const doc = useLoadDocQuery({type: type, name: name})
return <>
<h2 className="doc">{doc.data?.name}</h2>
<Markdown>{doc.data?.text}</Markdown>
</>
}
export default Inventory;
+21 -1
View File
@@ -1,8 +1,23 @@
.inventory {
padding: 0 1em;
}
.inventory h2 {
font-size: 1.5em;
margin-top: 1em;
margin-bottom: .2em;
}
.inventory h2.doc {
margin-top: 1.5em;
font-weight: 900;
}
.inventory-list {
display: flex;
gap: .5em;
flex-wrap : wrap;
padding: 1em
}
.inventory .item {
@@ -14,3 +29,8 @@
.inventory .item.disabled {
color: #aaa;
}
.inventory .item:not(.locked):not(.disabled) {
cursor: pointer;
}
+10 -1
View File
@@ -20,6 +20,12 @@ interface LevelInfo {
descrFormat: null|string,
}
interface Doc {
name: string,
text: string
}
const customBaseQuery = async (
args : {method: string, params?: any},
{ signal, dispatch, getState, extra },
@@ -48,9 +54,12 @@ export const apiSlice = createApi({
loadLevel: builder.query<LevelInfo, {world: string, level: number}>({
query: ({world, level}) => {return {method: "loadLevel", params: {world, level}}},
}),
loadDoc: builder.query<Doc, {name: string, type: "lemma"|"tactic"}>({
query: ({name, type}) => {return {method: "loadDoc", params: {name, type}}},
}),
}),
})
// Export hooks for usage in functional components, which are
// auto-generated based on the defined endpoints
export const { useGetGameInfoQuery, useLoadLevelQuery } = apiSlice
export const { useGetGameInfoQuery, useLoadLevelQuery, useLoadDocQuery } = apiSlice