+++ /dev/null
-import PropTypes from 'prop-types';
-import React from 'react';
-
-import ZeldaIcon from '../common/ZeldaIcon';
-import {
- addDungeonCheck,
- decrement,
- getDungeonBoss,
- getDungeonRemainingItems,
- getDungeonPrize,
- getGTBoss,
- hasDungeonBoss,
- hasDungeonPrize,
- highestActive,
- increment,
- removeDungeonCheck,
- toggleBoolean,
- toggleBossDefeated,
-} from '../../helpers/tracker';
-import { useTracker } from '../../hooks/tracker';
-
-const ToggleIcon = ({ controller, className, icons, svg }) => {
- const { setManualState, state } = useTracker();
- const activeController = controller || ToggleIcon.nullController;
- const active = activeController.getActive(state, icons);
- const defaultIcon = activeController.getDefault(state, icons);
- const icon = active || defaultIcon || icons[0];
- const classNames = ['toggle-icon'];
- if (active) {
- classNames.push('active');
- } else {
- classNames.push('inactive');
- }
- if (className) {
- classNames.push(className);
- }
- if (svg) {
- return <g
- className={classNames.join(' ')}
- data-icon={icon}
- onClick={(e) => {
- activeController.handlePrimary(state, setManualState, icons);
- e.preventDefault();
- e.stopPropagation();
- }}
- onContextMenu={(e) => {
- activeController.handleSecondary(state, setManualState, icons);
- e.preventDefault();
- e.stopPropagation();
- }}
- >
- <ZeldaIcon name={icon} svg />
- </g>;
- }
- return <span
- className={classNames.join(' ')}
- onClick={(e) => {
- activeController.handlePrimary(state, setManualState, icons);
- e.preventDefault();
- e.stopPropagation();
- }}
- onContextMenu={(e) => {
- activeController.handleSecondary(state, setManualState, icons);
- e.preventDefault();
- e.stopPropagation();
- }}
- >
- <ZeldaIcon name={active || defaultIcon || icons[0]} />
- </span>;
-};
-
-const doNothing = () => { };
-
-const firstIcon = (state, icons) => icons[0];
-
-const nextIcon = (state, setState, icons) => {
- const highest = highestActive(state, icons);
- const highestIndex = highest ? icons.indexOf(highest) : -1;
- if (highestIndex + 1 < icons.length) {
- setState(toggleBoolean(icons[highestIndex + 1]));
- } else {
- const changes = {};
- icons.forEach(icon => {
- changes[icon] = false;
- });
- setState(s => ({ ...s, ...changes }));
- }
-};
-
-const previousIcon = (state, setState, icons) => {
- const highest = highestActive(state, icons);
- const highestIndex = highest ? icons.indexOf(highest) : -1;
- if (highestIndex >= 0) {
- setState(toggleBoolean(icons[highestIndex]));
- } else {
- const changes = {};
- icons.forEach(icon => {
- changes[icon] = true;
- });
- setState(s => ({ ...s, ...changes }));
- }
-};
-
-const nextString = property => (state, setState, icons) => {
- const current = state[property] || icons[0];
- const currentIndex = icons.indexOf(current);
- const nextIndex = (currentIndex + 1) % icons.length;
- const next = icons[nextIndex];
- setState(s => ({ ...s, [property]: next }));
-};
-
-const previousString = property => (state, setState, icons) => {
- const current = state[property] || icons[0];
- const currentIndex = icons.indexOf(current);
- const previousIndex = (currentIndex + icons.length - 1) % icons.length;
- const previous = icons[previousIndex];
- setState(s => ({ ...s, [property]: previous }));
-};
-
-ToggleIcon.bottleController = ctrl => ({
- getActive: (state, icons) => state[ctrl] ? icons[state[ctrl] - 1] : null,
- getDefault: () => 'bottle',
- handlePrimary: (state, setState, icons) => {
- if (state[ctrl] === 0) {
- // skip over mushroom
- setState(s => ({ ...s, [ctrl]: 2 }));
- } else {
- setState(increment(ctrl, icons.length));
- }
- },
- handleSecondary: (state, setState, icons) => {
- if (state[ctrl] === 2) {
- // skip over mushroom
- setState(s => ({ ...s, [ctrl]: 0 }));
- } else {
- setState(decrement(ctrl, icons.length));
- }
- },
-});
-
-ToggleIcon.countController = max => ({
- getActive: highestActive,
- getDefault: firstIcon,
- handlePrimary: (state, setState, icons) => {
- setState(increment(icons[0], max));
- },
- handleSecondary: (state, setState, icons) => {
- setState(decrement(icons[0], max));
- },
-});
-
-ToggleIcon.dungeonBossController = (dungeon) => ({
- getActive: (state) => hasDungeonBoss(state, dungeon) ? getDungeonBoss(state, dungeon) : null,
- getDefault: (state) => getDungeonBoss(state, dungeon),
- handlePrimary: dungeon.bosses.length > 1
- ? nextString(`${dungeon.id}-boss`)
- : (state, setState) => {
- setState(toggleBossDefeated(dungeon));
- },
- handleSecondary: dungeon.bosses.length > 1 ?
- previousString(`${dungeon.id}-boss`)
- : (state, setState) => {
- setState(toggleBossDefeated(dungeon));
- },
-});
-
-ToggleIcon.dungeonCheckController = (dungeon) => ({
- getActive: (state, icons) => getDungeonRemainingItems(state, dungeon) ? icons[1] : null,
- getDefault: firstIcon,
- handlePrimary: (state, setState) => {
- setState(addDungeonCheck(dungeon));
- },
- handleSecondary: (state, setState) => {
- setState(removeDungeonCheck(dungeon));
- },
-});
-
-ToggleIcon.dungeonController = dungeon => ({
- getActive: (state, icons) => state[`${dungeon.id}-${icons[0]}`] ? icons[0] : null,
- getDefault: firstIcon,
- handlePrimary: (state, setState, icons) => {
- setState(toggleBoolean(`${dungeon.id}-${icons[0]}`));
- },
- handleSecondary: (state, setState, icons) => {
- setState(toggleBoolean(`${dungeon.id}-${icons[0]}`));
- },
-});
-
-ToggleIcon.dungeonCountController = (dungeon, max) => ({
- getActive: (state, icons) => state[`${dungeon.id}-${icons[0]}`] ? icons[0] : null,
- getDefault: firstIcon,
- handlePrimary: (state, setState, icons) => {
- setState(increment(`${dungeon.id}-${icons[0]}`, max));
- },
- handleSecondary: (state, setState, icons) => {
- setState(decrement(`${dungeon.id}-${icons[0]}`, max));
- },
-});
-
-ToggleIcon.dungeonPrizeController = (dungeon) => ({
- getActive: (state) => hasDungeonPrize(state, dungeon) ? getDungeonPrize(state, dungeon) : null,
- getDefault: (state) => getDungeonPrize(state, dungeon),
- handlePrimary: nextString(`${dungeon.id}-prize`),
- handleSecondary: previousString(`${dungeon.id}-prize`),
-});
-
-ToggleIcon.gtBossController = (which) => ({
- getActive: (state) => getGTBoss(state, which),
- getDefault: (state) => getGTBoss(state, which),
- handlePrimary: nextString(`gt-${which}-boss`),
- handleSecondary: previousString(`gt-${which}-boss`),
-});
-
-ToggleIcon.medallionController = {
- getActive: highestActive,
- getDefault: firstIcon,
- handlePrimary: nextIcon,
- handleSecondary: (state, setState, icons) => {
- const mm = state['mm-medallion'];
- const tr = state['tr-medallion'];
- const isMM = mm === icons[0];
- const isTR = tr === icons[0];
- console.log({ mm, isMM, tr, isTR });
- if (!isMM && !isTR) {
- // empty: set as MM if mire is unset, else set as TR if TR is unset
- if (!mm) {
- setState(s => ({ ...s, 'mm-medallion': icons[0] }));
- } else if (!tr) {
- setState(s => ({ ...s, 'tr-medallion': icons[0] }));
- }
- } else if (isMM && !isTR) {
- // MM: if TR is free, switch to TR, otherwise remove MM
- if (!tr) {
- setState(s => ({ ...s, 'mm-medallion': null, 'tr-medallion': icons[0] }));
- } else {
- setState(s => ({ ...s, 'mm-medallion': null }));
- }
- } else if (!isMM && isTR) {
- // TR: if MM is free, switch to both, otherwise remove TR
- if (!mm) {
- setState(s => ({ ...s, 'mm-medallion': icons[0] }));
- } else {
- setState(s => ({ ...s, 'tr-medallion': null }));
- }
- } else {
- // both: remove both
- setState(s => ({ ...s, 'mm-medallion': null, 'tr-medallion': null }));
- }
- },
-};
-
-ToggleIcon.modulusController = ctrl => ({
- getActive: (state, icons) => icons[(state[ctrl] || 0) % icons.length],
- getDefault: firstIcon,
- handlePrimary: (state, setState, icons) => {
- setState(increment(ctrl, icons.length));
- },
- handleSecondary: (state, setState, icons) => {
- setState(decrement(ctrl, icons.length));
- },
-});
-
-ToggleIcon.nullController = {
- getActive: () => null,
- getDefault: firstIcon,
- handlePrimary: doNothing,
- handleSecondary: doNothing,
-};
-
-ToggleIcon.pinController = (pin, removePin) => ({
- getActive: firstIcon,
- getDefault: firstIcon,
- handlePrimary: doNothing,
- handleSecondary: () => removePin(pin),
-});
-
-ToggleIcon.simpleController = {
- getActive: highestActive,
- getDefault: firstIcon,
- handlePrimary: nextIcon,
- handleSecondary: previousIcon,
-};
-
-ToggleIcon.progressiveController = (master, min, max) => ({
- getActive: (state, icons) => {
- const count = Math.max(min, Math.min(max, state[master] || 0));
- return count ? icons[count - 1] : null;
- },
- getDefault: firstIcon,
- handlePrimary: (state, setState) => {
- setState(increment(master, max, min));
- },
- handleSecondary: (state, setState) => {
- setState(decrement(master, max, min));
- },
-});
-
-ToggleIcon.propTypes = {
- active: PropTypes.string,
- className: PropTypes.string,
- controller: PropTypes.shape({
- handlePrimary: PropTypes.func,
- handleSecondary: PropTypes.func,
- }),
- icons: PropTypes.arrayOf(PropTypes.string),
- svg: PropTypes.bool,
-};
-
-export default ToggleIcon;