import { useMemo, useState } from 'react' import PropTypes from 'prop-types' import { Button, Modal, Typography, theme, Flex } from 'antd' import { presentableDiff } from '@codemirror/merge' import CodeDiffViewer from './CodeDiffViewer' import { toEditorCode } from './codeBlockEditorUtils' const { Link, Text } = Typography const SQUARE_COUNT = 10 const countLines = (str) => { if (!str) return 0 const parts = str.split('\n') if (parts[parts.length - 1] === '') parts.pop() return Math.max(parts.length, 1) } export function getCodeDiffStats(oldCode, newCode, language = 'javascript') { const oldText = toEditorCode(oldCode, language) const newText = toEditorCode(newCode, language) const changes = presentableDiff(oldText, newText) let additions = 0 let deletions = 0 for (const change of changes) { const deleted = oldText.slice(change.fromA, change.toA) const added = newText.slice(change.fromB, change.toB) if (deleted) deletions += countLines(deleted) if (added) additions += countLines(added) } return { additions, deletions } } export default function DiffLabel({ oldCode = '', newCode = '', language = 'javascript' }) { const { token } = theme.useToken() const [open, setOpen] = useState(false) const [viewerReady, setViewerReady] = useState(false) const { additions, deletions } = useMemo( () => getCodeDiffStats(oldCode, newCode, language), [oldCode, newCode, language] ) const greenCount = Math.round( (additions / (additions + deletions)) * SQUARE_COUNT ) return ( <> { setOpen(true) }} > +{additions} {Array.from({ length: SQUARE_COUNT }).map((_, i) => (
))} -{deletions} { setOpen(false) }} footer={ } > {viewerReady ? ( ) : null} ) } DiffLabel.propTypes = { oldCode: PropTypes.oneOfType([PropTypes.string, PropTypes.object]), newCode: PropTypes.oneOfType([PropTypes.string, PropTypes.object]), language: PropTypes.oneOfType([ PropTypes.string, PropTypes.arrayOf(PropTypes.string) ]) }