Browse Source

refactoring, added scroll in profile page, added limit scroll.

makstravm 3 years ago
parent
commit
f5d05e2a58

+ 1 - 0
package.json

@@ -14,6 +14,7 @@
         "react-router-dom": "^5.3.0",
         "react-scripts": "5.0.0",
         "redux": "^4.1.2",
+        "redux-saga": "^1.1.3",
         "redux-thunk": "^2.4.1",
         "sass": "^1.45.0",
         "web-vitals": "^2.1.2"

+ 69 - 35
src/actions/index.js

@@ -10,17 +10,16 @@ export const actionRejected = (name, error) => ({ type: 'PROMISE', status: 'REJE
 export const actionAuthLogin = (token, remember) => ({ type: 'AUTH_LOGIN', token, remember })
 export const actionAuthLogout = () => ({ type: 'AUTH_LOGOUT' })
 
-export const actionRenderPostsFeedAC = (newResult) => ({ type: 'RENDER-POSTS-FEED', newResult })
+export const actionAboutMeAC = (data) => ({ type: 'ABOUTME-DATA-ADD', data })
+export const actionUpdateMyAvatart = (data) => ({ type: 'ABOUTME-UPDATE-AVATAR', data })
+export const actionAddPostsFeedAC = (count, newResult, userData) => ({ type: 'ADD-POSTS-FEED', newResult, userData, count })
 export const actionRemovePostsFeedAC = () => ({ type: 'REMOVE-POSTS-FEED' })
 
 export const actionAddLikePostAC = (postId, newResult) => ({ type: 'ADD-POST-LIKE', postId, newResult })
 export const actionRemoveLikePostAC = (postId, newResult) => ({ type: 'REMOVE-POST-LIKE', postId, newResult })
 export const actionAddCommentAC = (postId, newResult) => ({ type: 'ADD-COMMENT', postId, newResult })
 
-export const actionProfilePageDataAC = (userData, userPosts) => ({ type: 'PROFILE-PAGE-DATA', userData, userPosts })
-export const actionRemovePrfilePageAC = () => ({ type: 'REMOVE-POSTS-PAGE' })
-
-export const actionUpdateFollowingAC = (newResult) => ({ type: 'UPDATE-FOLLOWING', newResult })
+export const actionUpdateFollowersAC = (newResult) => ({ type: 'UPDATE-FOLLOWERS', newResult })
 
 //****************---Action Authirization ---*************************//
 
@@ -36,17 +35,41 @@ export const actionRegister = (login, password) =>
                                     }
                                 }`, { login, password }))
 
-export const actionAboutMe = () =>
-    async (dispatch, getState) => {
-        const { auth: { payload: { sub: { id } } } } = getState()
-        await dispatch(actionPromise('aboutMe', gql(`query userOned($myID:String!){
+export const actionAboutMe = (id) =>
+    actionPromise('aboutMe', gql(`query userOned($myID:String!){
                         UserFindOne(query: $myID){
                             _id  login nick
                             avatar { _id url }
                             following{ _id}
-                  }
-                }`, { myID: JSON.stringify([{ ___owner: id }]) })))
-    }
+                        }
+                }`, { myID: JSON.stringify([{ ___owner: id }]) }))
+
+
+
+
+export const actionMyFolowingPosts = (skip, myFollowing) =>
+    actionPromise('followingPosts',
+        gql(`query allposts($query: String!){
+        PostFind(query:$query){
+            _id, text, title
+            owner{_id, nick, login, avatar {url}}
+            likes { _id owner {_id}}   
+            images{url _id}
+            comments{_id text owner{_id nick login} likes{_id}}
+            createdAt
+        }
+    }`, {
+            query: JSON.stringify([{ ___owner: { $in: myFollowing } },
+            {
+                sort: [{ _id: -1 }],
+                skip: [skip || 0],
+                limit: [10]
+            }])
+        }))
+
+
+// 
+
 
 //****************---Action FindUsers ---*************************//
 
@@ -119,16 +142,36 @@ export const actionProfilePageData = (_id) =>
                 }
             } `, { id: JSON.stringify([{ _id }]) }))
 
