mirror of https://github.com/tootsuite/mastodon
Allow to open a modal for embedded photo (#5777)
parent
1266c66f79
commit
bf7757cbbc
|
@ -1,5 +1,6 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
import Immutable from 'immutable';
|
||||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||||
import punycode from 'punycode';
|
import punycode from 'punycode';
|
||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
|
@ -24,6 +25,7 @@ export default class Card extends React.PureComponent {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
card: ImmutablePropTypes.map,
|
card: ImmutablePropTypes.map,
|
||||||
maxDescription: PropTypes.number,
|
maxDescription: PropTypes.number,
|
||||||
|
onOpenMedia: PropTypes.func.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
|
@ -34,6 +36,27 @@ export default class Card extends React.PureComponent {
|
||||||
width: 0,
|
width: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
handlePhotoClick = () => {
|
||||||
|
const { card, onOpenMedia } = this.props;
|
||||||
|
|
||||||
|
onOpenMedia(
|
||||||
|
Immutable.fromJS([
|
||||||
|
{
|
||||||
|
type: 'image',
|
||||||
|
url: card.get('url'),
|
||||||
|
description: card.get('title'),
|
||||||
|
meta: {
|
||||||
|
original: {
|
||||||
|
width: card.get('width'),
|
||||||
|
height: card.get('height'),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]),
|
||||||
|
0
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
renderLink () {
|
renderLink () {
|
||||||
const { card, maxDescription } = this.props;
|
const { card, maxDescription } = this.props;
|
||||||
|
|
||||||
|
@ -73,9 +96,16 @@ export default class Card extends React.PureComponent {
|
||||||
const { card } = this.props;
|
const { card } = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<a href={card.get('url')} className='status-card-photo' target='_blank' rel='noopener'>
|
<img
|
||||||
<img src={card.get('url')} alt={card.get('title')} width={card.get('width')} height={card.get('height')} />
|
className='status-card-photo'
|
||||||
</a>
|
onClick={this.handlePhotoClick}
|
||||||
|
role='button'
|
||||||
|
tabIndex='0'
|
||||||
|
src={card.get('url')}
|
||||||
|
alt={card.get('title')}
|
||||||
|
width={card.get('width')}
|
||||||
|
height={card.get('height')}
|
||||||
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -73,7 +73,7 @@ export default class DetailedStatus extends ImmutablePureComponent {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else if (status.get('spoiler_text').length === 0) {
|
} else if (status.get('spoiler_text').length === 0) {
|
||||||
media = <CardContainer statusId={status.get('id')} />;
|
media = <CardContainer onOpenMedia={this.props.onOpenMedia} statusId={status.get('id')} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status.get('application')) {
|
if (status.get('application')) {
|
||||||
|
|
|
@ -7,7 +7,7 @@ export default class ImageLoader extends React.PureComponent {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
alt: PropTypes.string,
|
alt: PropTypes.string,
|
||||||
src: PropTypes.string.isRequired,
|
src: PropTypes.string.isRequired,
|
||||||
previewSrc: PropTypes.string.isRequired,
|
previewSrc: PropTypes.string,
|
||||||
width: PropTypes.number,
|
width: PropTypes.number,
|
||||||
height: PropTypes.number,
|
height: PropTypes.number,
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,7 @@ export default class ImageLoader extends React.PureComponent {
|
||||||
this.removeEventListeners();
|
this.removeEventListeners();
|
||||||
this.setState({ loading: true, error: false });
|
this.setState({ loading: true, error: false });
|
||||||
Promise.all([
|
Promise.all([
|
||||||
this.loadPreviewCanvas(props),
|
props.previewSrc && this.loadPreviewCanvas(props),
|
||||||
this.hasSize() && this.loadOriginalImage(props),
|
this.hasSize() && this.loadOriginalImage(props),
|
||||||
].filter(Boolean))
|
].filter(Boolean))
|
||||||
.then(() => {
|
.then(() => {
|
||||||
|
|
|
@ -92,7 +92,7 @@ export default class MediaModal extends ImmutablePureComponent {
|
||||||
const height = image.getIn(['meta', 'original', 'height']) || null;
|
const height = image.getIn(['meta', 'original', 'height']) || null;
|
||||||
|
|
||||||
if (image.get('type') === 'image') {
|
if (image.get('type') === 'image') {
|
||||||
return <ImageLoader previewSrc={image.get('preview_url')} src={image.get('url')} width={width} height={height} alt={image.get('description')} key={image.get('preview_url')} />;
|
return <ImageLoader previewSrc={image.get('preview_url')} src={image.get('url')} width={width} height={height} alt={image.get('description')} key={image.get('url')} />;
|
||||||
} else if (image.get('type') === 'gifv') {
|
} else if (image.get('type') === 'gifv') {
|
||||||
return <ExtendedVideoPlayer src={image.get('url')} muted controls={false} width={width} height={height} key={image.get('preview_url')} alt={image.get('description')} />;
|
return <ExtendedVideoPlayer src={image.get('url')} muted controls={false} width={width} height={height} key={image.get('preview_url')} alt={image.get('description')} />;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2182,15 +2182,12 @@ button.icon-button.active i.fa-retweet {
|
||||||
}
|
}
|
||||||
|
|
||||||
.status-card-photo {
|
.status-card-photo {
|
||||||
|
cursor: zoom-in;
|
||||||
display: block;
|
display: block;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
|
width: 100%;
|
||||||
img {
|
height: auto;
|
||||||
display: block;
|
margin: 0;
|
||||||
width: 100%;
|
|
||||||
height: auto;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.status-card-video {
|
.status-card-video {
|
||||||
|
|
Loading…
Reference in New Issue