diff --git a/bigbluebutton-html5/imports/ui/components/presentation/presentation-uploader/component.jsx b/bigbluebutton-html5/imports/ui/components/presentation/presentation-uploader/component.jsx index 1b78ac41a4d12995827a43031612dc9ee82ede59..6f78965be15b9799eab7e8d096f7cdb75339ab62 100755 --- a/bigbluebutton-html5/imports/ui/components/presentation/presentation-uploader/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/presentation/presentation-uploader/component.jsx @@ -6,6 +6,7 @@ import update from 'immutability-helper'; import cx from 'classnames'; import _ from 'lodash'; import logger from '/imports/startup/client/logger'; +import browser from 'browser-detect'; import { notify } from '/imports/ui/services/notification'; import ModalFullscreen from '/imports/ui/components/modal/fullscreen/component'; @@ -70,6 +71,10 @@ const intlMessages = defineMessages({ id: 'app.presentationUploder.browseFilesLabel', description: 'message use on the file browser', }, + browseImagesLabel: { + id: 'app.presentationUploder.browseImagesLabel', + description: 'message use on the image browser', + }, fileToUpload: { id: 'app.presentationUploder.fileToUpload', description: 'message used in the file selected for upload', @@ -119,6 +124,12 @@ const intlMessages = defineMessages({ }, }); +const BROWSER_RESULTS = browser(); +const isMobileBrowser = (BROWSER_RESULTS ? BROWSER_RESULTS.mobile : false) || + (BROWSER_RESULTS && BROWSER_RESULTS.os ? + BROWSER_RESULTS.os.includes('Android') : // mobile flag doesn't always work + false); + class PresentationUploader extends Component { constructor(props) { super(props); @@ -231,8 +242,10 @@ class PresentationUploader extends Component { }); } - handleFiledrop(files, rejected) { - const presentationsToUpload = files.map((file) => { + handleFiledrop(files, files2) { + const [ accepted, rejected ] = _.partition(files.concat(files2), (f) => this.props.fileValidMimeTypes.includes(f.type)); + + const presentationsToUpload = accepted.map((file) => { const id = _.uniqueId(file.name); return { @@ -467,6 +480,41 @@ class PresentationUploader extends Component { ); } + renderPicDropzone() { + const { + intl, + fileSizeMin, + fileSizeMax, + fileValidMimeTypes, + } = this.props; + + const { disableActions } = this.state; + + if (disableActions) return null; + + return ( + <Dropzone + multiple + className={styles.dropzone} + activeClassName={styles.dropzoneActive} + rejectClassName={styles.dropzoneReject} + accept="image/*" + minSize={fileSizeMin} + maxSize={fileSizeMax} + disablePreview + onDrop={this.handleFiledrop} + > + <Icon className={styles.dropzoneIcon} iconName="upload" /> + <p className={styles.dropzoneMessage}> + {intl.formatMessage(intlMessages.dropzoneLabel)} + <span className={styles.dropzoneLink}> + {intl.formatMessage(intlMessages.browseImagesLabel)} + </span> + </p> + </Dropzone> + ); + } + renderDropzone() { const { intl, @@ -485,7 +533,7 @@ class PresentationUploader extends Component { className={styles.dropzone} activeClassName={styles.dropzoneActive} rejectClassName={styles.dropzoneReject} - accept={fileValidMimeTypes.join()} + accept={isMobileBrowser ? '' : fileValidMimeTypes.join()} minSize={fileSizeMin} maxSize={fileSizeMax} disablepreview="true" @@ -526,7 +574,10 @@ class PresentationUploader extends Component { > <p>{intl.formatMessage(intlMessages.message)}</p> {this.renderPresentationList()} - {this.renderDropzone()} + <div className={styles.dropzoneWrapper}> + {isMobileBrowser ? this.renderPicDropzone() : null} + {this.renderDropzone()} + </div> </ModalFullscreen> ); } diff --git a/bigbluebutton-html5/imports/ui/components/presentation/presentation-uploader/styles.scss b/bigbluebutton-html5/imports/ui/components/presentation/presentation-uploader/styles.scss index c1c015f99f2a4b9861c73b2dc9619b632f5efbdc..491d80716dc7194717a3379a3ee12e0a14508404 100644 --- a/bigbluebutton-html5/imports/ui/components/presentation/presentation-uploader/styles.scss +++ b/bigbluebutton-html5/imports/ui/components/presentation/presentation-uploader/styles.scss @@ -149,13 +149,17 @@ } } -.dropzone { +.dropzoneWrapper { width: 100%; - display: block; + display: flex; + margin-top: calc(var(--lg-padding-y) * 5); +} + +.dropzone { + flex: auto; border: 2px dashed; border-radius: var(--border-radius); - padding: calc(var(--lg-padding-y) * 2.5) calc(var(--lg-padding-x) * 2.5); - margin-top: calc(var(--lg-padding-y) * 5); + padding: calc(var(--lg-padding-y) * 2.5) var(--lg-padding-x); text-align: center; font-size: var(--font-size-large); cursor: pointer; diff --git a/bigbluebutton-html5/private/locales/en.json b/bigbluebutton-html5/private/locales/en.json index 2c31f6871c188f7a3b900daffe0c864e38dcf3d4..d6fe7998e1e56a0f5a62b7034a2d43731ed17499 100755 --- a/bigbluebutton-html5/private/locales/en.json +++ b/bigbluebutton-html5/private/locales/en.json @@ -83,6 +83,7 @@ "app.presentationUploder.dismissDesc": "Close the modal window and discard your changes", "app.presentationUploder.dropzoneLabel": "Drag files here to upload", "app.presentationUploder.browseFilesLabel": "or browse for files", + "app.presentationUploder.browseImagesLabel": "or browse/capture for images", "app.presentationUploder.fileToUpload": "To be uploaded...", "app.presentationUploder.currentBadge": "Current", "app.presentationUploder.genericError": "Ops, something went wrong",