@kedao/finder
Version:
Media manager for Kedao Editor.
376 lines • 19.4 kB
JavaScript
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