@selfcommunity/react-core
Version:
React Core Components useful for integrating UI Community components (react-ui).
91 lines (88 loc) • 3.43 kB
JavaScript
import { jsx as _jsx } from "react/jsx-runtime";
import { createContext, useCallback, useContext, useEffect, useState } from 'react';
import { ReactionService } from '@selfcommunity/api-services';
import { Logger } from '@selfcommunity/utils';
import { SCOPE_SC_CORE } from '../../../constants/Errors';
import { useSCContext } from '../SCContextProvider';
import { SCFeatureName } from '@selfcommunity/types';
import { SCPreferencesContext } from '../SCPreferencesProvider';
/**
* Creates Vote Context
*
:::tip Context can be consumed in one of the following ways:
```jsx
1. <SCVoteContext.Consumer>{(reactions) => (...)}</SCVoteContext.Consumer>
```
```jsx
2. const scVoteContext: SCVoteContextType = useContext(SCVoteContext);
```
```jsx
3. const scVoteContext: SCVoteContextType = useSCVote();
````
:::
*/
export const SCVoteContext = createContext({});
/**
* #### Description:
* This component imports all reactions if the feature 'reaction' is enabled.
* @param children
* @return
* ```jsx
* <SCVoteContext.Provider value={{reactions}}>{!isLoading && children}</SCVoteContext.Provider>
* ```
*/
export default function SCVoteProvider({ children = null }) {
const scContext = useSCContext();
const scPreferencesContext = useContext(SCPreferencesContext);
const [reactions, setReactions] = useState(scContext.settings.vote.reactions);
const [, setError] = useState();
const [initialized, setInitialized] = useState((scPreferencesContext.features && !scPreferencesContext.features.includes(SCFeatureName.REACTION)) || scContext.settings.vote.reactions !== null);
const [isLoading, setIsLoading] = useState(scPreferencesContext.features && scPreferencesContext.features.includes(SCFeatureName.REACTION) && scContext.settings.vote.reactions === null);
/**
* Helper to refresh reactions list
*/
const refreshReactions = useCallback(() => ReactionService.getAllReactionsList().then((data) => {
setReactions(data);
return data;
}), []);
/**
* Initialize component
* Load all reactions if the feature 'reaction' is enabled
*/
const _initComponent = useCallback(() => {
if (!initialized) {
setInitialized(true);
setIsLoading(true);
refreshReactions()
.then(() => {
setIsLoading(false);
})
.catch((_error) => {
Logger.error(SCOPE_SC_CORE, _error);
setError(_error);
});
}
}, [isLoading, initialized]);
// EFFECTS
useEffect(() => {
let _t;
if (scPreferencesContext.features && scPreferencesContext.features.includes(SCFeatureName.REACTION) && !reactions) {
_t = setTimeout(_initComponent);
return () => {
_t && clearTimeout(_t);
};
}
}, [scPreferencesContext.features, reactions]);
/**
* Nesting all necessary providers
* All child components will use help contexts to works
*/
return _jsx(SCVoteContext.Provider, Object.assign({ value: { reactions, isLoading, refreshReactions } }, { children: initialized && children }));
}
/**
* Let's only export the `useSCPreferences` hook instead of the context.
* We only want to use the hook directly and never the context component.
*/
export function useSCVote() {
return useContext(SCVoteContext);
}