Переглянути джерело

Add scroll in postsFeed and subscribe/unsubscribe to user

LenDoc 2 роки тому
батько
коміт
e19dde65b5

+ 11 - 123
src/App.js

@@ -9,64 +9,28 @@ import { CPageAboutUser, PageAboutUser } from './components/User'
 import { PageCreatePost, AddPost } from './components/NewPost'
 import { CPost, MyCarousel } from './components/Post'
 
-import { sortableContainer, sortableElement } from 'react-sortable-hoc'
-import { arrayMove, arrayMoveImmutable, arrayMoveMutable } from 'array-move'
 import 'antd/dist/antd.css'
-
-import {
-  actionAboutMe,
-  actionAllPostsFeed,
-  actionAllPosts,
-  actionSetAvatar,
-  aboutMeWorker,
-  actionPostsFeed,
-  actionAllFollowing,
-  actionAllFollowers,
-  actionPostsMyFollowing2,
-  actionSearchUser,
-} from './actions'
+import {actionSetAvatar} from './actions'
 import { actionFullProfilePage } from './reducers'
-import { Upload, Button, DatePicker, Space } from 'antd'
+import { Upload, Button, DatePicker, Space, Avatar, Image, Divider, Radio } from 'antd'
 import moment from 'moment'
 import { UploadOutlined, SearchOutlined } from '@ant-design/icons'
 import ImgCrop from 'antd-img-crop'
-import { Avatar, Image, Divider, Radio } from 'antd'
 import { UserOutlined } from '@ant-design/icons'
 import user from './materials/user1.png'
 import photoNotFound from './materials/photoNotFound.png'
 // import "react-responsive-carousel/lib/styles/carousel.min.css"; // requires a loader
 // import { Carousel } from 'react-responsive-carousel';
 import { CPostForFeed,Feed } from './components/PostFeed'
-import { CSearch } from './components/Search_Users'
+
+import { Header } from './components/Header'
 
 console.log(store.getState())
 store.subscribe(() => console.log(store.getState()))
 console.log('ABOUT ME', store.getState().auth?.payload?.sub?.id)
-// console.log('ABOUT FOLLOWING',store.getState().promise.aboutUser?.payload?.following);
-//store.dispatch(actionPostsFeed())
 
 const PageMain = () => <div className="PageMain">ГЛАВНАЯ</div>
