Kaynağa Gözat

added functional added / edit post

makstravm 2 yıl önce
ebeveyn
işleme
2ecfa0fe50

+ 17 - 1
src/App.scss

@@ -510,7 +510,7 @@ video {
             margin-bottom: 5px;
         }
         .ant-divider {
-            margin: 0;
+            margin: 0 0 15px 0;
         }
     }
     &__description-inner {
@@ -525,6 +525,22 @@ video {
         overflow: auto;
         height: 100%;
     }
+    &__comment-edit {
+        display: block;
+        text-align: right;
+        margin-right: 10px;
+        margin-top: -5px;
+        margin-bottom: -5px;
+        margin-left: auto;
+        color: rgba(0, 0, 0, 0.45);
+        font-size: 12px;
+        cursor: pointer;
+        transition: color 0.3s;
+        font-size: 0.7em;
+        &:hover {
+            color: #595959;
+        }
+    }
     .ant-empty-image {
         height: auto;
     }

+ 3 - 1
src/actions/actionQueries.js

@@ -24,7 +24,9 @@ export const queries = {
                             }
                         }
                     }`,
-        variables: { id: JSON.stringify([{ _id: match.params.id }]) }
+        variables: {
+            id: JSON.stringify([{ _id: match.params.id }])
+        }
     }),
 }
 

+ 38 - 11
src/actions/index.js

@@ -214,8 +214,8 @@ export const actionMyLikePost = (findId) =>
 //****************---Action Like Comment ---*************************//
 
 
-export const actionAddLikeCommentAC = (findId, newResult) => ({ type: 'ADD-LIKE-COMMENT', findId, newResult })
-export const actionRemoveLikeCommentAC = (findId, newResult) => ({ type: 'REMOVE-LIKE-COMMENT', findId, newResult })
+export const actionUpsertLikeCommentAC = (findId, newResult) => ({ type: 'UPSERT-LIKE-COMMENT', findId, newResult })
+// export const actionRemoveLikeCommentAC = (findId, newResult) => ({ type: 'REMOVE-LIKE-COMMENT', findId, newResult })
 
 export const actionLikeComment = (commentId) => ({ type: 'LIKE_COMMENT', commentId })
 export const actionDelLikeComment = (likeId, commentId) => ({ type: 'DEL_LIKE_COMMENT', likeId, commentId })
@@ -276,6 +276,8 @@ export const actionOnLoadMyCollection = (_id, skip) =>
     }))
 
 //  posts{ images { url _id originalFileName } } 
+
+
 //****************---Action Subscribe ---*************************//
 
 
@@ -317,8 +319,12 @@ export const actionUpdateFollowers = (_id) =>
 
 
 export const actionAddCommentAC = (newResult) => ({ type: 'ADD-COMMENT', newResult })
+
 export const actionUpdateSubCommentAC = (findId, newResult) => ({ type: 'UPDATE-SUBCOMMENT', findId, newResult })
 
+export const actionEditCommentAC = (findId, newResult) => ({ type: 'EDIT-COMMENT', findId, newResult })
+export const actionEditComment = (commentId, text) => ({ type: 'COMMENT_EDIT', commentId, text })
+
 export const actionFullAddComment = (postId, text) => ({ type: 'COMMENT_POST', postId, text })
 
 export const actionAddSubComment = (commentId, text) => ({ type: 'ADD_SUB_COMMENT', commentId, text })
@@ -335,9 +341,12 @@ export const actionFindComment = (findId) =>
     actionPromise('findCommentPost', gql(`query commentFindPost ($id:String!){
         PostFindOne(query:$id){
             comments {
-                _id text owner{
+                _id text createdAt 
+                owner{
                     _id nick login
-                     avatar{_id url}
+                    avatar{
+                        _id url
+                        }
                     } 
                     likes{_id}
                 }
@@ -347,21 +356,23 @@ export const actionFindComment = (findId) =>
 export const actionFindSubComment = (findId) =>
     actionPromise('subComments', gql(`query commentFindOne ($id:String!){
         CommentFindOne(query:$id){
-        answers { 
+       _id text answers { 
                 _id text
                 post {_id }
                 answers { _id}
-                answerTo{_id owner{login, nick}}
-                likes{_id owner { login nick}}
-                 owner {
+                createdAt
+                likes { _id owner { login nick } }
+                owner {
                     _id login nick 
-                    avatar {url} 
+                    avatar { url } 
                     } 
                 }
         } 
-    }`, { id: JSON.stringify([{ _id: findId }]) }))
+    }`, {
+        id: JSON.stringify([{ _id: findId }])
+    }))
 
-export const actionSubAddComment = (commentId, text, _id) =>
+export const actionSubAddComment = (commentId, text) =>
     actionPromise('addSubcomment', gql(`mutation addSubcomment($comment: CommentInput ){
         CommentUpsert(comment:$comment){
             _id text
@@ -369,6 +380,22 @@ export const actionSubAddComment = (commentId, text, _id) =>
     }`, { comment: { answerTo: { _id: commentId }, text } }))
 
 
+export const actionFindCommentText = (findId) =>
+    actionPromise('subComments', gql(`query commentFindOne ($id:String!){
+        CommentFindOne(query:$id){
+       _id text 
+        } 
+    }`, {
+        id: JSON.stringify([{ _id: findId }])
+    }))
+
+export const actionUpsertEditComment = (commentId, text) =>
+    actionPromise('editcomment', gql(`mutation addSubcomment($comment: CommentInput ){
+        CommentUpsert(comment:$comment){
+            _id text
+        }
+    }`, { comment: { _id: commentId, text } }))
+
 //****************---Action Udate Avatar ---*************************//
 
 export const actionUpdateAvatar = (file) => ({ type: 'UPDATE_AVATAR', file })

+ 6 - 4
src/components/main/postsFeed/FieldComment.jsx

@@ -4,7 +4,7 @@ import TextArea from 'antd/lib/input/TextArea'
 import { SendOutlined, } from '@ant-design/icons'
 import { connect } from 'react-redux'
 import { Button, Col, Row } from 'antd'
-import { actionAddSubComment, actionFullAddComment } from '../../../actions'
+import { actionAddSubComment, actionEditComment, actionFullAddComment } from '../../../actions'
 
 
 const FieldCommentSend = ({ id, sentComment, autoFocus, value = '', setOpen }) => {
@@ -28,7 +28,7 @@ const FieldCommentSend = ({ id, sentComment, autoFocus, value = '', setOpen }) =
         sendCommentValid(commentValue)
         setOpen(false)
     }
-    
+
     const onKeyPressHandler = e => {
         if (e.charCode === 13) {
             sendCommentValid(commentValue)
@@ -44,7 +44,7 @@ const FieldCommentSend = ({ id, sentComment, autoFocus, value = '', setOpen }) =
                     <TextArea value={commentValue}
                         autoFocus={autoFocus || false}
                         placeholder="Add a comment ..."
-                        autoSize={{ minRows: 1, maxRows: 2 }}
+                        autoSize={{ minRows: 1, maxRows: 1 }}
                         onChange={changeComentTextarea}
                         bordered={false}
                         onKeyPress={onKeyPressHandler}
@@ -64,4 +64,6 @@ const FieldCommentSend = ({ id, sentComment, autoFocus, value = '', setOpen }) =
 
 export const CFieldCommentSend = connect(null, { sentComment: actionFullAddComment })(FieldCommentSend)
 
-export const CFieldSubCommentSend = connect(null, { sentComment: actionAddSubComment })(FieldCommentSend)
+export const CFieldSubCommentSend = connect(null, { sentComment: actionAddSubComment })(FieldCommentSend)
+
+export const CFieldUpsertCommentSend = connect(null, { sentComment: actionEditComment })(FieldCommentSend)

+ 5 - 11
src/components/main/postsFeed/PostUserPanel.jsx

@@ -21,18 +21,12 @@ const HeartLike = ({ styleFontSize, likeStatus, changeLike }) =>
 
 const PostUserPanel = ({ myID, postId = '', likes = [], collections, styleFontSize, addLikePost, removeLikePost, handlerCollection }) => {
     const [open, setOpen] = useState(false)
-    let likeStatus = false
-    let likeId
-    likes.find(l => {
-        if (l?.owner?._id === myID) {
-            likeStatus = true
-            likeId = l._id
-        }
-    })
-    const flag = collections?.posts.find(c => c._id === postId)
 
-    const changeLike = () => likeStatus ? removeLikePost(likeId, postId) : addLikePost(postId)
+    const likeId = likes.find(l => l?.owner?._id === myID)?._id
+
+    const flag = collections?.posts.find(c => c._id === postId)
 
+    const changeLike = () => likeId ? removeLikePost(likeId, postId) : addLikePost(postId)
 
     return (
         <>
@@ -43,7 +37,7 @@ const PostUserPanel = ({ myID, postId = '', likes = [], collections, styleFontSi
                         <Col className='Post__heart' >
                             <HeartLike
                                 changeLike={changeLike}
-                                likeStatus={likeStatus}
+                                likeStatus={likeId}
                                 styleFontSize={styleFontSize} />
                         </Col>
                         <Col offset={1}>

+ 97 - 104
src/pages/PostPage.jsx

@@ -1,19 +1,20 @@
 import React, { useState } from 'react'
-import { Divider } from 'antd';
+import { Button, Divider } from 'antd';
 import { connect } from 'react-redux'
 import PostImage from '../components/main/postsFeed/PostImage'
 import { PostDescription } from './MainPostsFeed';
 import Text from 'antd/lib/typography/Text';
-import { CFieldCommentSend, CFieldSubCommentSend } from '../components/main/postsFeed/FieldComment';
+import { CFieldCommentSend, CFieldSubCommentSend, CFieldUpsertCommentSend } from '../components/main/postsFeed/FieldComment';
 import { CPostUserPanel } from '../components/main/postsFeed/PostUserPanel';
 import { Comment, Tooltip } from 'antd';
 import moment from 'moment';
 import { Link } from 'react-router-dom';
-import { LikeFilled, LikeOutlined } from '@ant-design/icons';
+import { EditOutlined, LikeFilled, LikeOutlined } from '@ant-design/icons';
 import { actionLikeComment, actionDelLikeComment, actionSubComment } from '../actions';
 import { CPostTitle } from '../components/main/post/PostTitle';
 import { UserAvatar } from '../components/header/UserAvatar';
 import { CPreloader } from './Preloader';
+import Paragraph from 'antd/lib/typography/Paragraph';
 
 
 const PostPageTitle = ({ data: { owner }, postId }) =>
@@ -21,118 +22,110 @@ const PostPageTitle = ({ data: { owner }, postId }) =>
 
 const CPostPageTitle = connect(state => ({ data: state?.postsFeed?.posts || {}, postId: state?.postsFeed?.posts?._id }))(PostPageTitle)
 
-
-const PostCommentAuthor = ({ owner }) => {
-    return (
+const PostCommentAuthor = ({ owner }) =>
+    <>
         <Link className='PostCommentAuthor' to={`/profile/${owner?._id}`} >
             {owner?.nick ? owner.nick : owner?.login ? owner.login : 'Null'}
         </Link>
-    )
+    </>
+
+
+
+
+const PostCommentText = ({ myID, commentId, owner, text }) => {
+    const [editComment, setEditComment] = useState(false)
+    return (
+        <>
+            {owner?._id === myID && <span className='PostOne__comment-edit' onClick={() => setEditComment(true)}>Edit <EditOutlined /></span >}
+            {!editComment ? <Paragraph ellipsis={{ rows: 2, expandable: true, symbol: 'more' }} >
+                {text}
+            </ Paragraph> :
+                <CFieldUpsertCommentSend value={text} id={commentId} autoFocus={true} setOpen={setEditComment} />}
+        </>)
 }
 
+const CPostCommentText = connect(state => ({ myID: state.auth.payload.sub.id || '' }))(PostCommentText)
+
+
+const PostCommentDate = ({ createdAt }) =>
+    <Tooltip title={moment(new Date(+createdAt)).format('DD-MM-YYYY HH:mm:ss')} >
+        {moment(new Date(+createdAt)).startOf().fromNow()}
+    </ Tooltip>
+
 
+const PostCommentAction = ({ myID, commentId, likes, delLikeComment, addLikeComment }) => {
+    const [open, setOpen] = useState(false);
+    const likeId = likes.find(l => l?.owner?._id === myID)?._id
 
+    const changeLike = () => {
 
-// 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>
+
+        if (likeId) {
+
+            delLikeComment(likeId, commentId)
+        } else {
+            
+            addLikeComment(commentId)
+
+        }
+    }
+    return (
+        <>
+            <Button onClick={changeLike}>
+                {likeId ? <LikeFilled /> : <LikeOutlined />}
+                <span style={{ paddingLeft: 8, cursor: 'auto' }}>{likes.length ? likes.length : ''}</span>
+            </Button>
+            <span onClick={() => setOpen(!open)}>Reply to</span>
+            {open && <CFieldSubCommentSend autoFocus={true} id={commentId} setOpen={setOpen} />}
+        </>
+    )
+}
+
+const CPostCommentAction = connect(state => ({
+    myID: state.auth.payload.sub.id || ''
+}, {
+    addLikeComment: actionLikeComment,
+    delLikeComment: actionDelLikeComment
+}))(PostCommentAction)
+
+
+const PostComments = ({ comments, findSubComment, parentId, }) => {
+    return (<>
         {comments?.length && Object.keys(comments[0]).length > 1
-            ? comments.map(n => {
+            ? comments.map(c => {
                 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>
+                    <Comment
+                        key={c._id}
+                        author={<PostCommentAuthor owner={c.owner} />}
+                        avatar={< UserAvatar avatar={c?.owner?.avatar} avatarSize={'35px'} />}
+                        datetime={<PostCommentDate createdAt={c.createdAt} />}
+                        content={<CPostCommentText text={c.text} commentId={c._id} owner={c.owner} />}
+                        actions={[<CPostCommentAction likes={c.likes} commentId={c._id} />]}
+                    >
+                        {
+                            c.answers && c.answers?.length
+                                ? <>
+                                    <PostComments comments={c?.answers} parentId={c._id} findSubComment={findSubComment} />
+                                </>
+                                : null
+                        }
+                    </Comment>
                 )
             })
-            : <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} />)
-//             }
-//         </>
-//     )
-// }
+            :
+            !!comments.length && <Divider plain>
+                <Text type='secodary' onClick={() => findSubComment(parentId)} >
+                    View answers {comments.length}
+                </Text>
+            </Divider>
+        }
+    </>)
+}
 
 const CPostComments = connect(state => ({
-                comments: state?.postsFeed?.posts?.comments || [],
+    comments: state?.postsFeed?.posts?.comments || [],
 
-            }), { findSubComment: actionSubComment })(PostComments)
+}), { findSubComment: actionSubComment })(PostComments)
 
 const PostPageDescrption = ({ data: { _id, likes, text, title, createdAt, } }) =>
     <div className='PostOne__description-inner'>
@@ -142,10 +135,10 @@ const PostPageDescrption = ({ data: { _id, likes, text, title, createdAt, } }) =
             <CPostComments />
         </div>
         <div className='PostOne__description-bottom'>
-            <Divider ></Divider>
+            <Divider />
             <CPostUserPanel likes={likes} postId={_id}
                 styleFontSize='1.3em' />
-            <CFieldCommentSend postId={_id} setOpen={() => { }} />
+            <CFieldCommentSend setOpen={() => { }} /> {/* setOpen - функция заглушка для пропса компонента*/}
         </div>
     </div>
 
@@ -158,8 +151,8 @@ const PostPage = ({ data: { images } }) =>
         <CPreloader promiseName='postOne' />
         <div className='PostOne__inner'>
             <div className='PostOne__image'>
-                    <PostImage images={images} />
-                </div>
+                <PostImage images={images} />
+            </div>
             <div className='PostOne__title'>
                 <CPostPageTitle />
             </div>

+ 47 - 26
src/redux/reducers/postFeed-reducer.js

@@ -1,9 +1,6 @@
-import React from 'react'
-
 export const postsFeedReducer = (state = {}, { type, findId, newResult, userData = {}, count = null }) => {
     const { posts } = state
     const types = {
-        //=== Array.isArray(newResult)
         'ADD-POSTS-FEED': () => ({
             ...state,
             posts: Array.isArray(newResult)
@@ -36,52 +33,76 @@ export const postsFeedReducer = (state = {}, { type, findId, newResult, userData
             posts: Array.isArray(posts)
                 ? posts.map(p => p._id === findId ? p = { ...p, likes: [...newResult] } : p)
                 : { ...state.posts, likes: [...newResult] },
-
         }),
         'ADD-COMMENT': () => ({
             ...state, posts: { ...state.posts, comments: [...newResult] }
-
         }),
         'UPDATE-SUBCOMMENT': () => {
-            const recursiya = (commentList, id, nR) => {
+            const upsertSubComments = (commentList, id, nR) => {
                 return commentList.map(c => {
                     if (c._id === id) {
                         return { ...c, answers: [...nR] }
                     } else if (c?.answers?.length) {
-                        return ({
+                        return {
                             ...c,
-                            answers: recursiya(c.answers, id, nR)
-                        })
+                            answers: upsertSubComments(c.answers, id, nR)
+                        }
                     } else {
-                        return ({ ...c })
+                        return { ...c }
                     }
                 })
             }
             return ({
-                ...state, posts: { ...state.posts, comments: recursiya(posts.comments, findId, newResult) }
+                ...state, posts: { ...state.posts, comments: upsertSubComments(posts.comments, findId, newResult) }
             })
         },
-        'ADD-LIKE-COMMENT': () => ({
-            ...state,
-            posts: {
-                ...state.posts,
-                comments: posts.comments.map(c => c._id === findId ? c = { ...c, likes: [...newResult] } : c)
-
+        'EDIT-COMMENT': () => {
+            const { _id, text } = newResult
+            const editComments = (commentList, id, nR) => {
+                return commentList.map(c => {
+                    if (c._id === id) {
+                        return { ...c, text: nR }
+                    } else if (c?.answers?.length) {
+                        return {
+                            ...c,
+                            answers: editComments(c.answers, id, nR)
+                        }
+                    } else {
+                        return { ...c }
+                    }
+                })
             }
-        }),
-        'REMOVE-LIKE-COMMENT': () => ({
-            ...state,
-            posts: {
-                ...state.posts,
-                comments: posts.comments.map(c => c._id === findId ? c = { ...c, likes: [...newResult] } : c)
+            return ({
+                ...state, posts: { ...state.posts, comments: editComments(posts.comments, _id, text) }
+            })
+        },
+
+        'UPSERT-LIKE-COMMENT': () => {
+            const upsertLikeComments = (commentList, id, nR) => {
+                return commentList.map(c => {
+                    if (c._id === id) {
+                        return { ...c, likes: [...nR] }
+                    } else if (c?.answers?.length) {
+                        return {
+                            ...c,
+                            answers: upsertLikeComments(c.answers, id, nR)
+                        }
+                    } else {
+                        return { ...c }
+                    }
+                })
             }
-        }),
+
+            return ({
+                ...state, posts: {
+                    ...state.posts, comments: upsertLikeComments(posts.comments, findId, newResult)
+                }
+            })
+        },
         'UPDATE-FOLLOWERS': () => ({
             ...state,
             userData: { ...state.userData, followers: [...newResult] }
         }),
-
-
     }
     if (type in types) {
         return types[type]()

Dosya farkı çok büyük olduğundan ihmal edildi
+ 17 - 9
src/redux/saga/index.js