import { NoteType, SNNote, classNames } from '@standardnotes/snjs' import { useEffect, useState } from 'react' import fastdiff from 'fast-diff' import { HeadlessSuperConverter } from '../../SuperEditor/Tools/HeadlessSuperConverter' const DiffSpan = ({ state, text }: { state: fastdiff.Diff[0]; text: fastdiff.Diff[1] }) => ( {text} ) export const DiffView = ({ selectedNotes, convertSuperToMarkdown, }: { selectedNotes: SNNote[] convertSuperToMarkdown: boolean }) => { const [titleDiff, setTitleDiff] = useState([]) const [textDiff, setTextDiff] = useState([]) useEffect(() => { const firstNote = selectedNotes[0] const firstTitle = firstNote.title const firstText = firstNote.noteType === NoteType.Super && convertSuperToMarkdown ? new HeadlessSuperConverter().convertString(firstNote.text, 'md') : firstNote.text const secondNote = selectedNotes[1] const secondTitle = secondNote.title const secondText = secondNote.noteType === NoteType.Super && convertSuperToMarkdown ? new HeadlessSuperConverter().convertString(secondNote.text, 'md') : secondNote.text const titleDiff = fastdiff(firstTitle, secondTitle, undefined, true) const textDiff = fastdiff(firstText, secondText, undefined, true) setTitleDiff(titleDiff) setTextDiff(textDiff) }, [convertSuperToMarkdown, selectedNotes]) const [preElement, setPreElement] = useState(null) const [diffVisualizer, setDiffVisualizer] = useState(null) const [hasOverflow, setHasOverflow] = useState(false) useEffect(() => { if (!preElement) { return } setHasOverflow(preElement.scrollHeight > preElement.clientHeight) }, [preElement, textDiff]) useEffect(() => { if (!preElement || !diffVisualizer) { return } if (!hasOverflow) { return } if (!textDiff.length) { return } diffVisualizer.innerHTML = '' const preElementRect = preElement.getBoundingClientRect() const diffVisualizerRect = diffVisualizer.getBoundingClientRect() const diffs = preElement.querySelectorAll('[data-diff]') diffs.forEach((diff) => { const state = diff.getAttribute('data-diff') if (!state) { return } const parsedState = parseInt(state) const rect = diff.getBoundingClientRect() const topAsPercent = (rect.top - preElementRect.top) / preElement.scrollHeight const topAdjustedForDiffVisualizer = diffVisualizerRect.height * topAsPercent const heightAsPercent = rect.height / preElement.scrollHeight const heightAdjustedForDiffVisualizer = diffVisualizerRect.height * heightAsPercent const div = document.createElement('div') div.className = `absolute top-0 left-0 w-full bg-${ parsedState === fastdiff.INSERT ? 'success' : 'danger' } opacity-50` div.style.height = `${heightAdjustedForDiffVisualizer}px` div.style.top = `${topAdjustedForDiffVisualizer}px` diffVisualizer.appendChild(div) }) }, [preElement, hasOverflow, textDiff, diffVisualizer]) return (
{titleDiff.map(([state, text], index) => ( ))}
        {textDiff.map(([state, text], index) => (
          
        ))}
      
{hasOverflow && (
)}
) }