diff --git a/.eslintrc.js b/.eslintrc.js index 9e749f1436..74c9677e37 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -340,6 +340,7 @@ module.exports = { { files: [ '*.test.js', + '*.test.ts', 'test/endtoend/*.js', 'bin/**.js', ], diff --git a/packages/@uppy/webcam/src/CameraIcon.jsx b/packages/@uppy/webcam/src/CameraIcon.jsx deleted file mode 100644 index add8393463..0000000000 --- a/packages/@uppy/webcam/src/CameraIcon.jsx +++ /dev/null @@ -1,9 +0,0 @@ -import { h } from 'preact' - -export default () => { - return ( - - ) -} diff --git a/packages/@uppy/webcam/src/CameraIcon.tsx b/packages/@uppy/webcam/src/CameraIcon.tsx new file mode 100644 index 0000000000..09084a86b6 --- /dev/null +++ b/packages/@uppy/webcam/src/CameraIcon.tsx @@ -0,0 +1,19 @@ +import { h, type ComponentChild } from 'preact' + +export default function CameraIcon(): ComponentChild { + return ( + + ) +} diff --git a/packages/@uppy/webcam/src/CameraScreen.jsx b/packages/@uppy/webcam/src/CameraScreen.jsx deleted file mode 100644 index 479a67b9c8..0000000000 --- a/packages/@uppy/webcam/src/CameraScreen.jsx +++ /dev/null @@ -1,119 +0,0 @@ -/* eslint-disable jsx-a11y/media-has-caption */ -import { h, Component } from 'preact' -import SnapshotButton from './SnapshotButton.jsx' -import RecordButton from './RecordButton.jsx' -import RecordingLength from './RecordingLength.jsx' -import VideoSourceSelect from './VideoSourceSelect.jsx' -import SubmitButton from './SubmitButton.jsx' -import DiscardButton from './DiscardButton.jsx' - -function isModeAvailable (modes, mode) { - return modes.includes(mode) -} - -class CameraScreen extends Component { - componentDidMount () { - const { onFocus } = this.props - onFocus() - } - - componentWillUnmount () { - const { onStop } = this.props - onStop() - } - - render () { - const { - src, - recordedVideo, - recording, - modes, - supportsRecording, - videoSources, - showVideoSourceDropdown, - showRecordingLength, - onSubmit, - i18n, - mirror, - onSnapshot, - onStartRecording, - onStopRecording, - onDiscardRecordedVideo, - recordingLengthSeconds, - } = this.props - - const hasRecordedVideo = !!recordedVideo - const shouldShowRecordButton = !hasRecordedVideo && supportsRecording && ( - isModeAvailable(modes, 'video-only') - || isModeAvailable(modes, 'audio-only') - || isModeAvailable(modes, 'video-audio') - ) - const shouldShowSnapshotButton = !hasRecordedVideo && isModeAvailable(modes, 'picture') - const shouldShowRecordingLength = supportsRecording && showRecordingLength && !hasRecordedVideo - const shouldShowVideoSourceDropdown = showVideoSourceDropdown && videoSources && videoSources.length > 1 - - const videoProps = { - playsinline: true, - } - - if (recordedVideo) { - videoProps.muted = false - videoProps.controls = true - videoProps.src = recordedVideo - - // reset srcObject in dom. If not resetted, stream sticks in element - if (this.videoElement) { - this.videoElement.srcObject = undefined - } - } else { - videoProps.muted = true - videoProps.autoplay = true - videoProps.srcObject = src - } - - return ( -
-
-
-
-
- {shouldShowVideoSourceDropdown - ? VideoSourceSelect(this.props) - : null} -
-
- {shouldShowSnapshotButton && } - - {shouldShowRecordButton && ( - - )} - - {hasRecordedVideo && } - - {hasRecordedVideo && } -
- -
- {shouldShowRecordingLength && ( - - )} -
-
-
- ) - } -} - -export default CameraScreen diff --git a/packages/@uppy/webcam/src/CameraScreen.tsx b/packages/@uppy/webcam/src/CameraScreen.tsx new file mode 100644 index 0000000000..c7b7cf275e --- /dev/null +++ b/packages/@uppy/webcam/src/CameraScreen.tsx @@ -0,0 +1,164 @@ +/* eslint-disable jsx-a11y/media-has-caption */ +import type { I18n } from '@uppy/utils/lib/Translator' +import { h, Component, type ComponentChild } from 'preact' +import type { HTMLAttributes } from 'preact/compat' +import SnapshotButton from './SnapshotButton.tsx' +import RecordButton from './RecordButton.tsx' +import RecordingLength from './RecordingLength.tsx' +import VideoSourceSelect, { + type VideoSourceSelectProps, +} from './VideoSourceSelect.tsx' +import SubmitButton from './SubmitButton.tsx' +import DiscardButton from './DiscardButton.tsx' + +function isModeAvailable(modes: T[], mode: any): mode is T { + return modes.includes(mode) +} + +interface CameraScreenProps extends VideoSourceSelectProps { + onFocus: () => void + onStop: () => void + + src: MediaStream | null + recording: boolean + modes: string[] + supportsRecording: boolean + showVideoSourceDropdown: boolean + showRecordingLength: boolean + onSubmit: () => void + i18n: I18n + mirror: boolean + onSnapshot: () => void + onStartRecording: () => void + onStopRecording: () => void + onDiscardRecordedVideo: () => void + recordingLengthSeconds: number +} + +class CameraScreen extends Component { + private videoElement: HTMLVideoElement + + refs: any + + componentDidMount(): void { + const { onFocus } = this.props + onFocus() + } + + componentWillUnmount(): void { + const { onStop } = this.props + onStop() + } + + render(): ComponentChild { + const { + src, + // @ts-expect-error TODO: remove unused + recordedVideo, + recording, + modes, + supportsRecording, + videoSources, + showVideoSourceDropdown, + showRecordingLength, + onSubmit, + i18n, + mirror, + onSnapshot, + onStartRecording, + onStopRecording, + onDiscardRecordedVideo, + recordingLengthSeconds, + } = this.props + + const hasRecordedVideo = !!recordedVideo + const shouldShowRecordButton = + !hasRecordedVideo && + supportsRecording && + (isModeAvailable(modes, 'video-only') || + isModeAvailable(modes, 'audio-only') || + isModeAvailable(modes, 'video-audio')) + const shouldShowSnapshotButton = + !hasRecordedVideo && isModeAvailable(modes, 'picture') + const shouldShowRecordingLength = + supportsRecording && showRecordingLength && !hasRecordedVideo + const shouldShowVideoSourceDropdown = + showVideoSourceDropdown && videoSources && videoSources.length > 1 + + const videoProps: HTMLAttributes = { + playsInline: true, + } + + if (recordedVideo) { + videoProps.muted = false + videoProps.controls = true + videoProps.src = recordedVideo + + // reset srcObject in dom. If not resetted, stream sticks in element + if (this.videoElement) { + this.videoElement.srcObject = null + } + } else { + videoProps.muted = true + videoProps.autoPlay = true + // @ts-expect-error srcObject does not exist on