Skip to content

Commit b14ea29

Browse files
committed
fix(client): Make chatMessages and sendChatMessage always available
This change makes sure the chat fields on the client class are always present, so consumers don’t have to double check whether they are there before using them. This commit also moves the dummy transport logic out of the client and into a dedicated `DummyTransport`.
1 parent 6df7bf6 commit b14ea29

6 files changed

Lines changed: 57 additions & 46 deletions

File tree

examples/react-web/src/chess/board.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ class Board extends React.Component {
6767

6868
{this._getStatus()}
6969
{disconnected}
70-
{this.props.sendChatMessage && this.props.chatMessages && (
70+
{this.props.isMultiplayer && this.props.playerID !== null && (
7171
<Chat
7272
onSend={this.props.sendChatMessage}
7373
messages={this.props.chatMessages}

examples/react-web/src/chess/chat.js

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ const Chat = ({ onSend, messages }) => {
77
setMessage(event.target.value);
88
};
99

10-
const triggerSend = () => {
10+
const triggerSend = (event) => {
11+
event.preventDefault();
1112
onSend(message);
1213
setMessage('');
1314
};
@@ -18,19 +19,21 @@ const Chat = ({ onSend, messages }) => {
1819
style={{
1920
height: 200,
2021
maxWidth: 400,
22+
padding: '.5em',
2123
overflow: 'scroll',
2224
border: '1px solid black',
2325
}}
2426
>
2527
{messages.map((message) => (
26-
<div key={message.id}>
27-
<div>{message.sender}</div>
28-
<div>{JSON.stringify(message.payload)}</div>
28+
<div key={message.id} style={{ marginBottom: '.25em' }}>
29+
<strong>Player {message.sender}:</strong> {message.payload}
2930
</div>
3031
))}
3132
</div>
32-
<input onChange={onChange} value={message} />
33-
<button onClick={triggerSend}>Send</button>
33+
<form onSubmit={triggerSend}>
34+
<input onChange={onChange} value={message} />
35+
<button type="submit">Send</button>
36+
</form>
3437
</div>
3538
);
3639
};

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@
177177
},
178178
"coveragePathIgnorePatterns": [
179179
"/node_modules/",
180-
"src/.*/random.alea.js",
180+
"src/client/transport/dummy",
181181
"src/client/debug/.*",
182182
"src/types.ts"
183183
],

src/client/client.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,8 @@ describe('multiplayer', () => {
279279
subscribeMatchData(fn) {
280280
this.callback = fn;
281281
}
282+
283+
subscribeChatMessage() {}
282284
}
283285
const customTransport = () =>
284286
(new CustomTransport() as unknown) as Transport;

src/client/client.ts

Lines changed: 23 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import { CreateGameReducer } from '../core/reducer';
1818
import { InitializeGame } from '../core/initialize';
1919
import { PlayerView } from '../plugins/main';
2020
import type { Transport, TransportOpts } from './transport/transport';
21+
import { DummyTransport } from './transport/dummy';
2122
import { ClientManager } from './manager';
2223
import type {
2324
ActivePlayersArg,
@@ -308,31 +309,17 @@ export class _ClientImpl<G extends any = any> {
308309

309310
this.store = createStore(this.reducer, this.initialState, enhancer);
310311

311-
this.transport = ({
312-
isConnected: true,
313-
onAction: () => {},
314-
subscribe: () => {},
315-
subscribeMatchData: () => {},
316-
subscribeChatMessage: () => {},
317-
connect: () => {},
318-
disconnect: () => {},
319-
updateMatchID: () => {},
320-
updatePlayerID: () => {},
321-
} as unknown) as Transport;
322-
323-
if (multiplayer) {
324-
// typeof multiplayer is 'function'
325-
this.transport = multiplayer({
326-
gameKey: game,
327-
game: this.game,
328-
store: this.store,
329-
matchID,
330-
playerID,
331-
credentials,
332-
gameName: this.game.name,
333-
numPlayers,
334-
});
335-
}
312+
if (!multiplayer) multiplayer = DummyTransport;
313+
this.transport = multiplayer({
314+
gameKey: game,
315+
game: this.game,
316+
store: this.store,
317+
matchID,
318+
playerID,
319+
credentials,
320+
gameName: this.game.name,
321+
numPlayers,
322+
});
336323

337324
this.createDispatchers();
338325

@@ -341,20 +328,18 @@ export class _ClientImpl<G extends any = any> {
341328
this.notifySubscribers();
342329
});
343330

344-
if (this.transport.onChatMessage) {
345-
this.chatMessages = [];
346-
this.sendChatMessage = (payload) => {
347-
this.transport.onChatMessage(this.matchID, {
348-
id: nanoid(7),
349-
sender: this.playerID,
350-
payload: payload,
351-
});
352-
};
353-
this.transport.subscribeChatMessage((message) => {
354-
this.chatMessages = [...this.chatMessages, message];
355-
this.notifySubscribers();
331+
this.chatMessages = [];
332+
this.sendChatMessage = (payload) => {
333+
this.transport.onChatMessage(this.matchID, {
334+
id: nanoid(7),
335+
sender: this.playerID,
336+
payload: payload,
356337
});
357-
}
338+
};
339+
this.transport.subscribeChatMessage((message) => {
340+
this.chatMessages = [...this.chatMessages, message];
341+
this.notifySubscribers();
342+
});
358343
}
359344

360345
private notifySubscribers() {

src/client/transport/dummy.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { Transport } from './transport';
2+
import type { TransportOpts } from './transport';
3+
4+
/**
5+
* This class doesn’t do anything, but simplifies the client class by providing
6+
* dummy functions to call, so we don’t need to mock them in the client.
7+
*/
8+
class DummyImpl extends Transport {
9+
connect() {}
10+
disconnect() {}
11+
onAction() {}
12+
onChatMessage() {}
13+
subscribe() {}
14+
subscribeChatMessage() {}
15+
subscribeMatchData() {}
16+
updateCredentials() {}
17+
updateMatchID() {}
18+
updatePlayerID() {}
19+
}
20+
21+
export const DummyTransport = (opts: TransportOpts) => new DummyImpl(opts);

0 commit comments

Comments
 (0)