[NEW] PDF message attachment preview (#10519)

Preview of PDF files
Rendering first page on a canvas using a `Worker` on client side

Closes #2741
![pdf-preview](https://user-images.githubusercontent.com/8899152/38177213-db9a42f8-361a-11e8-922b-328a19b5324a.png)
pull/12337/head^2
Karan Bedi 7 years ago committed by Guilherme Gazzo
parent f31eca3b67
commit 9ac5b552ed
  1. 3
      .eslintrc
  2. 1
      .meteor/packages
  3. 6541
      package-lock.json
  4. 2
      package.json
  5. 8
      packages/rocketchat-message-attachments/client/messageAttachment.html
  6. 7
      packages/rocketchat-message-attachments/client/messageAttachment.js
  7. 10
      packages/rocketchat-message-attachments/client/stylesheets/messageAttachments.css
  8. 30
      packages/rocketchat-ui-message/client/message.js
  9. 2
      packages/rocketchat-ui-message/package.js

@ -1,5 +1,6 @@
{
"extends": ["@rocket.chat/eslint-config"],
"parser": "babel-eslint",
"globals": {
"__meteor_runtime_config__" : false,
"AccountBox" : false,
@ -30,7 +31,7 @@
"LivechatDepartment" : false,
"LivechatDepartmentAgents" : false,
"livechatManagerRoutes" : true,
"LivechatMonitoring" : false,
"LivechatMonitoring" : false,
"LivechatPageVisited" : false,
"LivechatTrigger" : false,
"Logger" : false,

@ -195,7 +195,6 @@ rocketchat:e2e
rocketchat:blockstack
rocketchat:version-check
rocketchat:search
chatpal:search
rocketchat:lazy-load

6541
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -91,6 +91,7 @@
"@octokit/rest": "^15.8.1",
"@rocket.chat/eslint-config": "^0.1.2",
"autoprefixer": "^8.6.0",
"babel-eslint": "^10.0.1",
"babel-mocha-es6-compiler": "^0.1.0",
"babel-plugin-array-includes": "^2.0.3",
"chimp": "^0.51.1",
@ -171,6 +172,7 @@
"moment-timezone": "^0.5.17",
"node-dogstatsd": "^0.0.7",
"object-path": "^0.11.4",
"pdfjs-dist": "^2.0.489",
"photoswipe": "^4.1.2",
"poplib": "^0.1.7",
"prom-client": "^11.0.0",

@ -130,6 +130,14 @@
{{/unless}}
{{/if}}
{{#if isPDF}}
{{#unless collapsed}}
<div id="js-loading-{{fileId}}" class="attachment-pdf-loading">
{{> icon block="rc-input__icon-svg" icon="loading"}}
</div>
<canvas id="{{fileId}}" class="attachment-canvas"></canvas>
{{/unless}}
{{/if}}
{{#if fields}}
{{#unless collapsed}}
<div class="attachment-fields">

@ -69,4 +69,11 @@ Template.messageAttachment.helpers({
isFile() {
return this.type === 'file';
},
isPDF() {
if (this.type === 'file' && this.title_link.endsWith('.pdf') && Template.parentData().file) {
this.fileId = Template.parentData().file._id;
return true;
}
return false;
},
});

@ -145,6 +145,16 @@ html.rtl .attachment {
border-radius: 5px;
}
& .attachment-canvas {
display: none;
}
& .attachment-pdf-loading {
display: none;
font-size: 1.5rem;
}
& .actions-container {
margin-top: 6px;
}

@ -3,6 +3,31 @@ import _ from 'underscore';
import moment from 'moment';
import { DateFormat } from 'meteor/rocketchat:lib';
async function renderPdfToCanvas(canvasId, pdfLink) {
if (!pdfLink || !pdfLink.endsWith('.pdf')) { return; }
const canvas = document.getElementById(canvasId);
if (!canvas) { return; }
const pdfjsLib = await import('pdfjs-dist');
pdfjsLib.GlobalWorkerOptions.workerSrc = `${ Meteor.absoluteUrl() }node_modules/pdfjs-dist/build/pdf.worker.js`;
const loader = document.getElementById('js-loading-${canvasId}');
if (loader) { loader.style.display = 'block'; }
const pdf = await pdfjsLib.getDocument(pdfLink);
const page = await pdf.getPage(1);
const scale = 0.5;
const viewport = page.getViewport(scale);
const context = canvas.getContext('2d');
canvas.height = viewport.height;
canvas.width = viewport.width;
page.render({
canvasContext: context,
viewport,
});
if (loader) { loader.style.display = 'none'; }
canvas.style.maxWidth = '-webkit-fill-available';
canvas.style.maxWidth = '-moz-available';
canvas.style.display = 'block';
}
Template.message.helpers({
encodeURI(text) {
return encodeURI(text);
@ -364,7 +389,10 @@ Template.message.onCreated(function() {
});
Template.message.onViewRendered = function(context) {
return this._domrange.onAttached(function(domRange) {
return this._domrange.onAttached((domRange) => {
if (context.file && context.file.type === 'application/pdf') {
Meteor.defer(() => { renderPdfToCanvas(context.file._id, context.attachments[0].title_link); });
}
const currentNode = domRange.lastNode();
const currentDataset = currentNode.dataset;
const getPreviousSentMessage = (currentNode) => {

@ -44,5 +44,7 @@ Package.onUse(function(api) {
api.addFiles('startup/messageBoxActions.js', 'client');
api.addAssets('../../node_modules/pdfjs-dist/build/pdf.worker.js', 'client');
api.export('renderMessageBody');
});

Loading…
Cancel
Save