@selfcommunity/react-core
Version:
React Core Components useful for integrating UI Community components (react-ui).
204 lines (203 loc) • 10 kB
JavaScript
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;
;