Skip to content
Snippets Groups Projects
Commit 6233d1d6 authored by Anthony's avatar Anthony
Browse files

Merge branch '20-fetch-thumbnail-on-annotation' into 'annotation-on-video'

WIP thumbnail on accordion.

See merge request iiif/mirador-video-annotation!17
parents 9b80751b 4624b6f9
No related branches found
No related tags found
1 merge request!17WIP thumbnail on accordion.
Pipeline #1678 failed
......@@ -5,11 +5,7 @@ import ExpandMoreIcon from '@material-ui/icons/ExpandMoreSharp';
import Typography from '@material-ui/core/Typography';
import AccordionDetails from '@material-ui/core/AccordionDetails';
import PropTypes from 'prop-types';
import {
Card, CardActionArea, CardActions, CardContent, CardMedia, Fab,
} from '@material-ui/core';
import Button from '@material-ui/core/Button';
import Tooltip from '@material-ui/core/Tooltip';
import AnnotationManifestsItem from '../containers/AnnotationManifestsItem';
/**
* AnnotationManifestsAccordion
......@@ -20,9 +16,9 @@ export class AnnotationManifestsAccordion extends Component {
*/
constructor(props) {
super(props);
this.handleOpenManifestSideToSide = this.handleOpenManifestSideToSide.bind(this);
this.handleOpenAccordion = this.handleOpenAccordion.bind(this);
/** Search if the annotation is a manifest. URL must be resolvable for the annotation. So the manifest url is added at the end of the id */
function searchManifestInID(id) {
const match = id.match(
......@@ -34,6 +30,7 @@ export class AnnotationManifestsAccordion extends Component {
const { annotation } = this.props;
annotation.manifestsOpen = false;
annotation.manifests = searchManifestInID(annotation.id);
if (annotation.manifests) {
annotation.manifests = annotation.manifests.map(id => ({ id }));
......@@ -44,38 +41,13 @@ export class AnnotationManifestsAccordion extends Component {
this.state = { annotation };
}
/** */
handleOpenManifestSideToSide(e, manifestId) {
const { addResource, addWindow } = this.props;
addResource(manifestId);
addWindow({ manifestId });
}
/** */
// eslint-disable-next-line class-methods-use-this,require-jsdoc
handleOpenAccordion(e) {
const { annotation } = this.state;
/** */
async function load(manifests) {
return Promise.all(manifests.map((manifest) => fetch(manifest.id)
.then((response) => response.json())
.then((data) => {
if (data.type === 'Manifest') {
return data;
}
return null;
})));
}
load(annotation.manifests)
.then((values) => {
if (values) {
annotation.manifests = values;
this.setState({ annotation });
}
});
let { annotation } = this.state;
annotation.manifestsOpen = true;
e.stopPropagation();
this.state = { annotation };
}
/** */
......@@ -84,8 +56,6 @@ export class AnnotationManifestsAccordion extends Component {
classes, t, i18n,
} = this.props;
const language = i18n.language;
const { annotation } = this.state;
if (annotation.manifests === null || annotation.manifests.length === 0) {
......@@ -101,34 +71,20 @@ export class AnnotationManifestsAccordion extends Component {
>
<Typography className={classes.heading}>{t('manifestFound')}</Typography>
</AccordionSummary>
{
annotation.manifestsOpen && (
<AccordionDetails className={classes.manifestContainer}>
{annotation.manifests.map(manifest => (
<Typography >
<Card className={classes.root}>
<CardActionArea>
<CardContent>
<Typography>
{ manifest.label ? manifest.label[language] : manifest.id }
</Typography>
</CardContent>
</CardActionArea>
<CardActions>
<Tooltip title={t('openManifestInOtherWindow', { manifest: manifest.id })}>
<Button
size="small"
color="primary"
onClick={(e) => {
this.handleOpenManifestSideToSide(e, manifest.id);
}}
>
{t('open')}
</Button>
</Tooltip>
</CardActions>
</Card>
</Typography>
<AnnotationManifestsItem
manifestId={manifest.id}
language={i18n.language}
key={manifest}
t={t}
/>
))}
</AccordionDetails>
)
}
</Accordion>
</div>
);
......@@ -136,16 +92,17 @@ export class AnnotationManifestsAccordion extends Component {
}
AnnotationManifestsAccordion.propsTypes = {
addResource: PropTypes.func.isRequired,
addWindow: PropTypes.func.isRequired,
annotation: PropTypes.shape(
{
content: PropTypes.string,
id: PropTypes.string,
manifests: PropTypes.arrayOf(PropTypes.string),
manifestsOpen: PropTypes.boolean,
},
),
classes: PropTypes.objectOf(PropTypes.string),
fetchManifest: PropTypes.func.isRequired,
t: PropTypes.func.isRequired,
};
......
import { Component } from 'react';
import Typography from '@material-ui/core/Typography';
import PropTypes from 'prop-types';
import {
Card, CardActionArea, CardActions, CardContent, CardMedia, Fab,
} from '@material-ui/core';
import Button from '@material-ui/core/Button';
import Tooltip from '@material-ui/core/Tooltip';
/**
* AnnotationManifestsItem
*/
export class AnnotationManifestsItem extends Component {
/**
* constructor
*/
constructor(props) {
super(props);
this.handleOpenManifestSideToSide = this.handleOpenManifestSideToSide.bind(this);
}
/** */
componentDidMount() {
const {
fetchManifest, manifestId, ready, isFetching, error, provider,
} = this.props;
if (!ready && !error && !isFetching && provider !== 'file') {
fetchManifest(manifestId);
}
}
/** */
handleOpenManifestSideToSide(e, manifestId) {
const { addResource, addWindow } = this.props;
addResource(manifestId);
addWindow({ manifestId });
}
/** */
render() {
const {
classes, t, manifestId, thumbnail, title, description, error, ready
} = this.props;
if (error) {
return (
<Typography className={classes.errorMessage}>{t('resourceError', { manifestId })}</Typography>
);
}
if (!ready) {
return (
<Typography>
<Typography>{t('resourceLoading')}</Typography>
</Typography>
);
}
return (
<Card className={classes.root}>
<CardActionArea>
{
thumbnail && (
<CardMedia
className={classes.thumbnail}
component="img"
height="140"
image={thumbnail}
alt="green iguana"
/>
)
}
<CardContent>
<Typography>
{ title || manifestId }
</Typography>
{
description && (
<Typography>
{ description }
</Typography>
)
}
</CardContent>
</CardActionArea>
<CardActions>
<Tooltip title={t('openManifestInOtherWindow', { manifestId })}>
<Button
size="small"
color="primary"
onClick={(e) => {
this.handleOpenManifestSideToSide(e, manifestId);
}}
>
{t('open')}
</Button>
</Tooltip>
</CardActions>
</Card>
);
}
}
AnnotationManifestsItem.propsTypes = {
addResource: PropTypes.func.isRequired,
addWindow: PropTypes.func.isRequired,
classes: PropTypes.objectOf(PropTypes.string),
description: PropTypes.string,
error: PropTypes.string,
fetchManifest: PropTypes.func.isRequired,
isFetching: PropTypes.bool,
manifestLogo: PropTypes.string,
manifests: PropTypes.arrayOf(PropTypes.string),
provider: PropTypes.string,
ready: PropTypes.bool,
t: PropTypes.func.isRequired,
thumbnail: PropTypes.string,
title: PropTypes.string,
};
AnnotationManifestsItem.defaultProps = {
classes: {},
error: null,
isFetching: false,
manifestLogo: null,
provider: null,
ready: false,
thumbnail: null,
title: null,
};
......@@ -7,8 +7,6 @@ import MenuItem from '@material-ui/core/MenuItem';
import ListItemText from '@material-ui/core/ListItemText';
import Typography from '@material-ui/core/Typography';
import SearchIcon from '@material-ui/icons/SearchSharp';
import InputBase from '@material-ui/core/InputBase';
import CircularProgress from '@material-ui/core/CircularProgress';
import TextField from '@material-ui/core/TextField';
import SanitizedHtml from '../containers/SanitizedHtml';
import { ScrollTo } from './ScrollTo';
......
......@@ -4,7 +4,6 @@ import { withTranslation } from 'react-i18next';
import { withStyles } from '@material-ui/core/styles';
import { withPlugins } from '../extend/withPlugins';
import { AnnotationManifestsAccordion } from '../components/AnnotationManifestsAccordion';
import * as actions from '../state/actions';
import { getConfig } from '../state/selectors';
/** For connect */
......@@ -18,8 +17,7 @@ const mapStateToProps = (state, { canvasId, windowId }) => ({
* @private
*/
const mapDispatchToProps = {
addResource: actions.addResource,
addWindow: actions.addWindow,
};
/** For withStyles */
......
import { compose } from 'redux';
import { connect } from 'react-redux';
import { withTranslation } from 'react-i18next';
import { withStyles } from '@material-ui/core/styles';
import { withPlugins } from '../extend/withPlugins';
import * as actions from '../state/actions';
import { AnnotationManifestsItem } from '../components/AnnotationManifestsItem';
import {
getManifest, getManifestDescription, getManifestLogo,
getManifestProvider, getManifestThumbnail, getManifestTitle,
getWindowManifests,
} from '../state/selectors';
/** For connect */
const mapStateToProps = (state, { manifestId }) => {
const manifest = getManifest(state, { manifestId }) || {};
return {
active: getWindowManifests(state)
.includes(manifestId),
description: getManifestDescription(state, { manifestId }),
error: manifest.error,
isFetching: manifest.isFetching,
manifestLogo: getManifestLogo(state, { manifestId }),
provider: getManifestProvider(state, { manifestId }),
ready: !!manifest.json,
thumbnail: getManifestThumbnail(state, { manifestId }),
title: getManifestTitle(state, { manifestId }),
};
};
/**
* mapDispatchToProps - to hook up connect
* @memberof WindowSideBarAnnotationsPanel
* @private
*/
const mapDispatchToProps = {
addResource: actions.addResource,
addWindow: actions.addWindow,
fetchManifest: actions.fetchManifest,
};
/** For withStyles */
const styles = theme => ({
errorMessage: {
color: theme.palette.error.main,
},
logo: {
height: '2.5rem',
maxWidth: '100%',
objectFit: 'contain',
paddingRight: 8,
},
thumbnail: {
maxWidth: '100%',
objectFit: 'contain',
},
});
const enhance = compose(
withTranslation(),
withStyles(styles),
connect(mapStateToProps, mapDispatchToProps),
withPlugins('AnnotationManifestsItem'),
);
export default enhance(AnnotationManifestsItem);
......@@ -108,7 +108,7 @@
"openCompanionWindow_layers": "Layers",
"openCompanionWindow_search": "Search",
"openInCompanionWindow": "Open in separate panel",
"openManifestInOtherWindow" : "Open {{manifest}} manifest in other Mirador window",
"openManifestInOtherWindow" : "Open {{manifestId}} manifest in other Mirador window",
"openWindows": "Current open windows",
"pagination": "{{current}} of {{total}}",
"position": "Position",
......@@ -116,6 +116,8 @@
"previousCanvas": "Previous item",
"related": "Related",
"resource": "Resource",
"resourceError": "Error when loading ressource from {{ manifestId }}",
"resourceLoading": "Loading ressource ... ",
"retry": "Retry",
"right": "Right",
"rights": "License",
......
......@@ -104,7 +104,7 @@
"openCompanionWindow_layers": "Calques",
"openCompanionWindow_search": "Rechercher",
"openInCompanionWindow": "Ouvrir dans un panneau séparé",
"openManifestInOtherWindow" : "Ouvrir le manifeste dans une autre fenêtre Mirador",
"openManifestInOtherWindow" : "Ouvrir {{manifestId }} dans une autre fenêtre Mirador",
"openWindows": "Fenêtres ouvertes",
"pagination": "{{current}} sur {{total}}",
"position": "Position",
......@@ -112,6 +112,8 @@
"previousCanvas": "Précédent",
"related": "En relation",
"resource": "Ressource",
"resourceError": "Erreur lors du changement de la ressource {{ manifestId }}",
"resourceLoading": "Chargement en cours de la ressource ... ",
"retry": "Réessayer",
"right": "Droite",
"rights": "Licence",
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment