diff --git a/src/editors/containers/VideoUploadEditor/hooks.js b/src/editors/containers/VideoUploadEditor/hooks.js index 7db83f47b..f7fde9866 100644 --- a/src/editors/containers/VideoUploadEditor/hooks.js +++ b/src/editors/containers/VideoUploadEditor/hooks.js @@ -1,4 +1,4 @@ -import * as requests from '../../data/redux/thunkActions/requests'; +import React from 'react'; import * as module from './hooks'; import { selectors } from '../../data/redux'; import store from '../../data/store'; @@ -8,59 +8,45 @@ export const { navigateTo, } = appHooks; -export const uploadVideo = async ({ dispatch, supportedFiles }) => { - const data = { files: [] }; - supportedFiles.forEach((file) => { - data.files.push({ - file_name: file.name, - content_type: file.type, - }); - }); - const onFileUploadedHook = module.onFileUploaded(); - dispatch(await requests.uploadVideo({ - data, - onSuccess: async (response) => { - const { files } = response.data; - await Promise.all(Object.values(files).map(async (fileObj) => { - const fileName = fileObj.file_name; - const edxVideoId = fileObj.edx_video_id; - const uploadUrl = fileObj.upload_url; - const uploadFile = supportedFiles.find((file) => file.name === fileName); - - if (!uploadFile) { - console.error(`Could not find file object with name "${fileName}" in supportedFiles array.`); - return; - } - const formData = new FormData(); - formData.append('uploaded-file', uploadFile); - await fetch(uploadUrl, { - method: 'PUT', - body: formData, - headers: { - 'Content-Type': 'multipart/form-data', - }, - }) - .then(() => onFileUploadedHook(edxVideoId)) - .catch((error) => console.error('Error uploading file:', error)); - })); - }, - })); +export const state = { + loading: (val) => React.useState(val), + errorMessage: (val) => React.useState(val), + textInputValue: (val) => React.useState(val), }; -export const onFileUploaded = () => { - const state = store.getState(); - const learningContextId = selectors.app.learningContextId(state); - const blockId = selectors.app.blockId(state); - return (edxVideoId) => navigateTo(`/course/${learningContextId}/editor/video/${blockId}?selectedVideoId=${edxVideoId}`); +export const uploadEditor = () => { + const [loading, setLoading] = module.state.loading(false); + const [errorMessage, setErrorMessage] = module.state.errorMessage(null); + return { + loading, + setLoading, + errorMessage, + setErrorMessage, + }; }; -export const onUrlUploaded = () => { - const state = store.getState(); - const learningContextId = selectors.app.learningContextId(state); - const blockId = selectors.app.blockId(state); +export const uploader = () => { + const [textInputValue, settextInputValue] = module.state.textInputValue(''); + return { + textInputValue, + settextInputValue, + }; +}; + +export const postUploadRedirect = (storeState) => { + const learningContextId = selectors.app.learningContextId(storeState); + const blockId = selectors.app.blockId(storeState); return (videoUrl) => navigateTo(`/course/${learningContextId}/editor/video/${blockId}?selectedVideoUrl=${videoUrl}`); }; -export default { - uploadVideo, +export const onVideoUpload = () => { + const storeState = store.getState(); + return module.postUploadRedirect(storeState); +}; + +export default { + postUploadRedirect, + uploadEditor, + uploader, + onVideoUpload, }; diff --git a/src/editors/containers/VideoUploadEditor/index.jsx b/src/editors/containers/VideoUploadEditor/index.jsx index 54780e719..d88c46a7b 100644 --- a/src/editors/containers/VideoUploadEditor/index.jsx +++ b/src/editors/containers/VideoUploadEditor/index.jsx @@ -1,19 +1,19 @@ -import React, { useState } from 'react'; +import React from 'react'; import PropTypes from 'prop-types'; import { useDropzone } from 'react-dropzone'; import { FormattedMessage, injectIntl, intlShape } from '@edx/frontend-platform/i18n'; -import { Icon, IconButton } from '@edx/paragon'; -import './index.scss'; -import { useDispatch } from 'react-redux'; +import { Icon, IconButton, Spinner } from '@edx/paragon'; import { ArrowForward, Close, FileUpload } from '@edx/paragon/icons'; +import { connect } from 'react-redux'; +import { thunkActions } from '../../data/redux'; +import './index.scss'; import * as hooks from './hooks'; -import messages from '../../messages'; +import messages from './messages'; import * as editorHooks from '../EditorContainer/hooks'; export const VideoUploader = ({ onUpload, errorMessage }) => { - const [, setUploadedFile] = useState(); - const [textInputValue, setTextInputValue] = useState(''); - const onUrlUpdatedHook = hooks.onUrlUploaded(); + const { textInputValue, setTextInputValue } = hooks.uploader(); + const onURLUpload = hooks.onVideoUpload(); const { getRootProps, getInputProps, isDragActive } = useDropzone({ accept: 'video/*', @@ -21,7 +21,6 @@ export const VideoUploader = ({ onUpload, errorMessage }) => { onDrop: (acceptedFiles) => { if (acceptedFiles.length > 0) { const uploadfile = acceptedFiles[0]; - setUploadedFile(uploadfile); onUpload(uploadfile); } }, @@ -32,7 +31,7 @@ export const VideoUploader = ({ onUpload, errorMessage }) => { }; const handleSaveButtonClick = () => { - onUrlUpdatedHook(textInputValue); + onURLUpload(textInputValue); }; if (errorMessage) { @@ -85,12 +84,21 @@ VideoUploader.propTypes = { intl: intlShape.isRequired, }; -const VideoUploadEditor = ({ intl, onClose }) => { - const dispatch = useDispatch(); - const [errorMessage, setErrorMessage] = useState(null); - const handleCancel = () => { - editorHooks.handleCancel({ onClose }); - }; +const VideoUploadEditor = ( + { + intl, + onClose, + // Redux states + uploadVideo, + }, +) => { + const { + loading, + setLoading, + errorMessage, + setErrorMessage, + } = hooks.uploadEditor(); + const handleCancel = editorHooks.handleCancel({ onClose }); const handleDrop = (file) => { if (!file) { @@ -113,24 +121,39 @@ const VideoUploadEditor = ({ intl, onClose }) => { const newFile = new File([file], file.name, { type }); if (supportedFormats.includes(ext)) { - hooks.uploadVideo({ dispatch, supportedFiles: [newFile] }); + uploadVideo({ + supportedFiles: [newFile], + setLoadSpinner: setLoading, + postUploadRedirect: hooks.onVideoUpload(), + }); } else { const errorMsg = 'Video must be an MP4 or MOV file'; - console.log(errorMsg); setErrorMessage(errorMsg); } }; return ( -