/** * * HomePage * */ import React, { useCallback } from 'react'; import { Button, Columns, Column, Content, Container, DropZone, Footer, Title, Notification, } from 'quinoa-design-library'; import { connect, useDispatch } from 'react-redux'; import { Helmet } from 'react-helmet'; import { toastr } from 'react-redux-toastr/lib'; import { FormattedMessage } from 'react-intl'; import { createStructuredSelector } from 'reselect'; import { compose } from 'redux'; import { propSatisfies, pipe, __, includes, head } from 'ramda'; import { ContainerState } from './types'; import injectSaga from 'utils/injectSaga'; import injectReducer from 'utils/injectReducer'; import makeSelectSlideshows from './selectors'; import reducer from './reducer'; import saga from './saga'; import messages from './messages'; import './styles.css'; import { createSlideshowAction, removeSlideshowAction, duplicationSlideshowAction } from './actions'; import SlideshowCartouche from 'components/SlideshowCartouche'; import { useSlicerState } from 'containers/App/hooks'; import medialabLogo from './assets/logo-medialab.svg'; import forccastLogo from './assets/logo-forccast.svg'; import appLogo from './assets/logo.svg'; import Slideshow from 'types/Slideshow'; import { importSlideshowAction } from 'containers/App/actions'; import Loader from 'containers/App/Loader'; import { useVideoModale } from 'components/Modal'; interface HomePageProps { createSlideshow: (file: File) => void; duplicateSlideshow: (slideshow: Slideshow) => void; importSlideshow: (file: File) => void; } const acceptedImages = [ 'image/svg+xml', 'image/jpeg', 'image/png', 'image/bmp', 'image/webp', ]; const acceptedApp = ['application/zip']; const acceptedFiles = [...acceptedImages, ...acceptedApp]; const validateImageTypes: (File) => boolean = propSatisfies( includes(__, acceptedImages), 'type', ); const validateImportTypes: (File) => boolean = propSatisfies( includes(__, acceptedApp), 'type', ); function HomePage(props: HomePageProps & ContainerState) { const dispatch = useDispatch(); const slicer = useSlicerState(); const onDrop = useCallback((files: File[]) => { const file = head(files); if (!file) { toastr.error(`Invalid file extension`, 'You tried to import a file which are not handled by Tesselle.'); } else if (validateImageTypes(file)) { return props.createSlideshow(file); } else if (validateImportTypes(file)) { return props.importSlideshow(file); } else { toastr.error( `Tesselle could not import the file ${file.name}`, 'It can be due to corrupted data or to insufficient disk space.', ); } }, [props.createSlideshow, props.importSlideshow]); const onDelete = useCallback(pipe(removeSlideshowAction.request, dispatch), []); const [opener, modale] = useVideoModale({ title: 'Video overview', vimeoIds: ['372868240'], }); return ( <> Tesselle <img src={appLogo} /> <span>Tesselle</span>

{modale}
{slicer.total === 0 ? { (props as any).loading ? 'Loading...' : 'Drop an image file (.jpg, .png, or .svg) or a tesselle project (.zip)' } : }

Your images

    {props.slideshows.size ? props.slideshows.map(slideshow => (
  • )) : <> {`Welcome to Tesselle, `} <a target="blank" rel="noopener" href="https://medialab.sciencespo.fr" >médialab</a>'s {` image annotation and publication tool`} All the data you will input in this tool will be stored in this browser local storage and therefore stay entirely private. You have no image projects on this browser yet. Drag and drop an image in the left column box to start annotating ! }
); } const mapStateToProps = createStructuredSelector({ slideshows: makeSelectSlideshows(), }); const withConnect = connect( mapStateToProps, { createSlideshow: createSlideshowAction.request, duplicateSlideshow: duplicationSlideshowAction, importSlideshow: importSlideshowAction.request, }, ); const withReducer = injectReducer({ key: 'homePage', reducer: reducer }); const withSaga = injectSaga({ key: 'homePage', saga: saga }); export const enhancer = compose( withReducer, withSaga, withConnect, ); export default enhancer(HomePage);