@kedao/finder
Version:
Media manager for Kedao Editor.
250 lines • 9.78 kB
JavaScript
import { UniqueIndex } from './utils/base';
import { compressImage } from './utils/image';
const defaultValidator = () => true;
export default class FinderController {
constructor(props = {}) {
this.setProps = (props = {}) => {
this.items = props.items || this.items || [];
this.uploadFn = props.uploader;
this.validateFn = props.validator || defaultValidator;
};
this.getMediaItem = (id) => {
return this.items.find((item) => item.id === id);
};
this.getSelectedItems = () => {
return this.items.filter((item) => item.selected);
};
this.getItems = () => {
return this.items;
};
this.setItems = (items) => {
this.items =
items.map((item) => (Object.assign(Object.assign({}, item), { id: item.id.toString() }))) || [];
this.applyChange();
this.uploadItems();
};
this.addMediaItem = (item) => {
this.addItems([item]);
};
this.addItems = (items) => {
this.items = [
...this.items,
...items.map((item) => (Object.assign(Object.assign({}, item), { id: item.id.toString() })))
];
this.applyChange();
this.uploadItems();
};
this.selectMediaItem = (id) => {
const item = this.getMediaItem(id);
if (item && (item.uploading || item.error)) {
return false;
}
this.setMediaItemState(id, {
selected: true
});
};
this.selectAllItems = () => {
this.items = this.items
.filter((item) => !item.error && !item.uploading)
.map((item) => (Object.assign(Object.assign({}, item), { selected: true })));
this.applyChange();
};
this.deselectMediaItem = (id) => {
this.setMediaItemState(id, {
selected: false
});
};
this.deselectAllItems = () => {
this.items = this.items.map((item) => (Object.assign(Object.assign({}, item), { selected: false })));
this.applyChange();
};
this.removeMediaItem = (id) => {
this.items = this.items.filter((item) => item.id !== id);
this.applyChange();
};
this.removeItems = (ids = []) => {
this.items = this.items.filter((item) => !ids.includes(item.id));
this.applyChange();
};
this.removeSelectedItems = () => {
this.items = this.items.filter((item) => !item.selected);
this.applyChange();
};
this.removeErrorItems = () => {
this.items = this.items.filter((item) => !item.error);
this.applyChange();
};
this.removeAllItems = () => {
this.items = [];
this.applyChange();
};
this.setMediaItemState = (id, state) => {
this.items = this.items.map((item) => item.id === id ? Object.assign(Object.assign({}, item), state) : item);
this.applyChange();
};
this.reuploadErrorItems = () => {
this.uploadItems(true);
};
this.uploadItems = (ignoreError = false) => {
this.items.forEach((item, index) => {
if (item.uploading || item.url) {
return false;
}
if (!ignoreError && item.error) {
return false;
}
if (item.type === 'IMAGE') {
this.createThumbnail(item);
this.uploadFn = this.uploadFn || this.createInlineImage;
}
else if (!this.uploadFn) {
this.setMediaItemState(item.id, { error: 1 });
return false;
}
this.setMediaItemState(item.id, {
uploading: true,
uploadProgress: 0,
error: 0
});
this.uploadFn({
id: item.id,
file: item.file,
success: (res) => {
this.handleUploadSuccess(item.id, res);
},
progress: (progress) => {
this.setMediaItemState(item.id, {
uploading: true,
uploadProgress: progress
});
},
error: () => {
this.setMediaItemState(item.id, {
uploading: false,
error: 2
});
}
});
});
};
this.createThumbnail = ({ id, file }) => {
compressImage(URL.createObjectURL(file), 226, 226).then((result) => {
this.setMediaItemState(id, { thumbnail: result.url });
}).catch(console.error);
};
this.createInlineImage = (param) => {
compressImage(URL.createObjectURL(param.file), 1280, 800)
.then((result) => {
param.success({ url: result.url });
})
.catch((error) => {
param.error(error);
});
};
this.handleUploadSuccess = (id, data) => {
var _a;
this.setMediaItemState(id, Object.assign(Object.assign({}, data), { file: null, uploadProgress: 1, uploading: false, selected: false }));
const item = this.getMediaItem(data.id || id);
(_a = item.onReady) === null || _a === void 0 ? void 0 : _a.call(item, item);
};
this.applyChange = () => {
this.changeListeners.forEach(({ callback }) => callback(this.items));
};
this.uploadImage = (file, callback) => {
const fileId = new Date().getTime() + '_' + UniqueIndex();
this.addMediaItem({
type: 'IMAGE',
id: fileId,
file: file,
name: fileId,
size: file.size,
uploadProgress: 0,
uploading: false,
selected: false,
error: 0,
onReady: callback
});
};
this.uploadImageRecursively = (files, callback, index = 0) => {
if (files[index] && files[index].type.indexOf('image') > -1) {
this.uploadImage(files[index], (image) => {
callback === null || callback === void 0 ? void 0 : callback(image);
index < files.length - 1 &&
this.uploadImageRecursively(files, callback, index + 1);
});
}
else {
index < files.length - 1 &&
this.uploadImageRecursively(files, callback, index + 1);
}
};
this.addResolvedFiles = (param, index, accepts) => {
const data = {
id: new Date().getTime() + '_' + UniqueIndex(),
file: param.files[index],
name: param.files[index].name,
size: param.files[index].size,
uploadProgress: 0,
uploading: false,
selected: false,
error: 0,
onReady: (item) => {
var _a;
(_a = param.onItemReady) === null || _a === void 0 ? void 0 : _a.call(param, item);
}
};
if (param.files[index].type.indexOf('image/') === 0 && accepts.image) {
data.type = 'IMAGE';
this.addMediaItem(data);
}
else if (param.files[index].type.indexOf('video/') === 0 &&
accepts.video) {
data.type = 'VIDEO';
this.addMediaItem(data);
}
else if (param.files[index].type.indexOf('audio/') === 0 &&
accepts.audio) {
data.type = 'AUDIO';
this.addMediaItem(data);
}
setTimeout(() => {
this.resolveFiles(param, index + 1, accepts);
}, 60);
};
this.resolveFiles = (param, index, accepts) => {
var _a;
if (index < param.files.length) {
const validateResult = this.validateFn(param.files[index]);
if (validateResult instanceof Promise) {
validateResult
.then(() => {
this.addResolvedFiles(param, index, accepts);
})
.catch(console.error);
}
else if (validateResult) {
this.addResolvedFiles(param, index, accepts);
}
}
else {
(_a = param.onAllReady) === null || _a === void 0 ? void 0 : _a.call(param);
}
};
this.onChange = (callback) => {
const listenerId = UniqueIndex();
this.changeListeners.push({
id: listenerId,
callback: callback
});
return listenerId;
};
this.offChange = (listenerId) => {
this.changeListeners = this.changeListeners.filter(({ id }) => id !== listenerId);
};
this.items = props.items || [];
this.uploadFn = props.uploader;
this.validateFn = props.validator || defaultValidator;
this.changeListeners = [];
}
}
//# sourceMappingURL=controller.js.map