From 08d59f4612cbb74428d64662203d778069fe03a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BD=95=E7=AB=A5=E5=B4=87?= <1261960504@qq.com> Date: Thu, 11 Aug 2022 16:19:19 +0800 Subject: [PATCH] =?UTF-8?q?=E5=9B=9E=E5=BD=92=E4=BB=A3=E7=A0=81=E8=AF=84?= =?UTF-8?q?=E5=AE=A1issue?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/index.html | 2 +- src/common/DateUtil.js | 10 +- .../codeReview/mock/component/index.jsx | 261 +++++++++++------- .../mock/component/style.module.less | 30 +- .../Newfile/codeReview/mock/pr.service.js | 6 + src/forge/Newfile/codeReview/model.jsx | 32 ++- 6 files changed, 217 insertions(+), 124 deletions(-) diff --git a/public/index.html b/public/index.html index de002ba64..8c3614218 100755 --- a/public/index.html +++ b/public/index.html @@ -31,7 +31,7 @@ - + <%= htmlWebpackPlugin.tags.bodyTags %> diff --git a/src/common/DateUtil.js b/src/common/DateUtil.js index 8846d274c..4808ae5a9 100644 --- a/src/common/DateUtil.js +++ b/src/common/DateUtil.js @@ -118,7 +118,7 @@ export function timeAgo(backDate) { var days = Math.floor(time / (1000 * 60 * 60 * 24)); var hours = Math.floor((time % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)); var minutes = Math.floor((time % (1000 * 60 * 60)) / (1000 * 60)); - var seconds = Math.floor((time % (1000 * 60 * 60)) / 1000); + // var seconds = Math.floor((time % (1000 * 60 * 60)) / 1000); if (time <= 0) { return "刚刚"; } @@ -129,10 +129,10 @@ export function timeAgo(backDate) { return hours + "小时前"; } if (minutes) { - return minutes + "分前"; - } - if (seconds) { - return seconds + "秒前"; + return minutes + "分钟前"; } + // if (seconds) { + // return seconds + "秒前"; + // } return "刚刚"; } \ No newline at end of file diff --git a/src/forge/Newfile/codeReview/mock/component/index.jsx b/src/forge/Newfile/codeReview/mock/component/index.jsx index 3648460b6..c2fd3def8 100755 --- a/src/forge/Newfile/codeReview/mock/component/index.jsx +++ b/src/forge/Newfile/codeReview/mock/component/index.jsx @@ -22,9 +22,9 @@ import { Popconfirm, Checkbox, } from "antd"; -// @ts-ignore +import { Link } from "react-router-dom"; import { usePersistFn } from "ahooks"; -import { getImageUrl } from "educoder"; +import { getImageUrl, timeAgo } from "educoder"; import { camelcaseToUnderscore } from '../utils/camelcase-convert'; import "./style.module.less"; import { useAcr, useNote, useGlobal } from "../../model"; @@ -42,21 +42,21 @@ const noteType = { export const Commenting = (props) => { const { user } = useGlobal(); const { addComment } = useNote(); - const { toVersion,stDiff } = useAcr(); + const { toVersion, stDiff } = useAcr(); console.log('Commenting--props'); console.log(props); // console.log(stDiff); const submit = usePersistFn(async (note, type) => { try { - console.log(note,type); + console.log(note, type); await addComment({ note, diffId: toVersion.id, line_code: props.lineCode, - discussionId: props.discussionId, + parent_id: props.id, path: props.path, - type, - diff:stDiff, + type: type || 'comment', + diff:props.id?null: stDiff, }); props.onClose && props.onClose(); } catch (e) { @@ -90,136 +90,186 @@ export const Commenting = (props) => { } return ( -
-
-
- - - -
- setNote(e.target.value)} - style={{ height: 150 }} - /> -
-
- + {note.trim() ? ( + - 评论 - - {note.trim() ? ( - - - - ) : ( - - )} -
-
- {replyNote && ( -
Reply to {replyNote.author.name}
- )} -
+ + + ) : ( + + )} +
+
+ {replyNote && ( +
Reply to {replyNote.author.name}
+ )}
+ // ); }; +const ReplyItem = memo(({note, isChild}) => { + const { user } = useGlobal(); + const { deleteComment } = useNote(); + const [visible, setVisible] = useState(false); + + return
+
+ + + + + {note.user && note.user.username} + 于 {timeAgo(note.createdAt)} 发表评论: + + {user && + (user.admin || + user.login === note.user.login) ? ( + deleteComment(note.id)} + > + + + ) : ( + "" + )} + {!isChild ? : ''} + +
+ +
{note.note}
+ {visible && { setVisible(false) }} {...note} />} +
+}) + export const DiscussionItem = memo((props) => { const { noteId } = props; - const { commentPack } = useNote(); + const { commentPack, deleteComment } = useNote(); - const [commenting, setCommenting] = useState(false); - const [commentReply, setCommentReply] = useState(); + // const [commenting, setCommenting] = useState(false); + // const [commentReply, setCommentReply] = useState(); const replyIdSet = commentPack.noteIdToReplyIdSet.get(noteId); const replyIds = replyIdSet ? Array.from(replyIdSet).sort((a, b) => a - b) : null; - const pending = (function () { - if (!commentPack.hasPendingReview) { - return false; - } - const reviewId = commentPack.noteIdToReviewId.get(noteId); - if (!reviewId) return false; - const review = reviewId ? commentPack.reviewIdToReview.get(reviewId) : null; - if (!review) return false; - return review.pending; - })(); - const hasPendingNote = (function () { - if (pending) return true; - if (replyIds) { - for (const replyId of replyIds) { - const reviewId = commentPack.noteIdToReviewId.get(replyId); - if (reviewId && commentPack.reviewIdToReview.get(reviewId) && commentPack.reviewIdToReview.get(reviewId).pending) { - return true; - } - } - } - return false; - })(); + // const pending = (function () { + // if (!commentPack.hasPendingReview) { + // return false; + // } + // const reviewId = commentPack.noteIdToReviewId.get(noteId); + // if (!reviewId) return false; + // const review = reviewId ? commentPack.reviewIdToReview.get(reviewId) : null; + // if (!review) return false; + // return review.pending; + // })(); + // const hasPendingNote = (function () { + // if (pending) return true; + // if (replyIds) { + // for (const replyId of replyIds) { + // const reviewId = commentPack.noteIdToReviewId.get(replyId); + // if (reviewId && commentPack.reviewIdToReview.get(reviewId) && commentPack.reviewIdToReview.get(reviewId).pending) { + // return true; + // } + // } + // } + // return false; + // })(); - const handleReply = (replyNote) => { - if (replyNote) { - setCommentReply(replyNote); - } - setCommenting(true); - }; + // const handleReply = (replyNote) => { + // if (replyNote) { + // setCommentReply(replyNote); + // } + // setCommenting(true); + // }; + + // useEffect(() => { + // if (!commenting) { + // setCommentReply(undefined); + // } + // }, [commenting]); - useEffect(() => { - if (!commenting) { - setCommentReply(undefined); - } - }, [commenting]); const note = commentPack.noteIdToNote.get(noteId); if (!note) return null; + console.log('note'); + console.log(note); return (
-
- {/* {note.type === noteType.problem && ( + {/*
+ {note.type === noteType.problem && ( {note.state === "resolved" && !pending && "已解决"} {note.state === "opened" && !pending && "待解决"} {pending && "需要回应"} - )} */} -
-
-
{note.author.name} 发表评论:
-
{note.note}
-
+ )} +
*/} + + {replyIds && ( -
- {replyIds.map((replyId) => { +
+ {replyIds.reverse().map((replyId) => { const note = commentPack.noteIdToNote.get(replyId); if (!note) return null; - return ( -
-
{note.author.name} 发表评论
-
{note.note}
-
- ); + return })}
)} @@ -248,7 +298,6 @@ export const Menubar = memo((props) => { }; }, [isFullscreen]); - const { project, pr } = useGlobal(); const { versions, fromVersion, toVersion, updateQuery } = useAcr(); const idToVerbose = new Map(); diff --git a/src/forge/Newfile/codeReview/mock/component/style.module.less b/src/forge/Newfile/codeReview/mock/component/style.module.less index 39679f5b6..3d2518027 100755 --- a/src/forge/Newfile/codeReview/mock/component/style.module.less +++ b/src/forge/Newfile/codeReview/mock/component/style.module.less @@ -1,8 +1,32 @@ .arc-container { - border: solid 1px #eee; - border-left: none; - border-right: none; + // border: solid 1px #eee; + // border-left: none; + // border-right: none; + + .reply-item{ + padding:16px 16px 20px; + + &.reply-item-child{ + margin-top:-10px; + padding:5px 0; + } + } + + .reply-item-head{ + line-height: 30px; + color: #666; + } + .btn-right{ + float: right; + } + .reply-item-content{ + padding-left:35px; + line-height: 1.4; + } + .show-user-link{ + font-weight: 600; + } } .arc-menubar { diff --git a/src/forge/Newfile/codeReview/mock/pr.service.js b/src/forge/Newfile/codeReview/mock/pr.service.js index 7f51de7a5..aaa55fb90 100755 --- a/src/forge/Newfile/codeReview/mock/pr.service.js +++ b/src/forge/Newfile/codeReview/mock/pr.service.js @@ -96,6 +96,7 @@ export const prService = { item.author.username=item.user.name; item.type='Common'; item.stDiff=item.diff; + item.discussionId=item.parentId // item.lineType='old'; } return journals; @@ -172,6 +173,11 @@ export const prService = { return commentData; }, + async deleteComment(projectsId, owner, mergeId,id){ + const res = await axios.delete(`/v1/${owner}/${projectsId}/pulls/${mergeId}/journals/${id}.json`); + return res.data; + }, + async createReview(projectsId, owner, mergeId, data) { const res = await axios.post(`/v1/${owner}/${projectsId}/pulls/${mergeId}/reviews.json`, data); console.log('createReview--data'); diff --git a/src/forge/Newfile/codeReview/model.jsx b/src/forge/Newfile/codeReview/model.jsx index 24a197486..c81602824 100644 --- a/src/forge/Newfile/codeReview/model.jsx +++ b/src/forge/Newfile/codeReview/model.jsx @@ -176,8 +176,7 @@ const useCommentPack = (projectId, prId) => { } fetchingRef.current = true; // 获取评论内容 - // const pack = await prService.getCommentPack(projectsId, owner, mergeId); - const commentPack = await prService.getCommentPack(projectsId, owner, mergeId,{path:filePath}); + const commentPack = await prService.getCommentPack(projectsId, owner, mergeId,{path:filePath,is_full:true}); const reviews = await prService.getReviews(projectsId, owner, mergeId); // debugger for (const review of reviews) { @@ -250,6 +249,11 @@ const useCommentPack = (projectId, prId) => { setUpdateFlag({}); } + function manualRemoveNote(id) { + noteIdToNote.delete(id); + setUpdateFlag({}); + } + function manualUpdateNote(note) { const reviewId = noteIdToReviewId.get(note.id); const review = reviewId ? reviewIdToReview.get(reviewId) : null; @@ -310,6 +314,7 @@ const useCommentPack = (projectId, prId) => { doRefresh, manualUpdateReview, manualAddNote, + manualRemoveNote, manualUpdateNote, pendingReviewRef, getRelatedFilePathByNoteId, @@ -346,6 +351,14 @@ const [NoteProvider, useNote] = createContainer(() => { commentPack.manualAddNote(note, commentPack.pendingReviewRef.current); } + async function deleteComment(id){ + const res = await prService.deleteComment(projectsId, owner, mergeId,id); + if(res.status==0){ + commentPack.manualRemoveNote(id); + } + console.log(res); + } + async function commitReview(body) { if (!commentPack.hasPendingReview) { let reviewData = { @@ -364,6 +377,7 @@ const [NoteProvider, useNote] = createContainer(() => { commentPack, ...commentPack, addComment, + deleteComment, commitReview, prId, activateRef, @@ -570,9 +584,9 @@ const [AcrProvider, useAcr] = createContainer(() => { } ); - // useEffect(() => { - // commentPack.doRefresh(); - // }, []); + useEffect(() => { + commentPack.doRefresh(); + }, []); async function getDiffById(diffId) { let thisStDiff= await prService.getDiffById(projectsId, owner, mergeId, toVersion.id, @@ -641,7 +655,7 @@ const [AcrProvider, useAcr] = createContainer(() => { export const Provider = (props) => { const match = props.match; let project = {}; - let user = mockService['/api/v3/user']; + // let user = mockService['/api/v3/user']; if (props.projectDetail) { let details = props.projectDetail; project = { @@ -650,12 +664,12 @@ export const Provider = (props) => { pathWithNamespace: details.full_name, } } + let user={}; if (props.current_user) { let current_user = props.current_user; - user = { ...user, ...current_user, avatar_url: current_user.image_url, name: current_user.username, }; + user = { ...current_user, avatar_url: current_user.image_url, name: current_user.username, }; } - console.log(user); - console.log('user'); + return (