-export const actionProfilePagePost = (_id) =>
-    actionPromise('userOneData', gql(` query userOned($id:String!){
+export const actionProfilePagePost = (_id, skip) =>
+    actionPromise('userOneDataPosts', gql(` query userOned($id:String!){
                 PostFind(query:$id){
                     _id   images{url _id}
                 }
-                }`, { id: JSON.stringify([{ ___owner: _id }]) }))
+                }`, {
+        id: JSON.stringify([{
+            ___owner: _id
+        },
+        {
+            sort: [{ _id: -1 }],
+            skip: [skip || 0],
+            limit: [10]
+        }])
+    }))
 
+export const actionProfilePostCount = (_id) =>
+    actionPromise('userPostsCount', gql(` query userPostsCount($id:String!){
+                PostCount(query:$id)
+                }`, { id: JSON.stringify([{ ___owner: { $in: _id } }]) }))
 
 //****************---Action ProfileData ---*************************//
 
+export const actionUpdateMyFollowing = (_id) =>
+    actionPromise('upDateFollowing', gql(` query followers($id:String!){
+        UserFindOne(query: $id){
+                            following {_id nick login}
+        }
+    }`, { id: JSON.stringify([{ _id }]) }))
+
 
 export const actionUpdateFollowers = (_id) =>
     actionPromise('upDateFollowers', gql(` query followers($id:String!){
@@ -144,7 +187,7 @@ export const actionSubscribe = (myID, myFollowing, userId) =>
         }
       }`, { user: { _id: myID, following: [...myFollowing || [], { _id: userId }] } }))
 
-export const actionUnSubscribe = (myID, myFollowing ) =>
+export const actionUnSubscribe = (myID, myFollowing) =>
     actionPromise('unSubscribe', gql(`mutation followingUn($user:UserInput){
         UserUpsert( user:$user){
             following{_id}
@@ -155,26 +198,17 @@ export const actionUnSubscribe = (myID, myFollowing ) =>
 
 //****************---Action Upload Images ---*************************//
 
-export const actionSetAvatar = (file) =>
-    async (dispatch, getState) => {
-        // const result = await dispatch(actionUploadFile(file))
-        // if (result) {
-        const { auth: { payload: { sub: { id } } } } = getState()
-        await actionPromise('uploadPhoto', gql(`mutation avaUpsert($ava: UserInput){
+
+export const actionSetAvatar = (file, id) =>
+    actionPromise('uploadPhoto', gql(`mutation avaUpsert($ava: UserInput){
                 UserUpsert(user: $ava){
                     _id avatar {_id}
                 }
               }`, { ava: { _id: id, avatar: { _id: file._id } } })
-        )
-        await dispatch(actionAboutMe())
-        // }
-    }
-// export const actionUploadFile = (file) => {
-//     let fd = new FormData()
-//     fd.append('photo', file)
-//     return actionPromise('upload', fetch(`${backURL}/upload`, {
-//         method: "POST",
-//         headers: localStorage.authToken ? { Authorization: 'Bearer ' + localStorage.authToken } : {},
-//         body: fd,
-//     }).then(res => res.json()))
-// }
+    )
+export const actionGetAvatar = (id) =>
+    actionPromise('uploadPhoto', gql(`query userOned($myID: String!){
+        UserFindOne(query: $myID) {
+                            avatar { _id url }
+        }
+    }`, { myID: JSON.stringify([{ ___owner: id }]) }))

+ 2 - 2
src/components/header/Header.jsx

@@ -32,7 +32,7 @@ export const UserAvatar = ({ avatarSize, avatar }) => {
     )
 }
 
-const ProfileDropMenu = ( {myID, onLogOut }) =>
+const ProfileDropMenu = ({ myID, onLogOut }) =>
     <Menu className='dropMenu'>
         <Menu.Item key={'0'}>
             <Link to={`${myID}`}><UserOutlined /> My Profile</Link>
@@ -72,7 +72,7 @@ const UserNavIcon = ({ userData: { _id, avatar, login } }) =>
 
 const CUserNav = connect(state => ({ id: state.auth?.payload.sub.id || {} }))(UserNav)
 
-const CUserNavIcon = connect(state => ({ userData: state.promise?.aboutMe?.payload || {} }))(UserNavIcon)
+const CUserNavIcon = connect(state => ({ userData: state.myData || {} }))(UserNavIcon)
 
 const Logo = () =>
     <Link className='Logo' to='/'>

+ 13 - 9
src/components/main/Add.js

