/**
* Copyright 2018, Plotly, Inc.
* All rights reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import PropTypes from 'prop-types';
import React, { PureComponent } from 'react';
import positionStoreMixin from './positionStoreMixin';
class PositionStoreProvider extends PureComponent {
constructor(props) {
}
updateFromPositionStore = () => {
const state = this.context.positionMSAStore.getState();
this.position = this.position || {};
if (this.props.withPosition) {
this.position.xPos = state.position.xPos;
this.position.yPos = state.position.yPos;
}
if (this.props.withX) {
this.position.xPosOffset = state.xPosOffset;
this.position.currentViewSequencePosition = state.currentViewSequencePosition;
}
if (this.props.withY) {
this.position.yPosOffset = state.yPosOffset;
this.position.currentViewSequence = state.currentViewSequence;
}
if (this.shouldRerender()) {
// this will always force a rerender as position is a new object
this.setState({
position: {
...this.position,
}
});
}
}
componentWillMount(){
this.updateFromPositionStore();
this.context.positionMSAStore.subscribe(this.updateFromPositionStore);
}
componentDidUpdate(){
if (oldComponentDidUpdate) {
oldComponentDidUpdate.call(this);
}
this.updateScrollPosition();
}
// inject the store via contexts
dispatch = (payload) => {
this.context.positionMSAStore.dispatch(payload);
};
shouldRerender = () => {
if (withY) {
if (Math.abs(this.position.currentViewSequence - this.position.lastCurrentViewSequence) >= this.props.cacheElements) {
return true;
}
}
if (withX) {
if (Math.abs(this.position.currentViewSequencePosition - this.position.lastCurrentViewSequencePosition) >= this.props.cacheElements) {
return true;
}
}
return this.updateScrollPosition() || false;
}
updateScrollPosition = () => {
if (this.el && this.el.current) {
if (withX) {
let offsetX = -this.position.xPosOffset;
offsetX += (this.position.lastCurrentViewSequencePosition - this.position.lastStartXTile) * this.props.tileWidth;
if (this.position.currentViewSequencePosition !== this.position.lastCurrentViewSequencePosition) {
offsetX += (this.position.currentViewSequencePosition - this.position.lastCurrentViewSequencePosition) * this.props.tileWidth;
}
this.el.current.scrollLeft = offsetX;
}
if (withY) {
let offsetY = -this.position.yPosOffset;
offsetY += (this.position.lastCurrentViewSequence - this.position.lastStartYTile) * this.props.tileHeight;
if (this.position.currentViewSequence !== this.position.lastCurrentViewSequence) {
offsetY += (this.position.currentViewSequence - this.position.lastCurrentViewSequence) * this.props.tileHeight;
}
this.el.current.scrollTop = offsetY;
}
}
return false;
};
}
PositionStoreProvider.defaultProps = {
withX: false,
withY: false,
withPosition: false,
};
PositionStoreProvider.contextTypes = {
positionMSAStore: PropTypes.object,
}
export default PositionStoreProvider;
|