Skip to content
Snippets Groups Projects
Commit 1c35cc4a authored by Jack Reed's avatar Jack Reed
Browse files

extract component for navigation controls, and handle info.json request separately

parent b4972418
No related branches found
No related tags found
No related merge requests found
......@@ -26,4 +26,7 @@ describe('WindowViewer', () => {
// do not effectively find elements (even though they are there)
expect(wrapper.render().find('.openseadragon-canvas').length).toBe(1);
});
it('has navigation controls', () => {
expect(wrapper.find('.mirador-osd-navigation').length).toBe(1);
});
});
import React, { Component, Fragment } from 'react';
import PropTypes from 'prop-types';
import OpenSeadragon from 'openseadragon';
import miradorWithPlugins from '../lib/miradorWithPlugins';
import ns from '../config/css-ns';
/**
* Represents a OpenSeadragonViewer in the mirador workspace. Responsible for mounting
* and rendering OSD.
*/
class OpenSeadragonViewer extends Component {
/**
* @param {Object} props
*/
constructor(props) {
super(props);
this.viewer = null;
this.ref = React.createRef();
}
/**
* React lifecycle event
*/
componentDidMount() {
const { tileSources } = this.props;
if (!this.ref.current) {
return;
}
this.viewer = new OpenSeadragon({
id: this.ref.current.id,
preserveViewport: true,
blendTime: 0.1,
alwaysBlend: false,
showNavigationControl: false,
});
tileSources.forEach(tileSource => this.addTileSource(tileSource));
}
/**
*/
componentDidUpdate() {
const { tileSources } = this.props;
tileSources.forEach(tileSource => this.addTileSource(tileSource));
}
/**
*/
componentWillUnmount() {
this.viewer.removeAllHandlers();
}
/**
*/
addTileSource(tileSource) {
this.viewer.addTiledImage({
tileSource,
success: (event) => {
},
});
}
/**
* Renders things
*/
render() {
const { window } = this.props;
return (
<Fragment>
<div
className={ns('osd-container')}
id={`${window.id}-osd`}
ref={this.ref}
/>
</Fragment>
);
}
}
OpenSeadragonViewer.defaultProps = {
tileSources: [],
};
OpenSeadragonViewer.propTypes = {
tileSources: PropTypes.arrayOf(PropTypes.object),
window: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
};
export default miradorWithPlugins(OpenSeadragonViewer);
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import miradorWithPlugins from '../lib/miradorWithPlugins';
import { actions } from '../store';
import ns from '../config/css-ns';
/**
*/
class ViewerNavigation extends Component {
/**
*/
constructor(props) {
super(props);
this.nextCanvas = this.nextCanvas.bind(this);
this.previousCanvas = this.previousCanvas.bind(this);
}
/**
*/
nextCanvas() {
const { window, nextCanvas } = this.props;
if (this.hasNextCanvas()) nextCanvas(window.id);
}
/**
*/
hasNextCanvas() {
const { window, canvases } = this.props;
return window.canvasIndex < canvases.length - 1;
}
/**
*/
previousCanvas() {
const { window, previousCanvas } = this.props;
if (this.hasPreviousCanvas()) previousCanvas(window.id);
}
/**
*/
hasPreviousCanvas() {
const { window } = this.props;
return window.canvasIndex > 0;
}
/**
* Renders things
*/
render() {
return (
<div className={ns('osd-navigation')}>
<button
type="button"
disabled={!this.hasPreviousCanvas()}
onClick={this.previousCanvas}
>
&#8249;
</button>
<button
type="button"
disabled={!this.hasNextCanvas()}
onClick={this.nextCanvas}
>
&#8250;
</button>
</div>
);
}
}
ViewerNavigation.propTypes = {
canvases: PropTypes.array.isRequired, // eslint-disable-line react/forbid-prop-types
nextCanvas: PropTypes.func.isRequired,
previousCanvas: PropTypes.func.isRequired,
window: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
};
/**
* mapDispatchToProps - used to hook up connect to action creators
* @memberof ManifestForm
* @private
*/
const mapDispatchToProps = dispatch => ({
nextCanvas: windowId => dispatch(actions.nextCanvas(windowId)),
previousCanvas: windowId => dispatch(actions.previousCanvas(windowId)),
});
export default connect(null, mapDispatchToProps)(miradorWithPlugins(ViewerNavigation));
import React, { Component } from 'react';
import React, { Component, Fragment } from 'react';
import PropTypes from 'prop-types';
import OpenSeaDragon from 'openseadragon';
import fetch from 'node-fetch';
import miradorWithPlugins from '../lib/miradorWithPlugins';
import ns from '../config/css-ns';
import OpenSeadragonViewer from './OpenSeadragonViewer';
import ViewerNavigation from './ViewerNavigation';
/**
* Represents a WindowViewer in the mirador workspace. Responsible for mounting
* and rendering OSD.
* OSD and Navigation
*/
class WindowViewer extends Component {
/**
......@@ -16,47 +16,43 @@ class WindowViewer extends Component {
constructor(props) {
super(props);
this.ref = React.createRef();
this.viewer = null;
const { manifest } = this.props;
this.canvases = manifest.manifestation.getSequences()[0].getCanvases();
this.state = {
tileSources: [],
};
}
/**
* React lifecycle event
* componentDidMount - React lifecycle method
* Request the initial canvas on mount
*/
componentDidMount() {
const { manifest } = this.props;
if (!this.ref.current) {
return false;
this.requestAndUpdateTileSources();
}
this.viewer = OpenSeaDragon({
id: this.ref.current.id,
showNavigationControl: false,
});
const that = this;
fetch(`${manifest.manifestation.getSequences()[0].getCanvases()[0].getImages()[0].getResource().getServices()[0].id}/info.json`)
.then(response => response.json())
.then((json) => {
that.viewer.addTiledImage({
tileSource: json,
success: (event) => {
const tiledImage = event.item;
/**
* A callback for the tile after its drawn
* @param {[type]} e event object
* componentDidUpdate - React lifecycle method
* Request a new canvas if it is needed
*/
const tileDrawnHandler = (e) => {
if (e.tiledImage === tiledImage) {
that.viewer.removeHandler('tile-drawn', tileDrawnHandler);
that.ref.current.style.display = 'block';
componentDidUpdate(prevProps) {
const { window } = this.props;
if (prevProps.window.canvasIndex !== window.canvasIndex) {
this.requestAndUpdateTileSources();
}
};
that.viewer.addHandler('tile-drawn', tileDrawnHandler);
},
}
/**
*/
requestAndUpdateTileSources() {
const { window } = this.props;
fetch(`${this.canvases[window.canvasIndex].getImages()[0].getResource().getServices()[0].id}/info.json`)
.then(response => response.json())
.then((json) => {
this.setState({
tileSources: [json],
});
});
})
.catch(error => console.log(error));
return false;
}
/**
......@@ -64,13 +60,12 @@ class WindowViewer extends Component {
*/
render() {
const { window } = this.props;
const { tileSources } = this.state;
return (
<div
className={ns('osd-container')}
style={{ display: 'none' }}
id={`${window.id}-osd`}
ref={this.ref}
/>
<Fragment>
<OpenSeadragonViewer tileSources={tileSources} window={window} />
<ViewerNavigation window={window} canvases={this.canvases} />
</Fragment>
);
}
}
......
......@@ -53,4 +53,12 @@ body {
top: 0;
width: 100%;
}
&-osd-navigation {
bottom: 10px;
left: 0;
position: absolute;
right: 0;
text-align: center;
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment