2024-05-29 10:17:37 -04:00
|
|
|
import { Dropdown, MenuItem } from 'react-bootstrap'
|
|
|
|
import { useEffect, useState } from 'react'
|
|
|
|
import { useTranslation } from 'react-i18next'
|
|
|
|
import ControlledDropdown from '@/shared/components/controlled-dropdown'
|
|
|
|
import classNames from 'classnames'
|
2024-06-21 04:39:50 -04:00
|
|
|
import { useFeatureFlag } from '@/shared/context/split-test-context'
|
2024-05-29 10:17:37 -04:00
|
|
|
|
|
|
|
const isMac = /Mac/.test(window.navigator?.platform)
|
|
|
|
|
|
|
|
const shortcuts = isMac
|
|
|
|
? {
|
|
|
|
'zoom-in': ['⌘', '+'],
|
|
|
|
'zoom-out': ['⌘', '-'],
|
|
|
|
'fit-to-width': ['⌘', '0'],
|
2024-07-04 08:34:32 -04:00
|
|
|
'fit-to-height': ['⌘', '9'],
|
2024-05-29 10:17:37 -04:00
|
|
|
}
|
|
|
|
: {
|
|
|
|
'zoom-in': ['Ctrl', '+'],
|
|
|
|
'zoom-out': ['Ctrl', '-'],
|
|
|
|
'fit-to-width': ['Ctrl', '0'],
|
2024-07-04 08:34:32 -04:00
|
|
|
'fit-to-height': ['Ctrl', '9'],
|
2024-05-29 10:17:37 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
type PdfZoomDropdownProps = {
|
2024-06-14 08:14:23 -04:00
|
|
|
requestPresentationMode: () => void
|
2024-05-29 10:17:37 -04:00
|
|
|
setZoom: (zoom: string) => void
|
|
|
|
rawScale: number
|
|
|
|
}
|
|
|
|
|
|
|
|
const zoomValues = ['0.5', '0.75', '1', '1.5', '2', '4']
|
|
|
|
|
|
|
|
const rawScaleToPercentage = (rawScale: number) => {
|
|
|
|
return `${Math.round(rawScale * 100)}%`
|
|
|
|
}
|
|
|
|
|
2024-06-14 08:14:23 -04:00
|
|
|
function PdfZoomDropdown({
|
|
|
|
requestPresentationMode,
|
|
|
|
setZoom,
|
|
|
|
rawScale,
|
|
|
|
}: PdfZoomDropdownProps) {
|
2024-05-29 10:17:37 -04:00
|
|
|
const { t } = useTranslation()
|
|
|
|
|
2024-06-21 04:39:50 -04:00
|
|
|
const enablePresentationMode = useFeatureFlag('pdf-presentation-mode')
|
|
|
|
|
2024-05-29 10:17:37 -04:00
|
|
|
const [customZoomValue, setCustomZoomValue] = useState<string>(
|
|
|
|
rawScaleToPercentage(rawScale)
|
|
|
|
)
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
setCustomZoomValue(rawScaleToPercentage(rawScale))
|
|
|
|
}, [rawScale])
|
|
|
|
|
2024-06-21 04:39:50 -04:00
|
|
|
const showPresentOption = enablePresentationMode && document.fullscreenEnabled
|
|
|
|
|
2024-05-29 10:17:37 -04:00
|
|
|
return (
|
|
|
|
<ControlledDropdown
|
|
|
|
id="pdf-zoom-dropdown"
|
|
|
|
onSelect={eventKey => {
|
2024-06-14 08:14:23 -04:00
|
|
|
if (eventKey === 'custom-zoom') {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if (eventKey === 'present') {
|
|
|
|
requestPresentationMode()
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
setZoom(eventKey)
|
2024-05-29 10:17:37 -04:00
|
|
|
}}
|
|
|
|
pullRight
|
|
|
|
>
|
|
|
|
<Dropdown.Toggle
|
2024-06-26 08:37:51 -04:00
|
|
|
bsStyle={null}
|
2024-05-31 04:51:27 -04:00
|
|
|
className="btn pdf-toolbar-btn pdfjs-zoom-dropdown-button small"
|
2024-05-29 10:17:37 -04:00
|
|
|
value={rawScale}
|
|
|
|
title={rawScaleToPercentage(rawScale)}
|
|
|
|
/>
|
|
|
|
<Dropdown.Menu className="pdfjs-zoom-dropdown-menu">
|
|
|
|
<MenuItem
|
|
|
|
draggable={false}
|
|
|
|
disabled
|
|
|
|
className="pdfjs-custom-zoom-menu-item"
|
|
|
|
key="custom-zoom"
|
|
|
|
eventKey="custom-zoom"
|
|
|
|
>
|
|
|
|
<input
|
|
|
|
type="text"
|
|
|
|
onFocus={event => event.target.select()}
|
|
|
|
value={customZoomValue}
|
|
|
|
onKeyDown={event => {
|
|
|
|
if (event.key === 'Enter') {
|
|
|
|
const zoom = Number(customZoomValue.replace('%', '')) / 100
|
|
|
|
|
|
|
|
// Only allow zoom values between 10% and 999%
|
|
|
|
if (zoom < 0.1) {
|
|
|
|
setZoom('0.1')
|
|
|
|
} else if (zoom > 9.99) {
|
|
|
|
setZoom('9.99')
|
|
|
|
} else {
|
|
|
|
setZoom(`${zoom}`)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}}
|
|
|
|
onChange={event => {
|
|
|
|
const rawValue = event.target.value
|
|
|
|
const parsedValue = rawValue.replace(/[^0-9%]/g, '')
|
|
|
|
setCustomZoomValue(parsedValue)
|
|
|
|
}}
|
|
|
|
/>
|
|
|
|
</MenuItem>
|
|
|
|
<MenuItem divider />
|
|
|
|
<MenuItem draggable={false} key="zoom-in" eventKey="zoom-in">
|
|
|
|
<span>{t('zoom_in')}</span>
|
|
|
|
<Shortcut keys={shortcuts['zoom-in']} />
|
|
|
|
</MenuItem>
|
|
|
|
<MenuItem draggable={false} key="zoom-out" eventKey="zoom-out">
|
|
|
|
<span>{t('zoom_out')}</span>
|
|
|
|
<Shortcut keys={shortcuts['zoom-out']} />
|
|
|
|
</MenuItem>
|
|
|
|
<MenuItem draggable={false} key="page-width" eventKey="page-width">
|
|
|
|
{t('fit_to_width')}
|
|
|
|
<Shortcut keys={shortcuts['fit-to-width']} />
|
|
|
|
</MenuItem>
|
|
|
|
<MenuItem draggable={false} key="page-height" eventKey="page-height">
|
|
|
|
{t('fit_to_height')}
|
2024-07-04 08:34:32 -04:00
|
|
|
<Shortcut keys={shortcuts['fit-to-height']} />
|
2024-05-29 10:17:37 -04:00
|
|
|
</MenuItem>
|
2024-06-21 04:39:50 -04:00
|
|
|
{showPresentOption && <MenuItem divider />}
|
|
|
|
{showPresentOption && (
|
2024-06-14 08:14:23 -04:00
|
|
|
<MenuItem draggable={false} key="present" eventKey="present">
|
2024-06-19 09:20:59 -04:00
|
|
|
{t('presentation_mode')}
|
2024-06-14 08:14:23 -04:00
|
|
|
</MenuItem>
|
|
|
|
)}
|
2024-05-29 10:17:37 -04:00
|
|
|
<MenuItem divider />
|
2024-06-14 08:14:23 -04:00
|
|
|
<MenuItem header>{t('zoom_to')}</MenuItem>
|
2024-05-29 10:17:37 -04:00
|
|
|
{zoomValues.map(value => (
|
|
|
|
<MenuItem draggable={false} key={value} eventKey={value}>
|
|
|
|
{rawScaleToPercentage(Number(value))}
|
|
|
|
</MenuItem>
|
|
|
|
))}
|
|
|
|
</Dropdown.Menu>
|
|
|
|
</ControlledDropdown>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
function Shortcut({ keys }: { keys: string[] }) {
|
|
|
|
return (
|
|
|
|
<span className="pull-right">
|
|
|
|
{keys.map((key, idx) => (
|
|
|
|
<span
|
|
|
|
className={classNames({
|
|
|
|
'pdfjs-zoom-dropdown-mac-shortcut-char': key.length === 1,
|
|
|
|
})}
|
|
|
|
key={`${key}${idx}`}
|
|
|
|
>
|
|
|
|
{key}
|
|
|
|
</span>
|
|
|
|
))}
|
|
|
|
</span>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
export default PdfZoomDropdown
|