mirror of https://github.com/acid-info/WebCave.git
feature: implement chatting functionality on react client
This commit is contained in:
parent
dce6a6220b
commit
e654773b81
|
@ -141,7 +141,7 @@ class Renderer implements IRenderer {
|
|||
let ctx = this.textContext = this.textCanvas.getContext( "2d" );
|
||||
ctx.textAlign = "left";
|
||||
ctx.textBaseline = "middle";
|
||||
ctx.font = "24px Minecraftia";
|
||||
ctx.font = "24px";
|
||||
}
|
||||
|
||||
public draw() {
|
||||
|
|
|
@ -14,10 +14,11 @@ import { PayloadBySocketEvent } from '@acid-info/webcave-core/src'
|
|||
import { MultiplayerClient, Player, Renderer } from '@acid-info/webcave-client/src'
|
||||
import { HandlerByMultiplayerEvent } from '@acid-info/webcave-client/src/types/multiplayer.ts'
|
||||
import { EChatActions } from '@acid-info/webcave-client/src/shared/controls.ts'
|
||||
import { DEFAULT_SELECTOR_WIDTH_PX } from '@acid-info/webcave-client/src'
|
||||
|
||||
const WebCaveMultiplayer: React.FC<WebCaveMultiplayerProps> = (props) => {
|
||||
const {
|
||||
selectorWidthPx,
|
||||
selectorWidthPx = DEFAULT_SELECTOR_WIDTH_PX,
|
||||
chunkSize,
|
||||
serverUrl
|
||||
} = props;
|
||||
|
@ -62,7 +63,7 @@ const WebCaveMultiplayer: React.FC<WebCaveMultiplayerProps> = (props) => {
|
|||
if (isReady) {
|
||||
intervalId = setInterval(() => {
|
||||
const currentTime = +new Date / 1000;
|
||||
renderWorld(lastUpdate); // Update local
|
||||
renderWorld(); // Update local
|
||||
|
||||
if (currentTime - lastUpdate > 0.033 && !renderer.shouldSkipRender()) {
|
||||
client.updatePlayer()
|
||||
|
@ -78,7 +79,7 @@ const WebCaveMultiplayer: React.FC<WebCaveMultiplayerProps> = (props) => {
|
|||
}
|
||||
}, [isReady])
|
||||
|
||||
const renderWorld = (lastUpdate: number) => {
|
||||
const renderWorld = () => {
|
||||
if (client) {
|
||||
const player = client.world.localPlayer
|
||||
|
||||
|
@ -110,11 +111,11 @@ const WebCaveMultiplayer: React.FC<WebCaveMultiplayerProps> = (props) => {
|
|||
return;
|
||||
}
|
||||
|
||||
addMessageToChat({
|
||||
type: 'chat',
|
||||
user: "pajicf",
|
||||
msg
|
||||
})
|
||||
chatBoxInputRef.current.blur()
|
||||
|
||||
client.sendMessage(msg);
|
||||
|
||||
chatBoxInputRef.current.value = "";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -145,6 +146,8 @@ const WebCaveMultiplayer: React.FC<WebCaveMultiplayerProps> = (props) => {
|
|||
client.on("connect", onConnectionHandler)
|
||||
client.on("world", onWorldHandler)
|
||||
client.on("spawn", onSpawnHandler)
|
||||
client.on("message", onMessageHandler)
|
||||
client.on("chat", onChatMessageHandler)
|
||||
client.connect(serverUrl, nickname)
|
||||
}
|
||||
|
||||
|
@ -173,9 +176,34 @@ const WebCaveMultiplayer: React.FC<WebCaveMultiplayerProps> = (props) => {
|
|||
setIsReady(true)
|
||||
setStatusMessage(undefined)
|
||||
|
||||
player.on(EChatActions.OPEN_CHAT, () => {
|
||||
setIsChatOpen(true)
|
||||
player.on(EChatActions.OPEN_CHAT, handleOpenChat)
|
||||
}
|
||||
|
||||
const onMessageHandler: HandlerByMultiplayerEvent<"message"> = (msg) => {
|
||||
addMessageToChat({
|
||||
type: 'generic',
|
||||
msg
|
||||
})
|
||||
}
|
||||
|
||||
const onChatMessageHandler: HandlerByMultiplayerEvent<"chat"> = (user, msg) => {
|
||||
addMessageToChat({
|
||||
type: 'chat',
|
||||
user,
|
||||
msg
|
||||
})
|
||||
return false;
|
||||
}
|
||||
|
||||
const handleOpenChat = (state?: boolean) => {
|
||||
setIsChatOpen(prevState => {
|
||||
const newState = state != undefined ? state : !prevState;
|
||||
|
||||
if (prevState === false) {
|
||||
chatBoxInputRef.current.focus()
|
||||
}
|
||||
|
||||
return newState;
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -197,7 +225,7 @@ const WebCaveMultiplayer: React.FC<WebCaveMultiplayerProps> = (props) => {
|
|||
</ItemsSelectorTableContainer>
|
||||
|
||||
<ChatContainer isChatOpen={isChatOpen}>
|
||||
<ChatBox>
|
||||
<ChatBox onClick={() => handleOpenChat(true)}>
|
||||
<ChatBoxText>
|
||||
{messages.map((m, index) => (
|
||||
<span key={`${m}-${index}`}>
|
||||
|
@ -221,6 +249,8 @@ const WebCaveMultiplayer: React.FC<WebCaveMultiplayerProps> = (props) => {
|
|||
maxLength={60}
|
||||
spellCheck={false}
|
||||
onKeyDown={onChatboxEntry}
|
||||
isChatOpen={isChatOpen}
|
||||
placeholder={"Enter message or close the chat by pressing 't'"}
|
||||
/>
|
||||
</ChatContainer>
|
||||
|
||||
|
|
|
@ -4,13 +4,13 @@ export const ChatContainer = styled.div<{isChatOpen: boolean}>`
|
|||
position: absolute;
|
||||
left: 20px;
|
||||
bottom: 18px;
|
||||
opacity: ${props => props.isChatOpen ? '1' : '0'};
|
||||
height: ${props => props.isChatOpen ? 'initial' : '0'};
|
||||
opacity: ${props => props.isChatOpen ? '1' : '0.2'};
|
||||
height: ${props => props.isChatOpen ? 'initial' : '100px'};
|
||||
overflow: hidden;
|
||||
`
|
||||
|
||||
export const ChatBox = styled.div`
|
||||
width: 600px;
|
||||
width: 400px;
|
||||
height: 195px;
|
||||
overflow: hidden;
|
||||
overflow-y: scroll;
|
||||
|
@ -32,9 +32,10 @@ export const ChatBoxText = styled.div`
|
|||
align-items: start;
|
||||
`
|
||||
|
||||
export const ChatBoxEntry = styled.input`
|
||||
width: 610px;
|
||||
height: 30px;
|
||||
export const ChatBoxEntry = styled.input<{isChatOpen: boolean}>`
|
||||
opacity: ${props => props.isChatOpen ? '1' : '0'};
|
||||
height: ${props => props.isChatOpen ? '30px' : '0'};
|
||||
width: 400px;
|
||||
padding-left: 10px;
|
||||
padding-bottom: 2px;
|
||||
background: rgba(0, 0, 0, 0.6);
|
||||
|
|
Loading…
Reference in New Issue