You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
71 lines
2.8 KiB
71 lines
2.8 KiB
import {ReactElement, useContext, useEffect, useRef, useState} from "react";
|
|
import {
|
|
CLIENT_ACT,
|
|
CLIENT_REFRESH,
|
|
ClientActCommand,
|
|
ClientGoodbyeAction,
|
|
ClientHelloCommand,
|
|
ClientRefreshCommand,
|
|
isClientCommand,
|
|
isClientGoodbyeCommand,
|
|
SendableAction,
|
|
SentAction
|
|
} from "../actions/ClientAction";
|
|
import {DispatchContext} from "../ui/context/DispatchContext";
|
|
import {WebsocketTranslator} from "./WebsocketTranslator";
|
|
import {ServerConnectionState} from "../state/NetworkState";
|
|
import {SERVER_SOCKET_STARTUP, SocketState} from "../actions/ServerAction";
|
|
|
|
export function WebsocketReactAdapter({url, protocols = ["v1.hexmap.deliciousreya.net"], state, specialMessage, pendingMessages, nextID}: {
|
|
url: string,
|
|
protocols?: readonly string[],
|
|
state: ServerConnectionState,
|
|
specialMessage: ClientHelloCommand | ClientRefreshCommand | ClientGoodbyeAction | null,
|
|
pendingMessages: readonly SendableAction[],
|
|
nextID: number
|
|
}): ReactElement {
|
|
const dispatch = useContext(DispatchContext)
|
|
if (dispatch === null) {
|
|
throw Error("What the heck?! No dispatch?! I quit!")
|
|
}
|
|
const connector = useRef(new WebsocketTranslator({
|
|
url,
|
|
protocols,
|
|
onStartup: dispatch,
|
|
onMessage: dispatch,
|
|
onError: dispatch,
|
|
onGoodbye: dispatch,
|
|
}))
|
|
useEffect(() => {
|
|
connector.current.connect();
|
|
dispatch({
|
|
type: SERVER_SOCKET_STARTUP,
|
|
state: SocketState.CONNECTING,
|
|
});
|
|
}, [dispatch])
|
|
const [lastSpecialMessage, setLastSpecialMessage] = useState<ClientHelloCommand | ClientRefreshCommand | ClientGoodbyeAction | null>(null)
|
|
useEffect(() => {
|
|
if (state === ServerConnectionState.CONNECTED && pendingMessages.length > 0) {
|
|
const sentMessages: SentAction[] = pendingMessages.map((action, index) => {
|
|
return {id: index + nextID, action}
|
|
});
|
|
const sentMessage: ClientActCommand = {
|
|
type: CLIENT_ACT,
|
|
actions: sentMessages,
|
|
};
|
|
connector.current.send(sentMessage)
|
|
dispatch(sentMessage)
|
|
}
|
|
}, [nextID, dispatch, pendingMessages, state])
|
|
useEffect(() => {
|
|
if (state === ServerConnectionState.CONNECTED && specialMessage !== null && specialMessage !== lastSpecialMessage) {
|
|
if (isClientCommand(specialMessage)) {
|
|
connector.current.send(specialMessage);
|
|
} else if (isClientGoodbyeCommand(specialMessage)) {
|
|
connector.current.close(specialMessage.code, specialMessage.reason)
|
|
}
|
|
setLastSpecialMessage(specialMessage);
|
|
}
|
|
}, [specialMessage, lastSpecialMessage, setLastSpecialMessage, state])
|
|
return <div className="connectionState" onClick={() => dispatch ? dispatch({type: CLIENT_REFRESH}) : null}>{state}</div>
|
|
} |