[apply-toast-shared-notes] - Removed some of the comments and separated toast controller

This commit is contained in:
GuiLeme 2022-08-09 12:24:44 -03:00
parent 93b51ded53
commit 246153e62c
4 changed files with 330 additions and 519 deletions

View File

@ -0,0 +1,320 @@
import Presentations from '/imports/api/presentations';
import React from 'react';
import { useTracker } from 'meteor/react-meteor-data';
import Icon from '/imports/ui/components/common/icon/component';
import { makeCall } from '/imports/ui/services/api';
import Styled from '/imports/ui/components/presentation/presentation-uploader/styles';
import { toast } from 'react-toastify';
import { defineMessages } from 'react-intl';
import _ from 'lodash';
import { UploadingPresentations } from '/imports/api/presentations';
const intlMessages = defineMessages({
item: {
id: 'app.presentationUploder.item',
description: 'single item label',
},
itemPlural: {
id: 'app.presentationUploder.itemPlural',
description: 'plural item label',
},
uploading: {
id: 'app.presentationUploder.uploading',
description: 'uploading label for toast notification',
},
uploadStatus: {
id: 'app.presentationUploder.uploadStatus',
description: 'upload status for toast notification',
},
completed: {
id: 'app.presentationUploder.completed',
description: 'uploads complete label for toast notification',
},
GENERATING_THUMBNAIL: {
id: 'app.presentationUploder.conversion.generatingThumbnail',
description: 'indicatess that it is generating thumbnails',
},
GENERATING_SVGIMAGES: {
id: 'app.presentationUploder.conversion.generatingSvg',
description: 'warns that it is generating svg images',
},
GENERATED_SLIDE: {
id: 'app.presentationUploder.conversion.generatedSlides',
description: 'warns that were slides generated',
},
PAGE_COUNT_EXCEEDED: {
id: 'app.presentationUploder.conversion.pageCountExceeded',
description: 'warns the user that the conversion failed because of the page count',
},
PDF_HAS_BIG_PAGE: {
id: 'app.presentationUploder.conversion.pdfHasBigPage',
description: 'warns the user that the conversion failed because of the pdf page siz that exceeds the allowed limit',
},
OFFICE_DOC_CONVERSION_INVALID: {
id: 'app.presentationUploder.conversion.officeDocConversionInvalid',
description: '',
},
OFFICE_DOC_CONVERSION_FAILED: {
id: 'app.presentationUploder.conversion.officeDocConversionFailed',
description: 'warns the user that the conversion failed because of wrong office file',
},
UNSUPPORTED_DOCUMENT: {
id: 'app.presentationUploder.conversion.unsupportedDocument',
description: 'warns the user that the file extension is not supported',
},
fileToUpload: {
id: 'app.presentationUploder.fileToUpload',
description: 'message used in the file selected for upload',
},
uploadProcess: {
id: 'app.presentationUploder.upload.progress',
description: 'message that indicates the percentage of the upload',
},
badConnectionError: {
id: 'app.presentationUploder.connectionClosedError',
description: 'message indicating that the connection was closed',
},
conversionProcessingSlides: {
id: 'app.presentationUploder.conversion.conversionProcessingSlides',
description: 'indicates how many slides were converted',
},
genericError: {
id: 'app.presentationUploder.genericError',
description: 'generic error while uploading/converting',
},
genericConversionStatus: {
id: 'app.presentationUploder.conversion.genericConversionStatus',
description: 'indicates that file is being converted',
},
});
function renderPresentationItemStatus(item, intl) {
if ((("progress" in item) && item.progress === 0) || (("conversion" in item && !item.conversion.done && !item.conversion.error))) {
return intl.formatMessage(intlMessages.fileToUpload);
}
if (("progress" in item) && item.progress < 100 && !("conversion" in item)) {
return intl.formatMessage(intlMessages.uploadProcess, {
0: Math.floor(item.progress).toString(),
});
}
const constraint = {};
if (("upload" in item) && (item.upload.done && item.upload.error)) {
if (item.conversion.status === 'FILE_TOO_LARGE') {
constraint['0'] = ((item.conversion.maxFileSize) / 1000 / 1000).toFixed(2);
}
if (item.progress < 100) {
const errorMessage = intlMessages.badConnectionError;
return intl.formatMessage(errorMessage);
}
const errorMessage = intlMessages[item.upload.status] || intlMessages.genericError;
return intl.formatMessage(errorMessage, constraint);
}
if (("conversion" in item) && (!item.conversion.done && item.conversion.error)) {
const errorMessage = intlMessages[item.conversion.status] || intlMessages.genericConversionStatus;
switch (item.conversion.status) {
case 'PAGE_COUNT_EXCEEDED':
constraint['0'] = item.conversion.maxNumberPages;
break;
case 'PDF_HAS_BIG_PAGE':
constraint['0'] = (item.conversion.bigPageSize / 1000 / 1000).toFixed(2);
break;
default:
break;
}
return intl.formatMessage(errorMessage, constraint);
}
if ((("conversion" in item) && (!item.conversion.done && !item.conversion.error)) || (("progress" in item) && item.progress == 100)) {
let conversionStatusMessage
if ("conversion" in item) {
if (item.conversion.pagesCompleted < item.conversion.numPages) {
return intl.formatMessage(intlMessages.conversionProcessingSlides, {
0: item.conversion.pagesCompleted,
1: item.conversion.numPages,
});
}
conversionStatusMessage = intlMessages[item.conversion.status]
|| intlMessages.genericConversionStatus;
} else {
conversionStatusMessage = intlMessages.genericConversionStatus;
}
return intl.formatMessage(conversionStatusMessage);
}
return null;
}
function renderToastItem(item, intl) {
const isUploading = ("progress" in item) && item.progress <= 100;
const isConverting = ("conversion" in item) && !item.conversion.done;
const hasError = ((("conversion" in item) && item.conversion.error) || (("upload" in item) && item.upload.error));
const isProcessing = (isUploading || isConverting) && !hasError;
let icon = isProcessing ? 'blank' : 'check';
if (hasError) icon = 'circle_close';
return (
<Styled.UploadRow
key={item.tmpPresId}
onClick={() => {
if (hasError || isProcessing) Session.set('showUploadPresentationView', true);
}}
>
<Styled.FileLine>
<span>
<Icon iconName="file" />
</span>
<Styled.ToastFileName>
<span>{item.filename || item.name}</span>
</Styled.ToastFileName>
<Styled.StatusIcon>
<Styled.ToastItemIcon
done={!isProcessing && !hasError}
error={hasError}
loading={ isProcessing }
iconName={icon}
/>
</Styled.StatusIcon>
</Styled.FileLine>
<Styled.StatusInfo>
<Styled.StatusInfoSpan data-test="presentationStatusInfo" styles={hasError ? 'error' : 'info'}>
{renderPresentationItemStatus(item, intl)}
</Styled.StatusInfoSpan>
</Styled.StatusInfo>
</Styled.UploadRow>
);
}
const renderToastList = (presentations, intl) => {
let converted = 0;
let presentationsSorted = presentations
.sort((a, b) => a.uploadTimestamp - b.uploadTimestamp)
.sort((a, b) => {
const presADone = a.conversion ? a.conversion.done : false;
const presBDone = b.conversion ? b.conversion.done : false;
return presADone - presBDone
});
presentationsSorted
.forEach((p) => {
const presDone = p.conversion ? p.conversion.done : false;
if (presDone) converted += 1;
return p;
});
let toastHeading = '';
const itemLabel = presentationsSorted.length > 1
? intl.formatMessage(intlMessages.itemPlural)
: intl.formatMessage(intlMessages.item);
if (converted === 0) {
toastHeading = intl.formatMessage(intlMessages.uploading, {
0: presentationsSorted.length,
1: itemLabel,
});
}
if (converted > 0 && converted !== presentationsSorted.length) {
toastHeading = intl.formatMessage(intlMessages.uploadStatus, {
0: converted,
1: presentationsSorted.length,
});
}
if (converted === presentationsSorted.length) {
toastHeading = intl.formatMessage(intlMessages.completed, {
0: converted,
});
}
return (
<Styled.ToastWrapper>
<Styled.UploadToastHeader>
<Styled.UploadIcon iconName="upload" />
<Styled.UploadToastTitle>{toastHeading}</Styled.UploadToastTitle>
</Styled.UploadToastHeader>
<Styled.InnerToast>
<div>
<div>
{presentationsSorted.map((item) => renderToastItem(item, intl))}
</div>
</div>
</Styled.InnerToast>
</Styled.ToastWrapper>
);
}
function handleDismissToast(toastId) {
return toast.dismiss(toastId);
}
export const ToastController = ({ intl }) => {
useTracker(() => {
const presentationsRenderedFalseAndConversionFalse = Presentations.find({ $or: [{renderedInToast: false}, {"conversion.done": false}] }).fetch();
const convertingPresentations = presentationsRenderedFalseAndConversionFalse.filter(p => !p.renderedInToast )
let tmpIdconvertingPresentations = presentationsRenderedFalseAndConversionFalse.filter(p => !p.conversion.done)
.map(p => p.tmpPresId)
// tmpIdconvertingPresentations = UploadingPresentations.find({}).fetch().filter(p => tmpIdconvertingPresentations.includes(p.tmpPresId))
// .map(p => p.tmpPresId)
UploadingPresentations.find({}).fetch().filter(p => tmpIdconvertingPresentations.includes(p.tmpPresId))
.map(p => UploadingPresentations.remove({tmpPresId: p.tmpPresId}));
// Remove all presentations from the uploading collection if they are already
// converting.
// UploadingPresentations.remove({tmpPresId: {$all: tmpIdconvertingPresentations}});
const uploadingPresentations = UploadingPresentations.find().fetch();
let presentationsToConvert = convertingPresentations.concat(uploadingPresentations);
let activeToast = Session.get("presentationUploaderToastId");
const showToast = presentationsToConvert.length > 0;
if (showToast && !activeToast) {
activeToast = toast.info(() => renderToastList(presentationsToConvert, intl), {
hideProgressBar: true,
autoClose: false,
newestOnTop: true,
closeOnClick: true,
onClose: () => {
Session.set("presentationUploaderToastId", null);
presentationsToConvert = [];
},
});
Session.set("presentationUploaderToastId", activeToast);
} else if (!showToast && activeToast) {
handleDismissToast(activeToast);
Session.set("presentationUploaderToastId", null);
} else {
toast.update(activeToast, {
render: renderToastList(presentationsToConvert, intl),
});
}
let tmpPresIdListToSetAsRendered = presentationsToConvert.filter(p =>
("conversion" in p && (p.conversion.done || p.conversion.error)))
tmpPresIdListToSetAsRendered = tmpPresIdListToSetAsRendered.map(p => p.tmpPresId);
makeCall('setPresentationRenderedInToast', tmpPresIdListToSetAsRendered);
}, [])
return null;
}
export default {
handleDismissToast,
renderPresentationItemStatus,
}

