META-INF.resources.js.components.document-previewer.DocumentPreviewer.js Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of com.liferay.digital.signature.web
Show all versions of com.liferay.digital.signature.web
Liferay Digital Signature Web
The newest version!
/**
* SPDX-FileCopyrightText: (c) 2000 Liferay, Inc. https://liferay.com
* SPDX-License-Identifier: LGPL-2.1-or-later OR LicenseRef-Liferay-DXP-EULA-2.0.0-2023-06
*/
import ClayButton from '@clayui/button';
import ClayIcon from '@clayui/icon';
import ClayLoadingIndicator from '@clayui/loading-indicator';
import {useIsMounted} from '@liferay/frontend-js-react-web';
import classNames from 'classnames';
import {debounce} from 'frontend-js-web';
import imagePromise from 'image-promise';
import React, {useEffect, useRef, useState} from 'react';
const KEY_CODE_ENTER = 13;
const KEY_CODE_ESC = 27;
/**
* Valid list of keycodes
* Includes backspace, tab, arrows, delete and numbers
* @type {Array}
*/
const VALID_KEY_CODES = [
8, 9, 37, 38, 39, 40, 46, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
];
/**
* Milisecons between goToPage calls
* @type {number}
*/
const WAIT_BETWEEN_GO_TO_PAGE = 250;
/**
* Component that creates a pdf preview
* @description this is a temporary component
*/
const DocumentPreviewer = ({baseImageURL, initialPage, totalPages}) => {
const [currentPage, setCurrentPage] = useState(initialPage);
const [currentPageLoading, setCurrentPageLoading] = useState(false);
const [expanded, setExpanded] = useState(false);
const [loadedPages] = useState({
[currentPage]: {
loaded: true,
pagePromise: Promise.resolve(),
},
});
const [nextPageDisabled, setNextPageDisabled] = useState(
currentPage === totalPages
);
const [previousPageDisabled, setPreviousPageDisabled] = useState(
currentPage === 1
);
const [showPageInput, setShowPageInput] = useState(false);
const imageContainerRef = useRef();
const pageInputRef = useRef();
const showPageInputButtonRef = useRef();
const isMounted = useIsMounted();
if (showPageInput) {
setTimeout(() => {
if (isMounted()) {
pageInputRef.current.focus();
}
}, 100);
}
const loadPage = (page) => {
let pagePromise = loadedPages[page] && loadedPages[page].pagePromise;
if (!pagePromise) {
pagePromise = imagePromise(`${baseImageURL}${page}`).then(() => {
loadedPages[page].loaded = true;
});
loadedPages[page] = {
loaded: false,
pagePromise,
};
}
return pagePromise;
};
const loadAdjacentPages = (page, adjacentPageCount = 2) => {
for (let i = 1; i <= adjacentPageCount; i++) {
if (page + i <= totalPages) {
loadPage(page + i);
}
if (page - i > 1) {
loadPage(page - i);
}
}
};
const loadCurrentPage = debounce((page) => {
loadPage(page)
.then(() => {
loadAdjacentPages(page);
setCurrentPageLoading(false);
})
.catch(() => {
setCurrentPageLoading(false);
});
}, WAIT_BETWEEN_GO_TO_PAGE);
const goToPage = (page) => {
setNextPageDisabled(page === totalPages);
setPreviousPageDisabled(page === 1);
if (!loadedPages[page] || !loadedPages[page].loaded) {
setCurrentPageLoading(true);
loadCurrentPage(page);
}
imageContainerRef.current.scrollTop = 0;
setCurrentPage(page);
};
const processPageInput = (value) => {
let pageNumber = Number.parseInt(value, 10);
pageNumber = pageNumber
? Math.min(Math.max(1, pageNumber), totalPages)
: currentPage;
goToPage(pageNumber);
};
const hidePageInput = (returnFocus = true) => {
setShowPageInput(false);
if (returnFocus) {
setTimeout(() => {
if (isMounted()) {
showPageInputButtonRef.current.focus();
}
}, 100);
}
};
const handleBlurPageInput = (event) => {
processPageInput(event.currentTarget.value);
hidePageInput(false);
};
const handleKeyDownPageInput = (event) => {
const code = event.keyCode || event.charCode;
if (code === KEY_CODE_ENTER) {
processPageInput(event.currentTarget.value);
hidePageInput();
}
else if (code === KEY_CODE_ESC) {
hidePageInput();
}
else if (VALID_KEY_CODES.indexOf(code) === -1) {
event.preventDefault();
}
};
useEffect(() => {
loadAdjacentPages(initialPage);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
return (
{currentPageLoading ? (
) : (
)}
{
setShowPageInput(true);
}}
ref={showPageInputButtonRef}
title={
totalPages > 1
? Liferay.Language.get(
'click-to-jump-to-a-page'
)
: undefined
}
>
{`${Liferay.Language.get(
'page'
)} ${currentPage} / ${totalPages}`}
{showPageInput && (
)}
{
goToPage(currentPage - 1);
}}
title={Liferay.Language.get('page-above')}
>
{
goToPage(currentPage + 1);
}}
title={Liferay.Language.get('page-below')}
>
{
setExpanded(!expanded);
}}
title={
expanded
? Liferay.Language.get('zoom-to-fit')
: Liferay.Language.get('expand')
}
>
);
};
export default DocumentPreviewer;