Merge pull request #12668 from overleaf/td-history-scroll-to-first-change

Scroll to first change in history document diff viewer

GitOrigin-RevId: e135877ca440c5eb2732890e8723d9098444727f
This commit is contained in:
Tim Down 2023-04-18 16:15:52 +02:00 committed by Copybot
parent 99e1ff0804
commit 5f5e07a334
3 changed files with 85 additions and 20 deletions

View file

@ -1,7 +1,12 @@
import { useCallback, useEffect, useRef, useState } from 'react'
import withErrorBoundary from '../../../../infrastructure/error-boundary'
import { ErrorBoundaryFallback } from '../../../../shared/components/error-boundary-fallback'
import { EditorState, Extension } from '@codemirror/state'
import {
EditorSelection,
EditorState,
Extension,
StateEffect,
} from '@codemirror/state'
import { EditorView, lineNumbers } from '@codemirror/view'
import { indentationMarkers } from '@replit/codemirror-indentation-markers'
import { highlights, setHighlightsEffect } from '../../extensions/highlights'
@ -100,9 +105,18 @@ function DocumentDiffViewer({
const { before, after } = highlightLocations
useEffect(() => {
const effects: StateEffect<unknown>[] = [setHighlightsEffect.of(highlights)]
if (highlights.length > 0) {
const { from, to } = highlights[0].range
effects.push(
EditorView.scrollIntoView(EditorSelection.range(from, to), {
y: 'center',
})
)
}
view.dispatch({
changes: { from: 0, to: view.state.doc.length, insert: doc },
effects: setHighlightsEffect.of(highlights),
effects,
})
}, [doc, highlights, view])

View file

@ -3,23 +3,6 @@ import DocumentDiffViewer from '../../js/features/history/components/diff-view/d
import React from 'react'
import { Highlight } from '../../js/features/history/services/types/doc'
export default {
title: 'History / Document Diff Viewer',
component: DocumentDiffViewer,
decorators: [
ScopeDecorator,
(Story: React.ComponentType) => (
<div style={{ height: '90vh' }}>
<Story />
</div>
),
],
}
export const Highlights = () => {
return <DocumentDiffViewer doc={content} highlights={highlights} />
}
const highlights: Highlight[] = [
{
type: 'addition',
@ -47,7 +30,7 @@ const highlights: Highlight[] = [
},
]
const content = `\\documentclass{article}
const doc = `\\documentclass{article}
% Language setting
% Replace \`english' with e.g. \`spanish' to change the document language
@ -131,3 +114,38 @@ Once you're familiar with the editor, you can find various project settings in t
\\bibliography{sample}
\\end{document}`
export default {
title: 'History / Document Diff Viewer',
component: DocumentDiffViewer,
args: { doc, highlights },
argTypes: {
doc: {
table: { disable: true },
},
highlights: {
table: { disable: true },
},
},
decorators: [
ScopeDecorator,
(Story: React.ComponentType) => (
<div style={{ height: '90vh' }}>
<Story />
</div>
),
],
}
export const Highlights = (
args: React.ComponentProps<typeof DocumentDiffViewer>
) => {
return <DocumentDiffViewer {...args} />
}
export const ScrollToFirstHighlight = (
args: React.ComponentProps<typeof DocumentDiffViewer>
) => {
const lastHighlightOnly = args.highlights.slice(-1)
return <DocumentDiffViewer {...args} highlights={lastHighlightOnly} />
}

View file

@ -144,4 +144,37 @@ describe('document diff viewer', function () {
cy.get('.previous-highlight-button').should('have.length', 1)
cy.get('.next-highlight-button').should('have.length', 1)
})
it('scrolls to first change', function () {
const scope = mockScope()
const finalHighlightOnly = highlights.slice(-1)
cy.mount(
<Container>
<EditorProviders scope={scope}>
<DocumentDiffViewer doc={doc} highlights={finalHighlightOnly} />
</EditorProviders>
</Container>
)
cy.get('.cm-scroller').first().invoke('scrollTop').should('not.equal', 0)
cy.get('.ol-addition-marker')
.first()
.then($marker => {
cy.get('.cm-content')
.first()
.then($content => {
const contentRect = $content[0].getBoundingClientRect()
const markerRect = $marker[0].getBoundingClientRect()
expect(markerRect.top).to.be.within(
contentRect.top,
contentRect.bottom
)
expect(markerRect.bottom).to.be.within(
contentRect.top,
contentRect.bottom
)
})
})
})
})