Prechádzať zdrojové kódy

added recursive functions for view comments

makstravm 2 rokov pred
rodič
commit
190fa486c9

+ 4 - 4
src/App.js

@@ -33,16 +33,16 @@ const AppContent = ({ isToken }) =>
                 <HeaderComponent />
                 <Main>
                     <Switch>
-                        <Route path='/' component={CMainPostsFeed} exact />
+                        <Route path='/feed' component={CMainPostsFeed} />
                         <Route path='/profile/:_id' component={CProfilePage} />
                         {/* <Route path='/message' component={Aside} /> */}
-                        <Route path='/edit/post/:_id' component={CEntityEditorPost} />
+                        <Route path='/edit/post/new' component={CEntityEditorPost} exact />
+                        <Route path='/edit/post/:_id' component={CEntityEditorPost}/>
                         <Route path='/my-settings' component={SettingsPage} />
                         <Route path='/all' component={CAllPosts} />
                         <Route path='/my-collection' component={CCollectionPage} />
                         <CRRoute path='/post/:id' component={CPostPage} />
-                        <Redirect from='/*' to='/' />
-                        {/* <Redirect from='/*' to='/post/:id' /> */}
+                        <Redirect from='/*' to='/feed' />
                     </Switch>
                 </Main>
             </Content >

+ 6 - 0
src/App.scss

