/* globals fileUploadHandler, Handlebars, fileUpload, modal, t */ /* exported fileUpload */ import s from 'underscore.string'; const readAsDataURL = (file, callback) => { const reader = new FileReader(); reader.onload = (e) => callback(e.target.result, file); return reader.readAsDataURL(file); }; const showUploadPreview = (file, callback) => { // If greater then 10MB don't try and show a preview if (file.file.size > (10 * 1000000)) { return callback(file, null); } if (file.file.type == null) { return callback(file, null); } if ((file.file.type.indexOf('audio') > -1) || (file.file.type.indexOf('video') > -1) || (file.file.type.indexOf('image') > -1)) { file.type = file.file.type.split('/')[0]; return readAsDataURL(file.file, (content) => callback(file, content)); } return callback(file, null); }; const getAudioUploadPreview = (file, preview) => `\
`; const getVideoUploadPreview = (file, preview) => `\
`; const getImageUploadPreview = (file, preview) => `\
`; const formatBytes = (bytes, decimals) => { if (bytes === 0) { return '0 Bytes'; } const k = 1000; const dm = (decimals + 1) || 3; const sizes = [ 'Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', ]; const i = Math.floor(Math.log(bytes) / Math.log(k)); return `${ parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) } ${ sizes[i] }`; }; const getGenericUploadPreview = (file) => `\
${ Handlebars._escape(file.name) } - ${ formatBytes(file.file.size) }
`; const getUploadPreview = async(file, preview) => { if (file.type === 'audio') { return getAudioUploadPreview(file, preview); } if (file.type === 'video') { return getVideoUploadPreview(file, preview); } const isImageFormatSupported = () => new Promise((resolve) => { const element = document.createElement('img'); element.onload = () => resolve(true); element.onerror = () => resolve(false); element.src = preview; }); if (file.type === 'image' && await isImageFormatSupported()) { return getImageUploadPreview(file, preview); } return getGenericUploadPreview(file, preview); }; fileUpload = async(files) => { files = [].concat(files); const roomId = Session.get('openedRoom'); const uploadNextFile = () => { const file = files.pop(); if (!file) { modal.close(); return; } if (!RocketChat.fileUploadIsValidContentType(file.file.type)) { modal.open({ title: t('FileUpload_MediaType_NotAccepted'), text: file.file.type || `*.${ s.strRightBack(file.file.name, '.') }`, type: 'error', timer: 3000, }); return; } if (file.file.size === 0) { modal.open({ title: t('FileUpload_File_Empty'), type: 'error', timer: 1000, }); return; } showUploadPreview(file, async(file, preview) => modal.open({ title: t('Upload_file_question'), text: await getUploadPreview(file, preview), showCancelButton: true, closeOnConfirm: false, closeOnCancel: false, confirmButtonText: t('Send'), cancelButtonText: t('Cancel'), html: true, onRendered: () => $('#file-name').focus(), }, (isConfirm) => { if (!isConfirm) { return; } const record = { name: document.getElementById('file-name').value || file.name || file.file.name, size: file.file.size, type: file.file.type, rid: roomId, description: document.getElementById('file-description').value, }; const upload = fileUploadHandler('Uploads', record, file.file); uploadNextFile(); const uploads = Session.get('uploading') || []; uploads.push({ id: upload.id, name: upload.getFileName(), percentage: 0, }); Session.set('uploading', uploads); upload.onProgress = (progress) => { const uploads = Session.get('uploading') || []; uploads.filter((u) => u.id === upload.id).forEach((u) => { u.percentage = Math.round(progress * 100) || 0; }); Session.set('uploading', uploads); }; upload.start((error, file, storage) => { if (error) { const uploads = Session.get('uploading') || []; uploads.filter((u) => u.id === upload.id).forEach((u) => { u.error = error.message; u.percentage = 0; }); Session.set('uploading', uploads); return; } if (!file) { return; } Meteor.call('sendFileMessage', roomId, storage, file, () => { Meteor.setTimeout(() => { const uploads = Session.get('uploading') || []; Session.set('uploading', uploads.filter((u) => u.id !== upload.id)); }, 2000); }); }); Tracker.autorun((computation) => { const isCanceling = Session.get(`uploading-cancel-${ upload.id }`); if (!isCanceling) { return; } computation.stop(); upload.stop(); const uploads = Session.get('uploading') || {}; Session.set('uploading', uploads.filter((u) => u.id !== upload.id)); }); })); }; uploadNextFile(); };