Skip to content

Commit

Permalink
fix: Update all menus to use callbacks instead of ids
Browse files Browse the repository at this point in the history
  • Loading branch information
mmcknett committed Jul 12, 2022
1 parent 5682771 commit 5191f29
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 76 deletions.
21 changes: 8 additions & 13 deletions src/demo-react/components/menu.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,23 @@ import { Box, useInput } from 'ink';

import Button from './button';

export const MenuEntry = (title, selectionId, color) => ({
export const MenuEntry = (title, onItemSelected, color) => ({
color,
title,
selectionId
onItemSelected
});

MenuEntry.propTypes = PropTypes.shape({
title: PropTypes.string,
selecitonId: PropTypes.string,
onItemSelected: PropTypes.func,
color: PropTypes.string
});

export const Menu = ({ isActive, items, onFocusPrevious, onItemSelected, width }) => {
export const Menu = ({ isActive, items, onFocusPrevious, width }) => {
const menu = items;
const [selectedIdx, setSelectedIdx] = useState(0);

const inputHandler = (input, key) => {
const inputHandler = (_, key) => {
if (key.upArrow || key.leftArrow || (key.shift && key.tab)) {
setSelectedIdx(Math.max(0, selectedIdx - 1));
if (selectedIdx - 1 < 0) {
Expand All @@ -31,12 +31,8 @@ export const Menu = ({ isActive, items, onFocusPrevious, onItemSelected, width }
} else if (key.downArrow || key.rightArrow || (key.tab)) {
setSelectedIdx(Math.min(menu.length - 1, selectedIdx + 1));
} else if (key.return) {
const selectedItemId = menu[selectedIdx].selectionId;
if (typeof selectedItemId === 'function') {
selectedItemId();
} else {
onItemSelected(selectedItemId);
}
const onItemSelected = menu[selectedIdx].onItemSelected;
onItemSelected();
}

};
Expand Down Expand Up @@ -74,6 +70,5 @@ Menu.propTypes = {

Menu.defaultProps = {
isActive: true,
onFocusPrevious: () => {},
onItemSelected: () => {}
onFocusPrevious: () => {}
}
18 changes: 3 additions & 15 deletions src/demo-react/screens/game-setup.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,21 +32,10 @@ export default function SetupGame() {
setSelectedField(fields[idxMenu - 1]);
}

// TODO: MenuEntry could use a callback instead of this selection ID concept.
const menu = [
MenuEntry('Enter Names', 'names'),
MenuEntry('Go Back', 'go-back')
]
const handleSelection = (selectionId) => {
switch(selectionId) {
case 'names':
dispatch(new SwitchScreenAction(ScreenId.ENTER_PLAYERS));
break;
case 'go-back':
dispatch(new SwitchScreenAction(ScreenId.MAIN_MENU));
break;
}
}
MenuEntry('Enter Names', () => dispatch(new SwitchScreenAction(ScreenId.ENTER_PLAYERS))),
MenuEntry('Go Back', () => dispatch(new SwitchScreenAction(ScreenId.MAIN_MENU)))
];

return (
<Box
Expand Down Expand Up @@ -86,7 +75,6 @@ export default function SetupGame() {
Seconds per player per round (10-60)
</NumberField>
<Menu
onItemSelected={ handleSelection }
onFocusPrevious={ selectFieldBeforeMenu }
items={ menu }
isActive={ selectedField === 'menu' }
Expand Down
21 changes: 14 additions & 7 deletions src/demo-react/screens/how-to.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,22 @@ import React from 'react';
import PropTypes from 'prop-types';

import { Menu, MenuEntry } from '../components/menu';
import { useGameStateContext } from '../components/gamestate-context';
import { SwitchScreenAction, ScreenId } from '../gamestate/screens';

import { Text, Box, Newline } from 'ink';

export default function HowTo({ showMainMenu }) {
const oneButtonMenu = [ MenuEntry('Go Back', 'goback') ];
export default function HowTo() {
const { dispatch } = useGameStateContext();

const oneButtonMenu = [
MenuEntry(
'Go Back',
() => dispatch(
new SwitchScreenAction(ScreenId.MAIN_MENU)
)
)
];

return (
<Box
Expand All @@ -28,11 +39,7 @@ export default function HowTo({ showMainMenu }) {
</Text>
<Text>Whoever has the highest scoring words across all rounds wins the game!</Text>
<Newline />
<Menu width='100%' items={ oneButtonMenu } onItemSelected={ showMainMenu } />
<Menu width='100%' items={ oneButtonMenu } />
</Box>
)
};

HowTo.propTypes = {
showMainMenu: PropTypes.func.isRequired
}
29 changes: 6 additions & 23 deletions src/demo-react/screens/index.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
import React from 'react';

import {
SwitchScreenAction,
ScreenId,
onHelpScreen,
onSetupScreen
} from '../gamestate/screens';
import { ScreenId } from '../gamestate/screens';

import HowTo from './how-to';
import MainMenu from './main-menu';
Expand All @@ -17,25 +12,13 @@ import { useGameStateContext } from '../components/gamestate-context';
import ErrorViewer from '../components/error-viewer';

export default function ScreenDisplayer() {
const { state, dispatch } = useGameStateContext();
const { state } = useGameStateContext();

const showHowTo = () => dispatch(new SwitchScreenAction(ScreenId.HOW_TO));
const showSetupGame = () => dispatch(new SwitchScreenAction(ScreenId.SETUP));
let screen = <MainMenu />;

let screen = (
<MainMenu
onHelpSelected={ showHowTo }
onStartSelected={ showSetupGame }
/>
);

if (onHelpScreen(state)) {
const showMainMenu = () => dispatch(
new SwitchScreenAction(ScreenId.MAIN_MENU)
);

screen = <HowTo showMainMenu={ showMainMenu } />;
} else if (onSetupScreen(state)) {
if (state.currentScreen === ScreenId.HOW_TO) {
screen = <HowTo />;
} else if (state.currentScreen === ScreenId.SETUP) {
screen = <SetupGame />;
} else if (state.currentScreen === ScreenId.ENTER_PLAYERS) {
screen = <EnterPlayers />;
Expand Down
27 changes: 9 additions & 18 deletions src/demo-react/screens/main-menu.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,20 @@ import PropTypes from 'prop-types';

import { Box, useApp } from 'ink';

import { useGameStateContext } from '../components/gamestate-context';
import { Menu, MenuEntry } from '../components/menu';
import { SwitchScreenAction, ScreenId } from '../gamestate/screens';

export default function MainMenu({ onHelpSelected, onStartSelected }) {
export default function MainMenu() {
const { exit } = useApp();
const { dispatch } = useGameStateContext();

const mainMenu = [
MenuEntry('Start New Game', 'start'),
MenuEntry('How to Play', 'help'),
MenuEntry('Quit', 'quit', 'red')
MenuEntry('Start New Game', () => dispatch(new SwitchScreenAction(ScreenId.SETUP))),
MenuEntry('How to Play', () => dispatch(new SwitchScreenAction(ScreenId.HOW_TO))),
MenuEntry('Quit', exit, 'red')
];

const handleSelection = (selectionId) => {
switch(selectionId) {
case 'quit': exit(); break;
case 'help': onHelpSelected(); break;
case 'start': onStartSelected(); break;
}
}

return (
<Box
flexDirection='row'
Expand All @@ -29,12 +25,7 @@ export default function MainMenu({ onHelpSelected, onStartSelected }) {
borderStyle='single'
paddingY='2'
>
<Menu onItemSelected={ handleSelection } items={ mainMenu } />
<Menu items={ mainMenu } />
</Box>
);
}

MainMenu.propTypes = {
onHelpSelected: PropTypes.func.isRequired,
onStartSelected: PropTypes.func.isRequired
}

0 comments on commit 5191f29

Please sign in to comment.