mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-07 20:31:06 -05:00
Sync cursor position to PDF when double-clicking on a heading in the file outline (#7314)
GitOrigin-RevId: ef98f5d20e99bfc03c91cbf4027d277e738ab176
This commit is contained in:
parent
5cb46643da
commit
aca889a3e0
4 changed files with 30 additions and 16 deletions
|
@ -40,12 +40,9 @@ function OutlineItem({ outlineItem, jumpToLine, highlightedLine }) {
|
|||
setExpanded(!expanded)
|
||||
}
|
||||
|
||||
function handleOutlineItemLinkClick() {
|
||||
jumpToLine(outlineItem.line, false)
|
||||
}
|
||||
|
||||
function handleOutlineItemLinkDoubleClick() {
|
||||
jumpToLine(outlineItem.line, true)
|
||||
function handleOutlineItemLinkClick(event) {
|
||||
const syncToPdf = event.detail === 2 // double-click = sync to PDF
|
||||
jumpToLine(outlineItem.line, syncToPdf)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
|
@ -87,7 +84,6 @@ function OutlineItem({ outlineItem, jumpToLine, highlightedLine }) {
|
|||
<button
|
||||
className={itemLinkClasses}
|
||||
onClick={handleOutlineItemLinkClick}
|
||||
onDoubleClick={handleOutlineItemLinkDoubleClick}
|
||||
ref={titleElementRef}
|
||||
>
|
||||
{outlineItem.title}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import classNames from 'classnames'
|
||||
import { memo, useCallback, useEffect, useState } from 'react'
|
||||
import { memo, useCallback, useEffect, useState, useRef } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { useIdeContext } from '../../../shared/context/ide-context'
|
||||
import { useProjectContext } from '../../../shared/context/project-context'
|
||||
|
@ -16,6 +16,7 @@ import useDetachState from '../../../shared/hooks/use-detach-state'
|
|||
import useDetachAction from '../../../shared/hooks/use-detach-action'
|
||||
import localStorage from '../../../infrastructure/local-storage'
|
||||
import { useFileTreeData } from '../../../shared/context/file-tree-data-context'
|
||||
import useScopeEventListener from '../../../shared/hooks/use-scope-event-listener'
|
||||
|
||||
function GoToCodeButton({
|
||||
position,
|
||||
|
@ -233,6 +234,18 @@ function PdfSynctexControls() {
|
|||
[getCurrentFilePath, goToPdfLocation]
|
||||
)
|
||||
|
||||
const cursorPositionRef = useRef(cursorPosition)
|
||||
|
||||
useEffect(() => {
|
||||
cursorPositionRef.current = cursorPosition
|
||||
}, [cursorPosition])
|
||||
|
||||
const handleSyncToPdf = useCallback(() => {
|
||||
syncToPdf(cursorPositionRef.current)
|
||||
}, [syncToPdf])
|
||||
|
||||
useScopeEventListener('cursor:editor:syncToPdf', handleSyncToPdf)
|
||||
|
||||
const _syncToCode = useCallback(
|
||||
(position, visualOffset = 0) => {
|
||||
setSyncToCodeInFlight(true)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { expect } from 'chai'
|
||||
import sinon from 'sinon'
|
||||
import { screen, render, fireEvent } from '@testing-library/react'
|
||||
import { screen, render, fireEvent, waitFor } from '@testing-library/react'
|
||||
|
||||
import OutlineItem from '../../../../../frontend/js/features/outline/components/outline-item'
|
||||
|
||||
|
@ -82,7 +82,7 @@ describe('<OutlineItem />', function () {
|
|||
screen.getByRole('treeitem', { name: 'Parent', current: true })
|
||||
})
|
||||
|
||||
it('click and double-click jump to location', function () {
|
||||
it('click and double-click jump to location', async function () {
|
||||
const outlineItem = {
|
||||
title: 'Parent',
|
||||
line: 1,
|
||||
|
@ -91,13 +91,17 @@ describe('<OutlineItem />', function () {
|
|||
|
||||
const titleButton = screen.getByRole('button', { name: outlineItem.title })
|
||||
|
||||
fireEvent.click(titleButton)
|
||||
expect(jumpToLine).to.be.calledOnce
|
||||
expect(jumpToLine).to.be.calledWith(1, false)
|
||||
fireEvent.click(titleButton, { detail: 1 })
|
||||
await waitFor(() => {
|
||||
expect(jumpToLine).to.be.calledOnce
|
||||
expect(jumpToLine).to.be.calledWith(1, false)
|
||||
})
|
||||
|
||||
jumpToLine.reset()
|
||||
fireEvent.doubleClick(titleButton)
|
||||
expect(jumpToLine).to.be.calledOnce
|
||||
expect(jumpToLine).to.be.calledWith(1, true)
|
||||
fireEvent.click(titleButton, { detail: 2 })
|
||||
await waitFor(() => {
|
||||
expect(jumpToLine).to.be.calledOnce
|
||||
expect(jumpToLine).to.be.calledWith(1, true)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -79,6 +79,7 @@ export function EditorProviders({
|
|||
callback(get($scope, path))
|
||||
return () => null
|
||||
},
|
||||
$on: sinon.stub(),
|
||||
$applyAsync: sinon.stub(),
|
||||
toggleHistory: sinon.stub(),
|
||||
permissionsLevel,
|
||||
|
|
Loading…
Reference in a new issue