@selfcommunity/react-ui
Version:
React UI Components to integrate a Community created with SelfCommunity Platform.
214 lines (213 loc) • 9.95 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const chunked_uploady_1 = require("@rpldy/chunked-uploady");
const api_services_1 = require("@selfcommunity/api-services");
const types_1 = require("@selfcommunity/types");
const react_core_1 = require("@selfcommunity/react-core");
const uploady_1 = require("@rpldy/uploady");
const react_1 = tslib_1.__importStar(require("react"));
const react_intl_1 = require("react-intl");
const common_1 = tslib_1.__importDefault(require("../../messages/common"));
const thumbnailCoverter_1 = require("../../utils/thumbnailCoverter");
const Errors_1 = require("../../constants/Errors");
const utils_1 = require("@selfcommunity/utils");
exports.default = (props) => {
// PROPS
const { type = null, onSuccess = null, onProgress = null, onError = null } = props;
// REFS
const firstRender = (0, react_1.useRef)(true);
const chunkStateRef = react_1.default.useRef({ chunks: {}, setChunk: null, setChunks: null });
// STATE
const [chunks, setChunks] = (0, react_1.useState)({});
const setChunk = (chunk) => {
const _chunks = Object.assign(Object.assign({}, chunkStateRef.current.chunks), { [chunk.id]: Object.assign(Object.assign({}, chunkStateRef.current.chunks[chunk.id]), chunk) });
setChunks(_chunks);
chunkStateRef.current.chunks = _chunks;
};
// Using refs to have the correct chunks values in the callbacks
// https://stackoverflow.com/questions/57847594/react-hooks-accessing-up-to-date-state-from-within-a-callback
chunkStateRef.current = { chunks, setChunk, setChunks };
// CONTEXT
const scContext = (0, react_core_1.useSCContext)();
// INTL
const intl = (0, react_intl_1.useIntl)();
const isImageType = (type) => {
return type.startsWith(types_1.SCMessageFileType.IMAGE);
};
// component update
(0, react_1.useEffect)(() => {
if (firstRender.current) {
firstRender.current = false;
return;
}
onProgress && onProgress(chunks);
}, [chunks]);
// LISTENERS
(0, uploady_1.useItemStartListener)((item) => {
if (!item.file.type.startsWith(types_1.SCMessageFileType.DOCUMENT)) {
const reader = new FileReader();
reader.onload = (e) => {
if (isImageType(item.file.type)) {
chunkStateRef.current.setChunk({ id: item.id, file_url: e.target.result });
}
else {
chunkStateRef.current.setChunk({ id: item.id, video_url: e.target.result });
}
};
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
// @ts-ignore
reader.readAsDataURL(item.file);
}
chunkStateRef.current.setChunk({ id: item.id, file_uuid: null, completed: 0, file: item.file, totalparts: null });
});
(0, uploady_1.useItemProgressListener)((item) => {
chunkStateRef.current.setChunk({ id: item.id, completed: item.completed });
});
const uploadThumbnail = (item, file) => {
const formData = new FormData();
formData.append('file', file);
formData.append('parentuuid', item.uploadResponse.results[0].data.file_uuid);
api_services_1.http
.request({
url: api_services_1.Endpoints.PrivateMessageUploadThumbnail.url(),
method: api_services_1.Endpoints.PrivateMessageUploadThumbnail.method,
data: formData,
headers: { 'Content-Type': 'multipart/form-data' }
})
.then((res) => {
const _chunks = Object.assign({}, chunkStateRef.current.chunks);
delete _chunks[item.id];
chunkStateRef.current.setChunks(_chunks);
let data = res.data;
data.file = item.file;
onSuccess(data);
})
.catch((error) => {
error = (0, api_services_1.formatHttpErrorCode)(error);
onError(Object.assign({}, chunkStateRef.current.chunks[item.id]), error.fileError
? intl.formatMessage(common_1.default.fileUploadErrorGeneric)
: intl.formatMessage(common_1.default.messageFileUploadError, { filename: item.file.name }));
const _chunks = Object.assign({}, chunkStateRef.current.chunks);
delete _chunks[item.id];
chunkStateRef.current.setChunks(_chunks);
});
};
const generateImageThumbnail = (callBack, item, fileUrl) => {
callBack(fileUrl, item)
.then((file) => {
uploadThumbnail(item, file);
})
.catch((error) => {
console.log(error);
onError(Object.assign({}, chunkStateRef.current.chunks[item.id]), intl.formatMessage(common_1.default.messageFileUploadError, { filename: item.file.name }));
const _chunks = Object.assign({}, chunkStateRef.current.chunks);
delete _chunks[item.id];
chunkStateRef.current.setChunks(_chunks);
});
};
(0, chunked_uploady_1.useItemFinishListener)((item) => {
const callBack = item.file.type.startsWith(types_1.SCMessageFileType.VIDEO)
? thumbnailCoverter_1.createVideoThumbnail
: item.file.type.startsWith(types_1.SCMessageFileType.AUDIO)
? thumbnailCoverter_1.createAudioThumbnail
: thumbnailCoverter_1.createDocumentThumbnail;
const formData = new FormData();
formData.append('uuid', chunkStateRef.current.chunks[item.id].file_uuid);
formData.append('filename', chunkStateRef.current.chunks[item.id].file.name);
formData.append('totalparts', chunkStateRef.current.chunks[item.id].totalparts);
api_services_1.http
.request({
url: api_services_1.Endpoints.PrivateMessageChunkUploadDone.url(),
method: api_services_1.Endpoints.PrivateMessageChunkUploadDone.method,
data: formData,
headers: { 'Content-Type': 'multipart/form-data' }
})
.then((res) => {
isImageType(item.file.type) ? uploadThumbnail(item, item.file) : generateImageThumbnail(callBack, item, res.data.file_url);
})
.catch((error) => {
error = (0, api_services_1.formatHttpErrorCode)(error);
onError(Object.assign({}, chunkStateRef.current.chunks[item.id]), error.fileError
? intl.formatMessage(common_1.default.fileUploadErrorGeneric)
: intl.formatMessage(common_1.default.messageFileUploadError, { filename: item.file.name }));
const _chunks = Object.assign({}, chunkStateRef.current.chunks);
delete _chunks[item.id];
chunkStateRef.current.setChunks(_chunks);
});
});
(0, chunked_uploady_1.useItemErrorListener)((item) => {
onError(Object.assign({}, chunkStateRef.current.chunks[item.id]), intl.formatMessage(common_1.default.error));
const _chunks = Object.assign({}, chunkStateRef.current.chunks);
delete _chunks[item.id];
chunkStateRef.current.setChunks(_chunks);
});
(0, chunked_uploady_1.useChunkStartListener)((data) => {
const res = {
url: `${scContext.settings.portal}${api_services_1.Endpoints.PrivateMessageUploadMediaInChunks.url()}`,
sendOptions: {
paramName: 'file',
headers: { Authorization: `Bearer ${scContext.settings.session.authToken.accessToken}` },
method: api_services_1.Endpoints.PrivateMessageUploadMediaInChunks.method
}
};
if (data.totalCount > 1) {
let _params = {
partindex: data.chunk.index,
totalparts: data.totalCount
};
if (chunkStateRef.current.chunks[data.item.id].file_uuid) {
_params['uuid'] = chunkStateRef.current.chunks[data.item.id].file_uuid;
}
res.sendOptions.params = _params;
}
else {
chunkStateRef.current.setChunk({ id: data.item.id, type: type || data.sendOptions.paramName });
}
return res;
});
(0, chunked_uploady_1.useChunkFinishListener)((data) => {
chunkStateRef.current.setChunk({
id: data.item.id,
file_uuid: data.uploadData.response.data.file_uuid,
totalparts: data.chunk.index + 1
});
});
(0, chunked_uploady_1.useRequestPreSend)(({ items, options }) => {
if (items.length == 0) {
return Promise.resolve({ options });
}
else if (isImageType(items[0].file.type)) {
return new Promise((resolve, reject) => {
Promise.all(items.map((item) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
return Object.assign(Object.assign({}, item), { file: item.file.type === 'image/gif' ? item.file : yield (0, thumbnailCoverter_1.createThumbnail)(item.file) });
})))
.then((items) => {
resolve({
items: items,
options: {
inputFieldName: options.inputFieldName
}
});
})
.catch((error) => {
utils_1.Logger.error(error, Errors_1.SCOPE_SC_UI);
resolve({
options: {
inputFieldName: options.inputFieldName
}
});
});
});
}
else {
//returned object can be wrapped with a promise
return Promise.resolve({
options: {
inputFieldName: options.inputFieldName
}
});
}
});
return null;
};
;