diff options
author | Eugen Rochko <eugen@zeonfederated.com> | 2017-04-18 01:58:14 +0200 |
---|---|---|
committer | Eugen Rochko <eugen@zeonfederated.com> | 2017-04-18 01:58:14 +0200 |
commit | 93c13fe691750e8c7f0c90091bca2564b97ccba7 (patch) | |
tree | 17b12a54da0840e0e7f7e0c03f32fccc1a5b9137 /app/assets | |
parent | 16d50f60d1f802ee7760ca24883df2ed5a8f4ac0 (diff) | |
parent | 42d54dc9ea8c6e73008c4400a2d154f0e6bdd384 (diff) |
Merge branch 'patf-pause-gif'
Diffstat (limited to 'app/assets')
7 files changed, 81 insertions, 27 deletions
diff --git a/app/assets/javascripts/components/components/media_gallery.jsx b/app/assets/javascripts/components/components/media_gallery.jsx index 325fd8157..f334af9cf 100644 --- a/app/assets/javascripts/components/components/media_gallery.jsx +++ b/app/assets/javascripts/components/components/media_gallery.jsx @@ -78,7 +78,8 @@ const Item = React.createClass({ attachment: ImmutablePropTypes.map.isRequired, index: React.PropTypes.number.isRequired, size: React.PropTypes.number.isRequired, - onClick: React.PropTypes.func.isRequired + onClick: React.PropTypes.func.isRequired, + autoPlayGif: React.PropTypes.bool.isRequired }, mixins: [PureRenderMixin], @@ -158,15 +159,21 @@ const Item = React.createClass({ /> ); } else if (attachment.get('type') === 'gifv') { + const autoPlay = !isIOS() && this.props.autoPlayGif; + thumbnail = ( - <video - src={attachment.get('url')} - onClick={this.handleClick} - autoPlay={!isIOS()} - loop={true} - muted={true} - style={gifvThumbStyle} - /> + <div style={{ position: 'relative', width: '100%', height: '100%', overflow: 'hidden' }} className={`media-gallery__gifv ${autoPlay ? 'autoplay' : ''}`}> + <video + src={attachment.get('url')} + onClick={this.handleClick} + autoPlay={autoPlay} + loop={true} + muted={true} + style={gifvThumbStyle} + /> + + <span className='media-gallery__gifv__label'>GIF</span> + </div> ); } @@ -192,7 +199,8 @@ const MediaGallery = React.createClass({ media: ImmutablePropTypes.list.isRequired, height: React.PropTypes.number.isRequired, onOpenMedia: React.PropTypes.func.isRequired, - intl: React.PropTypes.object.isRequired + intl: React.PropTypes.object.isRequired, + autoPlayGif: React.PropTypes.bool.isRequired }, mixins: [PureRenderMixin], @@ -227,7 +235,7 @@ const MediaGallery = React.createClass({ ); } else { const size = media.take(4).size; - children = media.take(4).map((attachment, i) => <Item key={attachment.get('id')} onClick={this.handleClick} attachment={attachment} index={i} size={size} />); + children = media.take(4).map((attachment, i) => <Item key={attachment.get('id')} onClick={this.handleClick} attachment={attachment} autoPlayGif={this.props.autoPlayGif} index={i} size={size} />); } return ( diff --git a/app/assets/javascripts/components/components/status.jsx b/app/assets/javascripts/components/components/status.jsx index d2d2aaf20..abc123f26 100644 --- a/app/assets/javascripts/components/components/status.jsx +++ b/app/assets/javascripts/components/components/status.jsx @@ -29,6 +29,7 @@ const Status = React.createClass({ onBlock: React.PropTypes.func, me: React.PropTypes.number, boostModal: React.PropTypes.bool, + autoPlayGif: React.PropTypes.bool, muted: React.PropTypes.bool }, @@ -79,7 +80,7 @@ const Status = React.createClass({ if (status.getIn(['media_attachments', 0, 'type']) === 'video') { media = <VideoPlayer media={status.getIn(['media_attachments', 0])} sensitive={status.get('sensitive')} onOpenVideo={this.props.onOpenVideo} />; } else { - media = <MediaGallery media={status.get('media_attachments')} sensitive={status.get('sensitive')} height={110} onOpenMedia={this.props.onOpenMedia} />; + media = <MediaGallery media={status.get('media_attachments')} sensitive={status.get('sensitive')} height={110} onOpenMedia={this.props.onOpenMedia} autoPlayGif={this.props.autoPlayGif} />; } } diff --git a/app/assets/javascripts/components/containers/status_container.jsx b/app/assets/javascripts/components/containers/status_container.jsx index f704ac722..df091de04 100644 --- a/app/assets/javascripts/components/containers/status_container.jsx +++ b/app/assets/javascripts/components/containers/status_container.jsx @@ -27,7 +27,8 @@ const makeMapStateToProps = () => { const mapStateToProps = (state, props) => ({ status: getStatus(state, props.id), me: state.getIn(['meta', 'me']), - boostModal: state.getIn(['meta', 'boost_modal']) + boostModal: state.getIn(['meta', 'boost_modal']), + autoPlayGif: state.getIn(['meta', 'auto_play_gif']) }); return mapStateToProps; diff --git a/app/assets/javascripts/components/features/account/components/header.jsx b/app/assets/javascripts/components/features/account/components/header.jsx index c4619a3c7..a660dee37 100644 --- a/app/assets/javascripts/components/features/account/components/header.jsx +++ b/app/assets/javascripts/components/features/account/components/header.jsx @@ -5,6 +5,7 @@ import escapeTextContentForBrowser from 'escape-html'; import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; import IconButton from '../../../components/icon_button'; import { Motion, spring } from 'react-motion'; +import { connect } from 'react-redux'; const messages = defineMessages({ unfollow: { id: 'account.unfollow', defaultMessage: 'Unfollow' }, @@ -12,10 +13,19 @@ const messages = defineMessages({ requested: { id: 'account.requested', defaultMessage: 'Awaiting approval' } }); +const makeMapStateToProps = () => { + const mapStateToProps = (state, props) => ({ + autoPlayGif: state.getIn(['meta', 'auto_play_gif']) + }); + + return mapStateToProps; +}; + const Avatar = React.createClass({ propTypes: { - account: ImmutablePropTypes.map.isRequired + account: ImmutablePropTypes.map.isRequired, + autoPlayGif: React.PropTypes.bool.isRequired }, getInitialState () { @@ -37,7 +47,7 @@ const Avatar = React.createClass({ }, render () { - const { account } = this.props; + const { account, autoPlayGif } = this.props; const { isHovered } = this.state; return ( @@ -48,13 +58,12 @@ const Avatar = React.createClass({ className='account__header__avatar' target='_blank' rel='noopener' - style={{ display: 'block', width: '90px', height: '90px', margin: '0 auto', marginBottom: '10px', borderRadius: `${radius}px`, overflow: 'hidden' }} + style={{ display: 'block', width: '90px', height: '90px', margin: '0 auto', marginBottom: '10px', borderRadius: `${radius}px`, overflow: 'hidden', backgroundSize: '90px 90px', backgroundImage: `url(${autoPlayGif || isHovered ? account.get('avatar') : account.get('avatar_static')})` }} onMouseOver={this.handleMouseOver} onMouseOut={this.handleMouseOut} onFocus={this.handleMouseOver} - onBlur={this.handleMouseOut}> - <img src={account.get('avatar')} alt={account.get('acct')} style={{ display: 'block', width: '90px', height: '90px' }} /> - </a> + onBlur={this.handleMouseOut} + /> } </Motion> ); @@ -68,7 +77,8 @@ const Header = React.createClass({ account: ImmutablePropTypes.map, me: React.PropTypes.number.isRequired, onFollow: React.PropTypes.func.isRequired, - intl: React.PropTypes.object.isRequired + intl: React.PropTypes.object.isRequired, + autoPlayGif: React.PropTypes.bool.isRequired }, mixins: [PureRenderMixin], @@ -119,7 +129,7 @@ const Header = React.createClass({ return ( <div className='account__header' style={{ backgroundImage: `url(${account.get('header')})` }}> <div style={{ padding: '20px 10px' }}> - <Avatar account={account} /> + <Avatar account={account} autoPlayGif={this.props.autoPlayGif} /> <span style={{ display: 'inline-block', fontSize: '20px', lineHeight: '27px', fontWeight: '500' }} className='account__header__display-name' dangerouslySetInnerHTML={displayNameHTML} /> <span className='account__header__username' style={{ fontSize: '14px', fontWeight: '400', display: 'block', marginBottom: '10px' }}>@{account.get('acct')} {lockedIcon}</span> @@ -134,4 +144,4 @@ const Header = React.createClass({ }); -export default injectIntl(Header); +export default connect(makeMapStateToProps)(injectIntl(Header)); diff --git a/app/assets/javascripts/components/features/status/components/detailed_status.jsx b/app/assets/javascripts/components/features/status/components/detailed_status.jsx index ceafc1a32..bd386b251 100644 --- a/app/assets/javascripts/components/features/status/components/detailed_status.jsx +++ b/app/assets/javascripts/components/features/status/components/detailed_status.jsx @@ -19,6 +19,7 @@ const DetailedStatus = React.createClass({ status: ImmutablePropTypes.map.isRequired, onOpenMedia: React.PropTypes.func.isRequired, onOpenVideo: React.PropTypes.func.isRequired, + autoPlayGif: React.PropTypes.bool, }, mixins: [PureRenderMixin], @@ -42,7 +43,7 @@ const DetailedStatus = React.createClass({ if (status.getIn(['media_attachments', 0, 'type']) === 'video') { media = <VideoPlayer sensitive={status.get('sensitive')} media={status.getIn(['media_attachments', 0])} width={300} height={150} onOpenVideo={this.props.onOpenVideo} autoplay />; } else { - media = <MediaGallery sensitive={status.get('sensitive')} media={status.get('media_attachments')} height={300} onOpenMedia={this.props.onOpenMedia} />; + media = <MediaGallery sensitive={status.get('sensitive')} media={status.get('media_attachments')} height={300} onOpenMedia={this.props.onOpenMedia} autoPlayGif={this.props.autoPlayGif} />; } } else { media = <CardContainer statusId={status.get('id')} />; diff --git a/app/assets/javascripts/components/features/status/index.jsx b/app/assets/javascripts/components/features/status/index.jsx index 7ead68807..ca6e08cdc 100644 --- a/app/assets/javascripts/components/features/status/index.jsx +++ b/app/assets/javascripts/components/features/status/index.jsx @@ -39,7 +39,8 @@ const makeMapStateToProps = () => { ancestorsIds: state.getIn(['timelines', 'ancestors', Number(props.params.statusId)]), descendantsIds: state.getIn(['timelines', 'descendants', Number(props.params.statusId)]), me: state.getIn(['meta', 'me']), - boostModal: state.getIn(['meta', 'boost_modal']) + boostModal: state.getIn(['meta', 'boost_modal']), + autoPlayGif: state.getIn(['meta', 'auto_play_gif']) }); return mapStateToProps; @@ -57,7 +58,8 @@ const Status = React.createClass({ ancestorsIds: ImmutablePropTypes.list, descendantsIds: ImmutablePropTypes.list, me: React.PropTypes.number, - boostModal: React.PropTypes.bool + boostModal: React.PropTypes.bool, + autoPlayGif: React.PropTypes.bool }, mixins: [PureRenderMixin], @@ -126,7 +128,7 @@ const Status = React.createClass({ render () { let ancestors, descendants; - const { status, ancestorsIds, descendantsIds, me } = this.props; + const { status, ancestorsIds, descendantsIds, me, autoPlayGif } = this.props; if (status === null) { return ( @@ -155,7 +157,7 @@ const Status = React.createClass({ <div className='scrollable'> {ancestors} - <DetailedStatus status={status} me={me} onOpenVideo={this.handleOpenVideo} onOpenMedia={this.handleOpenMedia} /> + <DetailedStatus status={status} autoPlayGif={autoPlayGif} me={me} onOpenVideo={this.handleOpenVideo} onOpenMedia={this.handleOpenMedia} /> <ActionBar status={status} me={me} onReply={this.handleReplyClick} onFavourite={this.handleFavouriteClick} onReblog={this.handleReblogClick} onDelete={this.handleDeleteClick} onMention={this.handleMentionClick} onReport={this.handleReport} /> {descendants} diff --git a/app/assets/stylesheets/components.scss b/app/assets/stylesheets/components.scss index 6f407a6d5..b646b0c77 100644 --- a/app/assets/stylesheets/components.scss +++ b/app/assets/stylesheets/components.scss @@ -2315,3 +2315,34 @@ button.icon-button.active i.fa-retweet { top: 0; left: 0; } + +.media-gallery__gifv__label { + display: block; + position: absolute; + color: $color5; + background: rgba($color8, 0.5); + bottom: 6px; + left: 6px; + padding: 2px 6px; + border-radius: 2px; + font-size: 11px; + font-weight: 600; + z-index: 1; + pointer-events: none; + opacity: 0.9; + transition: opacity 0.1s ease; +} + +.media-gallery__gifv { + &.autoplay { + .media-gallery__gifv__label { + display: none; + } + } + + &:hover { + .media-gallery__gifv__label { + opacity: 1; + } + } +} |