--- /dev/null
+import React from 'react';
+import PropTypes from 'prop-types';
+
+class ImageLoader extends React.PureComponent {
+
+ static propTypes = {
+ src: PropTypes.string.isRequired,
+ }
+
+ state = {
+ loading: true,
+ error: false,
+ }
+
+ componentWillMount() {
+ this.loadImage(this.props.src);
+ }
+
+ componentWillReceiveProps(props) {
+ this.loadImage(props.src);
+ }
+
+ loadImage(src) {
+ const image = new Image();
+ image.onerror = () => this.setState({loading: false, error: true});
+ image.onload = () => this.setState({loading: false, error: false});
+ image.src = src;
+ this.lastSrc = src;
+ this.setState({loading: true});
+ }
+
+ render() {
+ const { src } = this.props;
+ const { loading, error } = this.state;
+
+ // TODO: handle image error state
+
+ const imageClass = `image-loader__img ${loading ? 'image-loader__img-loading' : ''}`;
+
+ return <img className={imageClass} src={src} />; // eslint-disable-line jsx-a11y/img-has-alt
+ }
+
+}
+
+export default ImageLoader;
import ImmutablePropTypes from 'react-immutable-proptypes';
import PropTypes from 'prop-types';
import ExtendedVideoPlayer from '../../../components/extended_video_player';
-import ImageLoader from 'react-imageloader';
import { defineMessages, injectIntl } from 'react-intl';
import IconButton from '../../../components/icon_button';
import ImmutablePureComponent from 'react-immutable-pure-component';
+import ImageLoader from './image_loader';
const messages = defineMessages({
close: { id: 'lightbox.close', defaultMessage: 'Close' },
}
if (attachment.get('type') === 'image') {
- content = <ImageLoader src={url} imgProps={{ style: { display: 'block' } }} />;
+ content = <ImageLoader src={url} />;
} else if (attachment.get('type') === 'gifv') {
content = <ExtendedVideoPlayer src={url} muted={true} controls={false} />;
}
}
}
-.transparent-background,
-.imageloader {
- background: url('../images/void.png');
+.image-loader__img {
+ transition: opacity 0.3s linear;
+ opacity: 1;
}
-.imageloader {
- display: block;
+.image-loader__img-loading {
+ opacity: 0.7;
}
.navigation-bar {
max-width: 80vw;
max-height: 80vh;
}
+
+ img {
+ display: block;
+ background: url('../images/void.png') repeat;
+ }
}
.media-modal__close {
"react-addons-perf": "^15.4.2",
"react-addons-shallow-compare": "^15.5.2",
"react-dom": "^15.5.4",
- "react-imageloader": "^2.1.0",
"react-immutable-proptypes": "^2.1.0",
"react-immutable-pure-component": "^0.0.4",
"react-intl": "^2.3.0",
classnames "^2.2.3"
fuse.js "^2.2.0"
-react-imageloader@^2.1.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/react-imageloader/-/react-imageloader-2.1.0.tgz#a58401970b3282386aeb810c43175165634f6308"
-
react-immutable-proptypes@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/react-immutable-proptypes/-/react-immutable-proptypes-2.1.0.tgz#023d6f39bb15c97c071e9e60d00d136eac5fa0b4"