Icon.INFO = makePreset('Info', 'circle-info');
Icon.INVERT = makePreset('InvertIcon', 'circle-half-stroke');
Icon.LANGUAGE = makePreset('LanguageIcon', 'language');
+Icon.LOAD = makePreset('LoadIcon', 'upload');
Icon.LOCKED = makePreset('LockedIcon', 'lock');
Icon.LOGOUT = makePreset('LogoutIcon', 'sign-out-alt');
Icon.MENU = makePreset('MenuIcon', 'bars');
Icon.RACETIME = makePreset('RacetimeIcon', 'stopwatch');
Icon.REJECT = makePreset('RejectIcon', 'square-xmark');
Icon.REMOVE = makePreset('RemoveIcon', 'square-xmark');
+Icon.RESET = makePreset('ResetIcon', 'rotate-left');
Icon.RESULT = makePreset('ResultIcon', 'clock');
+Icon.SAVE = makePreset('SaveIcon', 'download');
Icon.SECOND_PLACE = makePreset('SecondPlaceIcon', 'medal');
Icon.SETTINGS = makePreset('SettingsIcon', 'cog');
Icon.SLASH = makePreset('SlashIcon', 'slash');
import FuzzySearch from 'fuzzy-search';
import PropTypes from 'prop-types';
import React from 'react';
+import { Button } from 'react-bootstrap';
+import { useTranslation } from 'react-i18next';
+import toastr from 'toastr';
+
+import Icon from '../common/Icon';
const AREAS = [
{
};
const MixedPoolsTracker = () => {
+ const { t } = useTranslation();
+
const [connections, setConnections] = React.useState({});
const [dragging, setDragging] = React.useState(null);
return ans;
}, [connections]);
+ const save = React.useCallback(() => {
+ try {
+ const dump = JSON.stringify({ connections });
+ localStorage.setItem('zootr.mixed-pools-tracker-save', dump);
+ toastr.success(t('general.saveSuccess'));
+ } catch (e) {
+ toastr.error(t('general.saveError'));
+ console.error(e);
+ }
+ }, [connections, t]);
+
+ const load = React.useCallback(() => {
+ try {
+ const dump = localStorage.getItem('zootr.mixed-pools-tracker-save');
+ if (!dump) {
+ toastr.error(t('general.loadError'));
+ return;
+ }
+ const { connections } = JSON.parse(dump);
+ if (connections) {
+ setConnections(connections);
+ }
+ toastr.success(t('general.loadSuccess'));
+ } catch (e) {
+ toastr.error(t('general.loadError'));
+ console.error(e);
+ }
+ }, [setConnections, t]);
+
+ const reset = React.useCallback(() => {
+ try {
+ setConnections({});
+ toastr.success(t('general.resetSuccess'));
+ } catch (e) {
+ toastr.error(t('general.resetError'));
+ }
+ }, [setConnections, t]);
+
return <CONTEXT.Provider value={context}>
<div className="mixed-pools-tracker">
+ <div className="menu-bar button-bar">
+ <Button
+ onClick={save}
+ size="sm"
+ title={t('button.save')}
+ variant="outline-secondary"
+ >
+ <Icon.SAVE title="" />
+ </Button>
+ <Button
+ onClick={load}
+ size="sm"
+ title={t('button.load')}
+ variant="outline-secondary"
+ >
+ <Icon.LOAD title="" />
+ </Button>
+ <Button
+ onClick={reset}
+ size="sm"
+ title={t('button.reset')}
+ variant="outline-secondary"
+ >
+ <Icon.RESET title="" />
+ </Button>
+ </div>
<div className="columns">
{superGroups.map((sg) =>
<div className="column" key={sg.key}>
generate: 'Generieren',
help: 'Hilfe',
invert: 'Umkehren',
+ load: 'Laden',
login: 'Login',
logout: 'Logout',
new: 'Neu',
playPause: 'Play/Pause',
protocol: 'Protokoll',
remove: 'Entfernen',
+ reset: 'Zurücksetzen',
retry: 'Neu versuchen',
save: 'Speichern',
search: 'Suche',
anonymous: 'Anonym',
appDescription: 'Turniere und Tutorials für The Legend of Zelda: A Link to the Past Randomizer',
appName: 'ALttP',
- pleaseSelect: 'Bitte wählen',
languages: {
de: 'Deutsch',
en: 'Englisch',
es: 'Spanisch',
fr: 'Französisch',
},
+ loadError: 'Fehler beim Laden',
+ loadSuccess: 'Geladen',
+ pleaseSelect: 'Bitte wählen',
+ resetError: 'Fehler beim Zurücksetzen',
+ resetSuccess: 'Zurückgesetzt',
+ saveError: 'Fehler beim Speichern',
+ saveSuccess: 'Gespeichert',
},
icon: {
AddIcon: 'Hinzufügen',
generate: 'Generate',
help: 'Help',
invert: 'Invert',
+ load: 'Load',
login: 'Login',
logout: 'Logout',
new: 'New',
playPause: 'Play/Pause',
protocol: 'Protocol',
remove: 'Remove',
+ reset: 'Reset',
retry: 'Retry',
save: 'Save',
search: 'Search',
anonymous: 'Anonym',
appDescription: 'Tournaments and tutorials for The Legend of Zelda: A Link to the Past Randomizer',
appName: 'ALttP',
- pleaseSelect: 'Please select',
languages: {
de: 'German',
en: 'English',
es: 'Spanish',
fr: 'French',
},
+ loadError: 'Error loading',
+ loadSuccess: 'Loading successful',
+ pleaseSelect: 'Please select',
+ resetError: 'Error resetting',
+ resetSuccess: 'Reset successful',
+ saveError: 'Error saving',
+ saveSuccess: 'Saved successfully',
},
icon: {
AddIcon: 'Add',