Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 28 additions & 2 deletions src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -145,13 +145,15 @@ export class App extends React.Component<AppProps, AppState> {
customBackgroundSerializer: CustomBackgroundSerializer;
speedLookUp: Array<number>;
pushStateTimeoutID: ?TimeoutID;
languageSelectorRef: { current: any };
programBlockEditorRef: { current: any };
sequenceInProgress: Array<KeyboardEvent>;
announcementBuilder: AnnouncementBuilder;
characterDescriptionBuilder: CharacterDescriptionBuilder;
designModeCursorDescriptionBuilder: DesignModeCursorDescriptionBuilder;
programChangeController: ProgramChangeController;
defaultWorld: WorldName;
focusLanguageSelector: boolean;

constructor(props: any) {
super(props);
Expand Down Expand Up @@ -180,6 +182,8 @@ export class App extends React.Component<AppProps, AppState> {

this.defaultWorld = 'Sketchpad';

this.focusLanguageSelector = false;

// Initialize startingX, startingY, and startingDirection to the world starting position
const startingX = getWorldProperties(this.defaultWorld).startingX;
const startingY = getWorldProperties(this.defaultWorld).startingY;
Expand Down Expand Up @@ -247,6 +251,8 @@ export class App extends React.Component<AppProps, AppState> {
this.programChangeController = new ProgramChangeController(this,
this.audioManager);

this.languageSelectorRef = React.createRef();

this.programBlockEditorRef = React.createRef();

const actionsHandler = new ActionsHandler(this, this.audioManager,
Expand Down Expand Up @@ -333,6 +339,15 @@ export class App extends React.Component<AppProps, AppState> {

// Handlers

handleChangeLanguage = (language: LanguageTag) => {
// Changing the language will cause the App to update and for focus to
// be lost. Set this.focusLanguageSelector to true to indicate that we
// want to set focus back to the language selector after the update.
this.focusLanguageSelector = true;
// Call the provided handler
this.props.onChangeLanguage(language);
};

handleProgramSequenceChange = (programSequence: ProgramSequence) => {
this.setState({
programSequence: programSequence
Expand Down Expand Up @@ -1278,7 +1293,8 @@ export class App extends React.Component<AppProps, AppState> {
<div className='App__PrivacyButtonLanguageSelectorRow'>
<LanguageSelector
value={this.props.language}
onChange={this.props.onChangeLanguage}
onChange={this.handleChangeLanguage}
ref={this.languageSelectorRef}
/>
<button
aria-label={this.props.intl.formatMessage({id: 'App.privacyModalToggle.ariaLabel'})}
Expand Down Expand Up @@ -1881,7 +1897,7 @@ export class App extends React.Component<AppProps, AppState> {
document.addEventListener('keydown', this.handleDocumentKeyDown);
}

componentDidUpdate(prevProps: {}, prevState: AppState) {
componentDidUpdate(prevProps: AppProps, prevState: AppState) {
if (this.state.programSequence !== prevState.programSequence
|| this.state.characterState !== prevState.characterState
|| this.state.settings.theme !== prevState.settings.theme
Expand Down Expand Up @@ -1981,6 +1997,16 @@ export class App extends React.Component<AppProps, AppState> {
);
}
}

// If the language has been changed and this.focusLanguageSelector is
// set, then set focus to the language selector
if (this.props.language !== prevProps.language
&& this.focusLanguageSelector) {
if (this.languageSelectorRef.current) {
this.languageSelectorRef.current.focus();
}
this.focusLanguageSelector = false;
}
}

componentWillUnmount() {
Expand Down
21 changes: 12 additions & 9 deletions src/LanguageSelector.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,26 @@ type LanguageSelectorProps = {
onChange: (value: LanguageTag) => void
};

export default class LanguageSelector extends React.PureComponent<LanguageSelectorProps, {}> {
handleClick = () => {
this.props.onChange(this.props.value === 'en' ? 'fr' : 'en');
};
const LanguageSelector = React.forwardRef<LanguageSelectorProps, HTMLButtonElement>(
(props, ref) => {
const handleClick = () => {
props.onChange(props.value === 'en' ? 'fr' : 'en');
};

render() {
const label = this.props.value === 'en' ? 'Français' : 'English';
const labelLang = this.props.value === 'en' ? 'fr' : 'en';
const label = props.value === 'en' ? 'Français' : 'English';
const labelLang = props.value === 'en' ? 'fr' : 'en';

return (
<button
className='LanguageSelector'
lang={labelLang}
onClick={this.handleClick}
onClick={handleClick}
ref={ref}
>
{label}
</button>
);
}
};
);

export default LanguageSelector;
Loading