import AsyncStorage from '@react-native-community/async-storage'; import React, {createContext, useEffect, useState} from 'react'; import {INTEGRATED_SOCIAL_LIST} from '../../constants'; import { loadAvatar, loadCover, loadFollowers, loadFollowing, loadMoments, loadProfileInfo, loadRecentlySearchedUsers, loadSocialPosts, } from '../../services'; import { MomentType, ProfilePreviewType, ProfileType, SocialAccountType, UserType, } from '../../types'; interface AuthContextProps { user: UserType; profile: ProfileType; login: (userId: string, username: string) => void; logout: () => void; avatar: string | null; cover: string | null; socialAccounts: Record; recentSearches: Array; newMomentsAvailable: boolean; updateMoments: (value: boolean) => void; socialsNeedUpdate: (_: string[]) => void; moments: MomentType[]; followers: ProfilePreviewType[]; following: ProfilePreviewType[]; followersNeedUpdate: boolean; updateFollowers: (value: boolean) => void; } const NO_USER: UserType = { userId: '', username: '', }; const NO_PROFILE: ProfileType = { biography: '', website: '', name: '', }; const NO_SOCIAL_ACCOUNTS: Record = { Instagram: {posts: []}, Facebook: {posts: []}, Twitter: {posts: []}, }; export const AuthContext = createContext({ user: NO_USER, profile: NO_PROFILE, login: () => {}, logout: () => {}, avatar: null, cover: null, recentSearches: [], newMomentsAvailable: true, updateMoments: () => {}, socialAccounts: NO_SOCIAL_ACCOUNTS, socialsNeedUpdate: () => {}, moments: [], followers: [], following: [], followersNeedUpdate: true, updateFollowers: () => {}, }); /** * Authentication provider for the application. */ const AuthProvider: React.FC = ({children}) => { const [user, setUser] = useState(NO_USER); const [profile, setProfile] = useState(NO_PROFILE); const [avatar, setAvatar] = useState(null); const [cover, setCover] = useState(null); const [socialAccounts, setSocialAccounts] = useState< Record >(NO_SOCIAL_ACCOUNTS); const [recentSearches, setRecentSearches] = useState< Array >([]); const [newMomentsAvailable, setNewMomentsAvailable] = useState(true); // Default update all integrated social lists on start const [socialsNeedUpdate, setSocialsNeedUpdate] = useState([ ...INTEGRATED_SOCIAL_LIST, ]); const [moments, setMoments] = useState>([]); const [followers, setFollowers] = useState>([]); const [following, setFollowing] = useState>([]); const [followersNeedUpdate, setFollowersNeedUpdate] = useState(true); const {userId} = user; useEffect(() => { const loadUserInfoFromStorage = async () => { const [id, username, token] = await Promise.all([ AsyncStorage.getItem('userId'), AsyncStorage.getItem('username'), AsyncStorage.getItem('token'), ]); if (id && username && token) { setUser({...user, userId: id, username}); } }; if (user === NO_USER) { loadUserInfoFromStorage(); } }, [user]); useEffect(() => { if (!userId) { return; } const loadData = async () => { try { const token = await AsyncStorage.getItem('token'); if (!token) { setUser(NO_USER); return; } loadProfileInfo(token, userId, setProfile); loadAvatar(token, userId, setAvatar); loadCover(token, userId, setCover); loadRecentlySearchedUsers(setRecentSearches); } catch (err) { console.log(err); } }; loadData(); }, [userId]); useEffect(() => { const loadNewMoments = async () => { try { const token = await AsyncStorage.getItem('token'); if (!token) { setUser(NO_USER); return; } const newMoments = await loadMoments(userId, token); if (newMoments) { setMoments(newMoments); } setNewMomentsAvailable(false); } catch (error) { console.log(error); } }; if (newMomentsAvailable && userId) { loadNewMoments(); } }, [newMomentsAvailable, userId, moments]); useEffect(() => { const loadNewFollowers = async () => { try { const token = await AsyncStorage.getItem('token'); if (!token) { setUser(NO_USER); return; } loadFollowers(userId, token, setFollowers); loadFollowing(userId, token, setFollowing); setFollowersNeedUpdate(false); } catch (error) { console.log(error); } }; if (followersNeedUpdate && userId) { loadNewFollowers(); } }, [followersNeedUpdate, userId, followers, following]); useEffect(() => { if (socialsNeedUpdate.length > 0 && userId) { for (let social of socialsNeedUpdate) { loadSocialPosts(userId, social).then((accountData) => { socialAccounts[social] = accountData; setSocialAccounts(socialAccounts); console.log('Refreshed posts data:', social); }); } setSocialsNeedUpdate([]); } }, [socialAccounts, socialsNeedUpdate, userId]); return ( { setUser({...user, userId: id, username}); }, logout: () => { try { new Promise(() => { AsyncStorage.removeItem('token'); AsyncStorage.removeItem('userId'); AsyncStorage.removeItem('username'); }).then(() => { setUser(NO_USER); }); } catch (err) { console.log(err); } }, recentSearches, updateMoments: (value) => { setNewMomentsAvailable(value); }, socialsNeedUpdate: (socials: string[]) => { setSocialsNeedUpdate(socials); }, updateFollowers: (value) => { setFollowersNeedUpdate(value); }, }}> {children} ); }; export default AuthProvider;