diff --git a/src/components/CanvasThumbnail.js b/src/components/CanvasThumbnail.js index 6b397d534c..72fd512ea8 100644 --- a/src/components/CanvasThumbnail.js +++ b/src/components/CanvasThumbnail.js @@ -34,19 +34,22 @@ export default class CanvasThumbnail extends Component { /** */ render() { - const { height } = this.props; + const { + height, isValid, onClick, style, + } = this.props; const { loaded, image } = this.state; + const imgStyle = { height, width: '100%', ...style }; return ( -
- - - -
+ + + ); } } @@ -54,13 +57,17 @@ export default class CanvasThumbnail extends Component { // Transparent "gray" CanvasThumbnail.defaultImgPlaceholder = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mMMDQmtBwADgwF/Op8FmAAAAABJRU5ErkJggg=='; - CanvasThumbnail.propTypes = { imageUrl: PropTypes.string, + isValid: PropTypes.bool, height: PropTypes.number, + onClick: PropTypes.func.isRequired, + style: PropTypes.object, // eslint-disable-line react/forbid-prop-types, }; CanvasThumbnail.defaultProps = { imageUrl: null, + isValid: true, height: 150, + style: {}, }; diff --git a/src/components/ThumbnailNavigation.js b/src/components/ThumbnailNavigation.js index e7de786093..686f38fa4c 100644 --- a/src/components/ThumbnailNavigation.js +++ b/src/components/ThumbnailNavigation.js @@ -49,15 +49,13 @@ class ThumbnailNavigation extends Component { className={ns('thumbnail-nav-container')} >
setCanvas(window.id, canvas.index)} - onKeyPress={() => setCanvas(window.id, canvas.index)} - role="presentation" style={{ width: style.width - 8, }} className={ns(['thumbnail-nav-canvas', `thumbnail-nav-canvas-${canvas.index}`, this.currentCanvasClass(canvas.index)])} > setCanvas(window.id, canvas.index)} imageUrl={new ManifestoCanvas(canvas).thumbnail(config.thumbnailNavigation.height)} height={config.thumbnailNavigation.height} /> diff --git a/src/components/ValidationCanvas.js b/src/components/ValidationCanvas.js new file mode 100644 index 0000000000..67cbfe8c80 --- /dev/null +++ b/src/components/ValidationCanvas.js @@ -0,0 +1,35 @@ +import ManifestoCanvas from '../lib/ManifestoCanvas'; + +/** + */ +export default class ValidationCanvas extends ManifestoCanvas { + /** + * checks whether the canvas has a valid height + */ + get hasValidHeight() { + return ( + typeof this.canvas.getHeight() === 'number' + && this.canvas.getHeight() > 0 + ); + } + + /** + * checks whether the canvas has a valid height + */ + get hasValidWidth() { + return ( + typeof this.canvas.getHeight() === 'number' + && this.canvas.getHeight() > 0 + ); + } + + /** + * checks whether the canvas has valid dimensions + */ + get hasValidDimensions() { + return ( + this.hasValidHeight + && this.hasValidWidth + ); + } +} diff --git a/src/components/WindowSideBarCanvasPanel.js b/src/components/WindowSideBarCanvasPanel.js index 3071ec3680..3bbe4bfd72 100644 --- a/src/components/WindowSideBarCanvasPanel.js +++ b/src/components/WindowSideBarCanvasPanel.js @@ -1,38 +1,68 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; +import classNames from 'classnames'; import Typography from '@material-ui/core/Typography'; import List from '@material-ui/core/List'; import ListItem from '@material-ui/core/ListItem'; import { withStyles } from '@material-ui/core/styles'; +import ValidationCanvas from './ValidationCanvas'; +import CanvasThumbnail from './CanvasThumbnail'; +import { getIdAndLabelOfCanvases } from '../state/selectors'; /** * a panel showing the canvases for a given manifest */ class WindowSideBarCanvasPanel extends Component { + /** + * calculateScaledWidth - calculates the scaled width according to the given width and aspectRatio + */ + static calculateScaledWidth(height, aspectRatio) { + return Math.floor(height * aspectRatio); + } + /** * render */ render() { const { - canvasesIdAndLabel, setCanvas, windowId, classes, t, + canvases, classes, config, setCanvas, t, windowId, } = this.props; + const canvasesIdAndLabel = getIdAndLabelOfCanvases(canvases); + return ( <> {t('canvasIndex')} { - canvasesIdAndLabel.map((canvas, canvasIndex) => ( - - { setCanvas(windowId, canvasIndex); }} + canvasesIdAndLabel.map((canvas, canvasIndex) => { + const validationCanvas = new ValidationCanvas(canvases[canvasIndex]); + const isValid = validationCanvas.hasValidDimensions; + return ( + - {canvas.label} - - - )) + { setCanvas(windowId, canvasIndex); }} + style={{ + cursor: 'pointer', + height: config.canvasNavigation.height, + width: isValid ? WindowSideBarCanvasPanel.calculateScaledWidth(config.canvasNavigation.height, validationCanvas.aspectRatio) : 'auto', + }} + /> + { setCanvas(windowId, canvasIndex); }} + variant="body2" + > + {canvas.label} + + + ); + }) } @@ -41,11 +71,12 @@ class WindowSideBarCanvasPanel extends Component { } WindowSideBarCanvasPanel.propTypes = { - windowId: PropTypes.string.isRequired, - canvasesIdAndLabel: PropTypes.array.isRequired, // eslint-disable-line react/forbid-prop-types - setCanvas: PropTypes.func.isRequired, + canvases: PropTypes.array.isRequired, // eslint-disable-line react/forbid-prop-types classes: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types + config: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types + setCanvas: PropTypes.func.isRequired, t: PropTypes.func.isRequired, + windowId: PropTypes.string.isRequired, }; /** @@ -57,6 +88,10 @@ const styles = theme => ({ clickable: { cursor: 'pointer', }, + label: { + fontSize: '8pt', + paddingLeft: 8, + }, }); export default withStyles(styles)(WindowSideBarCanvasPanel); diff --git a/src/config/settings.js b/src/config/settings.js index 95065995db..df3444143d 100644 --- a/src/config/settings.js +++ b/src/config/settings.js @@ -1,4 +1,7 @@ export default { + canvasNavigation: { + height: 100, + }, theme: { // Sets up a MaterialUI theme. See https://material-ui.com/customization/default-theme/ palette: { type: 'light', // dark also available diff --git a/src/containers/WindowSideBarCanvasPanel.js b/src/containers/WindowSideBarCanvasPanel.js index 6188bc8e99..4eb5035292 100644 --- a/src/containers/WindowSideBarCanvasPanel.js +++ b/src/containers/WindowSideBarCanvasPanel.js @@ -6,7 +6,6 @@ import WindowSideBarCanvasPanel from '../components/WindowSideBarCanvasPanel'; import { getManifestCanvases, getWindowManifest, - getIdAndLabelOfCanvases, } from '../state/selectors'; /** @@ -15,8 +14,10 @@ import { const mapStateToProps = (state, { windowId }) => { const manifest = getWindowManifest(state, windowId); const canvases = getManifestCanvases(manifest); + const { config } = state; return { - canvasesIdAndLabel: getIdAndLabelOfCanvases(canvases), + canvases, + config, }; };