config.tsx 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. import React from "react";
  2. import { defaultConfig, defaultJson } from "src/constants/data";
  3. import {
  4. ConfigActionType,
  5. ReducerAction,
  6. useConfigReducer,
  7. } from "src/reducer/reducer";
  8. import { ReactComponent, StorageConfig } from "src/typings/global";
  9. export interface AppConfig {
  10. json: string;
  11. settings: StorageConfig;
  12. }
  13. export const initialStates: AppConfig = {
  14. json: JSON.stringify(defaultJson),
  15. settings: defaultConfig,
  16. };
  17. interface Config {
  18. json: string;
  19. settings: StorageConfig;
  20. dispatch: React.Dispatch<ReducerAction>;
  21. }
  22. const defaultContext: Config = {
  23. ...initialStates,
  24. dispatch: () => {},
  25. };
  26. const ConfigContext: React.Context<Config> =
  27. React.createContext(defaultContext);
  28. const useConfig = () => React.useContext(ConfigContext);
  29. const WithConfig: ReactComponent = ({ children }) => {
  30. const [render, setRender] = React.useState(false);
  31. const [states, dispatch] = React.useReducer(useConfigReducer, initialStates);
  32. const value = {
  33. dispatch,
  34. json: states.json,
  35. settings: states.settings,
  36. };
  37. React.useEffect(() => {
  38. const configStored = localStorage.getItem("config");
  39. if (configStored) {
  40. dispatch({
  41. type: ConfigActionType.SET_CONFIG,
  42. payload: JSON.parse(configStored),
  43. });
  44. }
  45. setRender(true);
  46. }, [dispatch]);
  47. React.useEffect(() => {
  48. if (render)
  49. localStorage.setItem(
  50. "config",
  51. JSON.stringify({
  52. ...states.settings,
  53. zoomPanPinch: undefined,
  54. performance: undefined,
  55. })
  56. );
  57. }, [states.settings, render]);
  58. return (
  59. <ConfigContext.Provider value={value}>{children}</ConfigContext.Provider>
  60. );
  61. };
  62. const withConfig = <P extends object>(
  63. Component: React.ComponentType<P>
  64. ): React.FC => {
  65. return (props) => (
  66. <WithConfig>
  67. <Component {...(props as P)} />
  68. </WithConfig>
  69. );
  70. };
  71. export { WithConfig, useConfig, ConfigContext, withConfig };