@@ -104,6 +104,12 @@ video {
             display: flex;
             align-items: center;
             justify-content: center;
+
+            &.active {
+                svg {
+                    fill: $defaultColorB;
+                }
+            }
         }
         svg {
             width: 24px;

+ 14 - 10
src/actions/index.js

@@ -345,16 +345,19 @@ export const actionFindComment = (findId) =>
     }`, { id: JSON.stringify([{ _id: findId }]) }))
 
 export const actionFindSubComment = (findId) =>
-    actionPromise('subComments#' + findId, gql(`query commentFindOne ($id:String!){
+    actionPromise('subComments', gql(`query commentFindOne ($id:String!){
         CommentFindOne(query:$id){
-             answers{
-                _id text createdAt
-                owner{ _id nick login avatar { _id url }} 
-                likes { _id }
-                answerTo {_id text 
+        answers { 
+                _id text
+                post {_id }
+                answers { _id}
+                answerTo{_id owner{login, nick}}
+                likes{_id owner { login nick}}
+                 owner {
+                    _id login nick 
+                    avatar {url} 
+                    } 
                 }
-                answers{ _id }
-            }
         } 
     }`, { id: JSON.stringify([{ _id: findId }]) }))
 
@@ -428,7 +431,7 @@ export const actionGetFindLiked = (_id) =>
 
 export const actionFullSentPost = (images, title, text) => ({ type: 'CREATE_POST', images, text, title })
 
-export const actionSentPost = (upSertPostObj) =>
+export const actionUpsertPost = (upSertPostObj) =>
     actionPromise('sentPost', gql(`mutation sentPost($post: PostInput){
               PostUpsert(post: $post){
                     _id images{_id url originalFileName}
@@ -442,4 +445,5 @@ export const actionSentPost = (upSertPostObj) =>
         // по ансверс.файди найти дочерные коменты и засунуть в массив ансверс как елементы
         // таким оюразом получтьь дерево
         // отдать в рекувсивный компонкнт на отрисовку дерева.
-        // каждый лист дерева приконектить к экшонам лайк и добавление дочернего коммета.Там жк=е должен быть известен пост.айди для создания комментов
+        // каждый лист дерева приконектить к экшонам лайк и добавление дочернего коммета.Там жк=е должен быть известен пост.айди для создания комментов
+

+ 0 - 1
src/components/uploadPhoto/EditPhotos.js

@@ -24,7 +24,6 @@ const SortableItemMask = ({ removePhotosItem, chekMedia, setVisible, id }) =>
 
 const Handle = SortableHandle(({ tabIndex, value, removePhotosItem }) => {
     const [visible, setVisible] = useState(false);
-    console.log(value);
     const chekMedia = videoRegExp.test(value.originalFileName)
     return (
         <div className="Handle" tabIndex={tabIndex} >

+ 16 - 12
src/pages/EntityEditorPost.jsx

@@ -13,22 +13,26 @@ import { history } from '../App'
 const ContainEditorPost = ({ children }) =>
     <div className='ContainEditPost ContainerInner'>{children}</div>
 
-const EntityEditorPost = ({ match: { params: { _id } }, myID, entity, status, onSave, updatePost, clearState }) => {
+const EntityEditorPost = ({ match: { params: { _id } }, myID, entity, status, onSave, updatePost, clearState}) => {
 
     const [photos, setPhotos] = useState(entity?.images || []);
     const [titleSend, setTitleSend] = useState(entity?.title || '')
     const [description, setDescription] = useState(entity?.text || '');
+
+
     useEffect(() => {
-        let newEntity
-        if (Array.isArray(entity)) {
-            newEntity = entity.find(e => e._id === _id)
-            setPhotos(newEntity?.images || [])
-            setTitleSend(newEntity?.title || '')
-            setDescription(newEntity?.text || '')
-        } else if (!Object.keys(entity = {}).length) history.push('/edit/post/new')
-        updatePost(newEntity)
-        return () => {
-            clearState()
+        if (_id !== 'new') {
+            let newEntity
+            if (Array.isArray(entity)) {
+                newEntity = entity.find(e => e._id === _id)
+                setPhotos(newEntity?.images || [])
+                setTitleSend(newEntity?.title || '')
+                setDescription(newEntity?.text || '')
+            } else if (!Object.keys(entity = {}).length) history.push('/edit/post/new')
+            updatePost(newEntity)
+            return () => {
+                clearState()
+            }
         }
     }, []);
 
@@ -37,7 +41,7 @@ const EntityEditorPost = ({ match: { params: { _id } }, myID, entity, status, on
         if (status === "RESOLVED") {
             message.success(`post published, can create a new one`)
             history.push(`/profile/${myID}`)
-        }else if(status === "REJECTED"){
+        } else if (status === "REJECTED") {
             message.error('Error')
         }
     }, [status])

+ 9 - 8
src/pages/Header.jsx

@@ -1,6 +1,6 @@
 import React from 'react'
 import logo from '../logo.svg';
-import { Link } from 'react-router-dom';
+import { Link, NavLink } from 'react-router-dom';
 import { CFieldSearch } from '../components/header/Search';
 import { connect } from 'react-redux';
 import { actionAuthLogout, actionRemoveMyDataAC } from '../actions';
@@ -10,14 +10,15 @@ import { UserOutlined, CompassOutlined, SettingOutlined, HomeOutlined, ImportOut
 import { UserAvatar } from '../components/header/UserAvatar';
 import { CollectionEmptySvg } from '../helpers';
 
-
-
-
 const UserNav = () =>
     <div className='UserNav'>
         <CUserNavIcon />
     </div>
 
+
+
+
+
 const ProfileDropMenu = ({ myID, onLogOut, removeMydata }) =>
     <Menu className='dropMenu'>
         <Menu.Item key={'0'}>
@@ -44,16 +45,16 @@ const CProfileDropMenu = connect(null, { onLogOut: actionAuthLogout, removeMydat
 const UserNavIcon = ({ userData: { _id, avatar, login } }) =>
     < Row justify="end" align="middle" className='Header__userNav' >
         <Col >
-            <Link to='/'><HomeOutlined /></Link>
+            <NavLink to='/feed'><HomeOutlined /></NavLink>
         </Col>
         <Col >
-            <Link to='/message'><MessageOutlined /></Link>
+            <NavLink to='/message'><MessageOutlined /></NavLink>
         </Col>
         <Col >
-            <Link to='/edit/post/new'><PlusCircleOutlined /></Link>
+            <NavLink to='/edit/post/new'><PlusCircleOutlined /></NavLink>
         </Col>
         <Col >
-            <Link to='/all'><CompassOutlined /></Link>
+            <NavLink to='/all'><CompassOutlined /></NavLink>
         </Col>
         <Col>
             <Popover placement="bottomRight" content={<CProfileDropMenu myID={_id} />}>

+ 108 - 81
src/pages/PostPage.jsx

@@ -31,81 +31,108 @@ const PostCommentAuthor = ({ owner }) => {
 }
 
 
-const PostComment = ({ myID, subComments, data: { _id, answers, createdAt, likes = [], text, owner }, addLikeComment, removeLikeComment, findSubComment }) => {
-    const [open, setOpen] = useState(false);
-
-    let likeStatus
-    let likeId
-    likes.find(l => {
-        if (l?.owner?._id === myID) {
-            likeStatus = true
-            likeId = l._id
-        } else {
-            likeStatus = false
-        }
-    })
-
-    const changeLike = () => likeStatus ? removeLikeComment(likeId, _id) : addLikeComment(_id)
-
-    const actions = [
-        <span onClick={changeLike}>
-            {likeStatus ? <LikeFilled /> : <LikeOutlined />}
-            <span style={{ paddingLeft: 8, cursor: 'auto' }}>{likes.length ? likes.length : ''}</span>
-        </span>,
-        <span onClick={() => setOpen(true)}>Reply to</span>,
-    ];
 
-    return (
-        <Comment
-            actions={actions}
-            author={<PostCommentAuthor owner={owner} />}
-            avatar={< UserAvatar avatar={owner?.avatar} avatarSize={'35px'} />}
-            content={<p>{text}</p >}
-            datetime={
-                < Tooltip title={moment(new Date(+createdAt)).format('DD-MM-YYYY HH:mm:ss')} >
-                    <span>
-                        {moment(new Date(+createdAt)).startOf('seconds').fromNow()}
-                    </span>
-                </ Tooltip>
-            }
-        >
-            {subComments && subComments['subComments#' + _id]
-                ? subComments['subComments#' + _id].map(s => < CPostSubComment key={s._id} data={s} />)
-                : answers?.length >= 0 && <Divider plain>
-                    <Text type='secodary' onClick={() => findSubComment(_id)}>View answers</Text>
-                </Divider>}
-
-            {open && <CFieldSubCommentSend id={_id} autoFocus={true} value={`@${owner?.nick || owner?.login || ''}, `} setOpen={setOpen} />}
-        </Comment>
-    )
-}
-const CPostComment = connect(state => ({
-    myID: state.auth.payload.sub.id || '',
-    subComments: state?.postsFeed?.subComments
-}), {
-    addLikeComment: actionLikeComment,
-    removeLikeComment: actionDelLikeComment,
-    findSubComment: actionSubComment,
-}
-)(PostComment)
 
-const CPostSubComment = connect(state => ({ comments: state?.postsFeed?.SubComments }), {
-    findSubComment: actionSubComment,
-})(PostComment)
-
-const PostComments = ({ comments }) => {
-    return (
-        <>
-            {
-                comments.map(c => <CPostComment key={c._id} data={c} cId={c._id} />)
-            }
-        </>
-    )
-}
+// const PostComment = ({ myID, subComments, data: { _id, answers, createdAt, likes = [], text, owner }, addLikeComment, removeLikeComment, findSubComment }) => {
+//     const [open, setOpen] = useState(false);
+
+//     let likeStatus
+//     let likeId
+//     likes.find(l => {
+//         if (l?.owner?._id === myID) {
+//             likeStatus = true
+//             likeId = l._id
+//         } else {
+//             likeStatus = false
+//         }
+//     })
+
+//     const changeLike = () => likeStatus ? removeLikeComment(likeId, _id) : addLikeComment(_id)
+
+//     const actions = [
+//         <span onClick={changeLike}>
+//             {likeStatus ? <LikeFilled /> : <LikeOutlined />}
+//             <span style={{ paddingLeft: 8, cursor: 'auto' }}>{likes.length ? likes.length : ''}</span>
+//         </span>,
+//         <span onClick={() => setOpen(true)}>Reply to</span>,
+//     ];
+
+//     return (
+//         <Comment
+//             actions={actions}
+//             author={<PostCommentAuthor owner={owner} />}
+//             avatar={< UserAvatar avatar={owner?.avatar} avatarSize={'35px'} />}
+//             content={<p>{text}</p >}
+//             datetime={
+//                 < Tooltip title={moment(new Date(+createdAt)).format('DD-MM-YYYY HH:mm:ss')} >
+//                     <span>
+//                         {moment(new Date(+createdAt)).startOf('seconds').fromNow()}
+//                     </span>
+//                 </ Tooltip>
+//             }
+//         >
+//             {subComments && subComments['subComments#' + _id]
+//                 ? subComments['subComments#' + _id].map(s => < CPostSubComment key={s._id} data={s} />)
+//                 : answers?.length >= 0 && <Divider plain>
+//                     <Text type='secodary' onClick={() => findSubComment(_id)}>View answers</Text>
+//                 </Divider>}
+
+//             {open && <CFieldSubCommentSend id={_id} autoFocus={true} value={`@${owner?.nick || owner?.login || ''}, `} setOpen={setOpen} />}
+//         </Comment>
+//     )
+// }
+// const CPostComment = connect(state => ({
+//     myID: state.auth.payload.sub.id || '',
+//     subComments: state?.postsFeed?.subComments
+// }), {
+//     addLikeComment: actionLikeComment,
+//     removeLikeComment: actionDelLikeComment,
+//     findSubComment: actionSubComment,
+// }
+// )(PostComment)
+
+// const CPostSubComment = connect(state => ({ comments: state?.postsFeed?.SubComments }), {
+//     findSubComment: actionSubComment,
+// })(PostComment)
+
+const PostComments = ({ comments, findSubComment, parentId }) =>
+    <div>
+        {comments?.length && Object.keys(comments[0]).length > 1
+            ? comments.map(n => {
+                return (
+                    <div className="comment" key={n._id}>
+                        <h3>{n.owner?.login}</h3>
+                        <div>{n.text}</div>
+                        {n.answers && n.answers?.length
+                            ? <> <PostComments comments={n?.answers} parentId={n._id} findSubComment={findSubComment} />
+                            </>
+                            : null}
+                    </div>
+                )
+            })
+            : <h1 onClick={() => findSubComment(parentId)} >{comments.length} мы есть</h1>}
+    </div >
+// n?.answers?.length
+//  <div key={n._id} onClick={() => {
+//                             console.log(parentId || n._id)
+//                             findSubComment(parentId)
+//                         }}
+//                         > vvvvvv Можно кукожитьvvvvvvv</ div >
+
+// const PostComments = ({comments}) => {
+//     return (
+//         <>
+//             {
+//                 comments.map(c => <CPostComment key={c._id} data={c} cId={c._id} />)
+//             }
+//         </>
+//     )
+// }
 
 const CPostComments = connect(state => ({
-    comments: state?.postsFeed?.posts?.comments || []
-}))(PostComments)
+                comments: state?.postsFeed?.posts?.comments || [],
+
+            }), { findSubComment: actionSubComment })(PostComments)
 
 const PostPageDescrption = ({ data: { _id, likes, text, title, createdAt, } }) =>
     <div className='PostOne__description-inner'>
@@ -127,19 +154,19 @@ const CPostPageDescrption = connect(state => ({ data: state?.postsFeed?.posts ||
 
 
 const PostPage = ({ data: { images } }) =>
-        <div className='PostOne'>
-            <CPreloader promiseName='postOne' />
-            <div className='PostOne__inner'>
-                <div className='PostOne__image'>
+    <div className='PostOne'>
+        <CPreloader promiseName='postOne' />
+        <div className='PostOne__inner'>
+            <div className='PostOne__image'>
                     <PostImage images={images} />
                 </div>
-                <div className='PostOne__title'>
-                    <CPostPageTitle />
-                </div>
-                <div className='PostOne__description'>
-                    <CPostPageDescrption />
-                </div>
+            <div className='PostOne__title'>
+                <CPostPageTitle />
+            </div>
+            <div className='PostOne__description'>
+                <CPostPageDescrption />
             </div>
         </div>
+    </div>
 
 export const CPostPage = connect(state => ({ data: state?.postsFeed?.posts || {} }))(PostPage)

+ 20 - 6
src/redux/reducers/postFeed-reducer.js

@@ -24,7 +24,6 @@ export const postsFeedReducer = (state = {}, { type, findId, newResult, userData
             userData: {},
             count: 0,
             subComments: {},
-            editPost: {}
         }),
         'ADD-POST-LIKE': () => ({
             ...state,
@@ -43,10 +42,25 @@ export const postsFeedReducer = (state = {}, { type, findId, newResult, userData
             ...state, posts: { ...state.posts, comments: [...newResult] }
 
         }),
-        'UPDATE-SUBCOMMENT': () => ({
-            ...state,
-            subComments: { ...state?.subComments, ...{ ['subComments#' + findId]: [...newResult] } }
-        }),
+        'UPDATE-SUBCOMMENT': () => {
+            const recursiya = (commentList, id, nR) => {
+                return commentList.map(c => {
+                    if (c._id === id) {
+                        return { ...c, answers: [...nR] }
+                    } else if (c?.answers?.length) {
+                        return ({
+                            ...c,
+                            answers: recursiya(c.answers, id, nR)
+                        })
+                    } else {
+                        return ({ ...c })
+                    }
+                })
+            }
+            return ({
+                ...state, posts: { ...state.posts, comments: recursiya(posts.comments, findId, newResult) }
+            })
+        },
         'ADD-LIKE-COMMENT': () => ({
             ...state,
             posts: {
@@ -66,7 +80,7 @@ export const postsFeedReducer = (state = {}, { type, findId, newResult, userData
             ...state,
             userData: { ...state.userData, followers: [...newResult] }
         }),
-      
+
 
     }
     if (type in types) {

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 8 - 9
src/redux/saga/index.js