UNPKG

@selfcommunity/react-core

Version:

React Core Components useful for integrating UI Community components (react-ui).

204 lines (203 loc) • 10 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const react_1 = require("react"); const api_services_1 = require("@selfcommunity/api-services"); const utils_1 = require("@selfcommunity/utils"); const Errors_1 = require("../constants/Errors"); const types_1 = require("@selfcommunity/types"); const Cache_1 = require("../constants/Cache"); const SCContextProvider_1 = require("../components/provider/SCContextProvider"); const SCUserProvider_1 = require("../components/provider/SCUserProvider"); const SCVoteProvider_1 = require("../components/provider/SCVoteProvider"); /** :::info This custom hook is used to fetch a contribution vote. ::: * @param object * @param object.id * @param object.contribution * @param object.contributionType * @param object.onVote * @param object.cacheStrategy */ function useSCFetchVote({ id, contribution = null, contributionType, onVote = null, cacheStrategy = utils_1.CacheStrategies.CACHE_FIRST, }) { // MEMO const __contributionCacheKey = (0, react_1.useMemo)(() => (contributionType === types_1.SCContributionType.COMMENT ? (0, Cache_1.getCommentObjectCacheKey)(id) : (0, Cache_1.getFeedObjectCacheKey)(id, contributionType)), [id, contributionType]); const __endpoint = (0, react_1.useMemo)(() => (contributionType === types_1.SCContributionType.COMMENT ? api_services_1.Endpoints.Comment : api_services_1.Endpoints.FeedObject), [id, contributionType]); // STATE const [isLoading, setIsLoading] = (0, react_1.useState)(false); const [obj, setObj] = (0, react_1.useState)(cacheStrategy !== utils_1.CacheStrategies.NETWORK_ONLY ? utils_1.LRUCache.get(__contributionCacheKey, contribution) : contribution); const [isVoting, setIsVoting] = (0, react_1.useState)(false); const [voteListNext, setVoteListNext] = (0, react_1.useState)(api_services_1.Endpoints.VotesList.url({ type: contributionType, id })); const [voteList, setVoteList] = (0, react_1.useState)([]); const [isLoadingVoteList, setIsLoadingVoteList] = (0, react_1.useState)(false); const [error, setError] = (0, react_1.useState)(null); // HOOKS const scContext = (0, SCContextProvider_1.useSCContext)(); const scUserContext = (0, SCUserProvider_1.useSCUser)(); const scVoteContext = (0, SCVoteProvider_1.useSCVote)(); const reactions = (0, react_1.useMemo)(() => { var _a; return { default: (_a = scVoteContext.reactions) === null || _a === void 0 ? void 0 : _a.find((reaction) => reaction.id === 1), reactions: scVoteContext.reactions, isLoading: scVoteContext.isLoading, }; }, [scVoteContext.reactions, scVoteContext.isLoading]); const fetchObject = (0, react_1.useMemo)(() => () => { setIsLoading(true); return api_services_1.http .request({ url: __endpoint.url({ type: contributionType, id: id }), method: __endpoint.method, }) .then((res) => { setIsLoading(false); if (res.status >= 300) { return Promise.reject(res); } return Promise.resolve(res.data); }); }, [id, contributionType]); const performVote = (0, react_1.useMemo)(() => (reaction) => { const params = {}; if (reaction && reactions.reactions) { params['reaction'] = reaction.id; } return api_services_1.http .request({ url: api_services_1.Endpoints.Vote.url({ type: obj.type, id: obj.id }), method: api_services_1.Endpoints.Vote.method, params, }) .then((res) => { if (res.status >= 300) { return Promise.reject(res); } return Promise.resolve(res.data); }); }, [obj, scContext]); // EFFECTS (0, react_1.useEffect)(() => { if (cacheStrategy !== utils_1.CacheStrategies.CACHE_FIRST || !obj || (scUserContext.user && !Object.prototype.hasOwnProperty.call(obj, 'voted'))) { fetchObject() .then((obj) => { setObj(obj); utils_1.LRUCache.set(__contributionCacheKey, obj); }) .catch((err) => { utils_1.LRUCache.delete(__contributionCacheKey); setError(`FeedObject with id ${id} not found`); utils_1.Logger.error(Errors_1.SCOPE_SC_CORE, `FeedObject with id ${id} not found`); utils_1.Logger.error(Errors_1.SCOPE_SC_CORE, err.message); }); } }, [id, contributionType, scUserContext.user]); (0, react_1.useEffect)(() => { if (contribution) { setObj(contribution); } }, [contribution]); // HANDLERS const handleVote = (reaction) => { if (scUserContext.user && obj && !isVoting) { setIsVoting(true); performVote(reaction) .then(() => { var _a, _b; let _obj = { voted: !obj.voted, vote_count: obj.voted ? obj.vote_count - 1 : obj.vote_count + 1, }; if (reaction && ((_a = obj === null || obj === void 0 ? void 0 : obj.reaction) === null || _a === void 0 ? void 0 : _a.id) !== reaction.id) { // AGGUINTA / MODIFICA const add = !(obj === null || obj === void 0 ? void 0 : obj.reaction); const addCount = obj.reactions_count.findIndex((count) => count.reaction.id === reaction.id) === -1; _obj = { voted: add ? true : obj.voted, vote_count: add ? obj.vote_count + 1 : obj.vote_count, reaction, reactions_count: [ ...obj.reactions_count.map((count) => { var _a, _b; if (count.reaction.id === ((_a = obj === null || obj === void 0 ? void 0 : obj.reaction) === null || _a === void 0 ? void 0 : _a.id) && count.count - 1 === 0) { return null; } else if (count.reaction.id === ((_b = obj === null || obj === void 0 ? void 0 : obj.reaction) === null || _b === void 0 ? void 0 : _b.id) && count.count - 1 > 0) { return { count: count.count - 1, reaction: count.reaction }; } else if (count.reaction.id === reaction.id) { return { count: count.count + 1, reaction: count.reaction }; } return count; }), addCount ? { count: 1, reaction } : null, ].filter((count) => Boolean(count)), }; } else if (reaction && (obj === null || obj === void 0 ? void 0 : obj.reaction) && ((_b = obj === null || obj === void 0 ? void 0 : obj.reaction) === null || _b === void 0 ? void 0 : _b.id) === reaction.id) { // RIMOZIONE _obj = Object.assign({}, _obj, { reaction: null, reactions_count: obj.reactions_count .map((count) => { var _a, _b; if (count.reaction.id === ((_a = obj === null || obj === void 0 ? void 0 : obj.reaction) === null || _a === void 0 ? void 0 : _a.id) && count.count - 1 === 0) { return null; } else if (count.reaction.id === ((_b = obj === null || obj === void 0 ? void 0 : obj.reaction) === null || _b === void 0 ? void 0 : _b.id) && count.count - 1 > 0) { return { count: count.count - 1, reaction: count.reaction }; } return count; }) .filter((count) => Boolean(count)), }); } const newObj = Object.assign({}, obj, _obj); setObj(newObj); setIsVoting(false); onVote && onVote(newObj, null); }) .catch((error) => { utils_1.Logger.error(Errors_1.SCOPE_SC_CORE, error); setIsVoting(false); onVote && onVote(obj, error); }); } }; const handleFetchVoteList = ({ reaction = null, reset = false }) => { const _url = reset ? `${api_services_1.Endpoints.VotesList.url({ type: contributionType, id, })}${reaction ? `?reaction=${reaction.id}` : ''}` : voteListNext; setIsLoadingVoteList(true); api_services_1.http .request({ url: _url, method: api_services_1.Endpoints.VotesList.method, }) .then((res) => { setVoteList(reset ? res.data.results : [...voteList, ...res.data.results]); setVoteListNext(res.data.next); }) .catch((error) => setError(error)) .then(() => setIsLoadingVoteList(false)); }; const data = (0, react_1.useMemo)(() => ({ contributionVoted: obj ? obj.voted : false, contributionVoteCount: obj ? obj.vote_count : 0, contributionReaction: obj ? obj.reaction : null, contributionReactionsCount: obj ? obj.reactions_count : null, }), [obj]); return Object.assign(Object.assign({}, data), { isLoading, isVoting, handleVote, reactions, error, handleFetchVoteList, voteList, isLoadingVoteList, voteListHasNext: Boolean(voteListNext) }); } exports.default = useSCFetchVote;