Skip to content

Commit 7025d49

Browse files
committed
Replace CharacterMessageBuilder with new UserMessage interface
1 parent 0a0b102 commit 7025d49

12 files changed

Lines changed: 102 additions & 111 deletions

src/ActionsHandler.js

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22

33
import { App } from './App';
44
import type { AppState } from './App';
5-
import CharacterMessageBuilder from './CharacterMessageBuilder';
65
import type { CharacterUpdate } from './CharacterState';
7-
import type { IntlShape } from 'react-intl';
6+
import EndOfSceneMessage from './EndOfSceneMessage';
7+
import HitWallMessage from './HitWallMessage';
88
import SceneDimensions from './SceneDimensions';
99
import type { AudioManager, MovementBlockName } from './types';
1010

@@ -18,15 +18,11 @@ export default class ActionsHandler {
1818
app: App;
1919
audioManager: AudioManager;
2020
sceneDimensions: SceneDimensions;
21-
characterMessageBuilder: CharacterMessageBuilder;
22-
intl: IntlShape;
2321

24-
constructor(app: App, audioManager: AudioManager, sceneDimensions: SceneDimensions, intl: IntlShape) {
22+
constructor(app: App, audioManager: AudioManager, sceneDimensions: SceneDimensions) {
2523
this.app = app;
2624
this.audioManager = audioManager;
2725
this.sceneDimensions = sceneDimensions;
28-
this.characterMessageBuilder = new CharacterMessageBuilder(sceneDimensions);
29-
this.intl = intl;
3026
}
3127

3228
doAction(action: MovementBlockName, stepTimeMs: number): Promise<ActionResult> {
@@ -140,9 +136,16 @@ export default class ActionsHandler {
140136
};
141137

142138
if (characterUpdate.event != null) {
143-
const message = this.characterMessageBuilder.buildMessage(characterUpdate.event, this.intl);
144-
if (message != null) {
145-
stateUpdate.message = message;
139+
switch(characterUpdate.event.type) {
140+
case 'endOfScene':
141+
stateUpdate.message = new EndOfSceneMessage();
142+
break;
143+
case 'hitWall':
144+
stateUpdate.message = new HitWallMessage(characterUpdate.event.x, characterUpdate.event.y, this.sceneDimensions);
145+
break;
146+
default:
147+
// Unhandled event type
148+
break;
146149
}
147150
}
148151

src/ActionsHandler.test.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ function createActionsHandler() {
3434
AudioManagerImpl.mockClear();
3535

3636
// $FlowFixMe: Jest mock API
37-
const actionsHandler = new ActionsHandler(new App(), new AudioManagerImpl(), sceneDimensions, intl);
37+
const actionsHandler = new ActionsHandler(new App(), new AudioManagerImpl(), sceneDimensions);
3838

3939
// $FlowFixMe: Jest mock API
4040
const appMock = App.mock.instances[0];
@@ -267,7 +267,11 @@ test.each(([
267267
expect(newState.characterState.xPos).toBe(testData.expectedX);
268268
expect(newState.characterState.yPos).toBe(testData.expectedY);
269269
expect(newState.characterState.direction).toBe(testData.expectedDirection);
270-
expect(newState.message).toBe(testData.expectedMessage);
270+
if (testData.expectedMessage != null) {
271+
expect(newState.message.getMessage(intl)).toBe(testData.expectedMessage);
272+
} else {
273+
expect(newState.message).toBe(testData.expectedMessage);
274+
}
271275
});
272276

273277
actionsHandler.doAction(testData.action, 0).then((result) => {

src/App.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ import ProgramSpeedController from './ProgramSpeedController';
4141
import ProgramSerializer from './ProgramSerializer';
4242
import ActionsSimplificationModal from './ActionsSimplificationModal';
4343
import type { TileCode } from './TileData';
44-
import type { ActionToggleRegister, AudioManager, CommandName, DeviceConnectionStatus, DisplayedCommandName, LanguageTag, RobotDriver, RunningState, ThemeName } from './types';
44+
import type { ActionToggleRegister, AudioManager, CommandName, DeviceConnectionStatus, DisplayedCommandName, LanguageTag, RobotDriver, RunningState, ThemeName, UserMessage } from './types';
4545
import type { WorldName } from './Worlds';
4646
import { getWorldProperties } from './Worlds';
4747
import WorldSelector from './WorldSelector';
@@ -141,7 +141,7 @@ export type AppState = {
141141
customBackgroundDesignMode: boolean,
142142
designModeCursorState: DesignModeCursorState,
143143
selectedCustomBackgroundTile: ?TileCode,
144-
message: ?string
144+
message: ?UserMessage
145145
};
146146

147147
export class App extends React.Component<AppProps, AppState> {
@@ -269,7 +269,7 @@ export class App extends React.Component<AppProps, AppState> {
269269
this.programBlockEditorRef = React.createRef();
270270

271271
const actionsHandler = new ActionsHandler(this, this.audioManager,
272-
this.sceneDimensions, this.props.intl);
272+
this.sceneDimensions);
273273

274274
this.interpreter = new Interpreter(
275275
this.speedLookUp[this.state.programSpeed - 1],

src/CharacterAriaLive.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import DesignModeCursorDescriptionBuilder from './DesignModeCursorDescriptionBui
88
import DesignModeCursorState from './DesignModeCursorState';
99
import { injectIntl } from 'react-intl';
1010
import type { IntlShape } from 'react-intl';
11-
import type { RunningState } from './types';
11+
import type { RunningState, UserMessage } from './types';
1212
import type { WorldName } from './Worlds';
1313

1414
type CharacterAriaLiveProps = {
@@ -23,11 +23,11 @@ type CharacterAriaLiveProps = {
2323
customBackgroundDesignMode: boolean,
2424
characterDescriptionBuilder: CharacterDescriptionBuilder,
2525
designModeCursorDescriptionBuilder: DesignModeCursorDescriptionBuilder,
26-
message: ?string
26+
message: ?UserMessage
2727
};
2828

2929
class CharacterAriaLive extends React.Component<CharacterAriaLiveProps, {}> {
30-
lastMessage: ?string;
30+
lastMessage: ?UserMessage;
3131

3232
constructor(props: any) {
3333
super(props);
@@ -59,7 +59,7 @@ class CharacterAriaLive extends React.Component<CharacterAriaLiveProps, {}> {
5959

6060
if (this.props.message != null
6161
&& this.props.message !== this.lastMessage) {
62-
text = this.props.message;
62+
text = this.props.message.getMessage(this.props.intl);
6363
if (text.endsWith('.')) {
6464
text += ' ';
6565
} else {

src/CharacterAriaLive.test.js

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -147,8 +147,11 @@ test('When a message is included in the props change, it is included in the live
147147
runningState: 'running'
148148
});
149149
expect(getLiveRegionText()).toBe('');
150+
const message = {
151+
getMessage: () => 'Example message'
152+
};
150153
wrapper.setProps({
151-
message: 'Example message',
154+
message: message,
152155
runningState: 'stopped'
153156
});
154157
expect(getLiveRegionText()).toBe('Example message. At A 1 facing right');
@@ -159,8 +162,11 @@ test('When a message already ends in a period, no extra period is added', () =>
159162
runningState: 'running'
160163
});
161164
expect(getLiveRegionText()).toBe('');
165+
const message = {
166+
getMessage: () => 'Message ending in a period.'
167+
};
162168
wrapper.setProps({
163-
message: 'Message ending in a period.',
169+
message: message,
164170
runningState: 'stopped'
165171
});
166172
expect(getLiveRegionText()).toBe('Message ending in a period. At A 1 facing right');
@@ -171,8 +177,11 @@ test('When a message is in a previous props change, it is included in the live r
171177
runningState: 'running'
172178
});
173179
expect(getLiveRegionText()).toBe('');
180+
const message = {
181+
getMessage: () => 'Example message'
182+
};
174183
wrapper.setProps({
175-
message: 'Example message'
184+
message: message
176185
});
177186
expect(getLiveRegionText()).toBe('');
178187
wrapper.setProps({
@@ -185,8 +194,11 @@ test('A message is only added to the live region once', () => {
185194
const wrapper = createMountCharacterAriaLive({
186195
runningState: 'running'
187196
});
197+
const message = {
198+
getMessage: () => 'Example message'
199+
};
188200
wrapper.setProps({
189-
message: 'Example message'
201+
message: message
190202
});
191203
wrapper.setProps({
192204
runningState: 'stopped'
@@ -202,8 +214,11 @@ test('If a message is set, then set to null, then set to the same text again, it
202214
const wrapper = createMountCharacterAriaLive({
203215
runningState: 'running'
204216
});
217+
const message = {
218+
getMessage: () => 'Example message'
219+
};
205220
wrapper.setProps({
206-
message: 'Example message'
221+
message: message
207222
});
208223
wrapper.setProps({
209224
runningState: 'stopped'
@@ -213,7 +228,7 @@ test('If a message is set, then set to null, then set to the same text again, it
213228
message: null
214229
});
215230
wrapper.setProps({
216-
message: 'Example message'
231+
message: message
217232
});
218233
wrapper.setProps({
219234
characterState: new CharacterState(2, 1, 2, [], sceneDimensions)

src/CharacterMessageBuilder.js

Lines changed: 0 additions & 46 deletions
This file was deleted.

src/CharacterMessageBuilder.test.js

Lines changed: 0 additions & 34 deletions
This file was deleted.

src/EndOfSceneMessage.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// @flow
2+
3+
import type { IntlShape } from 'react-intl';
4+
5+
// TODO: Change message key, there is no CharacterMessageBuilder now
6+
7+
export default class EndOfSceneMessage {
8+
getMessage(intl: IntlShape): string {
9+
return intl.formatMessage(
10+
{
11+
id:'CharacterMessageBuilder.endOfScene'
12+
}
13+
);
14+
}
15+
};

src/HitWallMessage.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// @flow
2+
3+
import type { IntlShape } from 'react-intl';
4+
import SceneDimensions from './SceneDimensions';
5+
6+
// TODO: Change message key, there is no CharacterMessageBuilder now
7+
8+
export default class HitWallMessage {
9+
x: number;
10+
y: number;
11+
dimensions: SceneDimensions;
12+
13+
constructor(x: number, y: number, dimensions: SceneDimensions) {
14+
this.x = x;
15+
this.y = y;
16+
this.dimensions = dimensions;
17+
}
18+
19+
getMessage(intl: IntlShape): string {
20+
const columnLabel = this.dimensions.getColumnLabel(this.x);
21+
const rowLabel = this.dimensions.getRowLabel(this.y);
22+
return intl.formatMessage(
23+
{
24+
id:'CharacterMessageBuilder.hitWall'
25+
},
26+
{
27+
columnLabel: columnLabel == null ? '' : columnLabel,
28+
rowLabel: rowLabel == null ? '' : rowLabel
29+
}
30+
);
31+
}
32+
};

src/Interpreter.test.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import ActionsHandler from './ActionsHandler';
44
import { App } from './App';
55
import Interpreter from './Interpreter';
66
import ProgramSequence from './ProgramSequence';
7-
import type { IntlShape } from 'react-intl';
87
import SceneDimensions from './SceneDimensions';
98
import type { AudioManager, MovementBlockName } from './types';
109

@@ -26,8 +25,7 @@ function createInterpreter() {
2625
const actionsHandlerMock = new ActionsHandler(
2726
((null: any): App),
2827
((null: any): AudioManager),
29-
((null: any): SceneDimensions),
30-
((null: any): IntlShape)
28+
((null: any): SceneDimensions)
3129
);
3230

3331
actionsHandlerMock.doAction.mockImplementation((action: MovementBlockName) => {

0 commit comments

Comments
 (0)