import React, {useEffect} from 'react'; import {createContext, useState} from 'react'; import RNFetchBlob from 'rn-fetch-blob'; import AsyncStorage from '@react-native-community/async-storage'; import { UserType, ProfileType, InstagramPostType, ProfilePreviewType, } from '../../types'; import { PROFILE_INFO_ENDPOINT, AVATAR_PHOTO_ENDPOINT, COVER_PHOTO_ENDPOINT, GET_IG_POSTS_ENDPOINT, } from '../../constants'; import {Alert} from 'react-native'; interface AuthContextProps { user: UserType; profile: ProfileType; login: (userId: string, username: string) => void; logout: () => void; avatar: string | null; cover: string | null; instaPosts: Array; recentSearches: Array; } const NO_USER: UserType = { userId: '', username: '', }; const NO_PROFILE: ProfileType = { biography: '', website: '', name: '', }; export const AuthContext = createContext({ user: NO_USER, profile: NO_PROFILE, login: () => {}, logout: () => {}, avatar: null, cover: null, instaPosts: [], recentSearches: [], }); /** * 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 [instaPosts, setInstaPosts] = useState>([]); const [recentSearches, setRecentSearches] = useState< Array >([]); const {userId} = user; useEffect(() => { if (!userId) { return; } const loadProfileInfo = async (token: string) => { try { const response = await fetch(PROFILE_INFO_ENDPOINT + `${userId}/`, { method: 'GET', headers: { Authorization: 'Token ' + token, }, }); const status = response.status; if (status === 200) { const info = await response.json(); let {name, biography, website} = info; setProfile({name, biography, website}); } } catch (error) { Alert.alert( 'Something went wrong! 😭', "Would you believe me if I told you that I don't know what happened?", ); } }; const loadAvatar = async (token: string) => { try { const response = await RNFetchBlob.config({ fileCache: true, appendExt: 'jpg', }).fetch('GET', AVATAR_PHOTO_ENDPOINT + `${userId}/`, { Authorization: 'Token ' + token, }); const status = response.info().status; if (status === 200) { setAvatar(response.path()); } else { setAvatar(''); } } catch (error) { console.log(error); } }; const loadCover = async (token: string) => { try { let response = await RNFetchBlob.config({ fileCache: true, appendExt: 'jpg', }).fetch('GET', COVER_PHOTO_ENDPOINT + `${userId}/`, { Authorization: 'Token ' + token, }); const status = response.info().status; if (status === 200) { setCover(response.path()); } else { setCover(''); } } catch (error) { console.log(error); } }; const loadInstaPosts = async (token: string) => { try { const response = await fetch(GET_IG_POSTS_ENDPOINT + `${userId}/`, { method: 'GET', headers: { Authorization: 'Token ' + token, }, }); const status = response.status; if (status === 200) { let ig_posts = await response.json(); setInstaPosts(ig_posts); } else { setInstaPosts([]); } } catch (error) { console.log(error); Alert.alert( 'Something went wrong! 😭', "Would you believe me if I told you that I don't know what happened?", ); } }; const loadRecentlySearchedUsers = async () => { try { const asyncCache = await AsyncStorage.getItem( '@recently_searched_users', ); asyncCache != null ? setRecentSearches(JSON.parse(asyncCache)) : null; } catch (e) { console.log(e); } }; const loadData = async () => { try { const token = await AsyncStorage.getItem('token'); if (!token) { setUser(NO_USER); return; } loadProfileInfo(token); loadAvatar(token); loadCover(token); loadInstaPosts(token); loadRecentlySearchedUsers(); } catch (err) { console.log(err); } }; loadData(); }, [userId]); return ( { setUser({...user, userId: id, username}); }, logout: () => { try { new Promise(() => { AsyncStorage.removeItem('token'); }).then(() => { setUser(NO_USER); }); } catch (err) { console.log(err); } }, recentSearches, }}> {children} ); }; export default AuthProvider;