diff options
-rw-r--r-- | app/javascript/mastodon/features/ui/components/image_loader.js | 45 | ||||
-rw-r--r-- | app/javascript/mastodon/features/ui/components/media_modal.js | 4 | ||||
-rw-r--r-- | app/javascript/styles/components.scss | 15 | ||||
-rw-r--r-- | package.json | 1 | ||||
-rw-r--r-- | yarn.lock | 4 |
5 files changed, 57 insertions, 12 deletions
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 <img className={imageClass} src={src} />; // 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 = <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} />; } 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 { diff --git a/package.json b/package.json index 92221d8e4..c686e99e7 100644 --- a/package.json +++ b/package.json @@ -81,7 +81,6 @@ "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", diff --git a/yarn.lock b/yarn.lock index d3317f59c..5bef1e0b9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5436,10 +5436,6 @@ react-fuzzy@^0.3.3: 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" |