]> git.localhorst.tv Git - alttp.git/blob - resources/js/hooks/tracker.js
svg dungeon tracker
[alttp.git] / resources / js / hooks / tracker.js
1 import PropTypes from 'prop-types';
2 import React from 'react';
3
4 import {
5         CONFIG,
6         DUNGEONS,
7         applyLogic,
8         configureDungeons,
9         makeEmptyState,
10         mergeStates,
11 } from '../helpers/tracker';
12
13 const context = React.createContext({});
14
15 export const useTracker = () => React.useContext(context);
16
17 export const TrackerProvider = ({ children }) => {
18         const [config, setConfig] = React.useState(CONFIG);
19         const [state, setState] = React.useState(makeEmptyState());
20         const [autoState, setAutoState] = React.useState(makeEmptyState());
21         const [manualState, setManualState] = React.useState(makeEmptyState());
22         const [dungeons, setDungeons] = React.useState(DUNGEONS);
23         const [logic, setLogic] = React.useState({});
24
25         const saveConfig = React.useCallback((values) => {
26                 setConfig(s => {
27                         const newConfig = { ...s, ...values };
28                         localStorage.setItem('tracker.config', JSON.stringify(newConfig));
29                         return newConfig;
30                 });
31         }, []);
32
33         React.useEffect(() => {
34                 const savedConfig = localStorage.getItem('tracker.config');
35                 if (savedConfig) {
36                         setConfig(c => ({ ...c, ...JSON.parse(savedConfig) }));
37                 }
38         }, []);
39
40         React.useEffect(() => {
41                 const newDungeons = configureDungeons(config);
42                 setDungeons(newDungeons);
43         }, [config]);
44
45         React.useEffect(() => {
46                 setState(mergeStates(autoState, manualState));
47         }, [autoState, manualState]);
48
49         React.useEffect(() => {
50                 setLogic(applyLogic(config, dungeons, state));
51         }, [config, dungeons, state]);
52
53         const value = React.useMemo(() => {
54                 return { config, dungeons, logic, saveConfig, setAutoState, setManualState, state };
55         }, [config, dungeons, logic, state]);
56
57         return <context.Provider value={value}>
58                 {children}
59         </context.Provider>;
60 };
61
62 TrackerProvider.propTypes = {
63         children: PropTypes.node,
64 };