View File

@ -1,7 +1,7 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { defineMessages, injectIntl } from 'react-intl';
import { ToastController } from './service';
import { ToastController } from '/imports/ui/components/presentation/presentation-toast/presentation-toast-controller';
import { TAB } from '/imports/utils/keyCodes';
import deviceInfo from '/imports/utils/deviceInfo';
import Button from '/imports/ui/components/common/button/component';
@ -385,32 +385,12 @@ class PresentationUploader extends Component {
const selected = propPresentations.filter((p) => p.isCurrent);
if (selected.length > 0) Session.set('selectedToBeNextCurrent', selected[0].id);
}
const toastId = Session.get("presentationUploaderToastId");
// toast.update(this.toastId, {
// render: this.renderToastList(),
// });
// }
// if (this.exportToastId) {
// if (!prevProps.isOpen && isOpen) {
// this.handleDismissToast(this.exportToastId);
// }
//
// toast.update(this.exportToastId, {
// render: this.renderExportToast(),
// });
// }
}
componentWillUnmount() {
Session.set('showUploadPresentationView', false);
}
// handleDismissToast(toastId) {
// return toast.dismiss(toastId);
// }
handleFiledrop(files, files2) {
const { fileValidMimeTypes, intl } = this.props;
const { toUploadCount } = this.state;
@ -553,7 +533,7 @@ class PresentationUploader extends Component {
this.updateFileKey(id, key, applyValue, '$apply');
}
handleConfirm(hasNewUpload) {
handleConfirm() {
const {
handleSave,
selectedToBeNextCurrent,
@ -576,18 +556,6 @@ class PresentationUploader extends Component {
}
});
// if (hasNewUpload) {
// this.toastId = toast.info(this.renderToastList(), {
// hideProgressBar: true,
// autoClose: false,
// newestOnTop: true,
// closeOnClick: true,
// onClose: () => {
// this.toastId = null;
// },
// });
// }
if (!disableActions) {
Session.set('showUploadPresentationView', false);
return handleSave(presentationsToSave)
@ -711,47 +679,6 @@ class PresentationUploader extends Component {
});
}
// renderToastItem(item) {
// const isUploading = !item.upload.done && item.upload.progress > 0;
// const isConverting = !item.conversion.done && item.upload.done;
// const hasError = item.conversion.error || item.upload.error;
// const isProcessing = (isUploading || isConverting) && !hasError;
// let icon = isProcessing ? 'blank' : 'check';
// if (hasError) icon = 'circle_close';
// return (
// <Styled.UploadRow
// key={item.id}
// onClick={() => {
// if (hasError || isProcessing) Session.set('showUploadPresentationView', true);
// }}
// >
// <Styled.FileLine>
// <span>
// <Icon iconName="file" />
// </span>
// <Styled.ToastFileName>
// <span>{item.filename}</span>
// </Styled.ToastFileName>
// <Styled.StatusIcon>
// <Styled.ToastItemIcon
// done={!isProcessing && !hasError}
// error={hasError}
// loading={isProcessing}
// iconName={icon}
// />
// </Styled.StatusIcon>
// </Styled.FileLine>
// <Styled.StatusInfo>
// <Styled.StatusInfoSpan data-test="presentationStatusInfo" styles={hasError ? 'error' : 'info'}>
// {this.renderPresentationItemStatus(item)}
// </Styled.StatusInfoSpan>
// </Styled.StatusInfo>
// </Styled.UploadRow>
// );
// }
renderExtraHint() {
const {
intl,
@ -826,70 +753,6 @@ class PresentationUploader extends Component {
);
}
// renderToastList() {
// const { presentations, toUploadCount } = this.state;
// if (toUploadCount === 0) {
// return this.handleDismissToast(this.toastId);
// }
// const { intl } = this.props;
// let converted = 0;
// let presentationsSorted = presentations
// .filter((p) => (p.upload.progress || p.conversion.status) && p.file)
// .sort((a, b) => a.uploadTimestamp - b.uploadTimestamp)
// .sort((a, b) => a.conversion.done - b.conversion.done);
// presentationsSorted = presentationsSorted
// .splice(0, toUploadCount)
// .map((p) => {
// if (p.conversion.done) converted += 1;
// return p;
// });
// let toastHeading = '';
// const itemLabel = presentationsSorted.length > 1
// ? intl.formatMessage(intlMessages.itemPlural)
// : intl.formatMessage(intlMessages.item);
// if (converted === 0) {
// toastHeading = intl.formatMessage(intlMessages.uploading, {
// 0: presentationsSorted.length,
// 1: itemLabel,
// });
// }
// if (converted > 0 && converted !== presentationsSorted.length) {
// toastHeading = intl.formatMessage(intlMessages.uploadStatus, {
// 0: converted,
// 1: presentationsSorted.length,
// });
// }
// if (converted === presentationsSorted.length) {
// toastHeading = intl.formatMessage(intlMessages.completed, {
// 0: converted,
// });
// }
// return (
// <Styled.ToastWrapper>
// <Styled.UploadToastHeader>
// <Styled.UploadIcon iconName="upload" />
// <Styled.UploadToastTitle>{toastHeading}</Styled.UploadToastTitle>
// </Styled.UploadToastHeader>
// <Styled.InnerToast>
// <div>
// <div>
// {presentationsSorted.map((item) => this.renderToastItem(item))}
// </div>
// </div>
// </Styled.InnerToast>
// </Styled.ToastWrapper>
// );
// }
renderExportToast() {
const { intl } = this.props;
const { presExporting } = this.state;
@ -961,7 +824,9 @@ class PresentationUploader extends Component {
}
return (
<Styled.UploadRow>
<Styled.UploadRow
key={item.tmpPresId}
>
<Styled.FileLine>
<span>
<Icon iconName="file" />
@ -1194,67 +1059,6 @@ class PresentationUploader extends Component {
);
}
// renderPresentationItemStatus(item) {
// const { intl } = this.props;
// if (!item.upload.done && item.upload.progress === 0) {
// return intl.formatMessage(intlMessages.fileToUpload);
// }
// if (!item.upload.done && !item.upload.error) {
// return intl.formatMessage(intlMessages.uploadProcess, {
// 0: Math.floor(item.upload.progress).toString(),
// });
// }
// const constraint = {};
// if (item.upload.done && item.upload.error) {
// if (item.conversion.status === 'FILE_TOO_LARGE') {
// constraint['0'] = ((item.conversion.maxFileSize) / 1000 / 1000).toFixed(2);
// }
// if (item.upload.progress < 100) {
// const errorMessage = intlMessages.badConnectionError;
// return intl.formatMessage(errorMessage);
// }
// const errorMessage = intlMessages[item.upload.status] || intlMessages.genericError;
// return intl.formatMessage(errorMessage, constraint);
// }
// if (!item.conversion.done && item.conversion.error) {
// const errorMessage = intlMessages[item.conversion.status] || intlMessages.genericConversionStatus;
// switch (item.conversion.status) {
// case 'PAGE_COUNT_EXCEEDED':
// constraint['0'] = item.conversion.maxNumberPages;
// break;
// case 'PDF_HAS_BIG_PAGE':
// constraint['0'] = (item.conversion.bigPageSize / 1000 / 1000).toFixed(2);
// break;
// default:
// break;
// }
// return intl.formatMessage(errorMessage, constraint);
// }
// if (!item.conversion.done && !item.conversion.error) {
// if (item.conversion.pagesCompleted < item.conversion.numPages) {
// return intl.formatMessage(intlMessages.conversionProcessingSlides, {
// 0: item.conversion.pagesCompleted,
// 1: item.conversion.numPages,
// });
// }
// const conversionStatusMessage = intlMessages[item.conversion.status]
// || intlMessages.genericConversionStatus;
// return intl.formatMessage(conversionStatusMessage);
// }
// return null;
// }
render() {
const {
isOpen,
@ -1288,7 +1092,7 @@ class PresentationUploader extends Component {
<Styled.ConfirmButton
data-test="confirmManagePresentation"
color="primary"
onClick={() => this.handleConfirm(hasNewUpload)}
onClick={() => this.handleConfirm()}
disabled={disableActions}
label={hasNewUpload
? intl.formatMessage(intlMessages.uploadLabel)
@ -1301,7 +1105,7 @@ class PresentationUploader extends Component {
{`${intl.formatMessage(intlMessages.message)}`}
{fileUploadConstraintsHint ? this.renderExtraHint() : null}
</Styled.ModalHint>
{this.renderPresentationList()}
{this.renderPresentationList()}
<Styled.ExportHint>
{intl.formatMessage(intlMessages.exportHint)}
</Styled.ExportHint>

View File

@ -4,6 +4,7 @@ import { withTracker } from 'meteor/react-meteor-data';
import ErrorBoundary from '/imports/ui/components/common/error-boundary/component';
import FallbackModal from '/imports/ui/components/common/fallback-errors/fallback-modal/component';
import Service from './service';
import PresUploaderController from '/imports/ui/components/presentation/presentation-toast/presentation-toast-controller';
import PresentationUploader from './component';
import { UsersContext } from '/imports/ui/components/components-data/users-context/context';
import Auth from '/imports/ui/services/auth';
@ -40,9 +41,9 @@ export default withTracker(() => {
fileValidMimeTypes: PRESENTATION_CONFIG.uploadValidMimeTypes,
allowDownloadable: PRESENTATION_CONFIG.allowDownloadable,
handleSave: Service.handleSavePresentation,
handleDismissToast: Service.handleDismissToast,
handleDismissToast: PresUploaderController.handleDismissToast,
renderToastList: Service.renderToastList,
renderPresentationItemStatus: Service.renderPresentationItemStatus,
renderPresentationItemStatus: PresUploaderController.renderPresentationItemStatus,
dispatchDisableDownloadable,
dispatchEnableDownloadable,
dispatchTogglePresentationDownloadable,

View File

@ -1,16 +1,10 @@
import Presentations from '/imports/api/presentations';
import React, { useEffect, useState } from 'react';
import { useTracker } from 'meteor/react-meteor-data';
import Icon from '/imports/ui/components/common/icon/component';
import PresentationUploadToken from '/imports/api/presentation-upload-token';
import Auth from '/imports/ui/services/auth';
import Poll from '/imports/api/polls/';
import { Meteor } from 'meteor/meteor';
import { defineMessages, injectIntl, useIntl } from 'react-intl';
import { makeCall } from '/imports/ui/services/api';
import logger from '/imports/startup/client/logger';
import Styled from './styles';
import { toast } from 'react-toastify';
import _ from 'lodash';
import update from 'immutability-helper';
import { Random } from 'meteor/random';
@ -20,87 +14,6 @@ const CONVERSION_TIMEOUT = 300000;
const TOKEN_TIMEOUT = 5000;
const PRESENTATION_CONFIG = Meteor.settings.public.presentation;
const intlMessages = defineMessages({
item: {
id: 'app.presentationUploder.item',
description: 'single item label',
},
itemPlural: {
id: 'app.presentationUploder.itemPlural',
description: 'plural item label',
},
uploading: {
id: 'app.presentationUploder.uploading',
description: 'uploading label for toast notification',
},
uploadStatus: {
id: 'app.presentationUploder.uploadStatus',
description: 'upload status for toast notification',
},
completed: {
id: 'app.presentationUploder.completed',
description: 'uploads complete label for toast notification',
},
GENERATING_THUMBNAIL: {
id: 'app.presentationUploder.conversion.generatingThumbnail',
description: 'indicatess that it is generating thumbnails',
},
GENERATING_SVGIMAGES: {
id: 'app.presentationUploder.conversion.generatingSvg',
description: 'warns that it is generating svg images',
},
GENERATED_SLIDE: {
id: 'app.presentationUploder.conversion.generatedSlides',
description: 'warns that were slides generated',
},
PAGE_COUNT_EXCEEDED: {
id: 'app.presentationUploder.conversion.pageCountExceeded',
description: 'warns the user that the conversion failed because of the page count',
},
PDF_HAS_BIG_PAGE: {
id: 'app.presentationUploder.conversion.pdfHasBigPage',
description: 'warns the user that the conversion failed because of the pdf page siz that exceeds the allowed limit',
},
OFFICE_DOC_CONVERSION_INVALID: {
id: 'app.presentationUploder.conversion.officeDocConversionInvalid',
description: '',
},
OFFICE_DOC_CONVERSION_FAILED: {
id: 'app.presentationUploder.conversion.officeDocConversionFailed',
description: 'warns the user that the conversion failed because of wrong office file',
},
UNSUPPORTED_DOCUMENT: {
id: 'app.presentationUploder.conversion.unsupportedDocument',
description: 'warns the user that the file extension is not supported',
},
fileToUpload: {
id: 'app.presentationUploder.fileToUpload',
description: 'message used in the file selected for upload',
},
uploadProcess: {
id: 'app.presentationUploder.upload.progress',
description: 'message that indicates the percentage of the upload',
},
badConnectionError: {
id: 'app.presentationUploder.connectionClosedError',
description: 'message indicating that the connection was closed',
},
conversionProcessingSlides: {
id: 'app.presentationUploder.conversion.conversionProcessingSlides',
description: 'indicates how many slides were converted',
},
genericError: {
id: 'app.presentationUploder.genericError',
description: 'generic error while uploading/converting',
},
genericConversionStatus: {
id: 'app.presentationUploder.conversion.genericConversionStatus',
description: 'indicates that file is being converted',
},
});
// fetch doesn't support progress. So we use xhr which support progress.
const futch = (url, opts = {}, onProgress) => new Promise((res, rej) => {
const xhr = new XMLHttpRequest();
@ -341,230 +254,6 @@ const removePresentations = (
podId,
) => Promise.all(presentationsToRemove.map((p) => removePresentation(p.id, podId)));
function renderPresentationItemStatus(item, intl) {
if ((("progress" in item) && item.progress === 0) || (("conversion" in item && !item.conversion.done && !item.conversion.error))) {
return intl.formatMessage(intlMessages.fileToUpload);
}
if (("progress" in item) && item.progress < 100 && !("conversion" in item)) {
return intl.formatMessage(intlMessages.uploadProcess, {
0: Math.floor(item.progress).toString(),
});
}
const constraint = {};
if (("upload" in item) && (item.upload.done && item.upload.error)) {
if (item.conversion.status === 'FILE_TOO_LARGE') {
constraint['0'] = ((item.conversion.maxFileSize) / 1000 / 1000).toFixed(2);
}
if (item.progress < 100) {
const errorMessage = intlMessages.badConnectionError;
return intl.formatMessage(errorMessage);
}
const errorMessage = intlMessages[item.upload.status] || intlMessages.genericError;
return intl.formatMessage(errorMessage, constraint);
}
if (("conversion" in item) && (!item.conversion.done && item.conversion.error)) {
const errorMessage = intlMessages[item.conversion.status] || intlMessages.genericConversionStatus;
switch (item.conversion.status) {
case 'PAGE_COUNT_EXCEEDED':
constraint['0'] = item.conversion.maxNumberPages;
break;
case 'PDF_HAS_BIG_PAGE':
constraint['0'] = (item.conversion.bigPageSize / 1000 / 1000).toFixed(2);
break;
default:
break;
}
return intl.formatMessage(errorMessage, constraint);
}
if ((("conversion" in item) && (!item.conversion.done && !item.conversion.error)) || (("progress" in item) && item.progress == 100)) {
let conversionStatusMessage
if ("conversion" in item) {
if (item.conversion.pagesCompleted < item.conversion.numPages) {
return intl.formatMessage(intlMessages.conversionProcessingSlides, {
0: item.conversion.pagesCompleted,
1: item.conversion.numPages,
});
}
conversionStatusMessage = intlMessages[item.conversion.status]
|| intlMessages.genericConversionStatus;
} else {
conversionStatusMessage = intlMessages.genericConversionStatus;
}
return intl.formatMessage(conversionStatusMessage);
}
return null;
}
function renderToastItem(item, intl) {
const isUploading = ("progress" in item) && item.progress <= 100;
const isConverting = ("conversion" in item) && !item.conversion.done;
const hasError = ((("conversion" in item) && item.conversion.error) || (("upload" in item) && item.upload.error));
const isProcessing = (isUploading || isConverting) && !hasError;
let icon = isProcessing ? 'blank' : 'check';
if (hasError) icon = 'circle_close';
return (
<Styled.UploadRow
key={item.id}
onClick={() => {
if (hasError || isProcessing) Session.set('showUploadPresentationView', true);
}}
>
<Styled.FileLine>
<span>
<Icon iconName="file" />
</span>
<Styled.ToastFileName>
<span>{item.filename || item.name}</span>
</Styled.ToastFileName>
<Styled.StatusIcon>
<Styled.ToastItemIcon
done={!isProcessing && !hasError}
error={hasError}
loading={isProcessing}
iconName={icon}
/>
</Styled.StatusIcon>
</Styled.FileLine>
<Styled.StatusInfo>
<Styled.StatusInfoSpan data-test="presentationStatusInfo" styles={hasError ? 'error' : 'info'}>
{renderPresentationItemStatus(item, intl)}
</Styled.StatusInfoSpan>
</Styled.StatusInfo>
</Styled.UploadRow>
);
}
const renderToastList = (presentations, intl) => {
let converted = 0;
let presentationsSorted = presentations
.sort((a, b) => a.uploadTimestamp - b.uploadTimestamp)
.sort((a, b) => {
const presADone = a.conversion ? a.conversion.done : false;
const presBDone = b.conversion ? b.conversion.done : false;
return presADone - presBDone
});
presentationsSorted
.forEach((p) => {
const presDone = p.conversion ? p.conversion.done : false;
if (presDone) converted += 1;
return p;
});
let toastHeading = '';
const itemLabel = presentationsSorted.length > 1
? intl.formatMessage(intlMessages.itemPlural)
: intl.formatMessage(intlMessages.item);
if (converted === 0) {
toastHeading = intl.formatMessage(intlMessages.uploading, {
0: presentationsSorted.length,
1: itemLabel,
});
}
if (converted > 0 && converted !== presentationsSorted.length) {
toastHeading = intl.formatMessage(intlMessages.uploadStatus, {
0: converted,
1: presentationsSorted.length,
});
}
if (converted === presentationsSorted.length) {
toastHeading = intl.formatMessage(intlMessages.completed, {
0: converted,
});
}
return (
<Styled.ToastWrapper>
<Styled.UploadToastHeader>
<Styled.UploadIcon iconName="upload" />
<Styled.UploadToastTitle>{toastHeading}</Styled.UploadToastTitle>
</Styled.UploadToastHeader>
<Styled.InnerToast>
<div>
<div>
{presentationsSorted.map((item) => renderToastItem(item, intl))}
</div>
</div>
</Styled.InnerToast>
</Styled.ToastWrapper>
);
}
function handleDismissToast(toastId) {
return toast.dismiss(toastId);
}
export const ToastController = ({ intl }) => {
useTracker(() => {
const presentationsRenderedFalseAndConversionFalse = Presentations.find({ $or: [{renderedInToast: false}, {"conversion.done": false}] }).fetch();
const convertingPresentations = presentationsRenderedFalseAndConversionFalse.filter(p => !p.renderedInToast )
let tmpIdconvertingPresentations = presentationsRenderedFalseAndConversionFalse.filter(p => !p.conversion.done)
.map(p => p.tmpPresId)
// tmpIdconvertingPresentations = UploadingPresentations.find({}).fetch().filter(p => tmpIdconvertingPresentations.includes(p.tmpPresId))
// .map(p => p.tmpPresId)
UploadingPresentations.find({}).fetch().filter(p => tmpIdconvertingPresentations.includes(p.tmpPresId))
.map(p => UploadingPresentations.remove({tmpPresId: p.tmpPresId}));
// Remove all presentations from the uploading collection if they are already
// converting.
// UploadingPresentations.remove({tmpPresId: {$all: tmpIdconvertingPresentations}});
const uploadingPresentations = UploadingPresentations.find().fetch();
let presentationsToConvert = convertingPresentations.concat(uploadingPresentations);
let activeToast = Session.get("presentationUploaderToastId");
const showToast = presentationsToConvert.length > 0;
if (showToast && !activeToast) {
activeToast = toast.info(() => renderToastList(presentationsToConvert, intl), {
hideProgressBar: true,
autoClose: false,
newestOnTop: true,
closeOnClick: true,
onClose: () => {
Session.set("presentationUploaderToastId", null);
presentationsToConvert = [];
},
});
Session.set("presentationUploaderToastId", activeToast);
} else if (!showToast && activeToast) {
handleDismissToast(activeToast);
Session.set("presentationUploaderToastId", null);
} else {
toast.update(activeToast, {
render: renderToastList(presentationsToConvert, intl),
});
}
let tmpPresIdListToSetAsRendered = presentationsToConvert.filter(p =>
("conversion" in p && (p.conversion.done || p.conversion.error)))
tmpPresIdListToSetAsRendered = tmpPresIdListToSetAsRendered.map(p => p.tmpPresId);
makeCall('setPresentationRenderedInToast', tmpPresIdListToSetAsRendered);
}, [])
return null;
}
const persistPresentationChanges = (oldState, newState, uploadEndpoint, podId) => {
const presentationsToUpload = newState.filter((p) => !p.upload.done);
@ -667,8 +356,5 @@ export default {
setPresentation,
requestPresentationUploadToken,
exportPresentationToChat,
renderToastList,
handleDismissToast,
renderPresentationItemStatus,
uploadAndConvertPresentation,
};