Refactoring the talk npcs component.

This commit is contained in:
Sergiotarxz 2023-07-12 16:01:27 +02:00
parent c7f299eb79
commit 3530c253a1
4 changed files with 116 additions and 79 deletions

View File

@ -1,18 +1,21 @@
import * as React from 'react' import * as React from 'react'
import type { Action, ActionHash } from '@lastres/action' import type { Action, ActionHash } from '@lastres/action'
import type { TalkNPCs, TalkNPC } from '@lastres/talk-npc' import type { TalkNPCs } from '@lastres/talk-npc'
import type { StateGame, OnWordSelectCallback } from '@lastres/components/game'
import OutputPacketExecuteAction from '@lastres/output-packet/execute_action' import OutputPacketExecuteAction from '@lastres/output-packet/execute_action'
import OutputPacketTalk from '@lastres/output-packet/talk';
import PresentationItem from '@lastres/components/presentation-item' import PresentationItem from '@lastres/components/presentation-item'
import Presentation from '@lastres/components/presentation' import Presentation from '@lastres/components/presentation'
import TalkNPCsComponent from '@lastres/components/talk-npcs'
export interface BottomPanelProps { export interface BottomPanelProps {
websocket: WebSocket | null websocket: WebSocket | null
actionHash: ActionHash | null actionHash: ActionHash | null
talkNPCs: TalkNPCs | null talkNPCs: TalkNPCs | null
setStateGame: (set: StateGame) => void
setOnWordSelect: (set: OnWordSelectCallback) => void
} }
export interface Style { export interface Style {
@ -21,7 +24,7 @@ export interface Style {
export default function BottomPanel (props: BottomPanelProps): JSX.Element { export default function BottomPanel (props: BottomPanelProps): JSX.Element {
const actionHash = props.actionHash const actionHash = props.actionHash
function printListActions(): JSX.Element { function printListActions (): JSX.Element {
if (actionHash === null) { if (actionHash === null) {
return <></> return <></>
} }
@ -74,60 +77,6 @@ export default function BottomPanel (props: BottomPanelProps): JSX.Element {
} }
</> </>
} }
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 ( return (
<Presentation> <Presentation>
<PresentationItem> <PresentationItem>
@ -136,9 +85,8 @@ export default function BottomPanel (props: BottomPanelProps): JSX.Element {
} }
</PresentationItem> </PresentationItem>
<PresentationItem> <PresentationItem>
{ <TalkNPCsComponent websocket={props.websocket}
printTalkNpcs() talkNPCs={props.talkNPCs}/>
}
</PresentationItem> </PresentationItem>
<PresentationItem> <PresentationItem>
</PresentationItem> </PresentationItem>

View File

@ -25,6 +25,13 @@ export interface GameProps {
setWebsocket: (websocket: WebSocket | null | SetWebsocketCallback) => void setWebsocket: (websocket: WebSocket | null | SetWebsocketCallback) => void
} }
export enum StateGame {
MainScreen,
SelectingWord,
}
export type OnWordSelectCallback = (word: string) => void
export default function Game (props: GameProps): JSX.Element { export default function Game (props: GameProps): JSX.Element {
const selectedPJ = props.selectedPJ const selectedPJ = props.selectedPJ
if (selectedPJ === null) { if (selectedPJ === null) {
@ -51,6 +58,8 @@ export default function Game (props: GameProps): JSX.Element {
const [remainingFrames, setRemainingFrames] = React.useState<number | null>(null) const [remainingFrames, setRemainingFrames] = React.useState<number | null>(null)
const [actionHash, setActionHash] = React.useState<ActionHash | null>(null) const [actionHash, setActionHash] = React.useState<ActionHash | null>(null)
const [talkNPCs, setTalkNPCs] = React.useState<TalkNPCs | null>(null) const [talkNPCs, setTalkNPCs] = React.useState<TalkNPCs | null>(null)
const [onWordSelect, setOnWordSelect] = React.useState<OnWordSelectCallback | null>(null)
const [stateGame, setStateGame] = React.useState<StateGame>(StateGame.MainScreen)
const logPresentationRef = React.useRef<HTMLDivElement>(null) const logPresentationRef = React.useRef<HTMLDivElement>(null)
const websocket = props.websocket const websocket = props.websocket
const setWebsocket = props.setWebsocket const setWebsocket = props.setWebsocket
@ -101,21 +110,29 @@ export default function Game (props: GameProps): JSX.Element {
return websocket return websocket
}) })
}, 300) }, 300)
return ( if (stateGame === StateGame.SelectingWord) {
<> return <></>
<UpperPanel teamPJs={teamPJs} }
enemyTeamPJs={enemyTeamPJs} if (stateGame === StateGame.MainScreen) {
isBattling={isBattling} return (
currentLocation={currentLocation} <>
connectedLocations={connectedLocations} <UpperPanel teamPJs={teamPJs}
logLines={logLines} enemyTeamPJs={enemyTeamPJs}
websocket={websocket} isBattling={isBattling}
logPresentationRef={logPresentationRef} currentLocation={currentLocation}
movingTo={movingTo} connectedLocations={connectedLocations}
remainingFrames={remainingFrames}/> logLines={logLines}
<BottomPanel actionHash={actionHash} websocket={websocket}
websocket={websocket} logPresentationRef={logPresentationRef}
talkNPCs={talkNPCs}/> movingTo={movingTo}
</> remainingFrames={remainingFrames}/>
) <BottomPanel actionHash={actionHash}
websocket={websocket}
talkNPCs={talkNPCs}
setOnWordSelect={setOnWordSelect}
setStateGame={setStateGame}/>
</>
)
}
return <></>
} }

View File

@ -0,0 +1,62 @@
import * as React from 'react'
import type { TalkNPCs, TalkNPC } from '@lastres/talk-npc'
import OutputPacketTalk from '@lastres/output-packet/talk'
export interface TalkNPCsComponentProps {
talkNPCs: TalkNPCs | null
websocket: WebSocket | null
}
export default function TalkNPCsComponent (props: TalkNPCsComponentProps): JSX.Element {
const npcs = props.talkNPCs
function onWordlesslyTalk (npc: TalkNPC): void {
if (props.websocket === null) {
return
}
new OutputPacketTalk(npc.identifier).send(props.websocket)
}
function printAvatar (npc: TalkNPC): JSX.Element {
if (npc.icon === undefined) {
return <></>
}
return <div className="avatar">
<img src={npc.icon}/><div className="shadow"/>
</div>
}
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>
})
}
</>
)
}

File diff suppressed because one or more lines are too long