From c00ead8a72dd738013b8a132eff7de4959e59670 Mon Sep 17 00:00:00 2001 From: Nolan Lawson Date: Wed, 31 May 2017 08:07:25 -0700 Subject: Remove react-imageloader (#3423) * Remove react-imageloader * add eslint-disable-line * improve image loading experience * remove unneeded import * use PureComponent * Use componentWillMount instead of constructor --- .../features/ui/components/image_loader.js | 45 ++++++++++++++++++++++ .../mastodon/features/ui/components/media_modal.js | 4 +- app/javascript/styles/components.scss | 15 +++++--- 3 files changed, 57 insertions(+), 7 deletions(-) create mode 100644 app/javascript/mastodon/features/ui/components/image_loader.js (limited to 'app/javascript') diff --git a/app/javascript/mastodon/features/ui/components/image_loader.js b/app/javascript/mastodon/features/ui/components/image_loader.js new file mode 100644 index 000000000..af2870517 --- /dev/null +++ b/app/javascript/mastodon/features/ui/components/image_loader.js @@ -0,0 +1,45 @@ +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 ; // eslint-disable-line jsx-a11y/img-has-alt + } + +} + +export default ImageLoader; diff --git a/app/javascript/mastodon/features/ui/components/media_modal.js b/app/javascript/mastodon/features/ui/components/media_modal.js index a8912841b..effa0aea3 100644 --- a/app/javascript/mastodon/features/ui/components/media_modal.js +++ b/app/javascript/mastodon/features/ui/components/media_modal.js @@ -3,10 +3,10 @@ import LoadingIndicator from '../../../components/loading_indicator'; 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' }, @@ -73,7 +73,7 @@ class MediaModal extends ImmutablePureComponent { } if (attachment.get('type') === 'image') { - content = ; + content = ; } else if (attachment.get('type') === 'gifv') { content = ; } diff --git a/app/javascript/styles/components.scss b/app/javascript/styles/components.scss index 4afbd12cf..e396f04cc 100644 --- a/app/javascript/styles/components.scss +++ b/app/javascript/styles/components.scss @@ -1137,13 +1137,13 @@ } } -.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 { @@ -2852,6 +2852,11 @@ button.icon-button.active i.fa-retweet { max-width: 80vw; max-height: 80vh; } + + img { + display: block; + background: url('../images/void.png') repeat; + } } .media-modal__close { -- cgit