UNPKG

@oxyhq/services

Version:

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

181 lines (169 loc) • 6.87 kB
import { create } from 'zustand'; import type { OxyServices } from '../../core'; interface FollowState { followingUsers: Record<string, boolean>; loadingUsers: Record<string, boolean>; fetchingUsers: Record<string, boolean>; errors: Record<string, string | null>; // Follower counts for each user followerCounts: Record<string, number>; followingCounts: Record<string, number>; // Loading states for counts loadingCounts: Record<string, boolean>; setFollowingStatus: (userId: string, isFollowing: boolean) => void; clearFollowError: (userId: string) => void; resetFollowState: () => void; fetchFollowStatus: (userId: string, oxyServices: OxyServices) => Promise<void>; toggleFollowUser: (userId: string, oxyServices: OxyServices, isCurrentlyFollowing: boolean) => Promise<void>; // New methods for follower counts setFollowerCount: (userId: string, count: number) => void; setFollowingCount: (userId: string, count: number) => void; updateCountsFromFollowAction: (targetUserId: string, action: 'follow' | 'unfollow', counts: { followers: number; following: number }, currentUserId?: string) => void; fetchUserCounts: (userId: string, oxyServices: OxyServices) => Promise<void>; } export const useFollowStore = create<FollowState>((set: any, get: any) => ({ followingUsers: {}, loadingUsers: {}, fetchingUsers: {}, errors: {}, followerCounts: {}, followingCounts: {}, loadingCounts: {}, setFollowingStatus: (userId: string, isFollowing: boolean) => set((state: FollowState) => ({ followingUsers: { ...state.followingUsers, [userId]: isFollowing }, errors: { ...state.errors, [userId]: null }, })), clearFollowError: (userId: string) => set((state: FollowState) => ({ errors: { ...state.errors, [userId]: null }, })), resetFollowState: () => set({ followingUsers: {}, loadingUsers: {}, fetchingUsers: {}, errors: {}, followerCounts: {}, followingCounts: {}, loadingCounts: {}, }), fetchFollowStatus: async (userId: string, oxyServices: OxyServices) => { set((state: FollowState) => ({ fetchingUsers: { ...state.fetchingUsers, [userId]: true }, errors: { ...state.errors, [userId]: null }, })); try { const response = await oxyServices.getFollowStatus(userId); set((state: FollowState) => ({ followingUsers: { ...state.followingUsers, [userId]: response.isFollowing }, fetchingUsers: { ...state.fetchingUsers, [userId]: false }, errors: { ...state.errors, [userId]: null }, })); } catch (error: any) { set((state: FollowState) => ({ fetchingUsers: { ...state.fetchingUsers, [userId]: false }, errors: { ...state.errors, [userId]: error?.message || 'Failed to fetch follow status' }, })); } }, toggleFollowUser: async (userId: string, oxyServices: OxyServices, isCurrentlyFollowing: boolean) => { set((state: FollowState) => ({ loadingUsers: { ...state.loadingUsers, [userId]: true }, errors: { ...state.errors, [userId]: null }, })); try { let response: any; let newFollowState; if (isCurrentlyFollowing) { response = await oxyServices.unfollowUser(userId); newFollowState = false; } else { response = await oxyServices.followUser(userId); newFollowState = true; } // Update follow status set((state: FollowState) => ({ followingUsers: { ...state.followingUsers, [userId]: newFollowState }, loadingUsers: { ...state.loadingUsers, [userId]: false }, errors: { ...state.errors, [userId]: null }, })); // Update counts if the response includes them // The API returns counts for both users: // - followers: target user's follower count (the user being followed) // - following: current user's following count (the user doing the following) if (response && response.counts) { const { counts } = response; // Get current user ID from oxyServices const currentUserId = oxyServices.getCurrentUserId(); set((state: FollowState) => { const updates: any = {}; // Update target user's follower count (the user being followed) updates.followerCounts = { ...state.followerCounts, [userId]: counts.followers }; // Update current user's following count (the user doing the following) if (currentUserId) { updates.followingCounts = { ...state.followingCounts, [currentUserId]: counts.following }; } return updates; }); } } catch (error: any) { set((state: FollowState) => ({ loadingUsers: { ...state.loadingUsers, [userId]: false }, errors: { ...state.errors, [userId]: error?.message || 'Failed to update follow status' }, })); } }, setFollowerCount: (userId: string, count: number) => set((state: FollowState) => ({ followerCounts: { ...state.followerCounts, [userId]: count }, })), setFollowingCount: (userId: string, count: number) => set((state: FollowState) => ({ followingCounts: { ...state.followingCounts, [userId]: count }, })), updateCountsFromFollowAction: (targetUserId: string, action: 'follow' | 'unfollow', counts: { followers: number; following: number }, currentUserId?: string) => { set((state: FollowState) => { const updates: any = {}; // Update target user's follower count (the user being followed) updates.followerCounts = { ...state.followerCounts, [targetUserId]: counts.followers }; // Update current user's following count (the user doing the following) if (currentUserId) { updates.followingCounts = { ...state.followingCounts, [currentUserId]: counts.following }; } return updates; }); }, fetchUserCounts: async (userId: string, oxyServices: OxyServices) => { set((state: FollowState) => ({ loadingCounts: { ...state.loadingCounts, [userId]: true }, })); try { const user = await oxyServices.getUserById(userId); if (user && user._count) { set((state: FollowState) => ({ followerCounts: { ...state.followerCounts, [userId]: user._count?.followers || 0 }, followingCounts: { ...state.followingCounts, [userId]: user._count?.following || 0 }, loadingCounts: { ...state.loadingCounts, [userId]: false }, })); } } catch (error: unknown) { set((state: FollowState) => ({ loadingCounts: { ...state.loadingCounts, [userId]: false }, })); } }, }));