@instructure/quiz-interactions
Version:
A React UI component Library for quiz interaction types.
84 lines (70 loc) • 2.1 kB
JavaScript
import React, {useState, useRef, useEffect, useCallback} from 'react'
import PropTypes from 'prop-types'
import pickBy from 'lodash/fp/pickBy'
import forEach from 'lodash/fp/forEach'
import Alert from '../Alert'
const dummyImg = 'https://i.ytimg.com/vi/LgkAebhJ7iE/maxresdefault.jpg'
function clone(children, props) {
return React.cloneElement(
children,
pickBy(prop => prop !== void 0, props),
)
}
function TakeStateProvider({children}) {
const [userResponse, setUserResponse] = useState(undefined)
const alertRef = useRef(null)
const uploadRequestsRef = useRef({})
// Cleanup on unmount
useEffect(() => {
return () => {
forEach(clearTimeout, uploadRequestsRef.current)
}
}, [])
// generates the callback used when an upload has finished
const makeUploadHandler = useCallback((id, callback) => {
return () => {
delete uploadRequestsRef.current[id]
callback(dummyImg)
}
}, [])
const cancelMediaUpload = useCallback(id => {
clearTimeout(uploadRequestsRef.current[id])
delete uploadRequestsRef.current[id]
}, [])
const handleResponseUpdate = useCallback((value, properties) => {
setUserResponse({value, properties})
}, [])
const notifyScreenreader = useCallback(content => {
alertRef.current?.setAlert(content)
}, [])
const mediaUpload = useCallback(
(id, file, callback) => {
// Simulates the upload of file
// calls callback when the upload has finished
if (uploadRequestsRef.current[id] !== void 0) {
cancelMediaUpload(id)
}
uploadRequestsRef.current[id] = setTimeout(
makeUploadHandler(id, callback),
2000 + Math.random() * 2000,
)
},
[cancelMediaUpload, makeUploadHandler],
)
return (
<div>
<Alert ref={alertRef} />
{clone(children, {
notifyScreenreader,
userResponse,
handleResponseUpdate,
cancelMediaUpload,
mediaUpload,
})}
</div>
)
}
TakeStateProvider.propTypes = {
children: PropTypes.node.isRequired,
}
export default TakeStateProvider