react-file-previewer
Version:
A browser/device-agnostic file previewer for PDF and image file types built on top of React-PDF.
1,065 lines (909 loc) • 28.9 kB
JavaScript
import { converge, assoc, compose, map, add, when, is, of, propOr, identity, subtract, __, cond, has, prop, o, T, always, match, modulo, pathOr, either, endsWith, propEq, times, clamp, pick } from 'ramda';
import saveFile from 'file-saver';
import PropTypes from 'prop-types';
import React, { useState, useEffect, useRef } from 'react';
import { extension } from 'mime-types';
import ChevronUp from 'mdi-material-ui/ChevronUp';
import ChevronDown from 'mdi-material-ui/ChevronDown';
import Download from 'mdi-material-ui/Download';
import RotateRight from 'mdi-material-ui/RotateRight';
import PlusBox from 'mdi-material-ui/PlusBox';
import MinusBox from 'mdi-material-ui/MinusBox';
import ArrowExpandHorizontal from 'mdi-material-ui/ArrowExpandHorizontal';
import { pdfjs, Document, Page } from 'react-pdf';
import { useInView } from 'react-intersection-observer';
function _typeof(obj) {
"@babel/helpers - typeof";
if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
_typeof = function (obj) {
return typeof obj;
};
} else {
_typeof = function (obj) {
return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
};
}
return _typeof(obj);
}
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
try {
var info = gen[key](arg);
var value = info.value;
} catch (error) {
reject(error);
return;
}
if (info.done) {
resolve(value);
} else {
Promise.resolve(value).then(_next, _throw);
}
}
function _asyncToGenerator(fn) {
return function () {
var self = this,
args = arguments;
return new Promise(function (resolve, reject) {
var gen = fn.apply(self, args);
function _next(value) {
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
}
function _throw(err) {
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
}
_next(undefined);
});
};
}
function _defineProperty(obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
return obj;
}
function ownKeys(object, enumerableOnly) {
var keys = Object.keys(object);
if (Object.getOwnPropertySymbols) {
var symbols = Object.getOwnPropertySymbols(object);
if (enumerableOnly) symbols = symbols.filter(function (sym) {
return Object.getOwnPropertyDescriptor(object, sym).enumerable;
});
keys.push.apply(keys, symbols);
}
return keys;
}
function _objectSpread2(target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i] != null ? arguments[i] : {};
if (i % 2) {
ownKeys(Object(source), true).forEach(function (key) {
_defineProperty(target, key, source[key]);
});
} else if (Object.getOwnPropertyDescriptors) {
Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
} else {
ownKeys(Object(source)).forEach(function (key) {
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
});
}
}
return target;
}
function _inherits(subClass, superClass) {
if (typeof superClass !== "function" && superClass !== null) {
throw new TypeError("Super expression must either be null or a function");
}
subClass.prototype = Object.create(superClass && superClass.prototype, {
constructor: {
value: subClass,
writable: true,
configurable: true
}
});
if (superClass) _setPrototypeOf(subClass, superClass);
}
function _getPrototypeOf(o) {
_getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {
return o.__proto__ || Object.getPrototypeOf(o);
};
return _getPrototypeOf(o);
}
function _setPrototypeOf(o, p) {
_setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
o.__proto__ = p;
return o;
};
return _setPrototypeOf(o, p);
}
function isNativeReflectConstruct() {
if (typeof Reflect === "undefined" || !Reflect.construct) return false;
if (Reflect.construct.sham) return false;
if (typeof Proxy === "function") return true;
try {
Date.prototype.toString.call(Reflect.construct(Date, [], function () {}));
return true;
} catch (e) {
return false;
}
}
function _construct(Parent, args, Class) {
if (isNativeReflectConstruct()) {
_construct = Reflect.construct;
} else {
_construct = function _construct(Parent, args, Class) {
var a = [null];
a.push.apply(a, args);
var Constructor = Function.bind.apply(Parent, a);
var instance = new Constructor();
if (Class) _setPrototypeOf(instance, Class.prototype);
return instance;
};
}
return _construct.apply(null, arguments);
}
function _isNativeFunction(fn) {
return Function.toString.call(fn).indexOf("[native code]") !== -1;
}
function _wrapNativeSuper(Class) {
var _cache = typeof Map === "function" ? new Map() : undefined;
_wrapNativeSuper = function _wrapNativeSuper(Class) {
if (Class === null || !_isNativeFunction(Class)) return Class;
if (typeof Class !== "function") {
throw new TypeError("Super expression must either be null or a function");
}
if (typeof _cache !== "undefined") {
if (_cache.has(Class)) return _cache.get(Class);
_cache.set(Class, Wrapper);
}
function Wrapper() {
return _construct(Class, arguments, _getPrototypeOf(this).constructor);
}
Wrapper.prototype = Object.create(Class.prototype, {
constructor: {
value: Wrapper,
enumerable: false,
writable: true,
configurable: true
}
});
return _setPrototypeOf(Wrapper, Class);
};
return _wrapNativeSuper(Class);
}
function _slicedToArray(arr, i) {
return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest();
}
function _arrayWithHoles(arr) {
if (Array.isArray(arr)) return arr;
}
function _iterableToArrayLimit(arr, i) {
if (!(Symbol.iterator in Object(arr) || Object.prototype.toString.call(arr) === "[object Arguments]")) {
return;
}
var _arr = [];
var _n = true;
var _d = false;
var _e = undefined;
try {
for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
_arr.push(_s.value);
if (i && _arr.length === i) break;
}
} catch (err) {
_d = true;
_e = err;
} finally {
try {
if (!_n && _i["return"] != null) _i["return"]();
} finally {
if (_d) throw _e;
}
}
return _arr;
}
function _nonIterableRest() {
throw new TypeError("Invalid attempt to destructure non-iterable instance");
}
function _wrapRegExp(re, groups) {
_wrapRegExp = function (re, groups) {
return new BabelRegExp(re, undefined, groups);
};
var _RegExp = _wrapNativeSuper(RegExp);
var _super = RegExp.prototype;
var _groups = new WeakMap();
function BabelRegExp(re, flags, groups) {
var _this = _RegExp.call(this, re, flags);
_groups.set(_this, groups || _groups.get(re));
return _this;
}
_inherits(BabelRegExp, _RegExp);
BabelRegExp.prototype.exec = function (str) {
var result = _super.exec.call(this, str);
if (result) result.groups = buildGroups(result, this);
return result;
};
BabelRegExp.prototype[Symbol.replace] = function (str, substitution) {
if (typeof substitution === "string") {
var groups = _groups.get(this);
return _super[Symbol.replace].call(this, str, substitution.replace(/\$<([^>]+)>/g, function (_, name) {
return "$" + groups[name];
}));
} else if (typeof substitution === "function") {
var _this = this;
return _super[Symbol.replace].call(this, str, function () {
var args = [];
args.push.apply(args, arguments);
if (typeof args[args.length - 1] !== "object") {
args.push(buildGroups(args, _this));
}
return substitution.apply(this, args);
});
} else {
return _super[Symbol.replace].call(this, str, substitution);
}
};
function buildGroups(result, re) {
var g = _groups.get(re);
return Object.keys(g).reduce(function (groups, name) {
groups[name] = result[g[name]];
return groups;
}, Object.create(null));
}
return _wrapRegExp.apply(this, arguments);
}
var SCALE_FACTOR = 0.25;
/**
* Scale the document by 25%.
*
* @param {Object} files
* @return {Object}
*/
var setZoomIn = converge(assoc('scale'), [compose(map(add(SCALE_FACTOR)), when(is(Number), of), propOr([1], 'scale')), identity]);
var SCALE_FACTOR$1 = 0.25;
/**
* Reduce the document scale by 25%.
*
* @param {Object} files
* @return {Object}
*/
var setZoomOut = converge(assoc('scale'), [compose(map(subtract(__, SCALE_FACTOR$1)), when(is(Number), of), propOr([1], 'scale')), identity]);
var DEFAULT_NAME = 'download.pdf';
/**
* Get the name to download this file.
*
* @param {Object} file
* @return {String}
*/
var getFilename = cond([[has('name'), prop('name')], [has('mimeType'), o(extension, prop('mimeType'))], [T, always(DEFAULT_NAME)]]);
/**
* Read the file `url`, in case it matches a base64 url.
*
* @param {Object} file
* @return {Object}
*/
var getFileDataInBase64 = compose(prop('groups'), match( /*#__PURE__*/_wrapRegExp(/^data:([a-z]+\/[a-z]+);base64,(.*)/, {
mimeType: 1,
data: 2
})), propOr('', 'url'));
/**
* Get the `file` from the properties, in the correct format.
*
* @param {Object} props
*/
var getFileProp = function getFileProp(props) {
// Check if the file url is base64.
if (getFileDataInBase64(props.file)) {
// Update the file to include the data and mimeType extracted from the url.
return getFileDataInBase64(props.file);
}
return props.file;
};
/**
* Rotate the file 90 degrees.
*
* @param {Object} files
* @return {Object}
*/
var setNewRotation = converge(assoc('rotate'), [compose(modulo(__, 360), add(90), propOr(0, 'rotate')), identity]);
var useViewportSize = function useViewportSize(viewportElem) {
var isClient = (typeof window === "undefined" ? "undefined" : _typeof(window)) === 'object';
var _useState = useState({
width: pathOr(0, ['current', 'clientWidth'], viewportElem),
height: pathOr(0, ['current', 'clientHeight'], viewportElem)
}),
_useState2 = _slicedToArray(_useState, 2),
size = _useState2[0],
setSize = _useState2[1];
useEffect(function () {
setSize({
width: pathOr(0, ['current', 'clientWidth'], viewportElem),
height: pathOr(0, ['current', 'clientHeight'], viewportElem)
});
}, [viewportElem]);
useEffect(function () {
if (!isClient) {
return false;
}
function handleResize() {
setSize({
width: pathOr(0, ['current', 'clientWidth'], viewportElem),
height: pathOr(0, ['current', 'clientHeight'], viewportElem)
});
}
window.addEventListener('resize', handleResize);
return function () {
return window.removeEventListener('resize', handleResize);
};
}, [viewportElem]);
return size;
};
// Make sure to leave a padding.
var PADDING = 12 * 4; // Get the preview bar height.
var getViewportWidth = function getViewportWidth(viewportElem) {
return viewportElem.width || viewportElem.clientWidth;
};
/**
* Get the `scale` attribute for the "fit to width" option.
*
* @param {Object} viewportElem
* @param {Object} contentElem
* @return {Number}
*/
var getFitToWidthScale = function getFitToWidthScale(viewportElem, contentElem) {
// Get the viewport ratio.
var viewportWidth = getViewportWidth(viewportElem); // Get the content ratio.
var contentWidth = contentElem.width || contentElem.offsetWidth; // Get the scaling ratio, after removing the padding.
return (viewportWidth - PADDING) / contentWidth;
};
var Button = function Button(_ref) {
var children = _ref.children,
onClick = _ref.onClick,
disabled = _ref.disabled;
return React.createElement("button", {
type: "button",
onClick: onClick,
disabled: disabled,
className: "preview-button"
}, children);
};
var PageCount = function PageCount(_ref) {
var current = _ref.current,
total = _ref.total;
return React.createElement("span", {
className: "preview-pagecount"
}, current + 1, " of ", total);
};
var PreviewBarLeft = function PreviewBarLeft(props) {
return React.createElement("div", {
className: "preview-bar-left"
}, React.createElement(Button, {
onClick: props.onPageUp,
disabled: props.currentPage === 0
}, React.createElement(ChevronUp, null)), React.createElement(Button, {
onClick: props.onPageDown,
disabled: props.currentPage + 1 === props.totalPages
}, React.createElement(ChevronDown, null)), React.createElement(PageCount, {
current: props.currentPage,
total: props.totalPages
}));
};
PreviewBarLeft.propTypes = {
totalPages: PropTypes.number.isRequired,
currentPage: PropTypes.number.isRequired,
onPageUp: PropTypes.func.isRequired,
onPageDown: PropTypes.func.isRequired
};
var PreviewBarRight = function PreviewBarRight(props) {
return React.createElement("div", {
className: "preview-bar-left"
}, React.createElement(Button, {
onClick: props.onRotate
}, React.createElement(RotateRight, null)), React.createElement(Button, {
onClick: props.onDownload
}, React.createElement(Download, null)));
};
PreviewBarRight.propTypes = {
onRotate: PropTypes.func.isRequired,
onDownload: PropTypes.func.isRequired
};
var PreviewBar = function PreviewBar(props) {
if (props.hidden) {
return null;
}
return React.createElement("div", {
className: "preview-bar"
}, React.createElement(PreviewBarLeft, {
onPageUp: props.onPageUp,
onPageDown: props.onPageDown,
totalPages: props.totalPages,
currentPage: props.currentPage
}), React.createElement(PreviewBarRight, {
onRotate: props.onRotate,
onDownload: props.onDownload
}));
};
PreviewBar.propTypes = {
onPageUp: PropTypes.func.isRequired,
onRotate: PropTypes.func.isRequired,
onPageDown: PropTypes.func.isRequired,
onDownload: PropTypes.func.isRequired,
totalPages: PropTypes.number.isRequired,
currentPage: PropTypes.number.isRequired,
hidden: PropTypes.bool
};
var ViewportControl = function ViewportControl(props) {
if (props.hidden) {
return null;
}
return React.createElement("div", {
className: "preview-icons"
}, React.createElement(Button, {
onClick: props.onZoomIn
}, React.createElement(PlusBox, null)), React.createElement(Button, {
onClick: props.onZoomOut,
className: "preview-icons"
}, React.createElement(MinusBox, null)), React.createElement(Button, {
onClick: props.onFitToScreen,
className: "preview-icons"
}, React.createElement(ArrowExpandHorizontal, null)));
};
ViewportControl.propTypes = {
onZoomIn: PropTypes.func.isRequired,
onZoomOut: PropTypes.func.isRequired,
onFitToScreen: PropTypes.func.isRequired,
hidden: PropTypes.bool
};
/**
* Check if a file is a pdf.
*
* @param {Object}
* @return {Boolean}
*/
var isPDF = either(o(endsWith('.pdf'), propOr('', 'url')), propEq('mimeType', 'application/pdf'));
pdfjs.GlobalWorkerOptions.workerSrc = "//cdnjs.cloudflare.com/ajax/libs/pdf.js/2.1.266/pdf.worker.js";
var PDFPage = function PDFPage(_ref) {
var index = _ref.index,
onPageChange = _ref.onPageChange,
_ref$scale = _ref.scale,
scale = _ref$scale === void 0 ? 1 : _ref$scale;
var _useInView = useInView({
threshold: 0.5
}),
_useInView2 = _slicedToArray(_useInView, 2),
ref = _useInView2[0],
inView = _useInView2[1];
useEffect(function () {
if (inView) onPageChange(index);
}, [inView]);
return React.createElement("div", {
ref: ref,
className: "preview-pdf-page",
"data-pdfpage": index
}, React.createElement(Page, {
pageIndex: index,
scale: scale
}));
};
var PDFViewer = function PDFViewer(_ref2) {
var file = _ref2.file,
totalPages = _ref2.totalPages,
onLoadSuccess = _ref2.onLoadSuccess,
onPageChange = _ref2.onPageChange;
return React.createElement(Document, {
rotate: file.rotate,
onLoadSuccess: onLoadSuccess,
file: file.url || "data:".concat(file.mimeType, ";base64,").concat(file.data),
options: {
cMapPacked: true,
cMapUrl: "//cdn.jsdelivr.net/npm/pdfjs-dist@".concat(pdfjs.version, "/cmaps/")
}
}, times(function (index) {
return React.createElement(PDFPage, {
key: index,
index: index,
onPageChange: onPageChange,
scale: Array.isArray(file.scale) ? file.scale[index] : file.scale
});
}, totalPages));
};
PDFViewer.propTypes = {
file: PropTypes.shape({
url: PropTypes.string,
data: PropTypes.string,
name: PropTypes.string,
mimeType: PropTypes.string
}),
totalPages: PropTypes.number,
onPageChange: PropTypes.func.isRequired,
onLoadSuccess: PropTypes.func.isRequired
};
/**
* Get the scale for this image.
*
* @param {Object} file
* @return {Number}
*/
var getScale = pathOr(1, ['scale', 0]);
/**
* Get the rotation for this image.
*
* @param {Object} file
* @return {Number}
*/
var getRotation = propOr(0, 'rotate');
var getResponseLikePDF = function getResponseLikePDF(imgRef) {
var _imgRef$current = imgRef.current,
clientWidth = _imgRef$current.clientWidth,
clientHeight = _imgRef$current.clientHeight;
return {
numPages: 1,
getPage: function getPage() {
return {
getViewport: function getViewport() {
return {
width: clientWidth,
height: clientHeight
};
}
};
}
};
};
/**
* `ImageViewer` react component.
*
* @param {Object} params
* @param {Object} params.file
* @param {String} params.file.url
* @param {String} params.file.data
* @param {Array} params.file.scale
* @param {Number} params.file.rotate
* @param {String} params.file.mimeType
* @param {Array} params.originalSizes
* @param {Function} params.onLoadSuccess
*/
var ImageViewer = function ImageViewer(_ref) {
var file = _ref.file,
originalSizes = _ref.originalSizes,
onLoadSuccess = _ref.onLoadSuccess;
var imgRef = useRef(null);
var _useState = useState(true),
_useState2 = _slicedToArray(_useState, 2),
isLoading = _useState2[0],
setLoading = _useState2[1];
var onLoad = function onLoad() {
// Execute the callback.
onLoadSuccess(getResponseLikePDF(imgRef)); // Set the loading state to false.
setLoading(false);
};
var scaleImage = !originalSizes[0] || !getScale(file) ? {} : {
width: originalSizes[0].width * getScale(file),
height: originalSizes[0].height * getScale(file)
};
return React.createElement("img", {
ref: imgRef,
onLoad: onLoad,
src: file.url || "data:".concat(file.mimeType, ";base64,").concat(file.data),
style: _objectSpread2({}, scaleImage, {
opacity: isLoading ? 0 : 1,
transform: "rotate(".concat(getRotation(file), "deg)")
})
});
};
ImageViewer.propTypes = {
file: PropTypes.shape({
url: PropTypes.string,
data: PropTypes.string,
scale: PropTypes.array,
rotate: PropTypes.number,
mimeType: PropTypes.string
}),
originalSizes: PropTypes.array,
onLoadSuccess: PropTypes.func.isRequired
};
var ViewportContent = function ViewportContent(_ref) {
var file = _ref.file,
totalPages = _ref.totalPages,
containerRef = _ref.containerRef,
onPageChange = _ref.onPageChange,
originalSizes = _ref.originalSizes,
onLoadSuccess = _ref.onLoadSuccess;
return React.createElement("div", {
ref: containerRef,
className: 'preview-content'
}, React.createElement("div", {
className: "preview-file"
}, isPDF(file) ? React.createElement(PDFViewer, {
file: file,
totalPages: totalPages,
onPageChange: onPageChange,
onLoadSuccess: onLoadSuccess
}) : React.createElement(ImageViewer, {
file: file,
onLoadSuccess: onLoadSuccess,
originalSizes: originalSizes
})));
};
ViewportContent.propTypes = {
file: PropTypes.shape({
url: PropTypes.string,
data: PropTypes.string,
name: PropTypes.string,
mimeType: PropTypes.string
}),
totalPages: PropTypes.number,
onPageChange: PropTypes.func.isRequired,
onLoadSuccess: PropTypes.func.isRequired
};
/**
* `FilePreviewer` react component.
*
* @param {Object} props
* @param {Function} props.onClick
* @param {Object} props.file
* @param {String} props.file.url
* @param {String} props.file.data
* @param {String} props.file.name
* @param {String} props.file.mimeType
* @return {Object}
*/
var FilePreviewer = function FilePreviewer(props) {
var _useState = useState(1),
_useState2 = _slicedToArray(_useState, 2),
totalPages = _useState2[0],
setTotalPages = _useState2[1];
var _useState3 = useState(0),
_useState4 = _slicedToArray(_useState3, 2),
currentPage = _useState4[0],
setCurrentPage = _useState4[1];
var _useState5 = useState(getFileProp(props)),
_useState6 = _slicedToArray(_useState5, 2),
file = _useState6[0],
setFile = _useState6[1];
var _useState7 = useState([]),
_useState8 = _slicedToArray(_useState7, 2),
originalSizes = _useState8[0],
setOriginalSizes = _useState8[1];
var _useState9 = useState(false),
_useState10 = _slicedToArray(_useState9, 2),
usingFitToScreen = _useState10[0],
setUsingFitToScreen = _useState10[1];
var viewportRef = useRef(null);
var containerRef = useRef(null);
var viewportSize = useViewportSize(viewportRef);
useEffect(function () {
// Reset all the attributes when the file prop changes.
setTotalPages(1);
setCurrentPage(0);
setOriginalSizes([]);
setFile(getFileProp(props));
}, [props.file]);
/**
* Handler. Scroll to the pervious page and update the index.
*
* @return {void}
*/
var onPageUp = function onPageUp() {
var previousIndex = clamp(0, totalPages, currentPage - 1);
setCurrentPage(previousIndex);
var previousPage = document.querySelector("div[data-pdfpage=\"".concat(previousIndex, "\"]")); // Scroll the viewport to the page position.
containerRef.current.scrollTop = previousPage.offsetTop - 10;
};
/**
* Handler. Scroll to the next page and update the index.
*
* @return {void}
*/
var onPageDown = function onPageDown() {
var nextIndex = clamp(0, totalPages, currentPage + 1);
setCurrentPage(nextIndex);
var nextPage = document.querySelector("div[data-pdfpage=\"".concat(nextIndex, "\"]")); // Scroll the viewport to the page position.
containerRef.current.scrollTop = nextPage.offsetTop - 10;
};
/**
* Handler. Scale all the pages or image
* up by a factor of 0.25.
*
* @return {void}
*/
var onZoomIn = function onZoomIn() {
setUsingFitToScreen(false);
setFile(setZoomIn(file));
};
/**
* Handler. Scale all the pages or image
* down by a factor of 0.25.
*
* @return {void}
*/
var onZoomOut = function onZoomOut() {
setUsingFitToScreen(false);
setFile(setZoomOut(file));
};
/**
* Handler. Rotate the PDF (all pages) or Image.
*
* @return {void}
*/
var onRotate = function onRotate() {
setFile(setNewRotation(file));
};
/**
* Handler. Fit to screen.
*
* (This activates the "using fit to screen" mode, which
* makes the document or image resize based on the viewport size.)
*
* @return {void}
*/
var onFitToScreen = function onFitToScreen() {
setUsingFitToScreen(true); // Get the "fit to screen" scale.
var newScale = originalSizes.map(function (originalSize) {
return getFitToWidthScale(viewportSize, originalSize);
});
setFile(function (prevValue) {
return assoc('scale', newScale, prevValue);
});
};
/**
* Handler. Download the current file, it can be a
* PDF or Image, as `url` or `base64` content.
*
* @return {void}
*/
var onDownload = function onDownload() {
var url = file.url || "data:".concat(file.mimeType, ";base64,").concat(file.data);
return saveFile(url, getFilename(file));
};
/**
* Handler. Callback after the PDF gets
* processed successfully by `react-pdf`.
*
* @param {Object} file
* @return {void}
*/
var onLoadSuccess = function onLoadSuccess(file) {
// Wait until the original sizes gets calculated.
var promises = times( /*#__PURE__*/function () {
var _ref = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee(i) {
var page;
return regeneratorRuntime.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
_context.next = 2;
return file.getPage(i + 1);
case 2:
page = _context.sent;
return _context.abrupt("return", pick(['width', 'height'], page.getViewport({
scale: 1
})));
case 4:
case "end":
return _context.stop();
}
}
}, _callee);
}));
return function (_x) {
return _ref.apply(this, arguments);
};
}(), file.numPages); // Set the original sizes for this file.
Promise.all(promises).then(setOriginalSizes);
setTotalPages(file.numPages);
setUsingFitToScreen(true);
}; // Set an effect to process the file resizing when the
// viewport sizes changes and it's using "fit to screen".
useEffect(function () {
// Check if it's using "fit to screen".
if (usingFitToScreen) {
// Get the "fit to screen" scale.
var newScale = originalSizes.map(function (originalSize) {
return getFitToWidthScale(viewportSize, originalSize);
}); // Update the scale.
setFile(function (prevValue) {
return assoc('scale', newScale, prevValue);
});
}
return function () {};
}, [usingFitToScreen, originalSizes, viewportSize]);
return React.createElement("div", {
ref: viewportRef,
onClick: props.onClick,
className: "preview-wrapper"
}, React.createElement(PreviewBar, {
onPageUp: onPageUp,
onRotate: onRotate,
totalPages: totalPages,
onDownload: onDownload,
onPageDown: onPageDown,
currentPage: currentPage,
hidden: props.hideControls
}), React.createElement(ViewportContent, {
file: file,
totalPages: totalPages,
containerRef: containerRef,
originalSizes: originalSizes,
onPageChange: setCurrentPage,
onLoadSuccess: onLoadSuccess
}), React.createElement(ViewportControl, {
onZoomIn: onZoomIn,
onZoomOut: onZoomOut,
onFitToScreen: onFitToScreen,
hidden: props.hideControls
}));
};
FilePreviewer.propTypes = {
file: PropTypes.shape({
url: PropTypes.string,
mimeType: PropTypes.string,
data: PropTypes.string,
name: PropTypes.string
}).isRequired,
onClick: PropTypes.func,
hideControls: PropTypes.bool
};
FilePreviewer.defaultProps = {
onClick: function onClick() {}
};
var RenderPDF = function RenderPDF(_ref) {
var src = _ref.src;
return React.createElement(Document, {
file: src,
options: {
cMapPacked: true,
cMapUrl: "//cdn.jsdelivr.net/npm/pdfjs-dist@".concat(pdfjs.version, "/cmaps/")
}
}, React.createElement(Page, {
pageNumber: 1,
width: 80,
height: 85
}));
};
/**
* `FilePreviewerThumbnail` react component.
*
* @param {Object} props
* @param {Object} props.file
* @param {String} props.file.url
* @param {String} props.file.data
* @param {String} props.file.mimeType
* @param {Function} props.onClick
* @return {Object}
*/
var FilePreviewerThumbnail = function FilePreviewerThumbnail(props) {
var file = getFileProp(props);
var fileSrc = file.url || "data:".concat(file.mimeType, ";base64,").concat(file.data);
return React.createElement("div", {
style: props.style,
onClick: props.onClick,
className: "thumbnail-wrapper"
}, isPDF(file) ? React.createElement(RenderPDF, {
src: fileSrc
}) : React.createElement("img", {
src: fileSrc
}));
};
FilePreviewerThumbnail.propTypes = {
file: PropTypes.shape({
url: PropTypes.string,
mimeType: PropTypes.string,
data: PropTypes.string
}).isRequired,
style: PropTypes.object,
onClick: PropTypes.func
};
FilePreviewerThumbnail.defaultProps = {
style: {},
onClick: function onClick() {}
};
export default FilePreviewer;
export { FilePreviewerThumbnail };
//# sourceMappingURL=index.es.js.map