import React, { useRef, useState } from 'react'; import CircularProgress from '@mui/material/CircularProgress'; import IconButton from '@mui/material/IconButton'; import Tooltip from '@mui/material/Tooltip'; import { styled } from '@mui/material/styles'; import AddCircleOutline from '@mui/icons-material/AddCircleOutline'; import CameraAlt from '@mui/icons-material/CameraAlt'; import { ScreenshotDropzone } from './ScreenshotDropzone'; import { ScreenshotThumbnail } from './ScreenshotThumbnail'; import { MAX_FILE_COUNT } from './utils'; import { DEVTOOLS_Z_INDEX } from '../../constants'; import { useDialogContext, useDialogDispatch, } from '../TranslationDialogContextProvider'; import { ScreenshotDetail } from './ScreenshotDetail'; import { ScFieldTitle } from '../../common/FieldTitle'; import { ExtensionPrompt } from './ExtensionPrompt'; const ScPlaceholder = styled('div')` display: flex; flex-direction: column; height: 100px; width: 100%; align-items: center; justify-content: center; text-align: center; flex-grow: 1; border: 1px dashed lightgrey; `; const ScScreenshotDummy = styled('div')` display: flex; width: 100px; height: 100px; align-items: center; justify-content: center; margin: 1px; `; const ScHeading = styled('div')` display: flex; justify-content: space-between; align-items: flex-end; `; const ScControls = styled('div')` display: flex; `; const ScText = styled('div')` color: ${({ theme }) => theme.palette.text.secondary}; `; const ALLOWED_UPLOAD_TYPES = ['image/png', 'image/jpeg', 'image/gif']; export const ScreenshotGallery: React.FC = () => { const fileRef = useRef(null); const dispatch = useDialogDispatch(); const screenshots = useDialogContext((c) => c.screenshots); const screenshotDetails = useDialogContext((c) => c.screenshotDetail); const pluginAvailable = useDialogContext((c) => c.pluginAvailable); const dependencies = useDialogContext((c) => c.dependencies); const formDisabled = useDialogContext((c) => c.formDisabled); const screenshotsUploading = useDialogContext((c) => c.screenshotsUploading); const uploadImages = (files: File[]) => { dispatch({ type: 'HANDLE_UPLOAD_IMAGES', payload: { files } }); }; const removeScreenshot = (id: number) => { dispatch({ type: 'HANDLE_REMOVE_SCREENSHOT', payload: { id } }); }; const takeScreenshot = () => { dispatch({ type: 'HANDLE_TAKE_SCREENSHOT' }); }; const [extensionPrompt, setExtensionPrompt] = useState(false); const uploadEnabled = dependencies.coreService.isAuthorizedTo('screenshots.upload') && !formDisabled; const deleteEnabled = dependencies.coreService.isAuthorizedTo('screenshots.delete') && !formDisabled; function onFileSelected(e: React.SyntheticEvent) { const files = (e.target as HTMLInputElement).files; if (!files) { return; } const toUpload: File[] = []; for (let i = 0; i < files.length; i++) { const item = files.item(i); if (item) { toUpload.push(item); } } validateAndUpload(toUpload); } const validate = (files: File[]) => { const errors: string[] = []; if (files.length > MAX_FILE_COUNT) { errors.push('Too many files'); } files.forEach((file) => { if (ALLOWED_UPLOAD_TYPES.indexOf(file.type) < 0) { errors.push(`${file.name}: unsupported format`); } }); const valid = errors.length === 0; return { errors, valid }; }; const validateAndUpload = (files: File[]) => { const { valid } = validate(files); if (valid) { uploadImages(files); } }; const onFileSelect = () => { fileRef.current?.dispatchEvent(new MouseEvent('click')); }; const ableToTakeScreenshot = pluginAvailable; // @ts-ignore const isChrome = Boolean(window.chrome); return ( <> onFileSelected(e)} multiple accept={ALLOWED_UPLOAD_TYPES.join(',')} /> Screenshots {uploadEnabled && ( <> {(isChrome || ableToTakeScreenshot) && ( setExtensionPrompt(true) } > )} )} {screenshots.length ? screenshots.map((ss) => ( dispatch({ type: 'OPEN_SCREENSHOT_DETAIL', payload: ss }) } onDelete={ deleteEnabled || ss.justUploaded ? removeScreenshot : undefined } /> )) : null} {screenshotsUploading && ( )} {!screenshots.length && !screenshotsUploading && ( There are no screenshots. {ableToTakeScreenshot && uploadEnabled && ' Take screenshot by camera icon.'} {uploadEnabled && ( Add some by dropping or clicking on plus. )} )} {screenshotDetails && ( dispatch({ type: 'CLOSE_SCREENSHOT_DETAIL' })} /> )} {extensionPrompt && ( setExtensionPrompt(false)} /> )} ); };