UNPKG

@selfcommunity/react-core

Version:

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

161 lines (159 loc) • 6.18 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const tslib_1 = require("tslib"); 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 SCPreferencesProvider_1 = require("../components/provider/SCPreferencesProvider"); const Preferences_1 = require("../constants/Preferences"); const useSCCachingManager_1 = tslib_1.__importDefault(require("./useSCCachingManager")); /** * Used on refresh and in isFollowed method * Check if the user status is 'followed' * to update the cache and data */ const STATUS_FOLLOWED = 'followed'; /** :::info This custom hook is used to manage followed users. ::: :::tip How to use it: Follow these steps: ```jsx 1. const scUserContext: SCUserContextType = useSCUser(); 2. const scFollowedManager: SCFollowedManagerType = scUserContext.manager.followed; 3. scFollowedManager.isFollowed(user) ``` ::: */ function useSCFollowedManager(user) { const { cache, updateCache, emptyCache, data, setData, loading, setLoading, setUnLoading, isLoading } = (0, useSCCachingManager_1.default)(); const scPreferencesContext = (0, SCPreferencesProvider_1.useSCPreferences)(); const authUserId = user ? user.id : null; const followEnabled = Preferences_1.CONFIGURATIONS_FOLLOW_ENABLED in scPreferencesContext.preferences && scPreferencesContext.preferences[Preferences_1.CONFIGURATIONS_FOLLOW_ENABLED].value; /** * Memoized refresh all followed * It makes a single request to the server and retrieves * all the users followed by the authenticated user in a single solution * It might be useful for multi-tab sync */ const refresh = (0, react_1.useMemo)(() => () => { emptyCache(); if (user && cache.length > 0) { // Only if user is authenticated api_services_1.http .request({ url: api_services_1.Endpoints.UserConnectionStatuses.url({}), method: api_services_1.Endpoints.UserConnectionStatuses.method, data: { users: cache }, }) .then((res) => { if (res.status >= 300) { return Promise.reject(res); } updateCache(Object.keys(res.data.connection_statuses).map((id) => parseInt(id))); setData(Object.entries(res.data.connection_statuses) .filter(([, v]) => v === STATUS_FOLLOWED) .map(([k]) => parseInt(k))); return Promise.resolve(res.data); }) .catch((e) => { utils_1.Logger.error(Errors_1.SCOPE_SC_CORE, 'Unable to refresh users followed by the authenticated user.'); utils_1.Logger.error(Errors_1.SCOPE_SC_CORE, e); }); } }, [data, user, cache]); /** * Memoized follow/unfollow User * Toggle action */ const follow = (0, react_1.useMemo)(() => (user) => { setLoading(user.id); return api_services_1.http .request({ url: api_services_1.Endpoints.FollowUser.url({ id: user.id }), method: api_services_1.Endpoints.FollowUser.method, }) .then((res) => { if (res.status >= 300) { return Promise.reject(res); } updateCache([user.id]); const isFollowed = data.includes(user.id); setData((prev) => (isFollowed ? prev.filter((id) => id !== user.id) : [...[user.id], ...prev])); setUnLoading(user.id); return Promise.resolve(res); }) .catch((e) => { setUnLoading(user.id); return Promise.reject(e); }); }, [data, loading, cache]); /** * Check if the authenticated user follow the user * Update the followed cached * Update followed user * @param user */ const checkIsUserFollowed = (user) => { setLoading(user.id); api_services_1.http .request({ url: api_services_1.Endpoints.CheckUserFollowed.url({ id: user.id }), method: api_services_1.Endpoints.CheckUserFollowed.method, }) .then((res) => { if (res.status >= 300) { return Promise.reject(res); } updateCache([user.id]); setData((prev) => (res.data.is_followed ? [...prev, ...[user.id]] : prev.filter((id) => id !== user.id))); setUnLoading(user.id); return Promise.resolve(res.data); }); }; /** * Bypass remote check if the user is followed */ const getConnectionStatus = (0, react_1.useMemo)(() => (user) => { const isFollowed = user.connection_status === STATUS_FOLLOWED; updateCache([user.id]); setData((prev) => (isFollowed ? [...prev, ...[user.id]] : prev)); return isFollowed; }, [data, cache]); /** * Memoized isFollowed * If user is already in cache -> check if the user is in followed, * otherwise, check if auth user follow the user */ const isFollowed = (0, react_1.useMemo)(() => { return (user) => { if (cache.includes(user.id)) { return Boolean(data.includes(user.id)); } if (authUserId) { if ('connection_status' in user) { return getConnectionStatus(user); } if (!isLoading(user)) { checkIsUserFollowed(user); } } return false; }; }, [data, loading, cache, authUserId]); /** * Empty cache on logout */ (0, react_1.useEffect)(() => { if (!authUserId) { emptyCache(); } }, [authUserId]); if (!followEnabled || !user) { return { followed: data, loading, isLoading }; } return { followed: data, loading, isLoading, follow, isFollowed, refresh, emptyCache }; } exports.default = useSCFollowedManager;