From 8af7812b94b2da0707060b875d32cb23a16ffe5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A1=8C=E8=A8=80?= <2311595895@qq.com> Date: Tue, 26 Nov 2024 11:17:23 +0800 Subject: [PATCH] Xingyan/fix code review (#1919) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(CodeReview): 修复某些场景返回的行号列表与实际选中的行号列表不一致的问题 --------- Co-authored-by: TongxinXie --- .../composables/use-code-review-comment.ts | 38 +++++-------------- .../use-code-review-line-selection.ts | 13 +++---- .../devui-vue/devui/code-review/src/utils.ts | 37 ++++++++++++++++++ packages/devui-vue/package.json | 2 +- 4 files changed, 54 insertions(+), 36 deletions(-) diff --git a/packages/devui-vue/devui/code-review/src/composables/use-code-review-comment.ts b/packages/devui-vue/devui/code-review/src/composables/use-code-review-comment.ts index 6a86b07983..7874c30d08 100644 --- a/packages/devui-vue/devui/code-review/src/composables/use-code-review-comment.ts +++ b/packages/devui-vue/devui/code-review/src/composables/use-code-review-comment.ts @@ -14,7 +14,7 @@ import { export function useCodeReviewComment(reviewContentRef: Ref, props: CodeReviewProps, ctx: SetupContext) { const { outputFormat, allowComment, allowChecked } = toRefs(props); const ns = useNamespace('code-review'); - const { onMousedown } = useCodeReviewLineSelection(reviewContentRef, props, updateLineNumbers, afterCheckLines); + const { onMousedown } = useCodeReviewLineSelection(reviewContentRef, props, afterMouseup); const commentLeft = ref(-100); const commentTop = ref(-100); let currentLeftLineNumber = -1; @@ -117,26 +117,6 @@ export function useCodeReviewComment(reviewContentRef: Ref, props: resetLeftTop(); } }; - // 获代码行 取值方法 - const getLineNumbers = (currentNumber: number, currentNumbers: Array, moveDirection: 'up' | 'down') => { - if (currentNumber === -1) { - // 当前行没数据不代表之前选中的没数据,此时返回原来的 - return currentNumbers; - } - if (currentNumbers.length === 0) { - return [currentNumber]; - } - const numbers = [...currentNumbers]; - let max = Math.max(...numbers); - let min = Math.min(...numbers); - if (moveDirection === 'down') { - max = currentNumber; - } - if (moveDirection === 'up') { - min = currentNumber; - } - return Array.from({ length: max - min + 1 }, (_, i) => i + min); - }; // 获取一些公共类和判断 const getCommonClassAndJudge = () => { const checkedLine = [currentLeftLineNumbers, currentRightLineNumbers]; @@ -211,13 +191,9 @@ export function useCodeReviewComment(reviewContentRef: Ref, props: } getDoubleCheckedLineCode(shouldRenderClass); } - function updateLineNumbers(moveDirection: 'up' | 'down') { - currentLeftLineNumbers = - currentLeftLineNumber === -1 ? currentLeftLineNumbers : getLineNumbers(currentLeftLineNumber, currentLeftLineNumbers, moveDirection); - currentRightLineNumbers = - currentRightLineNumber === -1 - ? currentRightLineNumbers - : getLineNumbers(currentRightLineNumber, currentRightLineNumbers, moveDirection); + function updateLineNumbers({ lefts, rights }: { lefts: number[]; rights: number[] }) { + currentLeftLineNumbers = lefts; + currentRightLineNumbers = rights; getCheckedLineCode(false); afterCheckLinesEmitData = { left: currentLeftLineNumber, @@ -230,6 +206,8 @@ export function useCodeReviewComment(reviewContentRef: Ref, props: }; } const updateCheckedLineClass = () => { + const lineClassName = props.outputFormat === 'line-by-line' ? '.d2h-code-linenumber' : '.d2h-code-side-linenumber'; + allTrNodes = reviewContentRef.value.querySelectorAll(lineClassName); getCheckedLineCode(true); }; // 还原样式 @@ -280,6 +258,10 @@ export function useCodeReviewComment(reviewContentRef: Ref, props: function afterCheckLines() { ctx.emit('afterCheckLines', afterCheckLinesEmitData); } + function afterMouseup(lineNumbers: { lefts: number[]; rights: number[] }) { + updateLineNumbers(lineNumbers); + afterCheckLines(); + } // 图标或者单行的点击 const onCommentIconClick = (e: Event) => { if (e) { diff --git a/packages/devui-vue/devui/code-review/src/composables/use-code-review-line-selection.ts b/packages/devui-vue/devui/code-review/src/composables/use-code-review-line-selection.ts index 38edc38257..59448cee26 100644 --- a/packages/devui-vue/devui/code-review/src/composables/use-code-review-line-selection.ts +++ b/packages/devui-vue/devui/code-review/src/composables/use-code-review-line-selection.ts @@ -1,13 +1,12 @@ import type { Ref } from 'vue'; import type { CodeReviewProps } from '../code-review-types'; import { useNamespace } from '../../../shared/hooks/use-namespace'; -import { findParentTrNode } from '../utils'; +import { findParentTrNode, getLineNumbers } from '../utils'; export function useCodeReviewLineSelection( reviewContentRef: Ref, props: CodeReviewProps, - mouseMoveCb: (moveDirection: 'up' | 'down') => void, - mouseupCb: () => void + afterMouseup: (lineNumbers: { lefts: number[]; rights: number[] }) => void ) { const ns = useNamespace('code-review'); let dragging = false; @@ -16,7 +15,7 @@ export function useCodeReviewLineSelection( let isClickedLeft: boolean | undefined; let shouldClear: boolean; let isMouseMoved: boolean; - let startClientY: number; + let checkedTrNodes: HTMLElement[] = []; const onMousedown = (e: MouseEvent) => { // 鼠标左键按下 @@ -45,7 +44,6 @@ export function useCodeReviewLineSelection( dragging = true; shouldClear = true; isMouseMoved = false; - startClientY = e.clientY; e.preventDefault(); e.stopPropagation(); document.addEventListener('mousemove', onMousemove); @@ -76,7 +74,6 @@ export function useCodeReviewLineSelection( if (endIndex === -1) { return; } - mouseMoveCb(e.clientY > startClientY ? 'down' : 'up'); if (startIndex > endIndex) { [startIndex, endIndex] = [endIndex, startIndex]; } @@ -89,9 +86,11 @@ export function useCodeReviewLineSelection( } else { position = 'right'; } + checkedTrNodes = []; for (let i = 0; i < trNodes.length; i++) { if (i >= startIndex && i <= endIndex) { toggleCommentCheckedClass(trNodes[i], true, position); + checkedTrNodes.push(trNodes[i]); } else { toggleCommentCheckedClass(trNodes[i], false, position); } @@ -101,7 +100,7 @@ export function useCodeReviewLineSelection( function onMouseup() { dragging = false; if (isMouseMoved) { - mouseupCb(); + afterMouseup(getLineNumbers(checkedTrNodes, props.outputFormat, isClickedLeft ? 'left' : 'right')); } document.removeEventListener('mouseup', onMouseup); document.removeEventListener('mousemove', onMousemove); diff --git a/packages/devui-vue/devui/code-review/src/utils.ts b/packages/devui-vue/devui/code-review/src/utils.ts index 74180edba5..9064fd2105 100644 --- a/packages/devui-vue/devui/code-review/src/utils.ts +++ b/packages/devui-vue/devui/code-review/src/utils.ts @@ -528,3 +528,40 @@ export function findParentTrNode(node: HTMLElement | null) { } return findParentTrNode(node.parentElement); } + +/* 根据最大最小行号,获取从小到大的完整行号列表 */ +function getFullNumberList(min: number, max: number) { + return Array.from({ length: max - min + 1 }, (_, i) => i + min); +} + +/* 多行选中,返回选中行的左右侧行号 */ +export function getLineNumbers(trNodes: HTMLElement[], outputFormat: OutputFormat, side: LineSide) { + const leftNumbers: number[] = []; + const rightNumbers: number[] = []; + + for (let i = 0; i < trNodes.length; i++) { + const itemTrNode = trNodes[i]; + if (outputFormat === 'line-by-line') { + const lineNumberTdNode = Array.from(itemTrNode.children)[0] as HTMLElement; + const leftLineNumber = parseInt((lineNumberTdNode.children[0] as HTMLElement)?.innerText); + const rightLineNumber = parseInt((lineNumberTdNode.children[1] as HTMLElement)?.innerText); + + leftLineNumber && leftNumbers.push(leftLineNumber); + rightLineNumber && rightNumbers.push(leftLineNumber); + } else { + const tdNodes = Array.from(itemTrNode.children) as HTMLElement[]; + const lineNumberTdNode: HTMLElement = tdNodes[side === 'left' ? 0 : 2]; + if (lineNumberTdNode && notEmptyNode(lineNumberTdNode)) { + const lineNumber = parseInt(lineNumberTdNode.innerText); + if (lineNumber) { + side === 'left' ? leftNumbers.push(lineNumber) : rightNumbers.push(lineNumber); + } + } + } + } + + const lefts = leftNumbers.length ? getFullNumberList(leftNumbers[0], leftNumbers[leftNumbers.length - 1]) : leftNumbers; + const rights = rightNumbers.length ? getFullNumberList(rightNumbers[0], rightNumbers[rightNumbers.length - 1]) : rightNumbers; + + return { lefts, rights }; +} diff --git a/packages/devui-vue/package.json b/packages/devui-vue/package.json index 1d38592356..146742524a 100644 --- a/packages/devui-vue/package.json +++ b/packages/devui-vue/package.json @@ -1,6 +1,6 @@ { "name": "vue-devui", - "version": "1.6.25", + "version": "1.6.26", "license": "MIT", "description": "DevUI components based on Vite and Vue3", "keywords": [