UNPKG

@kedao/finder

Version:

Media manager for Kedao Editor.

376 lines 19.4 kB
import './styles.scss'; import React from 'react'; import { UniqueIndex } from './utils/base'; const defaultAccepts = { image: 'image/png,image/jpeg,image/gif,image/webp,image/apng,image/svg', video: 'video/mp4', audio: 'audio/mp3' }; export default class FinderView extends React.Component { constructor(props) { super(props); this.toggleSelectItem = (event) => { var _a, _b, _c, _d; const itemId = event.currentTarget.dataset.id; const item = this.controller.getMediaItem(itemId); if (!item) { return false; } if (item.selected) { if (!this.props.onBeforeDeselect || this.props.onBeforeDeselect([item], this.controller.getItems()) !== false) { this.controller.deselectMediaItem(itemId); (_b = (_a = this.props).onDeselect) === null || _b === void 0 ? void 0 : _b.call(_a, [item], this.controller.getItems()); } } else { if (!this.props.onBeforeSelect || this.props.onBeforeSelect([item], this.controller.getItems()) !== false) { this.controller.selectMediaItem(itemId); (_d = (_c = this.props).onSelect) === null || _d === void 0 ? void 0 : _d.call(_c, [item], this.controller.getItems()); } } }; this.removeItem = (event) => { var _a, _b; const itemId = event.currentTarget.dataset.id; const item = this.controller.getMediaItem(itemId); if (!item) { return false; } if (!this.props.onBeforeRemove || this.props.onBeforeRemove([item], this.controller.getItems()) !== false) { this.controller.removeMediaItem(itemId); (_b = (_a = this.props).onRemove) === null || _b === void 0 ? void 0 : _b.call(_a, [item], this.controller.getItems()); } event.stopPropagation(); }; this.selectAllItems = () => { var _a, _b; const allItems = this.controller.getItems(); if (!this.props.onBeforeSelect || this.props.onBeforeSelect(allItems, allItems) !== false) { this.controller.selectAllItems(); (_b = (_a = this.props).onSelect) === null || _b === void 0 ? void 0 : _b.call(_a, allItems, allItems); } }; this.deselectAllItems = () => { var _a, _b; const allItems = this.controller.getItems(); if (!this.props.onBeforeDeselect || this.props.onBeforeDeselect(allItems, allItems) !== false) { this.controller.deselectAllItems(); (_b = (_a = this.props).onDeselect) === null || _b === void 0 ? void 0 : _b.call(_a, allItems, allItems); } }; this.removeSelectedItems = () => { var _a, _b; const selectedItems = this.controller.getSelectedItems(); if (!this.props.onBeforeRemove || this.props.onBeforeRemove(selectedItems, this.controller.getItems()) !== false) { this.controller.removeSelectedItems(); (_b = (_a = this.props).onRemove) === null || _b === void 0 ? void 0 : _b.call(_a, selectedItems, this.controller.getItems()); } }; this.handleDragLeave = (event) => { event.preventDefault(); this.dragCounter--; this.dragCounter === 0 && this.setState({ draging: false }); }; this.handleDragDrop = (event) => { event.preventDefault(); this.dragCounter = 0; this.setState({ draging: false }); this.reslovePickedFiles(event); }; this.handleDragEnter = (event) => { event.preventDefault(); this.dragCounter++; this.setState({ draging: true }); }; this.reslovePickedFiles = (event) => { event.persist(); let { files } = event.type === 'drop' ? event.dataTransfer : event.target; if (this.props.onFileSelect) { const result = this.props.onFileSelect(files); if (result === false) { return false; } else if (result instanceof FileList || result instanceof Array) { files = result; } } const accepts = Object.assign(Object.assign({}, defaultAccepts), this.props.accepts); this.controller.resolveFiles({ files: files, onItemReady: ({ id }) => this.controller.selectMediaItem(id), onAllReady: () => { event.target.value = null; } }, 0, accepts); }; this.inputExternal = (event) => { this.setState({ external: Object.assign(Object.assign({}, this.state.external), { url: event.target.value }) }); }; this.switchExternalType = (event) => { this.setState({ external: Object.assign(Object.assign({}, this.state.external), { type: event.target.dataset.type }) }); }; this.confirmAddExternal = (event) => { if (event.target.nodeName.toLowerCase() === 'button' || event.keyCode === 13) { let { url, type } = this.state.external; url = url.split('|'); const name = url.length > 1 ? url[0] : this.props.language.unnamedItem; url = url.length > 1 ? url[1] : url[0]; const thumbnail = type === 'IMAGE' ? url : null; this.controller.addItems([ { thumbnail, url, name, type, id: new Date().getTime() + '_' + UniqueIndex(), uploading: false, uploadProgress: 1, selected: true } ]); this.setState({ showExternalForm: false, external: { url: '', type: 'IMAGE' } }); } }; this.toggleExternalForm = () => { this.setState({ showExternalForm: !this.state.showExternalForm }); }; this.cancelInsert = () => { var _a, _b; (_b = (_a = this.props).onCancel) === null || _b === void 0 ? void 0 : _b.call(_a); }; this.confirmInsert = () => { var _a, _b, _c, _d, _e, _f; const selectedItems = this.controller.getSelectedItems(); if (this.props.onBeforeInsert) { const filteredItems = this.props.onBeforeInsert(selectedItems); if (filteredItems && filteredItems instanceof Array) { this.controller.deselectAllItems(); (_b = (_a = this.props).onInsert) === null || _b === void 0 ? void 0 : _b.call(_a, filteredItems); } else if (filteredItems !== false) { this.controller.deselectAllItems(); (_d = (_c = this.props).onInsert) === null || _d === void 0 ? void 0 : _d.call(_c, selectedItems); } } else { this.controller.deselectAllItems(); (_f = (_e = this.props).onInsert) === null || _f === void 0 ? void 0 : _f.call(_e, selectedItems); } }; this.dragCounter = 0; this.controller = this.props.controller; const initialItems = this.controller.getItems(); this.state = { draging: false, error: false, confirmable: initialItems.find(({ selected }) => selected), external: { url: '', type: 'IMAGE' }, fileAccept: '', showExternalForm: false, allowExternal: false, items: initialItems }; this.changeListenerId = this.controller.onChange((items) => { var _a, _b; this.setState({ items, confirmable: items.find(({ selected }) => selected) }); (_b = (_a = this.props).onChange) === null || _b === void 0 ? void 0 : _b.call(_a, items); }); } mapPropsToState(props) { let { accepts, externals } = props; accepts = Object.assign(Object.assign({}, defaultAccepts), accepts); const fileAccept = !accepts ? [defaultAccepts.image, defaultAccepts.video, defaultAccepts.audio].join(',') : [accepts.image, accepts.video, accepts.audio] .filter((item) => item) .join(','); const external = { url: '', type: externals.image ? 'IMAGE' : externals.audio ? 'AUDIO' : externals.video ? 'VIDEO' : externals.embed ? 'EMBED' : '' }; return { fileAccept: fileAccept, external: external, allowExternal: externals && (externals.image || externals.audio || externals.video || externals.embed) }; } componentDidMount() { this.setState(this.mapPropsToState(this.props)); } UNSAFE_componentWillReceiveProps(nextProps) { this.setState(this.mapPropsToState(nextProps)); } componentWillUnmount() { this.controller.offChange(this.changeListenerId); } render() { const { language, externals } = this.props; const { items, draging, confirmable, fileAccept, external, showExternalForm, allowExternal } = this.state; return (React.createElement("div", { className: "kedao-finder" }, React.createElement("div", { onDragEnter: this.handleDragEnter, onDragLeave: this.handleDragLeave, onDrop: this.handleDragDrop, className: "bf-uploader" }, React.createElement("div", { className: 'bf-drag-uploader ' + (draging || !items.length ? 'active ' : ' ') + (draging ? 'draging' : '') }, React.createElement("span", { className: "bf-drag-tip" }, React.createElement("input", { accept: fileAccept, onChange: this.reslovePickedFiles, multiple: true, type: "file" }), draging ? language.dropTip : language.dragTip)), items.length ? (React.createElement("div", { className: "bf-list-wrap" }, React.createElement("div", { className: "bf-list-tools" }, React.createElement("span", { onClick: this.selectAllItems, className: "bf-select-all" }, React.createElement("i", { className: "kedao-icon-done" }), " ", language.selectAll), React.createElement("span", Object.assign({ onClick: this.deselectAllItems, className: "bf-deselect-all" }, { disabled: !confirmable }), React.createElement("i", { className: "kedao-icon-close" }), " ", language.deselect), React.createElement("span", Object.assign({ onClick: this.removeSelectedItems, className: "bf-remove-selected" }, { disabled: !confirmable }), React.createElement("i", { className: "kedao-icon-bin" }), " ", language.removeSelected)), this.buildItemList())) : null, showExternalForm && allowExternal ? (React.createElement("div", { className: "bf-add-external" }, React.createElement("div", { className: "bf-external-form" }, React.createElement("div", { className: "bf-external-input" }, React.createElement("div", null, React.createElement("input", { onKeyDown: this.confirmAddExternal, value: external.url, onChange: this.inputExternal, placeholder: language.externalInputPlaceHolder })), React.createElement("button", { type: "button", onClick: this.confirmAddExternal, disabled: !external.url.trim().length }, language.confirm)), React.createElement("div", { "data-type": external.type, className: "bf-switch-external-type" }, externals.image ? (React.createElement("button", { type: "button", onClick: this.switchExternalType, "data-type": "IMAGE" }, language.image)) : null, externals.audio ? (React.createElement("button", { type: "button", onClick: this.switchExternalType, "data-type": "AUDIO" }, language.audio)) : null, externals.video ? (React.createElement("button", { type: "button", onClick: this.switchExternalType, "data-type": "VIDEO" }, language.video)) : null, externals.embed ? (React.createElement("button", { type: "button", onClick: this.switchExternalType, "data-type": "EMBED" }, language.embed)) : null), React.createElement("span", { className: "bf-external-tip" }, language.externalInputTip)))) : null), React.createElement("footer", { className: "bf-manager-footer" }, React.createElement("div", { className: "pull-left" }, allowExternal ? (React.createElement("span", { onClick: this.toggleExternalForm, className: "bf-toggle-external-form" }, showExternalForm ? (React.createElement("span", { className: "bf-bottom-text" }, React.createElement("i", { className: "kedao-icon-add" }), " ", language.addLocalFile)) : (React.createElement("span", { className: "bf-bottom-text" }, React.createElement("i", { className: "kedao-icon-add" }), ' ', language.addExternalSource)))) : null), React.createElement("div", { className: "pull-right" }, React.createElement("button", { onClick: this.confirmInsert, className: "button button-insert", disabled: !confirmable }, language.insert), React.createElement("button", { onClick: this.cancelInsert, className: "button button-cancel" }, language.cancel))))); } buildItemList() { return (React.createElement("ul", { className: "bf-list" }, React.createElement("li", { className: "bf-add-item" }, React.createElement("i", { className: "kedao-icon-add" }), React.createElement("input", { accept: this.state.fileAccept, onChange: this.reslovePickedFiles, multiple: true, type: "file" })), this.state.items.map((item, index) => { let previewerComponents = null; const progressMarker = item.uploading && !this.props.hideProgress ? (React.createElement("div", { className: "bf-item-uploading" }, React.createElement("div", { className: "bf-item-uploading-bar", style: { width: item.uploadProgress / 1 + '%' } }))) : (''); switch (item.type) { case 'IMAGE': previewerComponents = (React.createElement("div", { className: "bf-image" }, progressMarker, React.createElement("img", { src: item.thumbnail || item.url }))); break; case 'VIDEO': previewerComponents = (React.createElement("div", { className: "bf-icon bf-video", title: item.url }, progressMarker, React.createElement("i", { className: "kedao-icon-film" }), React.createElement("span", null, item.name || item.url))); break; case 'AUDIO': previewerComponents = (React.createElement("div", { className: "bf-icon bf-audio", title: item.url }, progressMarker, React.createElement("i", { className: "kedao-icon-music" }), React.createElement("span", null, item.name || item.url))); break; case 'EMBED': previewerComponents = (React.createElement("div", { className: "bf-icon bf-embed", title: item.url }, progressMarker, React.createElement("i", { className: "kedao-icon-code" }), React.createElement("span", null, item.name || this.props.language.embed))); break; default: previewerComponents = (React.createElement("a", { className: "bf-icon bf-file", title: item.url, href: item.url }, progressMarker, React.createElement("i", { className: "kedao-icon-file-text" }), React.createElement("span", null, item.name || item.url))); break; } const className = ['bf-item']; item.selected && className.push('active'); item.uploading && className.push('uploading'); item.error && className.push('error'); return (React.createElement("li", { key: index, title: item.name, "data-id": item.id, className: className.join(' '), onClick: this.toggleSelectItem }, previewerComponents, React.createElement("span", { "data-id": item.id, onClick: this.removeItem, className: "bf-item-remove kedao-icon-close" }), React.createElement("span", { className: "bf-item-title" }, item.name))); }))); } } FinderView.defaultProps = { accepts: defaultAccepts, externals: { image: true, video: true, audio: true, embed: true } }; //# sourceMappingURL=view.js.map