@@ -1,40 +1,44 @@
 import { useState } from 'react';
 import { LoadingOutlined, PlusOutlined } from '@ant-design/icons';
 import { connect } from 'react-redux';
-import { Upload, message} from 'antd';
+import { Upload, message } from 'antd';
 import { backURL, gql } from '../../helpers';
 import { actionSetAvatar } from '../../actions';
+import { actionFullSetAvatar } from '../../redux/redux-thunk';
 
 const Add = ({ imageUrl, onUploadFile }) => {
     const [loading, setLoading] = useState(false)
-
+    const [imageLoad, setImageLoad] = useState(false)
     const props = {
         name: 'photo',
         action: `${backURL}/upload`,
-        headers: localStorage.authToken ? { Authorization: 'Bearer ' + localStorage.authToken } : {}
+        headers: localStorage.authToken || sessionStorage.authToken ? { Authorization: 'Bearer ' + (localStorage.authToken||sessionStorage.authToken) } : {}
     }
+
     const handleChange = async ({ file }) => {
-        if (file.status !== 'uploading') {
+   
+        if (file.status === 'uploading') {
             setLoading(true)
         }
         if (file.status === 'done') {
             message.success(`${file.name} file uploaded successfully`);
-            console.log(1);
             await onUploadFile(file.response)
+            console.log(file);
+            setImageLoad(true)
             setLoading(false)
-            console.log(2);
         } else if (file.status === 'error') {
             message.error(`${file.name} file upload failed.`);
         }
     }
+    
     return (
         <Upload {...props}
             listType="picture-card"
             showUploadList={false}
             onChange={handleChange}
             className="avatar-uploader">
-            {imageUrl ?
-                <img src={`${backURL +'/'+ imageUrl}`} alt="avatar" style={{ width: '100%' }} /> :
+            {imageLoad ?
+                <img src={`${backURL + '/' + imageUrl}`} alt="avatar" style={{ width: '100%' }} /> :
                 <div>
                     {loading ? <LoadingOutlined /> : <PlusOutlined />}
                     <div style={{ marginTop: 8 }}>Upload</div>
@@ -43,4 +47,4 @@ const Add = ({ imageUrl, onUploadFile }) => {
     )
 }
 
-export const CAdd = connect(state => ({ imageUrl: state.promise?.aboutMe?.payload?.avatar.url }), { onUploadFile: actionSetAvatar })(Add)
+export const CAdd = connect(state => ({ imageUrl: state?.myData?.avatar?.url}), { onUploadFile: actionFullSetAvatar })(Add)

+ 12 - 9
src/components/main/MainPostsFeed.js

@@ -9,7 +9,7 @@ import { HeartFilled, HeartOutlined, LeftCircleOutlined, RightCircleOutlined, Se
 import Paragraph from 'antd/lib/typography/Paragraph'
 import Text from 'antd/lib/typography/Text'
 import TextArea from 'antd/lib/input/TextArea'
-import { actionAddPostsFeed, actionFullAddComment, actionFullAddLikePost, actionFullRemoveLikePost, actionRenderPostsFeed } from '../../redux/redux-thunk'
+import { actionAddPostsFeed, actionFullAddComment, actionFullAddLikePost, actionFullRemoveLikePost } from '../../redux/redux-thunk'
 import { actionRemovePostsFeedAC } from '../../actions'
 
 const PostTitle = ({ owner }) =>
@@ -90,7 +90,7 @@ const HeartLike = ({ styleFontSize, likeStatus, changeLike }) =>
                 <HeartOutlined style={{ color: '#1890ff', fontSize: `${styleFontSize}` }} />}
     />
 
-const PostUserPanel = ({ myID, postId, likes, addLikePost, removeLikePost }) => {
+const PostUserPanel = ({ myID, postId, likes = [], addLikePost, removeLikePost }) => {
     let likeStatus
     let likeId
     likes.find(l => {
@@ -205,7 +205,7 @@ const FieldCommentSend = ({ postId, sentComment }) => {
 
 const CFieldCommentSend = connect(null, { sentComment: actionFullAddComment })(FieldCommentSend)
 
-const Post = ({ postData: { _id, text, title, owner, images, createdAt, comments, likes } }) => {
+const Post = ({ postData: { _id, text, title, owner, images, createdAt = '', comments, likes } }) => {
     const date = new Date(createdAt * 1)
     const resultDate = new Intl.DateTimeFormat('default').format(date)
     return (
@@ -223,14 +223,15 @@ const Post = ({ postData: { _id, text, title, owner, images, createdAt, comments
     )
 }
 
-const MainPostsFeed = ({ posts, postsFollowing, postsFollowingRemove }) => {
+const MainPostsFeed = ({ posts, countPosts, postsFollowing, postsFollowingRemove, following }) => {
     const [checkScroll, setCheckScroll] = useState(true)
+
     useEffect(async () => {
-        if (checkScroll) {
-            await postsFollowing(posts.length)
+        if (checkScroll && following.length !== 0 && posts.length < countPosts) {
+            await postsFollowing(posts.length, following)
             setCheckScroll(false)
         }
-    }, [checkScroll])
+    }, [checkScroll, following])
 
     useEffect(() => {
         document.addEventListener('scroll', scrollHandler)
@@ -253,8 +254,10 @@ const MainPostsFeed = ({ posts, postsFollowing, postsFollowingRemove }) => {
 }
 
 export const CMainPostsFeed = connect(state => ({
-    posts: state?.postsFeed?.posts || []
+    countPosts: state?.postsFeed?.count || 1,
+    posts: state?.postsFeed?.posts || [],
+    following: state?.myData.following || []
 }), {
-    postsFollowing: actionRenderPostsFeed,
+    postsFollowing: actionAddPostsFeed,
     postsFollowingRemove: actionRemovePostsFeedAC,
 })(MainPostsFeed)

+ 35 - 20
src/components/main/Profile.js

@@ -3,7 +3,7 @@ import Modal from 'antd/lib/modal/Modal'
 import React, { useEffect, useState } from 'react'
 import { connect } from 'react-redux'
 import { Link } from 'react-router-dom'
-import { actionRemovePostsAC } from '../../actions'
+import { actionRemovePostsAC, actionRemovePostsFeedAC } from '../../actions'
 import { backURL } from '../../helpers'
 import { actionFullProfilePageData, actionFullSubscribe, actionFullUnSubscribe, actionProfilePageData } from '../../redux/redux-thunk'
 import { UserAvatar } from '../header/Header'
@@ -40,8 +40,8 @@ const ModalFolower = ({ statusModal, data, title }) => {
     )
 }
 
-const CModalFollowers = connect(state => ({ data: state?.profileData?.userData?.followers || [] }))(ModalFolower)
-const CModalFollowing = connect(state => ({ data: state?.profileData?.userData?.following || [] }))(ModalFolower)
+const CModalFollowers = connect(state => ({ data: state?.postsFeed?.userData?.followers || [] }))(ModalFolower)
+const CModalFollowing = connect(state => ({ data: state?.postsFeed?.userData?.following || [] }))(ModalFolower)
 
 
 const ProfileSetting = ({ myID, userId, followers, onSubsuscribe, onUnSubsuscribe }) => {
@@ -49,18 +49,18 @@ const ProfileSetting = ({ myID, userId, followers, onSubsuscribe, onUnSubsuscrib
     return (
         <Col className='Profile__seting' offset={4}>
             {!!followCheck ?
-                <Button onClick={() => onUnSubsuscribe(userId)}>Primary Button</Button> :
-                <Button onClick={() => onSubsuscribe(userId)} type="primary">Primary Button</Button>}
+                <Button onClick={() => onUnSubsuscribe(userId)}>UnSubscribe</Button> :
+                <Button onClick={() => onSubsuscribe(userId)} type="primary">Subscribe</Button>}
         </Col>
     )
 }
 
 const CProfileSetting = connect(state => ({
     myID: state?.auth?.payload?.sub.id,
-    followers: state?.profileData?.userData?.followers || []
+    followers: state?.postsFeed?.userData?.followers || []
 }), { onSubsuscribe: actionFullSubscribe, onUnSubsuscribe: actionFullUnSubscribe })(ProfileSetting)
 
-const ProfilePageData = ({ data: { _id, avatar, login, nick, followers, following }, posts, setFollowing, setFollowers }) => {
+const ProfilePageData = ({ data: { _id, avatar, login, nick, followers, following }, count, setFollowing, setFollowers }) => {
 
     return (
         <Row className='Profile' align='middle'>
@@ -77,7 +77,7 @@ const ProfilePageData = ({ data: { _id, avatar, login, nick, followers, followin
                 </Row>
                 <Row className='Profile__count' align='middle' justify='space-between'>
                     <Col >
-                        <strong>{posts?.length || '0'}</strong>
+                        <strong>{count || '0'}</strong>
                         <span>Posts</span>
                     </Col>
                     <Col >
@@ -99,39 +99,51 @@ const ProfilePageData = ({ data: { _id, avatar, login, nick, followers, followin
 }
 
 const CProfilePageData = connect(state => ({
-    data: state?.profileData?.userData || {},
-    posts: state?.profileData?.userPosts || []
+    data: state?.postsFeed?.userData || {},
+    count: state?.postsFeed?.count || null
 }))(ProfilePageData)
 
 
 const ProfilePagePosts = ({ posts }) => {
-
-
     return (
         <Row>
             {posts.map(p => <Col key={p._id}>
-                {console.log(p)}
                 {p.images && p.images[0] && p.images[0].url && <img src={(backURL + '/' + p?.images[0].url)} alt='post Img' />}
             </Col>)
-
-
             }
         </Row >
     )
 
 }
 
-export const CProfilePagePosts = connect(state => ({ posts: state.profileData?.userPosts || [] }))(ProfilePagePosts)
+export const CProfilePagePosts = connect(state => ({ posts: state.postsFeed?.posts || [] }))(ProfilePagePosts)
 
-const ProfilePage = ({ match: { params: { _id } }, getProfileUser }) => {
+const ProfilePage = ({ match: { params: { _id } }, posts, countPost, getProfileUser, clearDataProfile }) => {
     const [followers, setFollowers] = useState(false)
     const [following, setFollowing] = useState(false)
+    const [checkScroll, setCheckScroll] = useState(true)
+
     useEffect(() => {
-        getProfileUser(_id)
+        document.addEventListener('scroll', scrollHandler)
         return () => {
-            // actionRemovePrfilePageAC 
+            document.removeEventListener('scroll', scrollHandler)
+            setCheckScroll(true)
+            clearDataProfile()
         }
     }, [_id])
+    useEffect(async () => {
+        if (checkScroll && posts.length < countPost) {
+            await getProfileUser(_id, posts.length)
+            setCheckScroll(false)
+        }
+    }, [_id, checkScroll])
+
+    const scrollHandler = (e) => {
+        if (e.target.documentElement.scrollHeight - (e.target.documentElement.scrollTop + window.innerHeight) < 500) {
+            setCheckScroll(true)
+        }
+    }
+
     return (
         <>
             <CProfilePageData setFollowing={setFollowing} setFollowers={setFollowers} />
@@ -142,4 +154,7 @@ const ProfilePage = ({ match: { params: { _id } }, getProfileUser }) => {
     )
 }
 
-export const CProfilePage = connect(null, { getProfileUser: actionFullProfilePageData, })(ProfilePage)
+export const CProfilePage = connect(state => ({
+    posts: state?.postsFeed?.posts || [],
+    countPost: state?.postsFeed?.count || 1
+}), { getProfileUser: actionFullProfilePageData, clearDataProfile: actionRemovePostsFeedAC })(ProfilePage)

+ 0 - 1
src/redux/auth-reducer.js

@@ -32,4 +32,3 @@ export const authReducer = (state, { type, token, remember }) => {
 
 
 
-

+ 17 - 0
src/redux/myProfile-reducer.js

@@ -0,0 +1,17 @@
+import React from 'react'
+
+export const myProfileReducer = (state = {}, { type, data }) => {
+    const types = {
+        'ABOUTME-DATA-ADD': () => {
+            return { ...state, ...data }
+        },
+        'ABOUTME-UPDATE-AVATAR': () => {
+            return { ...state, avatar: { ...data } }
+        },
+      
+    }
+    if (type in types) {
+        return types[type]()
+    }
+    return state
+}

+ 14 - 32
src/redux/postsFeed-reducer.js

@@ -1,20 +1,21 @@
 import React from 'react'
-import { gql } from '../helpers'
-import { actionPromise } from './redux-thunk'
 
-export const postsFeedReducer = (state = {}, { type, postId, newResult }) => {
+export const postsFeedReducer = (state = {}, { type, postId, newResult, userData = {}, count = null }) => {
     const { posts } = state
     const types = {
-        'RENDER-POSTS-FEED': () => {
+        'ADD-POSTS-FEED': () => {
             return {
                 ...state,
-                posts: !!posts ? [...posts, ...newResult] : [...newResult]
+                posts: !!posts ? [...posts, ...newResult] : [...newResult],
+                userData: { ...userData },
+                count
             }
         },
         'REMOVE-POSTS-FEED': () => {
             return {
                 ...state,
-                posts: []
+                posts: [],
+                userData: {}
             }
         },
         'ADD-POST-LIKE': () => {
@@ -27,7 +28,6 @@ export const postsFeedReducer = (state = {}, { type, postId, newResult }) => {
             return {
                 ...state,
                 posts: posts.map(p => p._id === postId ? p = { ...p, likes: [...newResult] } : p),
-
             }
         },
         'ADD-COMMENT': () => {
@@ -35,6 +35,12 @@ export const postsFeedReducer = (state = {}, { type, postId, newResult }) => {
                 ...state,
                 posts: posts.map(p => p._id === postId ? { ...p, comments: [...newResult] } : p)
             }
+        },
+        'UPDATE-FOLLOWERS': () => {
+            return {
+                ...state,
+                userData: { ...state.userData, followers: [...newResult] }
+            }
         }
     }
     if (type in types) {
@@ -42,32 +48,8 @@ export const postsFeedReducer = (state = {}, { type, postId, newResult }) => {
     }
     return state
 }
-// export const actionRemoveComment = (_id) =>
-//     actionPromise('removeComment', gql(`mutation CommentRemove($comment: CommentInput ){
-//         CommentDelete(comment:$comment){
-//             _id, text
-//         }
-//     }`, { comment: { _id } }))
 
 
 
 
-export const actionMyFolowingPosts = (skip) =>
-    actionPromise('followingPosts',
-        gql(`query allposts($query: String!){
-        PostFind(query:$query){
-            _id, text, title
-            owner{_id, nick, login, avatar {url}}
-            likes { _id owner {_id}}   
-            images{url _id}
-            comments{_id text owner{_id nick login} likes{_id}}
-            createdAt
-        }
-    }`, {
-            query: JSON.stringify([{ ___owner: { $in: ["614c8ef4f9fc3a5e42bddb28"] } },
-            {
-                sort: [{ _id: -1 }],
-                skip: [skip||0],
-                limit: [10]
-            }])
-        }))
+

+ 0 - 28
src/redux/profile-reducer.js

@@ -1,28 +0,0 @@
-import React from 'react'
-
-export const profileReducer = (state = {}, { type, userData,userPosts, newResult }) => {
-    const types = {
-        'PROFILE-PAGE-DATA': () => {
-            return {
-                ...state, userData, userPosts
-            }
-        },
-        'REMOVE-POSTS-PAGE': () => {
-            return {
-                ...state,
-                posts: []
-            }
-        },
-        'UPDATE-FOLLOWING': () => {
-            return {
-                ...state,
-                userData: { ...state.userData, followers: [...newResult] }
-            }
-        }
-
-    }
-    if (type in types) {
-        return types[type]()
-    }
-    return state
-}

+ 7 - 6
src/redux/redux-store.js

@@ -1,20 +1,21 @@
 import { createStore, combineReducers, applyMiddleware } from 'redux';
 import thunk from 'redux-thunk';
-import { actionAboutMe } from '../actions';
 import { authReducer } from './auth-reducer';
-import { postsFeedReducer } from './postsFeed-reducer';
-import { profileReducer } from './profile-reducer';
+import { myProfileReducer } from './myProfile-reducer';
+import { postsFeedReducer } from './postFeed-reducer';
 import { promiseReducer } from './promise-reducer';
+import { actionFullAboutMe } from './redux-thunk';
 
 
 
 const store = createStore(combineReducers({
-    promise: promiseReducer,
     auth: authReducer,
+    promise: promiseReducer,
+    myData: myProfileReducer,
     postsFeed: postsFeedReducer,
-    profileData:profileReducer
 }),
     applyMiddleware(thunk))
 
-store.dispatch(actionAboutMe())
+store.dispatch(actionFullAboutMe())
+
 export default store;

File diff suppressed because it is too large
+ 43 - 22
src/redux/redux-thunk.js


+ 72 - 2
yarn.lock

@@ -1049,7 +1049,7 @@
     core-js-pure "^3.19.0"
     regenerator-runtime "^0.13.4"
 
-"@babel/runtime@^7.1.2", "@babel/runtime@^7.10.1", "@babel/runtime@^7.10.2", "@babel/runtime@^7.10.4", "@babel/runtime@^7.11.1", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.13", "@babel/runtime@^7.12.5", "@babel/runtime@^7.15.4", "@babel/runtime@^7.16.3", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2":
+"@babel/runtime@^7.1.2", "@babel/runtime@^7.10.1", "@babel/runtime@^7.10.2", "@babel/runtime@^7.10.4", "@babel/runtime@^7.11.1", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.13", "@babel/runtime@^7.12.5", "@babel/runtime@^7.15.4", "@babel/runtime@^7.16.3", "@babel/runtime@^7.6.3", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2":
   version "7.16.7"
   resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.16.7.tgz#03ff99f64106588c9c403c6ecb8c3bafbbdff1fa"
   integrity sha512-9E9FJowqAsytyOY6LG+1KuueckRL+aQW+mKvXRXnuFGyRAyepJPmEo9vgMfXUA6O9u3IeEdv9MAkppFcaQwogQ==
@@ -1354,6 +1354,50 @@
     schema-utils "^3.0.0"
     source-map "^0.7.3"
 
+"@redux-saga/core@^1.1.3":
+  version "1.1.3"
+  resolved "https://registry.yarnpkg.com/@redux-saga/core/-/core-1.1.3.tgz#3085097b57a4ea8db5528d58673f20ce0950f6a4"
+  integrity sha512-8tInBftak8TPzE6X13ABmEtRJGjtK17w7VUs7qV17S8hCO5S3+aUTWZ/DBsBJPdE8Z5jOPwYALyvofgq1Ws+kg==
+  dependencies:
+    "@babel/runtime" "^7.6.3"
+    "@redux-saga/deferred" "^1.1.2"
+    "@redux-saga/delay-p" "^1.1.2"
+    "@redux-saga/is" "^1.1.2"
+    "@redux-saga/symbols" "^1.1.2"
+    "@redux-saga/types" "^1.1.0"
+    redux "^4.0.4"
+    typescript-tuple "^2.2.1"
+
+"@redux-saga/deferred@^1.1.2":
+  version "1.1.2"
+  resolved "https://registry.yarnpkg.com/@redux-saga/deferred/-/deferred-1.1.2.tgz#59937a0eba71fff289f1310233bc518117a71888"
+  integrity sha512-908rDLHFN2UUzt2jb4uOzj6afpjgJe3MjICaUNO3bvkV/kN/cNeI9PMr8BsFXB/MR8WTAZQq/PlTq8Kww3TBSQ==
+
+"@redux-saga/delay-p@^1.1.2":
+  version "1.1.2"
+  resolved "https://registry.yarnpkg.com/@redux-saga/delay-p/-/delay-p-1.1.2.tgz#8f515f4b009b05b02a37a7c3d0ca9ddc157bb355"
+  integrity sha512-ojc+1IoC6OP65Ts5+ZHbEYdrohmIw1j9P7HS9MOJezqMYtCDgpkoqB5enAAZrNtnbSL6gVCWPHaoaTY5KeO0/g==
+  dependencies:
+    "@redux-saga/symbols" "^1.1.2"
+
+"@redux-saga/is@^1.1.2":
+  version "1.1.2"
+  resolved "https://registry.yarnpkg.com/@redux-saga/is/-/is-1.1.2.tgz#ae6c8421f58fcba80faf7cadb7d65b303b97e58e"
+  integrity sha512-OLbunKVsCVNTKEf2cH4TYyNbbPgvmZ52iaxBD4I1fTif4+MTXMa4/Z07L83zW/hTCXwpSZvXogqMqLfex2Tg6w==
+  dependencies:
+    "@redux-saga/symbols" "^1.1.2"
+    "@redux-saga/types" "^1.1.0"
+
+"@redux-saga/symbols@^1.1.2":
+  version "1.1.2"
+  resolved "https://registry.yarnpkg.com/@redux-saga/symbols/-/symbols-1.1.2.tgz#216a672a487fc256872b8034835afc22a2d0595d"
+  integrity sha512-EfdGnF423glv3uMwLsGAtE6bg+R9MdqlHEzExnfagXPrIiuxwr3bdiAwz3gi+PsrQ3yBlaBpfGLtDG8rf3LgQQ==
+
+"@redux-saga/types@^1.1.0":
+  version "1.1.0"
+  resolved "https://registry.yarnpkg.com/@redux-saga/types/-/types-1.1.0.tgz#0e81ce56b4883b4b2a3001ebe1ab298b84237204"
+  integrity sha512-afmTuJrylUU/0OtqzaRkbyYFFNgCF73Bvel/sw90pvGrWIZ+vyoIJqA6eMSoA6+nb443kTmulmBtC9NerXboNg==
+
 "@rollup/plugin-babel@^5.2.0":
   version "5.3.0"
   resolved "https://registry.yarnpkg.com/@rollup/plugin-babel/-/plugin-babel-5.3.0.tgz#9cb1c5146ddd6a4968ad96f209c50c62f92f9879"
@@ -7671,12 +7715,19 @@ redent@^3.0.0:
     indent-string "^4.0.0"
     strip-indent "^3.0.0"
 
+redux-saga@^1.1.3:
+  version "1.1.3"
+  resolved "https://registry.yarnpkg.com/redux-saga/-/redux-saga-1.1.3.tgz#9f3e6aebd3c994bbc0f6901a625f9a42b51d1112"
+  integrity sha512-RkSn/z0mwaSa5/xH/hQLo8gNf4tlvT18qXDNvedihLcfzh+jMchDgaariQoehCpgRltEm4zHKJyINEz6aqswTw==
+  dependencies:
+    "@redux-saga/core" "^1.1.3"
+
 redux-thunk@^2.4.1:
   version "2.4.1"
   resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-2.4.1.tgz#0dd8042cf47868f4b29699941de03c9301a75714"
   integrity sha512-OOYGNY5Jy2TWvTL1KgAlVy6dcx3siPJ1wTq741EPyUKfn6W6nChdICjZwCd0p8AZBs5kWpZlbkXW2nE/zjUa+Q==
 
-redux@^4.0.0, redux@^4.1.2:
+redux@^4.0.0, redux@^4.0.4, redux@^4.1.2:
   version "4.1.2"
   resolved "https://registry.yarnpkg.com/redux/-/redux-4.1.2.tgz#140f35426d99bb4729af760afcf79eaaac407104"
   integrity sha512-SH8PglcebESbd/shgf6mii6EIoRM0zrQyjcuQ+ojmfxjTtE0z9Y8pa62iA/OJ58qjP6j27uyW4kUF4jl/jd6sw==
@@ -8733,6 +8784,25 @@ typedarray-to-buffer@^3.1.5:
   dependencies:
     is-typedarray "^1.0.0"
 
+typescript-compare@^0.0.2:
+  version "0.0.2"
+  resolved "https://registry.yarnpkg.com/typescript-compare/-/typescript-compare-0.0.2.tgz#7ee40a400a406c2ea0a7e551efd3309021d5f425"
+  integrity sha512-8ja4j7pMHkfLJQO2/8tut7ub+J3Lw2S3061eJLFQcvs3tsmJKp8KG5NtpLn7KcY2w08edF74BSVN7qJS0U6oHA==
+  dependencies:
+    typescript-logic "^0.0.0"
+
+typescript-logic@^0.0.0:
+  version "0.0.0"
+  resolved "https://registry.yarnpkg.com/typescript-logic/-/typescript-logic-0.0.0.tgz#66ebd82a2548f2b444a43667bec120b496890196"
+  integrity sha512-zXFars5LUkI3zP492ls0VskH3TtdeHCqu0i7/duGt60i5IGPIpAHE/DWo5FqJ6EjQ15YKXrt+AETjv60Dat34Q==
+
+typescript-tuple@^2.2.1:
+  version "2.2.1"
+  resolved "https://registry.yarnpkg.com/typescript-tuple/-/typescript-tuple-2.2.1.tgz#7d9813fb4b355f69ac55032e0363e8bb0f04dad2"
+  integrity sha512-Zcr0lbt8z5ZdEzERHAMAniTiIKerFCMgd7yjq1fPnDJ43et/k9twIFQMUYff9k5oXcsQ0WpvFcgzK2ZKASoW6Q==
+  dependencies:
+    typescript-compare "^0.0.2"
+
 unbox-primitive@^1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.1.tgz#085e215625ec3162574dc8859abee78a59b14471"