UNPKG

@oxyhq/services

Version:

Reusable OxyHQ module to handle authentication, user management, karma system, device-based session management and more 🚀

161 lines (152 loc) • 6.98 kB
"use strict"; import { useCallback, useMemo, useEffect } from 'react'; import { useFollowStore } from '../stores/followStore'; import { useOxy } from '../context/OxyContext'; export const useFollow = userId => { const { oxyServices } = useOxy(); const userIds = useMemo(() => Array.isArray(userId) ? userId : userId ? [userId] : [], [userId]); const isSingleUser = typeof userId === 'string'; // Zustand selectors const followState = useFollowStore(); // Single user helpers const isFollowing = isSingleUser && userId ? followState.followingUsers[userId] ?? false : false; const isLoading = isSingleUser && userId ? followState.loadingUsers[userId] ?? false : false; const error = isSingleUser && userId ? followState.errors[userId] ?? null : null; // Follower count helpers const followerCount = isSingleUser && userId ? followState.followerCounts[userId] ?? null : null; const followingCount = isSingleUser && userId ? followState.followingCounts[userId] ?? null : null; const isLoadingCounts = isSingleUser && userId ? followState.loadingCounts[userId] ?? false : false; const toggleFollow = useCallback(async () => { if (!isSingleUser || !userId) throw new Error('toggleFollow is only available for single user mode'); await followState.toggleFollowUser(userId, oxyServices, isFollowing); }, [isSingleUser, userId, followState, oxyServices, isFollowing]); const setFollowStatus = useCallback(following => { if (!isSingleUser || !userId) throw new Error('setFollowStatus is only available for single user mode'); followState.setFollowingStatus(userId, following); }, [isSingleUser, userId, followState]); const fetchStatus = useCallback(async () => { if (!isSingleUser || !userId) throw new Error('fetchStatus is only available for single user mode'); await followState.fetchFollowStatus(userId, oxyServices); }, [isSingleUser, userId, followState, oxyServices]); const clearError = useCallback(() => { if (!isSingleUser || !userId) throw new Error('clearError is only available for single user mode'); followState.clearFollowError(userId); }, [isSingleUser, userId, followState]); const fetchUserCounts = useCallback(async () => { if (!isSingleUser || !userId) throw new Error('fetchUserCounts is only available for single user mode'); await followState.fetchUserCounts(userId, oxyServices); }, [isSingleUser, userId, followState, oxyServices]); const setFollowerCount = useCallback(count => { if (!isSingleUser || !userId) throw new Error('setFollowerCount is only available for single user mode'); followState.setFollowerCount(userId, count); }, [isSingleUser, userId, followState]); const setFollowingCount = useCallback(count => { if (!isSingleUser || !userId) throw new Error('setFollowingCount is only available for single user mode'); followState.setFollowingCount(userId, count); }, [isSingleUser, userId, followState]); // Auto-fetch counts when hook is used for a single user and counts are missing. useEffect(() => { if (!isSingleUser || !userId) return; // If either count is not set and we're not already loading counts, trigger a fetch. if ((followerCount === null || followingCount === null) && !isLoadingCounts) { fetchUserCounts().catch(err => console.warn('useFollow: fetchUserCounts failed', err)); } }, [isSingleUser, userId, followerCount, followingCount, isLoadingCounts, fetchUserCounts]); // Multiple user helpers const followData = useMemo(() => { const data = {}; userIds.forEach(uid => { data[uid] = { isFollowing: followState.followingUsers[uid] ?? false, isLoading: followState.loadingUsers[uid] ?? false, error: followState.errors[uid] ?? null }; }); return data; }, [userIds, followState.followingUsers, followState.loadingUsers, followState.errors]); const toggleFollowForUser = useCallback(async targetUserId => { const currentState = followState.followingUsers[targetUserId] ?? false; await followState.toggleFollowUser(targetUserId, oxyServices, currentState); }, [followState, oxyServices]); const setFollowStatusForUser = useCallback((targetUserId, following) => { followState.setFollowingStatus(targetUserId, following); }, [followState]); const fetchStatusForUser = useCallback(async targetUserId => { await followState.fetchFollowStatus(targetUserId, oxyServices); }, [followState, oxyServices]); const fetchAllStatuses = useCallback(async () => { await Promise.all(userIds.map(uid => followState.fetchFollowStatus(uid, oxyServices))); }, [userIds, followState, oxyServices]); const clearErrorForUser = useCallback(targetUserId => { followState.clearFollowError(targetUserId); }, [followState]); const updateCountsFromFollowAction = useCallback((targetUserId, action, counts) => { const currentUserId = oxyServices.getCurrentUserId() || undefined; followState.updateCountsFromFollowAction(targetUserId, action, counts, currentUserId); }, [followState, oxyServices]); // Aggregate helpers for multiple users const isAnyLoading = userIds.some(uid => followState.loadingUsers[uid]); const hasAnyError = userIds.some(uid => !!followState.errors[uid]); const allFollowing = userIds.every(uid => followState.followingUsers[uid]); const allNotFollowing = userIds.every(uid => !followState.followingUsers[uid]); if (isSingleUser && userId) { return { isFollowing, isLoading, error, toggleFollow, setFollowStatus, fetchStatus, clearError, // Follower count methods followerCount, followingCount, isLoadingCounts, fetchUserCounts, setFollowerCount, setFollowingCount }; } return { followData, toggleFollowForUser, setFollowStatusForUser, fetchStatusForUser, fetchAllStatuses, clearErrorForUser, isAnyLoading, hasAnyError, allFollowing, allNotFollowing }; }; // Convenience hook for just follower counts export const useFollowerCounts = userId => { const { oxyServices } = useOxy(); const followState = useFollowStore(); const followerCount = followState.followerCounts[userId] ?? null; const followingCount = followState.followingCounts[userId] ?? null; const isLoadingCounts = followState.loadingCounts[userId] ?? false; const fetchUserCounts = useCallback(async () => { await followState.fetchUserCounts(userId, oxyServices); }, [userId, followState, oxyServices]); const setFollowerCount = useCallback(count => { followState.setFollowerCount(userId, count); }, [userId, followState]); const setFollowingCount = useCallback(count => { followState.setFollowingCount(userId, count); }, [userId, followState]); return { followerCount, followingCount, isLoadingCounts, fetchUserCounts, setFollowerCount, setFollowingCount }; }; //# sourceMappingURL=useFollow.js.map