UNPKG

@uppy/dashboard

Version:

Universal UI plugin for Uppy.

329 lines (324 loc) 13.2 kB
let _Symbol$for; // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-nocheck Typing this file requires more work, skipping it to unblock the rest of the transition. /* eslint-disable react/destructuring-assignment */ import { h, Component, Fragment } from 'preact'; _Symbol$for = Symbol.for('uppy test: disable unused locale key warning'); class AddFiles extends Component { constructor() { super(...arguments); this.triggerFileInputClick = () => { this.fileInput.click(); }; this.triggerFolderInputClick = () => { this.folderInput.click(); }; this.triggerVideoCameraInputClick = () => { this.mobileVideoFileInput.click(); }; this.triggerPhotoCameraInputClick = () => { this.mobilePhotoFileInput.click(); }; this.onFileInputChange = event => { this.props.handleInputChange(event); // We clear the input after a file is selected, because otherwise // change event is not fired in Chrome and Safari when a file // with the same name is selected. // ___Why not use value="" on <input/> instead? // Because if we use that method of clearing the input, // Chrome will not trigger change if we drop the same file twice (Issue #768). event.target.value = null; // eslint-disable-line no-param-reassign }; this.renderHiddenInput = (isFolder, refCallback) => { return h("input", { className: "uppy-Dashboard-input", hidden: true, "aria-hidden": "true", tabIndex: -1, webkitdirectory: isFolder, type: "file", name: "files[]", multiple: this.props.maxNumberOfFiles !== 1, onChange: this.onFileInputChange, accept: this.props.allowedFileTypes, ref: refCallback }); }; this.renderHiddenCameraInput = (type, nativeCameraFacingMode, refCallback) => { const typeToAccept = { photo: 'image/*', video: 'video/*' }; const accept = typeToAccept[type]; return h("input", { className: "uppy-Dashboard-input", hidden: true, "aria-hidden": "true", tabIndex: -1, type: "file", name: `camera-${type}`, onChange: this.onFileInputChange, capture: nativeCameraFacingMode, accept: accept, ref: refCallback }); }; this.renderMyDeviceAcquirer = () => { return h("div", { className: "uppy-DashboardTab", role: "presentation", "data-uppy-acquirer-id": "MyDevice" }, h("button", { type: "button", className: "uppy-u-reset uppy-c-btn uppy-DashboardTab-btn", role: "tab", tabIndex: 0, "data-uppy-super-focusable": true, onClick: this.triggerFileInputClick }, h("div", { className: "uppy-DashboardTab-inner" }, h("svg", { className: "uppy-DashboardTab-iconMyDevice", "aria-hidden": "true", focusable: "false", width: "32", height: "32", viewBox: "0 0 32 32" }, h("path", { d: "M8.45 22.087l-1.305-6.674h17.678l-1.572 6.674H8.45zm4.975-12.412l1.083 1.765a.823.823 0 00.715.386h7.951V13.5H8.587V9.675h4.838zM26.043 13.5h-1.195v-2.598c0-.463-.336-.75-.798-.75h-8.356l-1.082-1.766A.823.823 0 0013.897 8H7.728c-.462 0-.815.256-.815.718V13.5h-.956a.97.97 0 00-.746.37.972.972 0 00-.19.81l1.724 8.565c.095.44.484.755.933.755H24c.44 0 .824-.3.929-.727l2.043-8.568a.972.972 0 00-.176-.825.967.967 0 00-.753-.38z", fill: "currentcolor", "fill-rule": "evenodd" }))), h("div", { className: "uppy-DashboardTab-name" }, this.props.i18n('myDevice')))); }; this.renderPhotoCamera = () => { return h("div", { className: "uppy-DashboardTab", role: "presentation", "data-uppy-acquirer-id": "MobilePhotoCamera" }, h("button", { type: "button", className: "uppy-u-reset uppy-c-btn uppy-DashboardTab-btn", role: "tab", tabIndex: 0, "data-uppy-super-focusable": true, onClick: this.triggerPhotoCameraInputClick }, h("div", { className: "uppy-DashboardTab-inner" }, h("svg", { "aria-hidden": "true", focusable: "false", width: "32", height: "32", viewBox: "0 0 32 32" }, h("path", { d: "M23.5 9.5c1.417 0 2.5 1.083 2.5 2.5v9.167c0 1.416-1.083 2.5-2.5 2.5h-15c-1.417 0-2.5-1.084-2.5-2.5V12c0-1.417 1.083-2.5 2.5-2.5h2.917l1.416-2.167C13 7.167 13.25 7 13.5 7h5c.25 0 .5.167.667.333L20.583 9.5H23.5zM16 11.417a4.706 4.706 0 00-4.75 4.75 4.704 4.704 0 004.75 4.75 4.703 4.703 0 004.75-4.75c0-2.663-2.09-4.75-4.75-4.75zm0 7.825c-1.744 0-3.076-1.332-3.076-3.074 0-1.745 1.333-3.077 3.076-3.077 1.744 0 3.074 1.333 3.074 3.076s-1.33 3.075-3.074 3.075z", fill: "#02B383", "fill-rule": "nonzero" }))), h("div", { className: "uppy-DashboardTab-name" }, this.props.i18n('takePictureBtn')))); }; this.renderVideoCamera = () => { return h("div", { className: "uppy-DashboardTab", role: "presentation", "data-uppy-acquirer-id": "MobileVideoCamera" }, h("button", { type: "button", className: "uppy-u-reset uppy-c-btn uppy-DashboardTab-btn", role: "tab", tabIndex: 0, "data-uppy-super-focusable": true, onClick: this.triggerVideoCameraInputClick }, h("div", { className: "uppy-DashboardTab-inner" }, h("svg", { "aria-hidden": "true", width: "32", height: "32", viewBox: "0 0 32 32" }, h("path", { fill: "#FF675E", fillRule: "nonzero", d: "m21.254 14.277 2.941-2.588c.797-.313 1.243.818 1.09 1.554-.01 2.094.02 4.189-.017 6.282-.126.915-1.145 1.08-1.58.34l-2.434-2.142c-.192.287-.504 1.305-.738.468-.104-1.293-.028-2.596-.05-3.894.047-.312.381.823.426 1.069.063-.384.206-.744.362-1.09zm-12.939-3.73c3.858.013 7.717-.025 11.574.02.912.129 1.492 1.237 1.351 2.217-.019 2.412.04 4.83-.03 7.239-.17 1.025-1.166 1.59-2.029 1.429-3.705-.012-7.41.025-11.114-.019-.913-.129-1.492-1.237-1.352-2.217.018-2.404-.036-4.813.029-7.214.136-.82.83-1.473 1.571-1.454z " }))), h("div", { className: "uppy-DashboardTab-name" }, this.props.i18n('recordVideoBtn')))); }; this.renderBrowseButton = (text, onClickFn) => { const numberOfAcquirers = this.props.acquirers.length; return h("button", { type: "button", className: "uppy-u-reset uppy-c-btn uppy-Dashboard-browse", onClick: onClickFn, "data-uppy-super-focusable": numberOfAcquirers === 0 }, text); }; this.renderDropPasteBrowseTagline = numberOfAcquirers => { const browseFiles = this.renderBrowseButton(this.props.i18n('browseFiles'), this.triggerFileInputClick); const browseFolders = this.renderBrowseButton(this.props.i18n('browseFolders'), this.triggerFolderInputClick); // in order to keep the i18n CamelCase and options lower (as are defaults) we will want to transform a lower // to Camel const lowerFMSelectionType = this.props.fileManagerSelectionType; const camelFMSelectionType = lowerFMSelectionType.charAt(0).toUpperCase() + lowerFMSelectionType.slice(1); return h("div", { class: "uppy-Dashboard-AddFiles-title" }, // eslint-disable-next-line no-nested-ternary this.props.disableLocalFiles ? this.props.i18n('importFiles') : numberOfAcquirers > 0 ? this.props.i18nArray(`dropPasteImport${camelFMSelectionType}`, { browseFiles, browseFolders, browse: browseFiles }) : this.props.i18nArray(`dropPaste${camelFMSelectionType}`, { browseFiles, browseFolders, browse: browseFiles })); }; this.renderAcquirer = acquirer => { var _this$props$activePic; return h("div", { className: "uppy-DashboardTab", role: "presentation", "data-uppy-acquirer-id": acquirer.id }, h("button", { type: "button", className: "uppy-u-reset uppy-c-btn uppy-DashboardTab-btn", role: "tab", tabIndex: 0, "data-cy": acquirer.id, "aria-controls": `uppy-DashboardContent-panel--${acquirer.id}`, "aria-selected": ((_this$props$activePic = this.props.activePickerPanel) == null ? void 0 : _this$props$activePic.id) === acquirer.id, "data-uppy-super-focusable": true, onClick: () => this.props.showPanel(acquirer.id) }, h("div", { className: "uppy-DashboardTab-inner" }, acquirer.icon()), h("div", { className: "uppy-DashboardTab-name" }, acquirer.name))); }; this.renderAcquirers = acquirers => { // Group last two buttons, so we don’t end up with // just one button on a new line const acquirersWithoutLastTwo = [...acquirers]; const lastTwoAcquirers = acquirersWithoutLastTwo.splice(acquirers.length - 2, acquirers.length); return h(Fragment, null, acquirersWithoutLastTwo.map(acquirer => this.renderAcquirer(acquirer)), h("span", { role: "presentation", style: { 'white-space': 'nowrap' } }, lastTwoAcquirers.map(acquirer => this.renderAcquirer(acquirer)))); }; this.renderSourcesList = (acquirers, disableLocalFiles) => { const { showNativePhotoCameraButton, showNativeVideoCameraButton } = this.props; let list = []; const myDeviceKey = 'myDevice'; if (!disableLocalFiles) list.push({ key: myDeviceKey, elements: this.renderMyDeviceAcquirer() }); if (showNativePhotoCameraButton) list.push({ key: 'nativePhotoCameraButton', elements: this.renderPhotoCamera() }); if (showNativeVideoCameraButton) list.push({ key: 'nativePhotoCameraButton', elements: this.renderVideoCamera() }); list.push(...acquirers.map(acquirer => ({ key: acquirer.id, elements: this.renderAcquirer(acquirer) }))); // doesn't make sense to show only a lonely "My Device" const hasOnlyMyDevice = list.length === 1 && list[0].key === myDeviceKey; if (hasOnlyMyDevice) list = []; // Group last two buttons, so we don’t end up with // just one button on a new line const listWithoutLastTwo = [...list]; const lastTwo = listWithoutLastTwo.splice(list.length - 2, list.length); const renderList = l => l.map(_ref => { let { key, elements } = _ref; return h(Fragment, { key: key }, elements); }); return h(Fragment, null, this.renderDropPasteBrowseTagline(list.length), h("div", { className: "uppy-Dashboard-AddFiles-list", role: "tablist" }, renderList(listWithoutLastTwo), h("span", { role: "presentation", style: { 'white-space': 'nowrap' } }, renderList(lastTwo)))); }; } [_Symbol$for]() { // Those are actually used in `renderDropPasteBrowseTagline` method. this.props.i18nArray('dropPasteBoth'); this.props.i18nArray('dropPasteFiles'); this.props.i18nArray('dropPasteFolders'); this.props.i18nArray('dropPasteImportBoth'); this.props.i18nArray('dropPasteImportFiles'); this.props.i18nArray('dropPasteImportFolders'); } renderPoweredByUppy() { const { i18nArray } = this.props; const uppyBranding = h("span", null, h("svg", { "aria-hidden": "true", focusable: "false", className: "uppy-c-icon uppy-Dashboard-poweredByIcon", width: "11", height: "11", viewBox: "0 0 11 11" }, h("path", { d: "M7.365 10.5l-.01-4.045h2.612L5.5.806l-4.467 5.65h2.604l.01 4.044h3.718z", fillRule: "evenodd" })), h("span", { className: "uppy-Dashboard-poweredByUppy" }, "Uppy")); const linkText = i18nArray('poweredBy', { uppy: uppyBranding }); return h("a", { tabIndex: -1, href: "https://uppy.io", rel: "noreferrer noopener", target: "_blank", className: "uppy-Dashboard-poweredBy" }, linkText); } render() { const { showNativePhotoCameraButton, showNativeVideoCameraButton, nativeCameraFacingMode } = this.props; return h("div", { className: "uppy-Dashboard-AddFiles" }, this.renderHiddenInput(false, ref => { this.fileInput = ref; }), this.renderHiddenInput(true, ref => { this.folderInput = ref; }), showNativePhotoCameraButton && this.renderHiddenCameraInput('photo', nativeCameraFacingMode, ref => { this.mobilePhotoFileInput = ref; }), showNativeVideoCameraButton && this.renderHiddenCameraInput('video', nativeCameraFacingMode, ref => { this.mobileVideoFileInput = ref; }), this.renderSourcesList(this.props.acquirers, this.props.disableLocalFiles), h("div", { className: "uppy-Dashboard-AddFiles-info" }, this.props.note && h("div", { className: "uppy-Dashboard-note" }, this.props.note), this.props.proudlyDisplayPoweredByUppy && this.renderPoweredByUppy(this.props))); } } export default AddFiles;