LasTres/js-src/components/bottom-panel.tsx

148 lines
5.0 KiB
TypeScript

import * as React from 'react'
import type { Action, ActionHash } from '@lastres/action'
import type { TalkNPCs, TalkNPC } from '@lastres/talk-npc'
import OutputPacketExecuteAction from '@lastres/output-packet/execute_action'
import OutputPacketTalk from '@lastres/output-packet/talk';
import PresentationItem from '@lastres/components/presentation-item'
import Presentation from '@lastres/components/presentation'
export interface BottomPanelProps {
websocket: WebSocket | null
actionHash: ActionHash | null
talkNPCs: TalkNPCs | null
}
export interface Style {
background?: string
}
export default function BottomPanel (props: BottomPanelProps): JSX.Element {
const actionHash = props.actionHash
function printListActions(): JSX.Element {
if (actionHash === null) {
return <></>
}
const listOfActionKeys = Object.keys(actionHash).sort((a, b) => {
const isDisabledComparisionValue: number = +actionHash[a].is_disabled - +actionHash[b].is_disabled
if (isDisabledComparisionValue !== 0) {
return isDisabledComparisionValue
}
if (actionHash[a].name < actionHash[b].name) {
return -1
}
if (actionHash[a].name > actionHash[b].name) {
return 1
}
return 0
})
function printDisabledReason (action: Action): JSX.Element {
if (!action.is_disabled || action.disabled_reason === null) {
return <></>
}
return (
<p className="disabled-reason" style={{ color: 'red' }}>{action.disabled_reason}</p>
)
}
return <>
<p>Acciones disponibles.</p>
{
listOfActionKeys.map((key) => {
const style: Style = {}
const action = actionHash[key]
if (action.is_disabled) {
style.background = 'lightgray'
}
function onClick (): void {
if (action.is_disabled) {
return
}
if (props.websocket !== null) {
new OutputPacketExecuteAction(action.identifier)
.send(props.websocket)
}
}
return <a onClick={onClick} className="action" style={style} key={action.identifier}>
<p>{action.name}</p>
{
printDisabledReason(action)
}
</a>
})
}
</>
}
function printAvatar (npc: TalkNPC): JSX.Element {
if (npc.icon === undefined) {
return <></>
}
return <div className="avatar">
<img src={npc.icon}/><div className="shadow"/>
</div>
}
function onWordlesslyTalk (npc: TalkNPC): void {
if (props.websocket === null) {
return
}
new OutputPacketTalk(npc.identifier).send(props.websocket)
}
function printTalkNpcs (): JSX.Element {
const npcs = props.talkNPCs
if (npcs === null) {
return <></>
}
if (Object.keys(npcs).length < 1) {
return <>
<p>No hay nadie para hablar ahora.</p>
</>
}
return (
<>
<p>Disponible para hablar:</p>
{
Object.keys(npcs).map((identifier) => {
const npc = npcs[identifier]
return <div key={npc.identifier} className="talk-npc">
<div className="detail">
<div className="name-container">
{
printAvatar(npc)
}
<div className="name">
<p>{npc.name}</p>
</div>
</div>
<div className="buttons">
<button onClick={() => {
onWordlesslyTalk(npc)
}}>Hablar</button>
<button>Decir palabra</button>
</div>
</div>
</div>
})
}
</>
)
}
return (
<Presentation>
<PresentationItem>
{
printListActions()
}
</PresentationItem>
<PresentationItem>
{
printTalkNpcs()
}
</PresentationItem>
<PresentationItem>
</PresentationItem>
</Presentation>
)
}