import { FilesController } from '@/Controllers/FilesController' import { PhotoRecorder } from '@/Controllers/Moments/PhotoRecorder' import { formatDateAndTimeForNote } from '@/Utils/DateUtils' import { classNames } from '@standardnotes/snjs' import { observer } from 'mobx-react-lite' import { useCallback, useEffect, useMemo, useRef, useState } from 'react' import Dropdown from '../Dropdown/Dropdown' import Icon from '../Icon/Icon' import DecoratedInput from '../Input/DecoratedInput' import Modal from '../Modal/Modal' type Props = { filesController: FilesController close: () => void } const PhotoCaptureModal = ({ filesController, close }: Props) => { const [fileName, setFileName] = useState(formatDateAndTimeForNote(new Date())) const [recorder, setRecorder] = useState(() => new PhotoRecorder()) const [isRecorderReady, setIsRecorderReady] = useState(false) const [capturedPhoto, setCapturedPhoto] = useState() const fileNameInputRef = useRef(null) const previewRef = useRef(null) useEffect(() => { if (!recorder) { return } setIsRecorderReady(false) const init = async () => { await recorder.initialize() if (previewRef.current) { recorder.video.style.position = '' recorder.video.style.display = '' recorder.video.style.height = '100%' previewRef.current.append(recorder.video) } setIsRecorderReady(true) } void init() return () => { if (recorder.video) { recorder.finish() } } }, [recorder]) const takePhoto = useCallback(async () => { if (!recorder) { return } const file = await recorder.takePhoto(fileName) setCapturedPhoto(file) setRecorder(undefined) }, [fileName, recorder]) const devicesAsDropdownItems = useMemo(() => { return recorder?.devices ? recorder.devices.map((device) => ({ label: device.label || `Camera (${device.deviceId.slice(0, 10)})`, value: device.deviceId, })) : [] }, [recorder?.devices]) const savePhoto = useCallback(() => { if (!fileName) { fileNameInputRef.current?.focus() return } if (!capturedPhoto) { return } void filesController.uploadNewFile(capturedPhoto) close() }, [capturedPhoto, close, fileName, filesController]) const retryPhoto = () => { setCapturedPhoto(undefined) setRecorder(new PhotoRecorder()) } return (
Preview:
{!isRecorderReady && (
Initializing...
)}
{capturedPhoto && (
Captured photo
)}
{recorder && devicesAsDropdownItems.length > 1 && !capturedPhoto && (
)}
) } export default observer(PhotoCaptureModal)