aboutsummaryrefslogtreecommitdiff
path: root/src/routes/viewProfile/ProfileProvider.tsx
blob: 0600b65bd20366401a8a6ec042fc1961a5aacd5c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
import AsyncStorage from '@react-native-community/async-storage';
import React, {createContext, useEffect, useState} from 'react';
import {INTEGRATED_SOCIAL_LIST} from '../../constants';
import {
  loadAvatar,
  loadCover,
  loadProfileInfo,
  loadSocialPosts,
} from '../../services';
import {ProfileType, SocialAccountType, UserType} from '../../types';

interface ProfileContextProps {
  user: UserType;
  profile: ProfileType;
  loadProfile: (userId: string, username: string) => void;
  avatar: string | null;
  cover: string | null;
  newMomentsAvailable: boolean;
  updateMoments: (value: boolean) => void;
  socialAccounts: Record<string, SocialAccountType>;
  socialsNeedUpdate: (_: string[]) => void;
}
const NO_USER: UserType = {
  userId: '',
  username: '',
};
const NO_PROFILE: ProfileType = {
  biography: '',
  website: '',
  name: '',
};

const NO_SOCIAL_ACCOUNTS: Record<string, SocialAccountType> = {
  Instagram: {posts: []},
  Facebook: {posts: []},
  Twitter: {posts: []},
};

export const ProfileContext = createContext<ProfileContextProps>({
  user: NO_USER,
  profile: NO_PROFILE,
  loadProfile: () => {},
  avatar: null,
  cover: null,
  newMomentsAvailable: true,
  updateMoments: () => {},
  socialAccounts: NO_SOCIAL_ACCOUNTS,
  socialsNeedUpdate: () => {},
});

/**
 * This is the context provider for user profiles that the logged in user wants to see
 */
const ProfileProvider: React.FC = ({children}) => {
  const [user, setUser] = useState<UserType>(NO_USER);
  const [profile, setProfile] = useState<ProfileType>(NO_PROFILE);
  const [avatar, setAvatar] = useState<string | null>(null);
  const [cover, setCover] = useState<string | null>(null);
  const [newMomentsAvailable, setNewMomentsAvailable] = useState<boolean>(true);
  const [socialAccounts, setSocialAccounts] = useState<
    Record<string, SocialAccountType>
  >(NO_SOCIAL_ACCOUNTS);
  // Default update all integrated social lists on start
  const [socialsNeedUpdate, setSocialsNeedUpdate] = useState<string[]>([
    ...INTEGRATED_SOCIAL_LIST,
  ]);

  const {userId} = 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);
      } catch (err) {
        console.log(err);
      }
    };
    loadData();
  }, [userId]);

  useEffect(() => {
    if (socialsNeedUpdate.length > 0 && userId) {
      for (let social of socialsNeedUpdate) {
        loadSocialPosts(userId, social).then((accountData) => {
          socialAccounts[social] = accountData;
          setSocialAccounts(socialAccounts);
          console.log('Updated posts data', social);
        });
      }
      setSocialsNeedUpdate([]);
    }
  }, [socialAccounts, socialsNeedUpdate, userId]);

  return (
    <ProfileContext.Provider
      value={{
        user,
        profile,
        avatar,
        cover,
        newMomentsAvailable,
        socialAccounts,
        loadProfile: (id, username) => {
          setUser({...user, userId: id, username});
        },
        updateMoments: (value) => {
          setNewMomentsAvailable(value);
        },
        socialsNeedUpdate: (socials: string[]) => {
          setSocialsNeedUpdate(socials);
        },
      }}>
      {children}
    </ProfileContext.Provider>
  );
};

export default ProfileProvider;