tutorial-context.tsx 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. import getMeta from '@/utils/meta'
  2. import {
  3. createContext,
  4. Dispatch,
  5. FC,
  6. SetStateAction,
  7. useCallback,
  8. useContext,
  9. useMemo,
  10. useState,
  11. } from 'react'
  12. export const TutorialContext = createContext<
  13. | {
  14. deactivateTutorial: (tutorial: string) => void
  15. inactiveTutorials: string[]
  16. currentPopup: string | null
  17. setCurrentPopup: Dispatch<SetStateAction<string | null>>
  18. }
  19. | undefined
  20. >(undefined)
  21. export const TutorialProvider: FC<React.PropsWithChildren> = ({ children }) => {
  22. const [inactiveTutorials, setInactiveTutorials] = useState(
  23. () => getMeta('ol-inactiveTutorials') || []
  24. )
  25. const [currentPopup, setCurrentPopup] = useState<string | null>(null)
  26. const deactivateTutorial = useCallback(
  27. (tutorialKey: string) => {
  28. setInactiveTutorials([...inactiveTutorials, tutorialKey])
  29. },
  30. [inactiveTutorials]
  31. )
  32. const value = useMemo(
  33. () => ({
  34. deactivateTutorial,
  35. inactiveTutorials,
  36. currentPopup,
  37. setCurrentPopup,
  38. }),
  39. [deactivateTutorial, inactiveTutorials, currentPopup, setCurrentPopup]
  40. )
  41. return (
  42. <TutorialContext.Provider value={value}>
  43. {children}
  44. </TutorialContext.Provider>
  45. )
  46. }
  47. export function useTutorialContext() {
  48. const context = useContext(TutorialContext)
  49. if (!context) {
  50. throw new Error(
  51. 'useTutorialContext is only available inside TutorialProvider'
  52. )
  53. }
  54. return context
  55. }