UNPKG

@instructure/quiz-interactions

Version:

A React UI component Library for quiz interaction types.

84 lines (70 loc) 2.1 kB
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