--- /dev/null
+import PropTypes from 'prop-types';
+import React from 'react';
+import { Col, Form, Modal, Row } from 'react-bootstrap';
+import { useTranslation } from 'react-i18next';
+
+import LargeCheck from '../common/LargeCheck';
+import { useTracker } from '../../hooks/tracker';
+
+const ConfigDialog = ({
+ onHide,
+ show,
+}) => {
+ const { config, saveConfig } = useTracker();
+ const { t } = useTranslation();
+
+ const handleChange = React.useCallback(({ target: { name, value } }) => {
+ saveConfig({ [name]: value });
+ }, [saveConfig]);
+
+ return <Modal className="tracker-config-dialog" onHide={onHide} show={show} size="lg">
+ <Modal.Header closeButton>
+ <Modal.Title>
+ {t('tracker.config.title')}
+ </Modal.Title>
+ </Modal.Header>
+ <Modal.Body>
+ <Row>
+ <Col sm={6}>
+ <h3>{t('tracker.config.wildItems')}</h3>
+ <Form.Group
+ className="d-flex justify-content-between my-2"
+ controlId="tracker.wildMap"
+ >
+ <Form.Label>{t('tracker.config.wildMap')}</Form.Label>
+ <Form.Control
+ as={LargeCheck}
+ name="wildMap"
+ onChange={handleChange}
+ value={!!config.wildMap}
+ />
+ </Form.Group>
+ <Form.Group
+ className="d-flex justify-content-between my-2"
+ controlId="tracker.wildCompass"
+ >
+ <Form.Label>{t('tracker.config.wildCompass')}</Form.Label>
+ <Form.Control
+ as={LargeCheck}
+ name="wildCompass"
+ onChange={handleChange}
+ value={!!config.wildCompass}
+ />
+ </Form.Group>
+ <Form.Group
+ className="d-flex justify-content-between my-2"
+ controlId="tracker.wildSmall"
+ >
+ <Form.Label>{t('tracker.config.wildSmall')}</Form.Label>
+ <Form.Control
+ as={LargeCheck}
+ name="wildSmall"
+ onChange={handleChange}
+ value={!!config.wildSmall}
+ />
+ </Form.Group>
+ <Form.Group
+ className="d-flex justify-content-between my-2"
+ controlId="tracker.wildBig"
+ >
+ <Form.Label>{t('tracker.config.wildBig')}</Form.Label>
+ <Form.Control
+ as={LargeCheck}
+ name="wildBig"
+ onChange={handleChange}
+ value={!!config.wildBig}
+ />
+ </Form.Group>
+ </Col>
+ <Col sm={6}>
+ <h3>{t('tracker.config.showItems')}</h3>
+ <Form.Group
+ className="d-flex justify-content-between my-2"
+ controlId="tracker.showMap"
+ >
+ <Form.Label>{t('tracker.config.showMap')}</Form.Label>
+ <Form.Select
+ className="w-auto"
+ name="showMap"
+ onChange={handleChange}
+ value={config.showMap || 'always'}
+ >
+ <option value="never">
+ {t('tracker.config.showItemOptions.never')}
+ </option>
+ <option value="situational">
+ {t('tracker.config.showItemOptions.situational')}
+ </option>
+ <option value="always">
+ {t('tracker.config.showItemOptions.always')}
+ </option>
+ </Form.Select>
+ </Form.Group>
+ <Form.Group
+ className="d-flex justify-content-between my-2"
+ controlId="tracker.showCompass"
+ >
+ <Form.Label>{t('tracker.config.showCompass')}</Form.Label>
+ <Form.Select
+ className="w-auto"
+ name="showCompass"
+ onChange={handleChange}
+ value={config.showCompass || 'always'}
+ >
+ <option value="never">
+ {t('tracker.config.showItemOptions.never')}
+ </option>
+ <option value="situational">
+ {t('tracker.config.showItemOptions.situational')}
+ </option>
+ <option value="always">
+ {t('tracker.config.showItemOptions.always')}
+ </option>
+ </Form.Select>
+ </Form.Group>
+ <Form.Group
+ className="d-flex justify-content-between my-2"
+ controlId="tracker.showSmall"
+ >
+ <Form.Label>{t('tracker.config.showSmall')}</Form.Label>
+ <Form.Select
+ className="w-auto"
+ name="showSmall"
+ onChange={handleChange}
+ value={config.showSmall || 'always'}
+ >
+ <option value="never">
+ {t('tracker.config.showItemOptions.never')}
+ </option>
+ <option value="situational">
+ {t('tracker.config.showItemOptions.situational')}
+ </option>
+ <option value="always">
+ {t('tracker.config.showItemOptions.always')}
+ </option>
+ </Form.Select>
+ </Form.Group>
+ <Form.Group
+ className="d-flex justify-content-between my-2"
+ controlId="tracker.showBig"
+ >
+ <Form.Label>{t('tracker.config.showBig')}</Form.Label>
+ <Form.Select
+ className="w-auto"
+ name="showBig"
+ onChange={handleChange}
+ value={config.showBig || 'always'}
+ >
+ <option value="never">
+ {t('tracker.config.showItemOptions.never')}
+ </option>
+ <option value="situational">
+ {t('tracker.config.showItemOptions.situational')}
+ </option>
+ <option value="always">
+ {t('tracker.config.showItemOptions.always')}
+ </option>
+ </Form.Select>
+ </Form.Group>
+ </Col>
+ </Row>
+ </Modal.Body>
+ </Modal>;
+};
+
+ConfigDialog.propTypes = {
+ onHide: PropTypes.func,
+ show: PropTypes.bool,
+};
+
+export default ConfigDialog;
import PropTypes from 'prop-types';
import React from 'react';
-const CountDisplay = ({ className, count }) => {
+const CountDisplay = ({ className, count, full }) => {
const classNames = ['count-display'];
if (className) {
classNames.push(className);
if (!count) {
classNames.push('is-zero');
}
+ if (full && count >= full) {
+ classNames.push('is-full');
+ }
return <span className={classNames.join(' ')}>
{count}
</span>;
CountDisplay.propTypes = {
className: PropTypes.string,
count: PropTypes.number,
+ full: PropTypes.number,
};
export default CountDisplay;
import {
getDungeonAcquiredSKs,
getDungeonRemainingItems,
+ shouldShowDungeonItem,
} from '../../helpers/tracker';
import { useTracker } from '../../hooks/tracker';
const Dungeons = () => {
- const { dungeons, state } = useTracker();
+ const { config, dungeons, state } = useTracker();
return <div className="dungeons">
{dungeons.map(dungeon =>
<div className={`dungeon dungeon-${dungeon.id}`} key={dungeon.id}>
<span className="dungeon-tag">{dungeon.id.toUpperCase()}</span>
- <ToggleIcon
- controller={ToggleIcon.dungeonController(dungeon)}
- icons={['map']}
- />
- <ToggleIcon
- controller={ToggleIcon.dungeonController(dungeon)}
- icons={['compass']}
- />
- <span className="dungeon-smalls">
+ {shouldShowDungeonItem(config, 'Map') ?
<ToggleIcon
- controller={ToggleIcon.dungeonCountController(dungeon, dungeon.sk)}
- icons={['small-key']}
+ controller={ToggleIcon.dungeonController(dungeon)}
+ icons={['map']}
/>
- <CountDisplay count={getDungeonAcquiredSKs(state, dungeon)} />
- </span>
- <ToggleIcon
- controller={ToggleIcon.dungeonController(dungeon)}
- icons={['big-key']}
- />
+ : null}
+ {shouldShowDungeonItem(config, 'Compass') ?
+ <ToggleIcon
+ controller={ToggleIcon.dungeonController(dungeon)}
+ icons={['compass']}
+ />
+ : null}
+ {shouldShowDungeonItem(config, 'Small') ?
+ <span className="dungeon-smalls">
+ <ToggleIcon
+ controller={ToggleIcon.dungeonCountController(dungeon, dungeon.sk)}
+ icons={['small-key']}
+ />
+ <CountDisplay
+ count={getDungeonAcquiredSKs(state, dungeon)}
+ full={dungeon.sk}
+ />
+ </span>
+ : null}
+ {shouldShowDungeonItem(config, 'Big') ?
+ <ToggleIcon
+ controller={ToggleIcon.dungeonController(dungeon)}
+ icons={['big-key']}
+ />
+ : null}
<span className="dungeon-checks">
<ToggleIcon
controller={ToggleIcon.dungeonCheckController(dungeon)}
import React from 'react';
-import { Container, Navbar } from 'react-bootstrap';
+import { Button, Container, Navbar } from 'react-bootstrap';
import AutoTracking from './AutoTracking';
+import ConfigDialog from './ConfigDialog';
import ToggleIcon from './ToggleIcon';
+import Icon from '../common/Icon';
import { useTracker } from '../../hooks/tracker';
const mapWild = {
};
const Toolbar = () => {
+ const [showConfigDialog, setShowConfigDialog] = React.useState(false);
const { config, saveConfig } = useTracker();
const controller = React.useMemo(() => ({
return <Navbar bg="dark" className="tracker-toolbar" variant="dark">
<Container fluid>
<div className="button-bar">
+ <Button
+ className="me-3"
+ onClick={() => setShowConfigDialog(true)}
+ variant="outline-secondary"
+ >
+ <Icon.SETTINGS />
+ </Button>
<ToggleIcon controller={controller} icons={['map']} />
<ToggleIcon controller={controller} icons={['compass']} />
<ToggleIcon controller={controller} icons={['small-key']} />
</div>
<AutoTracking />
</Container>
+ <ConfigDialog onHide={() => setShowConfigDialog(false)} show={showConfigDialog} />
</Navbar>;
};
];
export const CONFIG = {
+ showMap: 'situational',
+ showCompass: 'situational',
+ showSmall: 'always',
+ showBig: 'always',
wildMap: false,
wildCompass: false,
wildSmall: false,
},
];
+export const shouldShowDungeonItem = (config, which) => {
+ const show = config[`show${which}`] || 'always';
+ const wild = config[`wild${which}`] || false;
+ switch (show) {
+ default:
+ case 'always':
+ return true;
+ case 'situational':
+ return wild;
+ case 'never':
+ return false;
+ }
+};
+
export const toggleBoolean = name => state => ({
...state,
[name]: !state[name],
seeAlso: 'Siehe auch',
},
tracker: {
+ config: {
+ showBig: 'Big Keys',
+ showCompass: 'Kompanden',
+ showItemOptions: {
+ always: 'Immer',
+ never: 'Nie',
+ situational: 'Situationsbedingt',
+ },
+ showItems: 'Zeige Dungeon Items',
+ showMap: 'Maps',
+ showSmall: 'Small Keys',
+ title: 'Konfiguration',
+ wildBig: 'Big Keys',
+ wildCompass: 'Kompanden',
+ wildItems: 'Wild Dungeon Items',
+ wildMap: 'Maps',
+ wildSmall: 'Small Keys',
+ },
location: {
aginah: 'Aginah',
blacksmith: 'Blacksmith',
seeAlso: 'See also',
},
tracker: {
+ config: {
+ showBig: 'Big Keys',
+ showCompass: 'Compasses',
+ showItemOptions: {
+ always: 'Always',
+ never: 'Never',
+ situational: 'Situational',
+ },
+ showItems: 'Show Dungeon Items',
+ showMap: 'Maps',
+ showSmall: 'Small Keys',
+ title: 'Configuration',
+ wildBig: 'Big Keys',
+ wildCompass: 'Compasses',
+ wildItems: 'Wild Dungeon Items',
+ wildMap: 'Maps',
+ wildSmall: 'Small Keys',
+ },
location: {
aginah: 'Aginah',
blacksmith: 'Blacksmith',
&.is-zero {
display: none;
}
+ &.is-full {
+ color: green;
+ }
}
}
}