user-features-context.tsx 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. import {
  2. createContext,
  3. FC,
  4. useCallback,
  5. useContext,
  6. useEffect,
  7. useState,
  8. } from 'react'
  9. import { User } from '../../../../types/user'
  10. import { useUserContext } from './user-context'
  11. import { useReceiveUser } from '../hooks/user-channel/use-receive-user'
  12. import { getJSON } from '@/infrastructure/fetch-json'
  13. import { useEditorContext } from './editor-context'
  14. export const UserFeaturesContext = createContext<User['features']>(undefined)
  15. export const UserFeaturesProvider: FC<React.PropsWithChildren> = ({
  16. children,
  17. }) => {
  18. const user = useUserContext()
  19. const { writefullInstance } = useEditorContext()
  20. const [features, setFeatures] = useState(user.features || {})
  21. useReceiveUser(
  22. useCallback(data => {
  23. if (data?.features) {
  24. setFeatures(data.features)
  25. }
  26. }, [])
  27. )
  28. useEffect(() => {
  29. const listener = async ({ isPremium }: { isPremium: boolean }) => {
  30. if (features?.aiErrorAssistant === isPremium) {
  31. // the user is premium on writefull and has the AI assist, no need to refresh the features
  32. return
  33. }
  34. const newFeatures = await getJSON('/user/features')
  35. setFeatures(newFeatures)
  36. }
  37. writefullInstance?.addEventListener('writefull-login-complete', listener)
  38. return () => {
  39. writefullInstance?.removeEventListener(
  40. 'writefull-login-complete',
  41. listener
  42. )
  43. }
  44. }, [features?.aiErrorAssistant, writefullInstance])
  45. return (
  46. <UserFeaturesContext.Provider value={features}>
  47. {children}
  48. </UserFeaturesContext.Provider>
  49. )
  50. }
  51. export function useUserFeaturesContext() {
  52. const context = useContext(UserFeaturesContext)
  53. if (!context) {
  54. throw new Error(
  55. 'useUserFeaturesContext is only available inside UserFeaturesContext'
  56. )
  57. }
  58. return context
  59. }