-
-
-// const PageFeed = ({ aboutMe,allFollowing, onPostsFeed, onAllFollowing}) => {
-//   console.log('ABOUT FOLLOWING',
-//   store.getState().promise.aboutMe?.payload?.following);
-//   useEffect(() => {
-//     onPostsFeed()
-//   }, [])
-//   return <>
-//  <div style={{background: '#FFFACD' }}>
-//     <h2>Feed</h2>
-
-//   </div>
-//    </>
-// }
-// const CPageFeed =connect((state)=>(
-//   {
-//     aboutMe: state.promise.aboutMe?.payload ,
-//   //  allPosts: state.promise?.allPosts?.payload,
-//    postsFeed: state.promise?.postsFeed?.payload,
-//   }), {onPostsFeed:actionPostsFeed})(PageFeed)
+const CUserEdit = connect((state) => ({}), {})(PageAboutUser)
 const Main = () => (
   <main>
     <Switch>
@@ -76,85 +40,15 @@ const Main = () => (
       <Route path="/post/:_id" component={CPost} />
       <Route path="/feed" component={CPostForFeed} />
       <Route path="/editProfile" component={CUserEdit} />
-
-      {/* <CBasic /> */}
     </Switch>
   </main>
 )
 
 
-{
-  /* { console.log('end') } */
-}
-
-// <div>
-//   <ResultUserFind userFind={followers} />
-//   {console.log('followers', followers)}
-// </div>
-
-
-const CUserEdit = connect((state) => ({}), {})(PageAboutUser)
-
-const Header = () => {
-  const CFeed = connect((state) => ({
-    aboutMe: state?.profileData?.aboutMe,
-  }))(Feed)
-  return (
-    <section className="Header">
-      <CSearch />
-      {/* <Button icon={<SearchOutlined />}>Search</Button> */}
-      <CFeed />
-      <AddPost />
-      <Recommendations />
-      <Likes />
-      <CUser />
-    </section>
-  )
-}
-
-const Likes = () => (
-  <Button size="large" className="Likes">
-    {' '}
-    Likes{' '}
-  </Button>
-)
-
-const Recommendations = () => (
-  <Button size="large" className="Recomendations">
-    {' '}
-    Recommendations{' '}
-  </Button>
-)
 
 const CBasic = connect(null, { onLoad: actionSetAvatar })(Basic)
-// const CAddPost =connect(null,{actionPostUpsert})
-const User = ({my_Id, aboutMe: { _id, login, avatar } = {}, onMyPage }) => {
-  return (
-    
-    <Link onClick={()=> onMyPage(_id)} className="User" to={`/profile/${_id}`}>
-      {
-        avatar?.url ? <Avatar src={'/' + avatar?.url} />
-          :
-          <Avatar src={user} />
-   }
-     
-      </Link>
-      
 
-  )
-}
-// backendURL
-const CUser = connect((state) => ({
-  my_Id: state.auth.payload.sub.id || '',
-  aboutMe: state.profileData.aboutMe,
-
-}),
-  { onMyPage:actionFullProfilePageUser }
-)(
-  User,
-)
 
-//  store.getState().auth?.payload?.sub?.id
 
 const ProtectedRoute = ({
   roles = [],
@@ -186,19 +80,17 @@ const history = createHistory()
 
 function App() {
   if (store.getState().auth?.token) {
-    console.log('токенчик ', store.getState().auth?.payload?.sub?.id)
-
-    // store.dispatch(actionAboutMe(store.getState().auth?.payload?.sub?.id))
-    // store.dispatch(actionAllPosts(store.getState().auth?.payload?.sub?.id))
+    console.log('токен', store.getState().auth?.payload?.sub?.id)
     store.dispatch(actionFullProfilePage(store.getState().auth?.payload?.sub?.id))
-    store.dispatch(actionFullProfilePageUser(store.getState().auth?.payload?.sub?.id))
-    
-    // actionFullProfilePageData
-    // aboutMeWorker()
   }
   else {
     console.log('ошибочка')
   }
+  if (document.body.offsetHeight > document.documentElement.clientHeight) 
+    console.log("Скролл есть");
+else {
+    console.log("Скролла нет");
+}
   return (
     <Router history={history}>
       <Provider store={store}>
@@ -212,10 +104,6 @@ function App() {
             path="/register"
             component={PageRegister}
           />
-
-          {/* <CPostEditor /> */}
-          {/* <CPost /> */}
-          {/* <Gallery/> */}
         </div>
       </Provider>
     </Router>

+ 18 - 4
src/App.scss

@@ -26,9 +26,13 @@ body{
 }
 .Header{
   display: flex;
-  padding: 10px;
-  margin: 10px;
   float: right;
+position: fixed;
+padding: 20px;
+ z-index: 4;
+  width: 100%; 
+ top: 0;
+ background-color: white;
 }
 .Recomendations{
   margin-left: 20px;
@@ -40,7 +44,7 @@ body{
   padding: 10px;
 }
 .Feed{
-  margin-right: 20px;
+  margin-right: 20px;  
 }
 .Post{
   max-width: 600px;
@@ -63,6 +67,7 @@ li {
 main{
   // margin-left:200px;
   // margin-right: 200px;
+  margin-top: 100px;
 }
 .Title{
   text-align: left;
@@ -76,7 +81,6 @@ main{
   display: flex;
   justify-content: center;
   //  float: left;
-  // margin:30px;
 }
 .Info{ 
   justify-content: center;
@@ -172,6 +176,9 @@ main{
   overflow-y: scroll;
   // text-align: center;
 }
+.Scrolling{
+  background-color: #7922CC;
+}
 .SpoilerButton{
   right: 30px;
   margin:20px;
@@ -193,4 +200,11 @@ Link{
 Link:hover{
   text-decoration: underline; 
   background-color: rgb(123, 119, 228);  
+}
+.ResultUserFind{
+  max-width: 500px;
+  min-width: 320px;
+  max-height: 500px;
+  padding: 15px 0;
+  overflow: auto;
 }

+ 357 - 177
src/actions/index.js

@@ -1,8 +1,9 @@
+import { actionFullProfilePageUser, actionFullProfilePage,actionFeedType,actionClearFeedPosts } from '../reducers'
+
 export const actionAuthLogin = (token) => ({ type: 'AUTH_LOGIN', token })
 export const actionAuthLogout = () => ({ type: 'AUTH_LOGOUT' })
 export const getGQL = (url) => (query, variables) =>
   fetch(url, {
-
     method: 'POST',
     headers: {
       'Content-Type': 'application/json',
@@ -21,8 +22,7 @@ export const getGQL = (url) => (query, variables) =>
       }
     })
 
-
-export const gql = getGQL('/graphql');
+export const gql = getGQL('/graphql')
 
 export const actionPending = (name) => ({
   type: 'PROMISE',
@@ -51,11 +51,11 @@ export const actionPromise = (name, promise) => async (dispatch) => {
     dispatch(actionRejected(name, error))
   }
 }
-  export const actionAboutMe = (_id) =>
-      actionPromise(
-      'aboutMe',
-        gql(
-          `query AboutMe($userId:String){
+export const actionAboutMe = (_id) =>
+  actionPromise(
+    'aboutMe',
+    gql(
+      `query AboutMe($userId:String){
             UserFindOne(query:$userId)
             {
               _id createdAt login nick avatar{_id url} 
@@ -63,11 +63,11 @@ export const actionPromise = (name, promise) => async (dispatch) => {
               following{_id login nick avatar{_id url}}
             }
           }`,
-          {
-            userId: JSON.stringify([{ _id }]),
-          },
-        ),
-      )
+      {
+        userId: JSON.stringify([{ _id }]),
+      },
+    ),
+  )
 
 export const actionFullLogin = (login, password) => async (dispatch) => {
   let token = await dispatch(
@@ -181,42 +181,62 @@ mutation PostUpsert($post:PostInput){
   )
 
 export const actionAllPosts = (userId) =>
-    actionPromise(
-      'allPostsMe',
-      gql(
-        `query allPosts($userId:String!){
+  actionPromise(
+    'allPostsMe',
+    gql(
+      `query allPosts($userId:String!){
   PostFind(query:$userId){
            owner{_id} _id title text images{_id url}
     }
 }`,
-        {
-          userId: JSON.stringify([
-            { ___owner: userId},
+      {
+        userId: JSON.stringify([
+          { ___owner: userId },
 
-            {
-              sort: [{ _id: -1 }],
-              skip: [0],
-              limit: [36]
-            },
+          {
+            sort: [{ _id: -1 }],
+            skip: [0],
+            limit: [36],
+          },
+        ]),
+      },
+    ),
+  )
 
-          ]),
-        },
-      ),
-    )
+export const actionPostsCount = (_id) =>
+  actionPromise(
+    'countAllPostsUser',
+    gql(
+      ` query CountAllPostsUser($_id:String!){
+                PostCount(query:$_id)
+
+                }`,
+
+      { _id: JSON.stringify([{ ___owner: { $in: [_id] } }]) },
+    ),
+  )
 
 export const actionAllPostsFeed = () =>
-    actionPromise('postsFeed', 
-    gql(` query allPosts($_id:String){
+  actionPromise(
+    'postsFeed',
+    gql(
+      ` query allPosts($_id:String){
                 PostFind(query:$_id){
                   owner{_id login avatar{_id url}} _id title text images{_id url}
                 }
-            }`, {
-        _id: JSON.stringify([{}, {
-          sort: [{ _id: -1 }],
-          skip: [0],
-              limit: [36]
-        }])
-    }))
+            }`,
+      {
+        _id: JSON.stringify([
+          {},
+          {
+            sort: [{ _id: -1 }],
+            skip: [0],
+            limit: [10],
+          },
+        ]),
+      },
+    ),
+  )
 
 export const actionOnePost = (_id) => async (dispatch) => {
   await dispatch(
@@ -243,9 +263,7 @@ export const actionOnePost = (_id) => async (dispatch) => {
         }
       }`,
         {
-          post: JSON.stringify([{ _id },
-            
-          ]),
+          post: JSON.stringify([{ _id }]),
         },
       ),
     ),
@@ -268,9 +286,7 @@ export const actionFindLikes = (_id) => async (dispatch) => {
         }
       }`,
         {
-          post: JSON.stringify([{ _id },
-            
-          ]),
+          post: JSON.stringify([{ _id }]),
         },
       ),
     ),
@@ -330,15 +346,16 @@ export const actionAddComment = (postId, text) => async (dispatch) => {
         {
           comment: {
             post: {
-              _id: postId
+              _id: postId,
             },
-            text: text
+            text: text,
           },
-        }
+        },
       ),
-    ))
+    ),
+  )
 }
-export const actionAddSubComment = (commentId,comment) => async (dispatch) => {
+export const actionAddSubComment = (commentId, comment) => async (dispatch) => {
   await dispatch(
     actionPromise(
       'addSubComment',
@@ -353,12 +370,11 @@ export const actionAddSubComment = (commentId,comment) => async (dispatch) => {
         }`,
         {
           comment: {
-      
             answerTo: {
-              _id: commentId
+              _id: commentId,
             },
-            text:comment
-          }
+            text: comment,
+          },
         },
       ),
     ),
@@ -372,36 +388,38 @@ export const actionAddSubComment = (commentId,comment) => async (dispatch) => {
 //   }
 // }
 
-export const actionAddFullComment = (postId,comment) => 
-async(dispatch,getState) => {
+export const actionAddFullComment = (postId, comment) => async (
+  dispatch,
+  getState,
+) => {
   await dispatch(actionAddComment(postId, comment))
   const {
     promise: {
       addComment: { status },
     },
-} = getState();
-  if(status==="FULFILLED")
-  {
-    await dispatch(actionOnePost(postId));
+  } = getState()
+  if (status === 'FULFILLED') {
+    await dispatch(actionOnePost(postId))
   }
   // await dispatch(actionOnePost(postId));
-  }
+}
 
-  export const actionAddSubFullComment = (postId,commentId,comment) => 
-async(dispatch,getState) => {
-  await dispatch(actionAddSubComment(commentId,comment))
+export const actionAddSubFullComment = (postId, commentId, comment) => async (
+  dispatch,
+  getState,
+) => {
+  await dispatch(actionAddSubComment(commentId, comment))
   const {
     promise: {
       addSubComment: { status },
     },
-} = getState();
-  if(status==="FULFILLED")
-  {
-    await dispatch(actionOnePost(postId));
+  } = getState()
+  if (status === 'FULFILLED') {
+    await dispatch(actionOnePost(postId))
   }
   // await dispatch(actionOnePost(postId));
 }
-// export const actionAddlike = _id => 
+// export const actionAddlike = _id =>
 //             actionPromise("addLike", gql(`mutation AddLike($like:LikeInput){
 //               LikeUpsert(like:$like){
 //                 _id
@@ -428,45 +446,47 @@ export const actionAddLike = (postId) => async (dispatch) => {
         {
           like: {
             post: {
-              _id: postId
-            }
-          }
-          
-        } 
+              _id: postId,
+            },
+          },
+        },
       ),
     ),
   )
 }
-export const actionAddFullLike = (postId) => 
-async(dispatch,getState) => {
+export const actionAddFullLike = (postId) => async (dispatch, getState) => {
   await dispatch(actionAddLike(postId))
   const {
     promise: {
       addLike: { status },
     },
-} = getState();
-  if(status==="FULFILLED")
-  {
-    await dispatch(actionOnePost(postId));
+  } = getState()
+  if (status === 'FULFILLED') {
+    await dispatch(actionOnePost(postId))
   }
   //  await dispatch(actionOnePost(postId));
 }
 
 export const actionGetFindLiked = (_id) => async (dispatch) => {
   await dispatch(
-    actionPromise('findLiked', gql(` query LikeFindPost($id:String!) {
+    actionPromise(
+      'findLiked',
+      gql(
+        ` query LikeFindPost($id:String!) {
                                         LikeFind(query:$id){
                                           owner { _id nick login
                                                 avatar{_id url}
                                     }
                 }
-            } `, {
-      id: JSON.stringify([{ "post._id": _id }])
-    }
-    )))
+            } `,
+        {
+          id: JSON.stringify([{ 'post._id': _id }]),
+        },
+      ),
+    ),
+  )
 }
 
-
 // export const actionDeleteFullLike = (likeId) => async(dispatch,getState) => {
 //   let unLike = await dispatch(actionDeleteLike(likeId));
 //   if(unLike){
@@ -474,21 +494,22 @@ export const actionGetFindLiked = (_id) => async (dispatch) => {
 //   }
 // }
 
-export const actionDeleteFullLike = (likeId, postId) => 
-async(dispatch,getState) => {
- await dispatch(actionDeleteLike(likeId,postId))
+export const actionDeleteFullLike = (likeId, postId) => async (
+  dispatch,
+  getState,
+) => {
+  await dispatch(actionDeleteLike(likeId, postId))
   const {
     promise: {
       deleteLike: { status },
     },
-} = getState();
-  if(status==="FULFILLED")
-  {
-    await dispatch(actionOnePost(postId));
+  } = getState()
+  if (status === 'FULFILLED') {
+    await dispatch(actionOnePost(postId))
   }
   //  await dispatch(actionOnePost(postId));
 }
-export const actionDeleteLike = (likeId,postId) => async (dispatch) => {
+export const actionDeleteLike = (likeId, postId) => async (dispatch) => {
   await dispatch(
     actionPromise(
       'deleteLike',
@@ -502,13 +523,13 @@ export const actionDeleteLike = (likeId,postId) => async (dispatch) => {
           }
         }`,
         {
-          like:{
+          like: {
             _id: likeId,
-            post:{
-                _id: postId
-             }
-          }
-        }
+            post: {
+              _id: postId,
+            },
+          },
+        },
       ),
     ),
   )
@@ -528,13 +549,13 @@ export const actionSetAvatar = (file) => async (dispatch) => {
     await dispatch(actionAboutMe())
   }
 }
-// let following =  getState().promise.aboutUser?.payload?.following  
+// let following =  getState().promise.aboutUser?.payload?.following
 // let result =  await dispatch (actionAboutMe())
-export const actionPostsFeed = () => async (dispatch,getState) => {
-  await dispatch(
+export const actionPostsFeed = (myFollowing,skip) => 
     actionPromise(
       'postsFeed',
-      gql(`query PostsFeed($ownerId:String){
+      gql(
+        `query PostsFeed($ownerId:String){
 	          PostFind(query:$ownerId){
             owner{_id login avatar{url}}
             images{_id url} title text
@@ -547,83 +568,177 @@ export const actionPostsFeed = () => async (dispatch,getState) => {
       	}
     }`,
         {
-            ownerId: JSON.stringify([
-            { ___owner: {$in:  
-              getState().promise.aboutMe?.payload?.following.map(({ _id }) => (_id))}},
+          ownerId: JSON.stringify([
+            {
+              ___owner: {
+                $in: myFollowing
+              },
+            },
             {
               sort: [{ _id: -1 }],
-              skip: [0],
-              limit: [36]
+              skip: [skip||0],
+              limit: [10],
               //  limit: [10],
             },
           ]),
         },
       ),
-    ),
-  )
-}
+    )
+
+    export const actionFullAllGetPosts = () => async (dispatch, getState) => {
+      const {
+        feed: { postsFeed = [] },
+      } = getState();
+      const myFollowing =  getState().promise.aboutMe?.payload?.following.map(
+        ({ _id }) => _id,
+      )
+      
+      let postsUsers = await dispatch(actionPostsFeed(myFollowing,postsFeed?.length));
+      if (postsUsers) {
+        dispatch(actionFeedType(postsUsers));
+      }
+    };
+    
+
+export const actionPostsFeedCount = (getState) =>
+    actionPromise(
+      'postsFeedCount',
+      gql(
+        ` query CountAllPostsUser($_id:String!){
+                PostCount(query:$_id)
+
+                }`,
+
+        {
+          _id: JSON.stringify([{
+            ___owner: {
+              $in: getState().promise.aboutMe?.payload?.following.map(
+                ({ _id }) => _id,
+              ),
+            },
+          }])
+        },
+      ),
+    )
+
+
+
 
 export const actionGetAllPosts = (skip) =>
-    actionPromise('allGetPosts', gql(` query allPosts($id:String!){
+  actionPromise(
+    'allGetPosts',
+    gql(
+      ` query allPosts($id:String!){
                 PostFind(query:$id){
                     _id   images{url _id }
                 }
-            }`, {
-        id: JSON.stringify([{}, {
+            }`,
+      {
+        id: JSON.stringify([
+          {},
+          {
             sort: [{ _id: -1 }],
             skip: [skip || 0],
-            limit: [36]
-        }])
-    }))
-
-    
-
-export const actionSearchUser =(userName)=> async (dispatch)=>{
+            limit: [36],
+          },
+        ]),
+      },
+    ),
+  )
 
-  await dispatch(actionPromise(
-    'searchUser', gql(`
+export const actionSearchUser = (userName) => async (dispatch) => {
+  await dispatch(
+    actionPromise(
+      'searchUser',
+      gql(
+        `
     query gf($query: String){
         UserFind(query: $query){
             _id, login avatar{url}
         }
-    }`, {query: JSON.stringify([
-                {
-                    $or: [{login: `/${userName}/`}] //регулярки пишутся в строках
-                },
-                {
-                    sort: [{login: 1}]} //сортируем по title алфавитно
-                ])
-    })
-  ))
+    }`,
+        {
+          query: JSON.stringify([
+            {
+              $or: [{ login: `/${userName}/` }], //регулярки пишутся в строках
+            },
+            {
+              sort: [{ login: 1 }],
+            }, //сортируем по title алфавитно
+          ]),
+        },
+      ),
+    ),
+  )
 }
 
 export const actionUserUpsert = (user) => async (dispatch, getState) => {
-
   await dispatch(
-      actionPromise(
-          "userUpsert",
-          gql(
-              `mutation UserUpsert($user:UserInput){
+    actionPromise(
+      'userUpsert',
+      gql(
+        `mutation UserUpsert($user:UserInput){
                   UserUpsert(user:$user){
                       _id login nick avatar{_id}
                   }
               }`,
-              {
-                  user: { ...user, 
-                    _id:  JSON.stringify([{ _id: 
-                      getState().auth?.payload?.sub?.id }]),
-                  },
-              }
-          )
-      )
-  );
-};
-export const actionSubscribe = (_id) =>
+        {
+          user: {
+            ...user,
+            _id: JSON.stringify([{ _id: getState().auth?.payload?.sub?.id }]),
+          },
+        },
+      ),
+    ),
+  )
+}
+
+export const actionAboutUser = (_id) =>
+  actionPromise(
+    'aboutUser',
+    gql(
+      `query AboutMe($userId:String){
+      UserFindOne(query:$userId)
+      {
+        _id createdAt login nick avatar{_id url} 
+        followers{_id login nick avatar{_id url}} 
+        following{_id login nick avatar{_id url}}
+      }
+    }`,
+      {
+        userId: JSON.stringify([{ _id }]),
+      },
+    ),
+  )
+
+export const actionAllPostsUser = (userId) =>
+  actionPromise(
+    'allPosts',
+    gql(
+      `query allPosts($userId:String!){
+PostFind(query:$userId){
+       owner{_id} _id title text images{_id url}
+}
+}`,
+      {
+        userId: JSON.stringify([
+          { ___owner: userId },
+
+          {
+            sort: [{ _id: -1 }],
+            skip: [0],
+            limit: [10],
+          },
+        ]),
+      },
+    ),
+  )
+export const actionSubscribe = (my_Id, followId, oldFollowing) =>
   actionPromise(
-    "subscribeTo", gql(
-      `mutation subscribe($_id:String!) {
-        UserUpsert(user: {following:{_id:$_id }}
-        ) {
+    'subscribe',
+    gql(
+      `mutation subscribe($user:UserInput) {
+        UserUpsert(user: $user) {
           _id following{_id login}
           followers{
             _id login
@@ -632,44 +747,109 @@ export const actionSubscribe = (_id) =>
       }
       `,
       {
-        _id: _id,
-      }
-    )
+        user: {
+          _id: my_Id,
+          following: [...oldFollowing || [], { _id: followId }],
+        },
+      },
+    ),
   )
 
-export const actionUserUpdate =
-    (user = {}) =>
-    async (dispatch, getState) => {
-        await dispatch(actionUserUpsert(user));
-        const {
-            promise: {
-              userUpsert: { status },
-            },
-        } = getState();
-        if (status === "FULFILLED") {
-            await dispatch(actionAboutMe());
+export const actionUnSubscribe = (my_Id, oldFollowing) =>
+  actionPromise(
+    'unSubscribe',
+    gql(
+      `mutation unSubscribe($user:UserInput) {
+        UserUpsert(user: $user) {
+          _id following{_id login}
+          followers{
+            _id login
+          }
         }
-        await dispatch(actionAboutMe());
-    };
+      }
+      `,
+      {
+        user: {
+          _id: my_Id,
+          following: oldFollowing || []
+        },
+      },
+    ),
+  )
 
-    export const actionFindSubComment = (findId) =>
-    actionPromise('subComments', gql(`query commentFindOne ($id:String!){
+export const actionFullSubscribe = (my_Id, followId) => async (dispatch, getState) => {
+  const oldFollowing = (
+    getState().promise.aboutMe?.payload?.following || []).map(({_id }) => ({ _id }) )
+  //console.log('FOLLOWING _ID ', oldFollowing)
+  let followingId = await dispatch(
+    actionSubscribe(my_Id, followId, oldFollowing),
+  )
+  if (followingId) {
+    Promise.all([
+      dispatch(actionFullProfilePageUser(followId)),
+      dispatch(actionFullProfilePage(my_Id))
+    ]);
+    await dispatch(actionClearFeedPosts())
+
+  }
+}
+
+export const actionFullUnSubscribe = (my_Id, followId) => async (dispatch,getState) => {
+  const oldFollowing= (
+    getState().promise.aboutMe?.payload?.following || []
+  ).filter((item) => item._id !== followId).map(({_id }) => ({ _id }));
+ // console.log('OLDFOLLOWING ', oldFollowing)
+  if (oldFollowing) {
+    await dispatch(actionUnSubscribe(my_Id, oldFollowing))
+    Promise.all([
+      await dispatch(actionFullProfilePageUser(followId)),
+    await dispatch(actionFullProfilePage(my_Id))
+    ])
+    await dispatch(actionClearFeedPosts())
+
+  }
+}
+
+
+export const actionUserUpdate = (user = {}) => async (dispatch, getState) => {
+  await dispatch(actionUserUpsert(user))
+  const {
+    promise: {
+      userUpsert: { status },
+    },
+  } = getState()
+  if (status === 'FULFILLED') {
+    await dispatch(actionAboutMe())
+  }
+  await dispatch(actionAboutMe())
+}
+
+export const actionFindSubComment = (findId) =>
+  actionPromise(
+    'subComments',
+    gql(
+      `query commentFindOne ($id:String!){
         CommentFindOne(query:$id){
        _id text answers { 
                 _id text
                 post {_id }
                 answers { _id}
                 createdAt
-                likes { _id owner {_id avatar{_id url} login nick } }
+                likes { _id owner 
+                {_id avatar{_id url} login nick } }
                 owner {
                     _id login nick 
                     avatar { _id url } 
                     } 
                 }
         } 
-    }`, {
-      id: JSON.stringify([{
-        _id: findId,
-      }
-      ])
-    }))
+    }`,
+      {
+        id: JSON.stringify([
+          {
+            _id: findId,
+          },
+        ]),
+      },
+    ),
+  )

+ 68 - 0
src/components/Header.js

@@ -0,0 +1,68 @@
+import user from '../materials/user1.png'
+import { actionFullProfilePageUser } from '../reducers'
+import { Avatar, Button } from 'antd'
+import { CSearch } from '../components/Search_Users'
+import { Link } from 'react-router-dom'
+import { connect } from 'react-redux'
+import {  AddPost } from '../components/NewPost'
+import React, { useEffect } from 'react'
+
+export const Feed = ({ aboutMe, onAllFollowing, onPostsFeed, postsFeed }) => {
+  console.log('POST FEED', postsFeed)
+  return (
+    <>
+      <Link className="Feed" to={`/feed`}>
+        <Button className="Feed" size="large">
+          {' '}
+          Feed{' '}
+        </Button>
+      </Link>
+    </>
+  )
+}
+export const CFeed = connect((state) => ({
+  aboutMe: state?.profileData?.aboutMe,
+}))(Feed)
+
+const Likes = () => (
+  <Button size="large" className="Likes">
+    {' '}
+    Likes{' '}
+  </Button>
+)
+
+const Recommendations = () => (
+  <Button size="large" className="Recomendations">
+    {' '}
+    Recommendations{' '}
+  </Button>
+)
+const User = ({ my_Id, aboutMe: { _id, login, avatar } = {}, onMyPage }) => {
+  useEffect(() => onMyPage(_id), [_id])
+  return (
+    <Link className="User" to={`/profile/${_id}`}>
+      {avatar?.url ? <Avatar src={'/' + avatar?.url} /> : <Avatar src={user} />}
+    </Link>
+  )
+}
+
+const CUser = connect(
+  (state) => ({
+    my_Id: state.auth.payload.sub.id || '',
+    aboutMe: state.profileData.aboutMe,
+  }),
+  { onMyPage: actionFullProfilePageUser },
+)(User)
+
+export const Header = () => {
+  return (
+    <section className="Header">
+      <CSearch />
+      <CFeed />
+      <AddPost />
+      <Recommendations />
+      <Likes />
+      <CUser />
+    </section>
+  )
+}

+ 21 - 13
src/components/Post.js

@@ -6,7 +6,7 @@ import {
 import photoNotFound from '../materials/photoNotFound.png'
 import { LeftCircleFilled, RightCircleFilled, HeartOutlined,HeartTwoTone,HeartFilled } from '@ant-design/icons'
 import { Carousel,Avatar,Tooltip } from 'antd'
-import user from '../materials/user.png'
+import user from '../materials/user1.png'
 import { Provider, connect } from 'react-redux'
 import { Row, Col } from 'antd';
 import { Divider, Input, Button, Modal } from 'antd';
@@ -19,8 +19,12 @@ import React, { useMemo, useState, useEffect } from 'react'
 export const Card = ({ post, onPost }) => (
   <>
     {/* <Link to={`/post/${postId}`} onClick={() => onPost(postId)}> */}
-    {/* {console.log('post id', post?._id)} */}
-    <Link to={`/post/${post?._id}`} onClick={() => onPost(post?._id)}>
+    {/* {console.log('post id', post?._id)}
+    
+     onClick={() => onPost(post?._id)}
+    
+    */}
+    <Link  to={`/post/${post?._id}`}>
       {post?.images && post?.images[0] && post.images[0]?.url ? (
         <img
           className="Card"
@@ -83,7 +87,7 @@ const SamplePrevArrow = (props) => {
 }
 
 export const MyCarousel = ({ images = [] }) => {
-  console.log('IMAGES', images)
+ // console.log('IMAGES', images)
   return (
     <>
       <div className='MyCarousel'>
@@ -100,6 +104,7 @@ export const MyCarousel = ({ images = [] }) => {
                 i?.url && (
                   <div key={index}>
                     <img
+                       key={index}
                       className="PostImage"
                       src={'/' + i?.url}
                       style={{
@@ -195,7 +200,8 @@ const Like = ({ my_Id, postId, addLike, deleteLike, likes=[], children }) =>
         :
         '0 likes'}
       </div>
-      <ConstructorModal isModalVisible={isModalVisible} setIsModalVisible={setIsModalVisible}>
+      <ConstructorModal title={'Likes'} isModalVisible={isModalVisible}
+        setIsModalVisible={setIsModalVisible}>
           <Likes likes={likes}/>
       </ConstructorModal>
     </>
@@ -203,15 +209,19 @@ const Like = ({ my_Id, postId, addLike, deleteLike, likes=[], children }) =>
 }
 
 export const PagePost = ({ my_Id, onePost, likes, addComment,
-  addCommentReply, addLike, findSubComment, deleteLike, aboutUser: { _id, avatar, login } = {}, onPost }) => {
+  addCommentReply, addLike, findSubComment, deleteLike,
+  match: { params: { _id } },
+  aboutUser: { avatar, login } = {}, onPost }) => {
 
- console.log('onePost ', onePost)
+  useEffect(() => {
+    onPost(_id)
+    console.log('ONE POST _ID',onePost?._id)
+  }, [_id])
   return (
     <>
      <Row>
       <Col span={14}>
-{/* <div  style={{display: 'flex'}}> */}
-
+      {/* <div  style={{display: 'flex'}}> */}
       <MyCarousel style={{position: 'absolute'}} images={onePost?.images} />
       <h3 style={{ textAlign: 'center', padding:'30px'}}>
             Created Post: {new Intl.DateTimeFormat('en-GB').format(onePost?.createdAt)}
@@ -219,13 +229,10 @@ export const PagePost = ({ my_Id, onePost, likes, addComment,
           <div style={{marginLeft:'100px'}}>
           {/* <Col span={3} offset={2}> */}
           <Like my_Id={my_Id} addLike={addLike} deleteLike={deleteLike} likes={onePost?.likes} postId={onePost?._id}>
-            
               <Likes likes={onePost?.likes} />
-            
           </Like>
               {/* </Col> */}
            </div>
-{/* </div> */}
     </Col>
 <Col span={8}>
 <div  style={{display: 'flex', flexDirection:'row'}}>
@@ -275,5 +282,6 @@ export const CPost = connect((state) => ({
   deleteLike: actionDeleteFullLike,
   addComment: actionAddFullComment, 
   addCommentReply: actionAddSubFullComment,
-  findLikes:actionFindLikes
+  findLikes: actionFindLikes,
+  onPost:actionOnePost
 })(PagePost)

+ 71 - 59
src/components/PostFeed.js

@@ -1,7 +1,11 @@
 import React, { useMemo, useState, useEffect } from 'react'
 import {
-    actionAllPostsFeed,
-  } from '../actions'
+  actionAllPostsFeed,
+  actionFullAllGetPosts,
+} from '../actions'
+import {actionFullFeed
+, actionClearFeedPosts} from '../reducers'
+
 import { Link} from 'react-router-dom'
 import { Provider, connect } from 'react-redux'
 import { Upload, Button, DatePicker, Space } from 'antd'
@@ -10,68 +14,76 @@ import { Avatar, Image, Divider, Radio } from 'antd'
 import { CPost, MyCarousel } from './Post'
 import { Row, Col } from 'antd';
 
-const MyPostFeed = ({ postsFeed, onPostsFeed }) => {
-    useEffect(() => {
-      onPostsFeed()
-    }, [])
+const MyPostFeed = ({ postsFeed = [], onPostsFeed, clearDataProfile }) => {
+  const [checkScroll, setCheckScroll] = useState(true);
+
+  useEffect(() => {
+    if (checkScroll) {
+      onPostsFeed();
+      setCheckScroll(false);
+    }
+  }, [checkScroll]);
+
+  useEffect(() => {
+    document.addEventListener('scroll', scrollHandler);
+    return () => {
+      document.removeEventListener('scroll', scrollHandler);
+      // clearDataProfile()
+    }
+  }, [postsFeed]);
+
+  const scrollHandler = (e) => {
+    if(e.target.documentElement.scrollHeight - e.target.documentElement.scrollTop - e.target.documentElement.clientHeight <20)
+    // if (e.target.documentElement.scrollHeight -
+    //   (e.target.documentElement.scrollTop + window.innerHeight) < 20)
+    { setCheckScroll(true) }
+  };
+
   
-    return (
-      <>
-        <h2>Feed</h2>
-        <Row>
+  return (
+    <>
+      <div className='Scrolling'>
+      <h2 >Feed</h2>
+      <Row>
 
         <Col span={12} offset={6}>
-            <div>
-                {console.log('POSTFEED', postsFeed)}
-          {
-            (postsFeed || []).map(({ images, title, text, owner }) => (
-              <div className='PostFeed'>
-                {owner?.avatar ? (
-                  <Avatar
-                    style={{ width: '50px', height: '50px' }}
-                    src={'/' + owner?.avatar?.url}
-                  />
-                ) : (
-                  <Avatar style={{ width: '50px', height: '50px' }} src={user} />
-                )}
-                <h1> {owner?.login || 'anon'}</h1>
+          <div >
+            {console.log('POSTFEED', postsFeed)}
+            {
+              (postsFeed || []).map(({ images, title, text, owner }) => (
+                <div className='PostFeed'>
+                  <Link to={`/profile/${owner?._id}`} >
+                    {owner?.avatar ? (
+                      <Avatar
+                        style={{ width: '50px', height: '50px' }}
+                        src={'/' + owner?.avatar?.url}
+                      />
+                    ) : (
+                      <Avatar style={{ width: '50px', height: '50px' }} src={user} />
+                    )}
+                    <h1> {owner?.login || 'anon'}</h1>
+                  </Link>
   
-                <MyCarousel images={images} style={{ marginTop: '60px' }} />
-                <h1> Title: {title || ''}</h1>
-                <h1> Text: {text || ''}</h1>
-              </div>
-            ))
-          }
-            </div>
-          </Col>
-    </Row>
-        {/* </div> */}
+                  <MyCarousel images={images} style={{ marginTop: '60px' }} />
+                  <h1> Title: {title || ''}</h1>
+                  <h1> Text: {text || ''}</h1>
+                </div>
+              ))
+            }
+          </div>
+        </Col>
+        </Row>
+        </div>
+      {/* </div> */}
   
-        {/* <PagePost onePost={postsFeed}/> <MyCarousel images={postsFeed?.images} />*/}
-      </>
-    )
-  }
+      {/* <PagePost onePost={postsFeed}/> <MyCarousel images={postsFeed?.images} />*/}
+    </>
+  )
+}
+
   export const CPostForFeed = connect(
     (state) => ({
-        postsFeed: state.promise?.postsFeed?.payload,
+        postsFeed: state.feed?.postsFeed,
     }),
-    { onPostsFeed: actionAllPostsFeed },
-)(MyPostFeed)
-  
-export const Feed = ({ aboutMe, onAllFollowing, onPostsFeed, postsFeed }) => {
-    console.log('POST FEED', postsFeed)
-    return (
-      <>
-        <Link className="Feed" to={`/feed`}>
-          <Button
-            className="Feed"
-            size="large"
-            onClick={() => console.log('click')}
-          >
-            {' '}
-            Feed{' '}
-          </Button>
-        </Link>
-      </>
-    )
-}
+    { onPostsFeed: actionFullAllGetPosts,clearDataProfile:actionClearFeedPosts },
+)(MyPostFeed)

+ 5 - 1
src/components/Post_Comment.js

@@ -3,8 +3,12 @@ import {
   actionAllPosts, actionOnePost, actionAddFullComment, actionGetFindLiked,
   actionFindSubComment, actionAddSubFullComment, actionDeleteFullLike, actionAddFullLike, actionAddLike, actionDeleteLike
 } from '../actions'
+
 import photoNotFound from '../materials/photoNotFound.png'
-import { LeftCircleFilled, RightCircleFilled, HeartOutlined,HeartTwoTone,HeartFilled } from '@ant-design/icons'
+import {
+  LeftCircleFilled, RightCircleFilled,
+  HeartOutlined, HeartTwoTone, HeartFilled
+} from '@ant-design/icons'
 import { Carousel,Avatar,Tooltip } from 'antd'
 import user from '../materials/user.png'
 import { Provider, connect } from 'react-redux'

+ 10 - 20
src/components/Search_Users.js

@@ -4,29 +4,18 @@ import { Row, Col } from 'antd';
 import { Avatar, Input  } from 'antd'
 import { Carousel, Popover } from 'antd'
 import user from '../materials/user1.png'
+import {actionSearchUser} from '../actions'
+import { UploadOutlined, SearchOutlined } from '@ant-design/icons'
 
-import {
-    actionAboutMe,
-    actionAllPostsFeed,
-    actionAllPosts,
-    actionSetAvatar,
-    actionPostsFeed,
-    actionAllFollowing,
-    actionAllFollowers,
-  actionPostsMyFollowing2,
-
-  actionSearchUser,
- 
-} from '../actions'
   import {actionFullProfilePageUser, actionFullProfilePage} from '../reducers'
-export const ResultUserFind = ({ my_Id, userFind = [], onPageData, size }) => {
+export const ResultUserFind = ({ my_Id, userFind = [], onPageData, size,handleCancel }) => {
   
   //const checkMyId = userFind.find(user => user?._id === my_Id)
-   return(<div>
+   return(<div className='ResultUserFind' >
      {
 
        userFind?.map(({ _id, login, avatar }) => (
-        <Link onClick={()=>onPageData(_id)} to={`/profile/${_id}`}>
+        <Link to={`/profile/${_id}`} onClick={handleCancel} key={_id}>
        
               <Row>
              <Col offset={1}>
@@ -54,7 +43,7 @@ export const ResultUserFind = ({ my_Id, userFind = [], onPageData, size }) => {
            
               
                 </Col>
-             <Col offset={1}>
+                <Col offset={1}>
                  <h3 style={{ marginBottom:'20px'}}> {login || 'Anon'}</h3>
       
                  </Col>
@@ -73,12 +62,13 @@ export const ResultUserFind = ({ my_Id, userFind = [], onPageData, size }) => {
       <>
         <Popover
           placement="bottom"
+          destroyTooltipOnHide={true}
           content={<ResultUserFind my_Id={my_Id} size={'20px'} onPageData={onPageData}
             userFind={searchUser} />}
-          trigger="click"
+            trigger="focus"
         >
-          <Search
-            placeholder="input search text"
+          <Search 
+            placeholder="Input search user"
             allowClear
             enterButton="Search"
             size="large"

+ 126 - 22
src/components/User.js

@@ -1,5 +1,6 @@
 import {
-  actionAllPosts, actionOnePost, actionAboutMe, actionUploadFile, actionUserUpsert,
+  actionAllPosts, actionOnePost, actionAboutMe, actionUploadFile,actionFullUnSubscribe, actionUserUpsert,
+  actionAddFullSubscribe,actionFullSubscribe,actionPostsCount,
   actionSetAvatar, actionAvatar} from '../actions'
 import user from '../materials/user1.png'
 import React, { useMemo, useState, useEffect } from 'react'
@@ -11,12 +12,15 @@ import { ConstructorModal} from '../helpers'
 
 import { Provider, connect } from 'react-redux'
 import { Avatar, Image, Divider, Radio } from 'antd'
-import { actionAboutUser, store,actionAllPostsUser,actionFullProfilePageUser } from '../reducers'
+import { actionAboutUser, store,actionAllPostsUser,actionFullProfilePageUser,actionRemoveDataUser } from '../reducers'
 import { useDropzone } from 'react-dropzone'
 import { Upload, Button, DatePicker, Space } from 'antd'
 import { UploadOutlined, SearchOutlined } from '@ant-design/icons'
 import { Row, Col } from 'antd';
 
+import { useDispatch } from "react-redux";
+import { useParams } from "react-router-dom";
+
 export function Basic({ onLoad }) {
   const { acceptedFiles, getRootProps, getInputProps } = useDropzone()
   const files = acceptedFiles.map((file) => (
@@ -113,24 +117,39 @@ export const CEditInfo = connect(
 )(EditInfo)
 
 
-export const PageAboutUser = ({
+export const PageAboutUser = ({ match: { params: { _id } },
   my_Id,
-  aboutUser: { _id, login, nick, createdAt, avatar, followers, following } = {},
+  aboutUser: { login, nick, createdAt, avatar, followers, following } = {},
   allPosts,
+  followId,
   onPosts,
   onPost,
+  userId,
+  addSubscribe,
+  deleteSubscribe,
   onePost,
   onAboutUser,
-  aboutUserFollowers={},
+  aboutUserFollowers=[],
   onPageData,
-  aboutUserFollowing={},
+  aboutUserFollowing = [],
+  clearDataProfile,
+  actionRemoveDataUser,
+  aboutMeFollowing,
+  countAllPostsUser,
+  actionPostsCount,
   post = {},
 }) => {
-  useEffect(() => {
-    onAboutUser(_id)
-    // onePost(post?._id)
-    // "62361ebb92c08631bc4b0e96")
-  }, [])
+  
+
+   useEffect(() => {
+     
+     onAboutUser(_id)
+     actionPostsCount(_id)
+         console.log('USER DATA ', login, _id)
+   }, [_id])
+  
+  
+  console.log('COUNT ', countAllPostsUser)
   const checkMyId =(_id === my_Id)
 
   const [isModalVisibleFollowing, setIsModalVisibleFollowing] = useState(false);
@@ -143,13 +162,20 @@ export const PageAboutUser = ({
   const showModalFollowers = () => {
     setIsModalVisibleFollowers(true);
   };
-
+  const handleCancelFollowing = () => {
+    setIsModalVisibleFollowing(false);
+  };
+  const handleCancelFollowers = () => {
+    setIsModalVisibleFollowers(false);
+  };
   return (
   
     <>
       <Row>
       <Col span={12} offset={6}>
           <section className="AboutMe">
+            <Row >
+           
             {avatar?.url ?
               <Avatar
                 style={{ marginRight: '20px', width: '150px', height: '150px' }}
@@ -171,9 +197,9 @@ export const PageAboutUser = ({
           Created Account: {new Intl.DateTimeFormat('en-GB').format(createdAt)}
         </h3>
         <div style={{ display: 'flex' }}>
-          {allPosts?.length > 0 ? (
+          {countAllPostsUser > 0 ? (
             <div style={{ display: 'flex', justifyContent: 'space-between' }}>
-              <h3> {allPosts?.length} posts </h3>
+              <h3> {countAllPostsUser} posts </h3>
             </div>
           ) : (
             <h3> 0 posts </h3>
@@ -211,7 +237,9 @@ export const PageAboutUser = ({
             <CEditInfo />
           </div>
                 </EditAccount>
-                : <button> subscribe</button>
+                    :
+                    <Subscribe my_Id={my_Id} deleteSubscribe={deleteSubscribe}
+                      followId={followId} addSubscribe={addSubscribe} aboutMeFollowing={aboutMeFollowing} />
                   
               }
               {/* <ConstructorModal>
@@ -220,20 +248,23 @@ export const PageAboutUser = ({
       </ConstructorModal> */}
 
 
-              <ConstructorModal isModalVisible={isModalVisibleFollowing}
+              <ConstructorModal title={'Following'}
+                isModalVisible={isModalVisibleFollowing}
                 setIsModalVisible={setIsModalVisibleFollowing}>
-         <ResultUserFind size={'40px'} onPageData={onPageData}
+                <ResultUserFind size={'40px'} handleCancel={handleCancelFollowing}
+                  onPageData={onPageData}
                   userFind={aboutUserFollowing} />
                 
               </ConstructorModal>
-              <ConstructorModal isModalVisible={isModalVisibleFollowers}
+              <ConstructorModal  title={'Followers'} isModalVisible={isModalVisibleFollowers}
                 setIsModalVisible={setIsModalVisibleFollowers}>
-         <ResultUserFind size={'40px'} onPageData={onPageData}
+         <ResultUserFind size={'40px'} onPageData={onPageData} handleCancel={handleCancelFollowers}
                   userFind={aboutUserFollowers} />
                 
       </ConstructorModal>
               
-       </div>
+              </div>
+              </Row>
         </section>
             
         </Col>
@@ -258,6 +289,74 @@ export const PageAboutUser = ({
      
   )
 }
+// const ProfileFollowButton = ({ myID, userId, followers, onSubsuscribe, onUnSubsuscribe }) => {
+//   const followCheck = followers.find(f => f._id === myID && true)
+//   return (
+//       <Col className='Profile__setting'>
+//           {!!followCheck ?
+//               <Button onClick={() => onUnSubsuscribe(userId)}>UnSubscribe</Button> :
+//               <Button onClick={() => onSubsuscribe(userId)} type="primary">Subscribe</Button>}
+//       </Col>
+//   )
+// }
+
+// export const CProfileFollowButton = connect(state => ({
+//   myID: state?.auth?.payload?.sub.id,
+//   followers: state?.post?.userData?.followers || []
+// }), { onSubsuscribe: actionSubscribe, onUnSubsuscribe: actionUnSubscribe })(ProfileFollowButton)
+
+
+const Subscribe = ({ my_Id, postId, addLike, deleteLike, following = [], deleteSubscribe,
+  aboutMeFollowing=[], aboutUserFollowing, addSubscribe, followId, children }) =>
+{
+
+ const checkFollowId =()=> aboutMeFollowing?.find(follower => follower?._id === followId)?._id
+
+ // console.log(' _id', aboutMeFollowing?.find(f => f._id === followId && true))
+  console.log('FOLLOWING ') 
+  // const [isModalVisible, setIsModalVisible] = useState(false);
+
+  // const showModal = () => {
+  //   setIsModalVisible(true);
+  // };
+  return(
+    <>
+      <div style={{display:'flex'}}>
+         
+            {checkFollowId ?
+            
+          <Button size="large" primary onClick={()=>deleteSubscribe(my_Id, followId)} >
+               unsubscribe
+            </Button> 
+            :
+            <Button size="large" danger onClick={()=>addSubscribe(my_Id, followId)}>
+            subscribe
+          </Button>
+                } 
+    
+      </div>
+      
+      {/* {console.log('follow _id', followId)} */}
+      
+      {/* <button style={{ cursor: 'pointer', fontSize: 'xx-large', color: 'red' }}
+        onClick={() => addSubscribe(my_Id,followId)}>
+              subscribe
+            </button> */}
+    
+       {/* {likes.length ? 
+          <h3 style={{ cursor: 'pointer', paddingLeft: 8 }} onClick={showModal}>
+            {likes.length} likes
+           
+        </h3>
+        :
+        '0 likes'}
+      </div>
+      <ConstructorModal isModalVisible={isModalVisible} setIsModalVisible={setIsModalVisible}>
+          <Likes likes={likes}/>
+      </ConstructorModal> */}
+    </>
+  )
+}
 
 export const CPageAboutUser = connect(
   (state) => ({
@@ -265,8 +364,9 @@ export const CPageAboutUser = connect(
     aboutUser: state.profilePage?.aboutUser,
     aboutUserFollowers: state.profilePage?.aboutUser?.followers,
     aboutUserFollowing: state.profilePage?.aboutUser?.following,
-
-
+    followId:state.profilePage?.aboutUser?._id,
+    aboutMeFollowing: state.profileData?.aboutMe?.following,
+    countAllPostsUser:state.promise?.countAllPostsUser?.payload,
     allPosts: state.profilePage?.allPosts,
     onePost: state.promise?.onePost?.payload,
     // post:state.promise?.onePost?.payload,
@@ -274,8 +374,12 @@ export const CPageAboutUser = connect(
   }),
   {
     onAboutUser: actionFullProfilePageUser,
+    actionRemoveDataUser:actionRemoveDataUser,
     onLoad: actionUploadFile,
     onPost: actionOnePost,
     onPageData: actionFullProfilePageUser,
+    addSubscribe: actionFullSubscribe,
+    deleteSubscribe: actionFullUnSubscribe,
+    actionPostsCount:actionPostsCount
   },
 )(PageAboutUser)

+ 5 - 9
src/helpers/index.js

@@ -1,27 +1,23 @@
 import { Modal } from 'antd';
 // import React, { useState } from 'react'
 
-export const ConstructorModal = ({ children, isModalVisible, setIsModalVisible }) =>
+export const ConstructorModal = ({title, children, isModalVisible, setIsModalVisible }) =>
 {
- // const [isModalVisible, setIsModalVisible] = useState(false);
-
-  const showModal = () => {
-    setIsModalVisible(true);
-  };
 
   const handleCancel = () => {
     setIsModalVisible(false);
   };
+
   return (
     <>
-        <Modal title="Likes" className="Modal"
+        <Modal title={title} centered className="Modal"
         footer={null}
         onCancel={handleCancel}
         visible={isModalVisible}>
 
-        {isModalVisible && children}
+        {children}
         </Modal>
     </>
   )
 }
-  
+  

+ 92 - 52
src/reducers/index.js

@@ -1,5 +1,9 @@
 import thunk from 'redux-thunk';
-import { actionAuthLogin, gql, actionPromise, actionAllPosts, actionAboutMe } from '../actions'
+import {
+  actionAuthLogin, gql, actionPromise,
+  actionAllPosts, actionAboutMe, actionAllPostsUser, actionAboutUser,
+  actionPostsFeed,actionPostsFeedCount,
+} from '../actions'
 import { createStore, combineReducers, applyMiddleware } from 'redux';
 
 function promiseReducer(state = {}, { type, name, status, payload, error }) {
@@ -23,55 +27,17 @@ const jwtDecode = (token) => {
 export const actionProfilePageDataTypeUser= (aboutUser, allPosts) =>
   ({ type: 'PROFILE-PAGE-USER', aboutUser, allPosts })
 
+export const actionProfilePageData = (id) => ({ type: 'DATA_PROFILE', id })
+  
   export const actionProfilePageDataType= (aboutMe) =>
   ({ type: 'PROFILE-PAGE', aboutMe })
 
-  export const actionAboutUser = (_id) =>
-  actionPromise(
-  'aboutUser',
-    gql(
-      `query AboutMe($userId:String){
-        UserFindOne(query:$userId)
-        {
-          _id createdAt login nick avatar{_id url} 
-          followers{_id login nick avatar{_id url}} 
-          following{_id login nick avatar{_id url}}
-        }
-      }`,
-      {
-        userId: JSON.stringify([{ _id }]),
-      },
-    ),
-  )
-
-  export const actionAllPostsUser = (userId) =>
-  actionPromise(
-    'allPosts',
-    gql(
-      `query allPosts($userId:String!){
-PostFind(query:$userId){
-         owner{_id} _id title text images{_id url}
-  }
-}`,
-      {
-        userId: JSON.stringify([
-          { ___owner: userId},
-
-          {
-            sort: [{ _id: -1 }],
-            skip: [0],
-            limit: [36]
-          },
-
-        ]),
-      },
-    ),
-  )
-
 export const actionFullProfilePageUser = (_id) =>
   async dispatch => {
     const aboutUser = await dispatch(actionAboutUser(_id))
+    console.log('ABOUTUSER ', aboutUser)
     const allPosts = await dispatch(actionAllPostsUser(_id))
+    console.log('ALLPOSTS ', allPosts )
     if (aboutUser && allPosts) {
       await dispatch(actionProfilePageDataTypeUser(aboutUser, allPosts))
     }
@@ -84,15 +50,23 @@ export const actionFullProfilePageUser = (_id) =>
       await dispatch(actionProfilePageDataType(aboutMe))
     }
   }
+  export const actionRemoveDataUser= () =>
+  ({ type: 'REMOVE-DATA' })
 
-export const profileUserReducer = (state = {}, { type, aboutUser, allPosts,
-  newResult }) => {
-    const types = {
-        'PROFILE-PAGE-USER': () => {
-            return {
-                ...state, aboutUser, allPosts
-            }
-        }
+export const profileUserReducer = (state = {}, { type, aboutUser, allPosts }) => {
+  const types = {
+    'PROFILE-PAGE-USER': () => {
+      return {
+        ...state, aboutUser, allPosts
+      }
+    },
+    'REMOVE-DATA': () => {
+      return {
+        ...state={},
+        aboutUser:{},
+        allPosts:[]
+      }
+  }
   
     }
     if (type in types) {
@@ -100,7 +74,72 @@ export const profileUserReducer = (state = {}, { type, aboutUser, allPosts,
     }
     return state
   }
+    export const actionFeedType= (newPosts) =>
+  ({ type: 'ADD-POSTS', newPosts })
+
+  export const actionFullFeed = () =>
+    async (dispatch, getState) => {
+  
+    const postsFeed = await dispatch(actionPostsFeed(getState))
+     const skip = postsFeed.length
+    console.log('postsFeed ', postsFeed)
+    const postsFeedCount = await dispatch(actionPostsFeedCount(getState))
+    console.log('postsFeedCount ', postsFeedCount)
+
+    // const allPosts = await dispatch(actionAllPostsUser(_id))
+    // console.log('ALLPOSTS ', allPosts )
+
+    // if (postsFeed?.length !== (postsFeedCount ? postsFeedCount : 1)) {
+    //   const postsFeedNew = await dispatch(actionPostsFeed(_id))
+    //   console.log('postsFeedNew ', postsFeedNew)
+    //   const postsFeedCountNew = await dispatch(actionPostsFeedCount(_id))
+    //   console.log('postsFeedCountNew ', postsFeedCountNew)
+   
+   
+        // if (postsFeed && postsFeedCount)
+        // await dispatch(actionFeedType(postsFeed, postsFeedCount))
+      
+      if (skip < postsFeedCount)
+      {
+        console.log('SKIIIP ', skip)
+        const newPosts = await dispatch(actionPostsFeed(getState, skip))
+        if (newPosts) {
+          dispatch(actionFeedType(newPosts));
+          const postsFeedCount = await dispatch(actionPostsFeedCount(getState))
+          console.log('postsFeedCount ', postsFeedCount)
+        }
+
+        }
+     
+    }
+  export const actionClearFeedPosts = () => ({ type: 'DELETE-POSTS' });
+
+  export const actionFullClearFeedPosts = () => (dispatch) => {
+    return dispatch(actionClearFeedPosts())
+  }
+  
+  
+export const feedReducer = (state = {}, {skip, type, newPosts=[], postsFeed,postsFeedCount }) => {
+  const types = {
+    'ADD-POSTS': () => {
+      return {
+        ...state,
+        postsFeed: state?.postsFeed ? [...state?.postsFeed, ...newPosts] : [...newPosts]
+      }
+    },
+    'DELETE-POSTS': () => {
+      return {
+        ...state,
+        postsFeed: []
+      }
+  }
   
+    }
+    if (type in types) {
+        return types[type]()
+    }
+    return state
+  }
 
 export const profileReducer = (state = {}, { type, aboutMe, newResult }) => {
   const types = {
@@ -139,7 +178,8 @@ export const profileReducer = (state = {}, { type, aboutMe, newResult }) => {
       promise: promiseReducer,
       auth: authReducer,
       profileData: profileReducer,
-      profilePage:profileUserReducer
+      profilePage: profileUserReducer,
+      feed:feedReducer
       
     }),
     applyMiddleware(thunk),