add canvas media package
fixes COMMS-2290 flag Assignments 2 Test Plan: - create a media upload assignment - in a2 as a sutdent go submit an assignment - notice a video upload button - click button - notice the modal is shown and you can drag and drop video files or record yourself - close modal - notice no console errors or crashes Change-Id: I9a6184efb99aa05d0d634d2744cca00abf5ae26e Reviewed-on: https://gerrit.instructure.com/204375 Tested-by: Jenkins QA-Review: Steven Burnett <sburnett@instructure.com> Product-Review: Steven Burnett <sburnett@instructure.com> Reviewed-by: Landon Gilbert-Bland <lbland@instructure.com>
This commit is contained in:
parent
0b4362749f
commit
1f7bf02c4d
|
@ -62,6 +62,7 @@ docker-compose.local.*
|
|||
# sub-packages
|
||||
/packages/*/node_modules
|
||||
/packages/*/es
|
||||
/packages/*/lib
|
||||
/packages/*/coverage/
|
||||
/packages/canvas-planner/.babel-cache
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@ import React, {Component} from 'react'
|
|||
import {STUDENT_VIEW_QUERY, SUBMISSION_HISTORIES_QUERY} from '../graphqlData/Queries'
|
||||
import {Submission} from '../graphqlData/Submission'
|
||||
import TextEntry from './TextEntry'
|
||||
import MediaAttempt from './AttemptType/MediaAttempt'
|
||||
|
||||
export default class AttemptTab extends Component {
|
||||
static propTypes = {
|
||||
|
@ -164,9 +165,21 @@ export default class AttemptTab extends Component {
|
|||
)
|
||||
}
|
||||
|
||||
renderMediaAttempt = createSubmissionDraft => {
|
||||
return (
|
||||
<MediaAttempt
|
||||
createSubmissionDraft={createSubmissionDraft}
|
||||
submission={this.props.submission}
|
||||
updateUploadState={this.updateUploadState}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
renderSubmissionByType = (createSubmission, createSubmissionDraft) => {
|
||||
// TODO: we need to ensure we handle multiple submission types eventually
|
||||
switch (this.props.assignment.submissionTypes[0]) {
|
||||
case 'media_recording':
|
||||
return this.renderMediaAttempt(createSubmission, createSubmissionDraft)
|
||||
case 'online_text_entry':
|
||||
return this.renderTextAttempt(createSubmissionDraft)
|
||||
case 'online_upload':
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright (C) 2019 - present Instructure, Inc.
|
||||
*
|
||||
* This file is part of Canvas.
|
||||
*
|
||||
* Canvas is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License as published by the Free
|
||||
* Software Foundation, version 3 of the License.
|
||||
*
|
||||
* Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import Billboard from '@instructure/ui-billboard/lib/components/Billboard'
|
||||
import Button from '@instructure/ui-buttons/lib/components/Button'
|
||||
import I18n from 'i18n!assignments_2_text_entry'
|
||||
import {IconAttachMediaLine} from '@instructure/ui-icons'
|
||||
import React, {useState} from 'react'
|
||||
import UploadMedia from '@instructure/canvas-media'
|
||||
import View from '@instructure/ui-layout/lib/components/View'
|
||||
|
||||
export default function MediaAttempt() {
|
||||
const [mediaModalOpen, setMediaModalOpen] = useState(false)
|
||||
|
||||
return (
|
||||
<View as="div" borderWidth="small">
|
||||
<UploadMedia onDismiss={() => setMediaModalOpen(false)} open={mediaModalOpen} />
|
||||
<Billboard
|
||||
heading={I18n.t('Add Media')}
|
||||
hero={<IconAttachMediaLine color="brand" />}
|
||||
message={
|
||||
<Button size="small" variant="primary" onClick={() => setMediaModalOpen(true)}>
|
||||
{I18n.t('Record/Upload')}
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
</View>
|
||||
)
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
{
|
||||
"name": "@instructure/canvas-media",
|
||||
"version": "1.0.0",
|
||||
"description": "A component that will handle upload/record and displaying of media",
|
||||
"author": "Instructure, Inc.",
|
||||
"main": "lib/index.js",
|
||||
"module": "es/index.js",
|
||||
"sideEffects": false,
|
||||
"scripts": {
|
||||
"test": "echo 'no tests yet...'",
|
||||
"build:canvas": "babel --root-mode upward src -d es & JEST_WORKER_ID=true babel --root-mode upward src -d lib"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/instructure/canvas-lms.git"
|
||||
},
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/instructure/canvas-lms/issues"
|
||||
},
|
||||
"homepage": "https://github.com/instructure/canvas-lms#readme",
|
||||
"dependencies": {
|
||||
"@instructure/canvas-theme": "^6.8.1",
|
||||
"@instructure/media-capture": "^5",
|
||||
"@instructure/ui-a11y": "^6.8.1",
|
||||
"@instructure/ui-alerts": "^6.8.1",
|
||||
"@instructure/ui-billboard": "^6.8.1",
|
||||
"@instructure/ui-buttons": "^6.8.1",
|
||||
"@instructure/ui-color-utils": "^6.8.1",
|
||||
"@instructure/ui-elements": "^6.8.1",
|
||||
"@instructure/ui-forms": "^6.8.1",
|
||||
"@instructure/ui-icons": "^6.8.1",
|
||||
"@instructure/ui-layout": "^6.8.1",
|
||||
"@instructure/ui-media-player": "^5",
|
||||
"@instructure/ui-overlays": "^6.8.1",
|
||||
"@instructure/ui-pagination": "^6.8.1",
|
||||
"@instructure/ui-react-utils": "^6.8.1",
|
||||
"@instructure/ui-svg-images": "^6.8.1",
|
||||
"@instructure/ui-tabs": "^6.8.1",
|
||||
"@instructure/ui-text-input": "^6.8.1",
|
||||
"@instructure/ui-themeable": "^6.8.1",
|
||||
"@instructure/ui-themes": "^6.8.1",
|
||||
"@instructure/ui-toggle-details": "^6.8.1",
|
||||
"@instructure/uid": "^6.8.1",
|
||||
"prop-types": "^15",
|
||||
"react": "^16",
|
||||
"react-dom": "^16"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
* Copyright (C) 2019 - present Instructure, Inc.
|
||||
*
|
||||
* This file is part of Canvas.
|
||||
*
|
||||
* Canvas is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License as published by the Free
|
||||
* Software Foundation, version 3 of the License.
|
||||
*
|
||||
* Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import React, {useState} from 'react'
|
||||
import {arrayOf, bool, func, instanceOf, oneOfType, string} from 'prop-types'
|
||||
|
||||
import {Billboard} from '@instructure/ui-billboard'
|
||||
import {Button} from '@instructure/ui-buttons'
|
||||
import {FileDrop} from '@instructure/ui-forms'
|
||||
import {Flex, View} from '@instructure/ui-layout'
|
||||
import {IconTrashLine} from '@instructure/ui-icons'
|
||||
import {PresentationContent, ScreenReaderContent} from '@instructure/ui-a11y'
|
||||
import {Text} from '@instructure/ui-elements'
|
||||
import {VideoPlayer} from '@instructure/ui-media-player'
|
||||
|
||||
import RocketSVG from './RocketSVG'
|
||||
|
||||
export default function ComputerPanel({
|
||||
theFile,
|
||||
setFile,
|
||||
hasUploadedFile,
|
||||
setHasUploadedFile,
|
||||
accept,
|
||||
label
|
||||
}) {
|
||||
const [messages, setMessages] = useState([])
|
||||
if (hasUploadedFile) {
|
||||
const sources = [{label: theFile.name, src: URL.createObjectURL(theFile)}]
|
||||
return (
|
||||
<>
|
||||
<Flex direction="row-reverse" margin="none none medium">
|
||||
<Flex.Item>
|
||||
<Button
|
||||
onClick={() => {
|
||||
setFile(null)
|
||||
setHasUploadedFile(false)
|
||||
}}
|
||||
icon={IconTrashLine}
|
||||
>
|
||||
<ScreenReaderContent>Clear selected file</ScreenReaderContent>
|
||||
</Button>
|
||||
</Flex.Item>
|
||||
<Flex.Item grow shrink>
|
||||
<PresentationContent>
|
||||
<Text>{theFile.name}</Text>
|
||||
</PresentationContent>
|
||||
</Flex.Item>
|
||||
</Flex>
|
||||
<View as="div" height="100%" width="100%" textAlign="center">
|
||||
<VideoPlayer sources={sources} />
|
||||
</View>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<FileDrop
|
||||
accept={accept}
|
||||
onDropAccepted={([file]) => {
|
||||
if (messages.length) {
|
||||
setMessages([])
|
||||
}
|
||||
setFile(file)
|
||||
setHasUploadedFile(true)
|
||||
}}
|
||||
onDropRejected={() => {
|
||||
setMessages((msgs) =>
|
||||
msgs.concat({
|
||||
text:'Invalid file type',
|
||||
type: 'error'
|
||||
})
|
||||
)
|
||||
}}
|
||||
messages={messages}
|
||||
label={
|
||||
<Billboard
|
||||
heading={label}
|
||||
hero={<RocketSVG width="3em" height="3em" />}
|
||||
message='Drag and drop, or click to browse your computer'
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
ComputerPanel.propTypes = {
|
||||
theFile: instanceOf(File),
|
||||
setFile: func.isRequired,
|
||||
hasUploadedFile: bool,
|
||||
setHasUploadedFile: func.isRequired,
|
||||
accept: oneOfType([string, arrayOf(string)]),
|
||||
label: string.isRequired
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright (C) 2019 - present Instructure, Inc.
|
||||
*
|
||||
* This file is part of Canvas.
|
||||
*
|
||||
* Canvas is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License as published by the Free
|
||||
* Software Foundation, version 3 of the License.
|
||||
*
|
||||
* Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import React from 'react'
|
||||
import { string, func } from 'prop-types'
|
||||
import { TextArea } from '@instructure/ui-forms'
|
||||
|
||||
export default function EmbedPanel ({embedCode, setEmbedCode}) {
|
||||
return (
|
||||
<TextArea
|
||||
maxHeight="10rem"
|
||||
label='Embed Video Code'
|
||||
value={embedCode}
|
||||
onChange={(e) =>{
|
||||
setEmbedCode(e.target.value)}
|
||||
}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
EmbedPanel.propTypes = {
|
||||
embedCode: string.isRequired,
|
||||
setEmbedCode: func.isRequired
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright (C) 2019 - present Instructure, Inc.
|
||||
*
|
||||
* This file is part of Canvas.
|
||||
*
|
||||
* Canvas is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License as published by the Free
|
||||
* Software Foundation, version 3 of the License.
|
||||
*
|
||||
* Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
const formatMessage = (string) => string
|
||||
|
||||
const MediaCaptureStrings = {
|
||||
ARIA_VIDEO_LABEL: formatMessage('Video Player'),
|
||||
ARIA_VOLUME: formatMessage('Current Volume Level'),
|
||||
ARIA_RECORDING: formatMessage('Recording'),
|
||||
DEFAULT_ERROR: formatMessage('Something went wrong accessing your mic or webcam.'),
|
||||
DEVICE_AUDIO: formatMessage('Mic'),
|
||||
DEVICE_VIDEO: formatMessage('Webcam'),
|
||||
FILE_PLACEHOLDER: formatMessage('Untitled'),
|
||||
FINISH: formatMessage('Finish'),
|
||||
NO_WEBCAM: formatMessage('No Video'),
|
||||
NOT_ALLOWED_ERROR: formatMessage('Please allow Canvas to access your microphone and webcam.'),
|
||||
NOT_READABLE_ERROR: formatMessage('Your webcam may already be in use.'),
|
||||
PLAYBACK_PAUSE: formatMessage('Pause'),
|
||||
PLAYBACK_PLAY: formatMessage('Play'),
|
||||
PREVIEW: formatMessage('PREVIEW'),
|
||||
SAVE: formatMessage('Save'),
|
||||
SR_FILE_INPUT: formatMessage('File name'),
|
||||
START: formatMessage('Start Recording'),
|
||||
START_OVER: formatMessage('Start Over')
|
||||
}
|
||||
|
||||
export {MediaCaptureStrings}
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright (C) 2019 - present Instructure, Inc.
|
||||
*
|
||||
* This file is part of Canvas.
|
||||
*
|
||||
* Canvas is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License as published by the Free
|
||||
* Software Foundation, version 3 of the License.
|
||||
*
|
||||
* Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import {Alert} from '@instructure/ui-alerts'
|
||||
import {canUseMediaCapture, MediaCapture} from '@instructure/media-capture'
|
||||
// import {object, func} from 'prop-types'
|
||||
import React from 'react'
|
||||
import {MediaCaptureStrings} from './MediaCaptureStrings'
|
||||
|
||||
export default class MediaRecorder extends React.Component {
|
||||
// saveFile = (file) => {
|
||||
// this.props.contentProps.saveMediaRecording(file, this.props.editor, this.props.dismiss)
|
||||
// }
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
{canUseMediaCapture() ? (
|
||||
<MediaCapture
|
||||
translations={MediaCaptureStrings}
|
||||
onCompleted={this.saveFile}
|
||||
/>
|
||||
) :
|
||||
(<Alert
|
||||
variant="error"
|
||||
margin="small"
|
||||
>
|
||||
{'Error uploading video/audio recording'}
|
||||
</Alert>)
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// MediaRecorder.propTypes = {
|
||||
// dismiss: func.isRequired,
|
||||
// }
|
|
@ -0,0 +1,144 @@
|
|||
/*
|
||||
* Copyright (C) 2019 - present Instructure, Inc.
|
||||
*
|
||||
* This file is part of Canvas.
|
||||
*
|
||||
* Canvas is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License as published by the Free
|
||||
* Software Foundation, version 3 of the License.
|
||||
*
|
||||
* Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import React from 'react'
|
||||
|
||||
const RocketSVG = props => (
|
||||
<svg id="filedrop-rocket_svg__Layer_1" data-name="Layer 1" viewBox="0 0 182 182" {...props}>
|
||||
<defs>
|
||||
<style>
|
||||
{
|
||||
'.filedrop-rocket_svg__cls-1{fill:#243038}.filedrop-rocket_svg__cls-2{fill:#c0c6cb}.filedrop-rocket_svg__cls-3{fill:#e5e7e9}.filedrop-rocket_svg__cls-4{fill:#d0d4d8}'
|
||||
}
|
||||
</style>
|
||||
</defs>
|
||||
<path className="filedrop-rocket_svg__cls-1" d="M152.21 138.46h-32v-93h32zm-30-2h28v-89h-28z" />
|
||||
<path
|
||||
className="filedrop-rocket_svg__cls-1"
|
||||
transform="rotate(-45 136.317 61.556)"
|
||||
d="M135.32 40.2h2v42.73h-2z"
|
||||
/>
|
||||
<path
|
||||
className="filedrop-rocket_svg__cls-1"
|
||||
transform="rotate(-45 136.317 61.556)"
|
||||
d="M114.95 60.56h42.73v2h-42.73z"
|
||||
/>
|
||||
<path
|
||||
className="filedrop-rocket_svg__cls-1"
|
||||
transform="rotate(-45 136.314 92.667)"
|
||||
d="M135.32 71.3h2v42.73h-2z"
|
||||
/>
|
||||
<path
|
||||
className="filedrop-rocket_svg__cls-1"
|
||||
transform="rotate(-45 136.314 92.667)"
|
||||
d="M114.95 91.66h42.73v2h-42.73z"
|
||||
/>
|
||||
<path
|
||||
className="filedrop-rocket_svg__cls-1"
|
||||
transform="rotate(-45 136.317 122.056)"
|
||||
d="M135.32 100.7h2v42.73h-2z"
|
||||
/>
|
||||
<path
|
||||
className="filedrop-rocket_svg__cls-1"
|
||||
transform="rotate(-45 136.317 122.056)"
|
||||
d="M114.95 121.06h42.73v2h-42.73z"
|
||||
/>
|
||||
<path
|
||||
className="filedrop-rocket_svg__cls-1"
|
||||
d="M121.21 76.56h30v2h-30zM121.21 106.56h30v2h-30zM87.39 50.56h33.82v2H87.39zM88.11 55.46h33.1v2h-33.1z"
|
||||
/>
|
||||
<path
|
||||
className="filedrop-rocket_svg__cls-2"
|
||||
d="M45.36 97.31a27 27 0 0 0-26.3 20.87 5 5 0 0 0 4.88 6.13h42.84a5 5 0 0 0 4.88-6.13 27 27 0 0 0-26.3-20.87z"
|
||||
/>
|
||||
<path
|
||||
className="filedrop-rocket_svg__cls-1"
|
||||
d="M66.78 125.31H23.94a6 6 0 0 1-5.85-7.31 28 28 0 0 1 54.55 0 6 6 0 0 1-5.86 7.36zm-21.42-27A25.87 25.87 0 0 0 20 118.4a4 4 0 0 0 3.91 4.91h42.87a4 4 0 0 0 3.14-1.52 4 4 0 0 0 .77-3.39 25.87 25.87 0 0 0-25.33-20.09z"
|
||||
/>
|
||||
<path
|
||||
className="filedrop-rocket_svg__cls-2"
|
||||
d="M78.36 97.31a27 27 0 0 0-26.3 20.87 5 5 0 0 0 4.88 6.13h42.84a5 5 0 0 0 4.88-6.13 27 27 0 0 0-26.3-20.87z"
|
||||
/>
|
||||
<path
|
||||
className="filedrop-rocket_svg__cls-1"
|
||||
d="M99.78 125.31H56.94a6 6 0 0 1-5.85-7.31 28 28 0 0 1 54.55 0 6 6 0 0 1-5.86 7.36zm-21.42-27A25.87 25.87 0 0 0 53 118.4a4 4 0 0 0 3.91 4.91h42.87a4 4 0 0 0 3.14-1.52 4 4 0 0 0 .77-3.39 25.87 25.87 0 0 0-25.33-20.09z"
|
||||
/>
|
||||
<path
|
||||
className="filedrop-rocket_svg__cls-3"
|
||||
d="M84.37 124.31c3.32-12.17 5.29-27.18 5.29-43.43 0-40.55-12.22-73.42-27.29-73.42s-27.3 32.87-27.3 73.42c0 16.25 2 31.26 5.29 43.43z"
|
||||
/>
|
||||
<path
|
||||
className="filedrop-rocket_svg__cls-1"
|
||||
d="M85.13 125.31H39.6l-.2-.74c-3.49-12.75-5.33-27.86-5.33-43.69 0-41.73 12.43-74.42 28.3-74.42s28.29 32.69 28.29 74.42c0 15.83-1.84 30.94-5.32 43.69zm-44-2h42.48a168.39 168.39 0 0 0 5-42.43C88.66 41 76.86 8.46 62.37 8.46S36.07 41 36.07 80.88a167.91 167.91 0 0 0 5.06 42.43z"
|
||||
/>
|
||||
<path className="filedrop-rocket_svg__cls-4" d="M75.37 136.87H49.36l-4-12.56h34.01l-4 12.56z" />
|
||||
<path
|
||||
className="filedrop-rocket_svg__cls-1"
|
||||
d="M76.1 137.87H48.63L44 123.31h36.74zm-26-2h24.54L78 125.31H46.73z"
|
||||
/>
|
||||
<circle className="filedrop-rocket_svg__cls-2" cx={62.37} cy={78.88} r={15.75} />
|
||||
<path
|
||||
className="filedrop-rocket_svg__cls-1"
|
||||
d="M62.37 95.63a16.75 16.75 0 1 1 16.75-16.75 16.76 16.76 0 0 1-16.75 16.75zm0-31.5a14.75 14.75 0 1 0 14.75 14.75 14.76 14.76 0 0 0-14.75-14.75z"
|
||||
/>
|
||||
<circle cx={62.37} cy={78.88} r={11} fill="#9ad6f5" />
|
||||
<path
|
||||
className="filedrop-rocket_svg__cls-1"
|
||||
d="M62.37 90.88a12 12 0 1 1 12-12 12 12 0 0 1-12 12zm0-22a10 10 0 1 0 10 10 10 10 0 0 0-10-10zM40.09 37.44h44.55v2H40.09z"
|
||||
/>
|
||||
<path
|
||||
className="filedrop-rocket_svg__cls-4"
|
||||
d="M171.21 147.46h-160l3.79-9.38a1 1 0 0 1 .93-.62h150.6a1 1 0 0 1 .93.62z"
|
||||
/>
|
||||
<path
|
||||
className="filedrop-rocket_svg__cls-1"
|
||||
d="M172.69 148.46H9.73L14 137.71a2 2 0 0 1 1.86-1.25h150.67a2 2 0 0 1 1.86 1.25zm-160-2h157l-3.2-8H15.89z"
|
||||
/>
|
||||
<path className="filedrop-rocket_svg__cls-3" d="M11.21 147.46h160v11h-160z" />
|
||||
<path
|
||||
className="filedrop-rocket_svg__cls-1"
|
||||
d="M172.21 159.46h-162v-13h162zm-160-2h158v-9h-158z"
|
||||
/>
|
||||
<path
|
||||
className="filedrop-rocket_svg__cls-2"
|
||||
d="M15.21 177.46H3.79a1 1 0 0 1-.9-1.43l8.32-17.57h30z"
|
||||
/>
|
||||
<path
|
||||
className="filedrop-rocket_svg__cls-1"
|
||||
d="M15.54 178.46H3.79A2 2 0 0 1 2 175.6l8.6-18.14h33.67zm-3.7-19l-8 17h11.04l23.27-17z"
|
||||
/>
|
||||
<path
|
||||
className="filedrop-rocket_svg__cls-2"
|
||||
d="M166.79 177.46h11.42a1 1 0 0 0 .9-1.43l-8.32-17.57h-30z"
|
||||
/>
|
||||
<path
|
||||
className="filedrop-rocket_svg__cls-1"
|
||||
d="M178.21 178.46h-11.75l-28.73-21h33.69L180 175.6a2 2 0 0 1-1.81 2.86zm-11.09-2h11.09l-8.05-17h-26.31z"
|
||||
/>
|
||||
<path
|
||||
className="filedrop-rocket_svg__cls-2"
|
||||
d="M85.49 177.05a1 1 0 0 0 .8.41h10.92c.73 0 15.58-19 15.58-19h-41z"
|
||||
/>
|
||||
<path
|
||||
className="filedrop-rocket_svg__cls-1"
|
||||
d="M97.21 178.46H86.29a2 2 0 0 1-1.6-.82l-14.88-20.18h45l-1.26 1.61c-15.12 19.39-15.74 19.39-16.34 19.39zm-10.92-2l-.8.59.8-.59zm0 0h10.6c1.47-1.4 8.71-10.46 13.85-17h-37z"
|
||||
/>
|
||||
</svg>
|
||||
)
|
||||
|
||||
export default RocketSVG
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright (C) 2019 - present Instructure, Inc.
|
||||
*
|
||||
* This file is part of Canvas.
|
||||
*
|
||||
* Canvas is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License as published by the Free
|
||||
* Software Foundation, version 3 of the License.
|
||||
*
|
||||
* Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
export const ACCEPTED_FILE_TYPES = [
|
||||
"3gp",
|
||||
"aac",
|
||||
"amr",
|
||||
"asf",
|
||||
"avi",
|
||||
"flac",
|
||||
"flv",
|
||||
"m4a",
|
||||
"m4v",
|
||||
"mkv",
|
||||
"mov",
|
||||
"mp3",
|
||||
"mp4",
|
||||
"mpeg",
|
||||
"mpg",
|
||||
"ogg",
|
||||
"qt",
|
||||
"wav",
|
||||
"wma",
|
||||
"wmv"
|
||||
]
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Copyright (C) 2019 - present Instructure, Inc.
|
||||
*
|
||||
* This file is part of Canvas.
|
||||
*
|
||||
* Canvas is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License as published by the Free
|
||||
* Software Foundation, version 3 of the License.
|
||||
*
|
||||
* Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import {
|
||||
IconDocumentLine,
|
||||
IconMsExcelLine,
|
||||
IconMsPptLine,
|
||||
IconMsWordLine,
|
||||
IconPdfLine
|
||||
} from '@instructure/ui-icons'
|
||||
|
||||
export function getIconFromType(type) {
|
||||
switch(type) {
|
||||
case 'application/msword':
|
||||
case 'application/vnd.openxmlformats-officedocument.wordprocessingml.document':
|
||||
return IconMsWordLine
|
||||
case 'application/vnd.ms-powerpoint':
|
||||
case 'application/vnd.openxmlformats-officedocument.presentationml.presentation':
|
||||
return IconMsPptLine
|
||||
case 'application/pdf':
|
||||
return IconPdfLine
|
||||
case 'application/vnd.ms-excel':
|
||||
case 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet':
|
||||
return IconMsExcelLine
|
||||
default:
|
||||
return IconDocumentLine
|
||||
}
|
||||
}
|
||||
|
||||
export function isImage(type) {
|
||||
return /^image/.test(type)
|
||||
}
|
||||
|
||||
export function isAudioOrVideo(type) {
|
||||
return isVideo(type) || isAudio(type)
|
||||
}
|
||||
|
||||
export function isVideo(type) {
|
||||
return /^video/.test(type)
|
||||
}
|
||||
|
||||
export function isAudio(type) {
|
||||
return /^audio/.test(type)
|
||||
}
|
||||
|
||||
export function isText(type) {
|
||||
return /^text/.test(type)
|
||||
}
|
|
@ -0,0 +1,156 @@
|
|||
/*
|
||||
* Copyright (C) 2019 - present Instructure, Inc.
|
||||
*
|
||||
* This file is part of Canvas.
|
||||
*
|
||||
* Canvas is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License as published by the Free
|
||||
* Software Foundation, version 3 of the License.
|
||||
*
|
||||
* Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import {bool, func} from 'prop-types'
|
||||
import {Button, CloseButton} from '@instructure/ui-buttons'
|
||||
import {Heading, Spinner} from '@instructure/ui-elements'
|
||||
import {Modal} from '@instructure/ui-overlays'
|
||||
import React, {Suspense} from 'react'
|
||||
import {Tabs} from '@instructure/ui-tabs'
|
||||
import {View} from '@instructure/ui-layout'
|
||||
|
||||
import {ACCEPTED_FILE_TYPES} from './acceptedMediaFileTypes'
|
||||
|
||||
const ComputerPanel = React.lazy(() => import('./ComputerPanel'))
|
||||
const EmbedPanel = React.lazy(() => import('./EmbedPanel'))
|
||||
const MediaRecorder = React.lazy(() => import('./MediaRecorder'))
|
||||
|
||||
export const PANELS = {
|
||||
COMPUTER: 0,
|
||||
RECORD: 1,
|
||||
EMBED: 2
|
||||
}
|
||||
|
||||
export const handleSubmit = (editor, selectedPanel, uploadData, saveMediaRecording, onDismiss) => {
|
||||
switch (selectedPanel) {
|
||||
case PANELS.COMPUTER: {
|
||||
const {theFile} = uploadData
|
||||
saveMediaRecording(theFile, editor, onDismiss)
|
||||
break;
|
||||
}
|
||||
case PANELS.EMBED: {
|
||||
const {embedCode} = uploadData
|
||||
editor.insertContent(embedCode)
|
||||
onDismiss()
|
||||
break
|
||||
}
|
||||
default:
|
||||
throw new Error('Selected Panel is invalid') // Should never get here
|
||||
}
|
||||
}
|
||||
|
||||
export default class UploadMedia extends React.Component {
|
||||
|
||||
static propTypes = {
|
||||
onDismiss: func,
|
||||
open: bool
|
||||
}
|
||||
|
||||
state = {
|
||||
theFile: null,
|
||||
hasUploadedFile: false,
|
||||
selectedPanel: 0,
|
||||
embedCode: ''
|
||||
}
|
||||
|
||||
|
||||
renderModalBody = () => {
|
||||
return (
|
||||
<Tabs shouldFocusOnRender maxWidth="large" onRequestTabChange={(_, { index }) => this.setState({selectedPanel: index})}>
|
||||
<Tabs.Panel isSelected={this.state.selectedPanel === PANELS.COMPUTER} renderTitle={() => 'Computer'}>
|
||||
<Suspense fallback={
|
||||
<View as="div" height="100%" width="100%" textAlign="center">
|
||||
<Spinner renderTitle={() => "Loading Media"} size="large" margin="0 0 0 medium" />
|
||||
</View>
|
||||
} size="large">
|
||||
<ComputerPanel
|
||||
theFile={this.state.theFile}
|
||||
setFile={(file) => this.setState({theFile: file})}
|
||||
hasUploadedFile={this.state.hasUploadedFile}
|
||||
setHasUploadedFile={(uploadFileState) => this.setState({hasUploadedFile: uploadFileState})}
|
||||
label='Drag a File Here'
|
||||
accept={ACCEPTED_FILE_TYPES}
|
||||
/>
|
||||
</Suspense>
|
||||
</Tabs.Panel>
|
||||
<Tabs.Panel isSelected={this.state.selectedPanel === PANELS.RECORD} renderTitle={() => 'Record'}>
|
||||
<Suspense fallback={
|
||||
<View as="div" height="100%" width="100%" textAlign="center">
|
||||
<Spinner renderTitle={() => "Loading Media"} size="large" margin="0 0 0 medium" />
|
||||
</View>
|
||||
}>
|
||||
<MediaRecorder dismiss={this.props.onDismiss}/>
|
||||
</Suspense>
|
||||
</Tabs.Panel>
|
||||
<Tabs.Panel isSelected={this.state.selectedPanel === PANELS.EMBED} renderTitle={() => 'Embed'}>
|
||||
<Suspense fallback={
|
||||
<View as="div" height="100%" width="100%" textAlign="center">
|
||||
<Spinner renderTitle={() => "Loading Media"} size="large" margin="0 0 0 medium" />
|
||||
</View>
|
||||
}>
|
||||
<EmbedPanel embedCode={this.state.embedCode} setEmbedCode={(embedCode) => this.setState({embedCode})} />
|
||||
</Suspense>
|
||||
</Tabs.Panel>
|
||||
</Tabs>
|
||||
)
|
||||
}
|
||||
|
||||
renderModalFooter = () => {
|
||||
if (this.state.selectedPanel !== PANELS.RECORD) {
|
||||
return (
|
||||
<Modal.Footer>
|
||||
<Button onClick={this.props.onDismiss}>Close</Button>
|
||||
<Button
|
||||
onClick={e => {
|
||||
e.preventDefault()
|
||||
handleSubmit()
|
||||
}}
|
||||
variant="primary"
|
||||
type="submit"
|
||||
>
|
||||
Submit
|
||||
</Button>
|
||||
</Modal.Footer>
|
||||
)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Modal
|
||||
label='Upload Media'
|
||||
size="medium"
|
||||
onDismiss={this.props.onDismiss}
|
||||
open={this.props.open}
|
||||
shouldCloseOnDocumentClick={false}
|
||||
>
|
||||
<Modal.Header>
|
||||
<CloseButton onClick={this.props.onDismiss} offset="medium" placement="end">
|
||||
Close
|
||||
</CloseButton>
|
||||
<Heading>Upload Media</Heading>
|
||||
</Modal.Header>
|
||||
<Modal.Body>
|
||||
{this.renderModalBody()}
|
||||
</Modal.Body>
|
||||
{this.renderModalFooter()}
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
}
|
|
@ -16242,7 +16242,7 @@ react-dnd@^2.5.2:
|
|||
lodash "^4.2.0"
|
||||
prop-types "^15.5.10"
|
||||
|
||||
"react-dom@^0.14.7 || ^15 || 16", "react-dom@^0.14.8 || ^15.0.0 || ^16", react-dom@^16.6.0:
|
||||
"react-dom@^0.14.7 || ^15 || 16", "react-dom@^0.14.8 || ^15.0.0 || ^16", react-dom@^16, react-dom@^16.6.0:
|
||||
version "16.8.6"
|
||||
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.8.6.tgz#71d6303f631e8b0097f56165ef608f051ff6e10f"
|
||||
integrity sha512-1nL7PIq9LTL3fthPqwkvr2zY7phIPjYrT0jp4HjyEQrEROnw4dG41VVwi/wfoCneoleqrNX7iAD+pXebJZwrwA==
|
||||
|
@ -16383,7 +16383,7 @@ react@0.14.9:
|
|||
envify "^3.0.0"
|
||||
fbjs "^0.6.1"
|
||||
|
||||
"react@^0.14.7 || ^15 || 16", "react@^0.14.8 || ^15.0.0 || ^16", "react@^0.14.9 || ^15 || ^16", "react@^15 || ^16", react@^16.8.0:
|
||||
"react@^0.14.7 || ^15 || 16", "react@^0.14.8 || ^15.0.0 || ^16", "react@^0.14.9 || ^15 || ^16", "react@^15 || ^16", react@^16, react@^16.8.0:
|
||||
version "16.8.6"
|
||||
resolved "https://registry.yarnpkg.com/react/-/react-16.8.6.tgz#ad6c3a9614fd3a4e9ef51117f54d888da01f2bbe"
|
||||
integrity sha512-pC0uMkhLaHm11ZSJULfOBqV4tIZkx87ZLvbbQYunNixAAvjnC+snJCg0XQXn9VIsttVsbZP/H/ewzgsd5fxKXw==
|
||||
|
|
Loading…
Reference in New Issue