Fix avatars not using image tags in web UI (#19488)

Fix #19483
pull/1876/head
Eugen Rochko 2022-10-28 00:48:45 +02:00 committed by GitHub
parent 07cc201acc
commit 8dfe5179ee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 103 additions and 79 deletions

View File

@ -2,36 +2,38 @@
exports[`<Avatar /> Autoplay renders a animated avatar 1`] = ` exports[`<Avatar /> Autoplay renders a animated avatar 1`] = `
<div <div
aria-label="alice"
className="account__avatar" className="account__avatar"
onMouseEnter={[Function]} onMouseEnter={[Function]}
onMouseLeave={[Function]} onMouseLeave={[Function]}
role="img"
style={ style={
{ {
"backgroundImage": "url(/animated/alice.gif)",
"backgroundSize": "100px 100px",
"height": "100px", "height": "100px",
"width": "100px", "width": "100px",
} }
} }
/> >
<img
alt="alice"
src="/animated/alice.gif"
/>
</div>
`; `;
exports[`<Avatar /> Still renders a still avatar 1`] = ` exports[`<Avatar /> Still renders a still avatar 1`] = `
<div <div
aria-label="alice"
className="account__avatar" className="account__avatar"
onMouseEnter={[Function]} onMouseEnter={[Function]}
onMouseLeave={[Function]} onMouseLeave={[Function]}
role="img"
style={ style={
{ {
"backgroundImage": "url(/static/alice.jpg)",
"backgroundSize": "100px 100px",
"height": "100px", "height": "100px",
"width": "100px", "width": "100px",
} }
} }
/> >
<img
alt="alice"
src="/static/alice.jpg"
/>
</div>
`; `;

View File

@ -3,22 +3,52 @@
exports[`<AvatarOverlay renders a overlay avatar 1`] = ` exports[`<AvatarOverlay renders a overlay avatar 1`] = `
<div <div
className="account__avatar-overlay" className="account__avatar-overlay"
style={
{
"height": 46,
"width": 46,
}
}
> >
<div <div
className="account__avatar-overlay-base" className="account__avatar-overlay-base"
style={ >
{ <div
"backgroundImage": "url(/static/alice.jpg)", className="account__avatar"
onMouseEnter={[Function]}
onMouseLeave={[Function]}
style={
{
"height": "36px",
"width": "36px",
}
} }
} >
/> <img
alt="alice"
src="/static/alice.jpg"
/>
</div>
</div>
<div <div
className="account__avatar-overlay-overlay" className="account__avatar-overlay-overlay"
style={ >
{ <div
"backgroundImage": "url(/static/eve.jpg)", className="account__avatar"
onMouseEnter={[Function]}
onMouseLeave={[Function]}
style={
{
"height": "24px",
"width": "24px",
}
} }
} >
/> <img
alt="eve@blackhat.lair"
src="/static/eve.jpg"
/>
</div>
</div>
</div> </div>
`; `;

View File

@ -42,30 +42,20 @@ export default class Avatar extends React.PureComponent {
...this.props.style, ...this.props.style,
width: `${size}px`, width: `${size}px`,
height: `${size}px`, height: `${size}px`,
backgroundSize: `${size}px ${size}px`,
}; };
if (account) { let src;
const src = account.get('avatar');
const staticSrc = account.get('avatar_static');
if (hovering || animate) { if (hovering || animate) {
style.backgroundImage = `url(${src})`; src = account?.get('avatar');
} else { } else {
style.backgroundImage = `url(${staticSrc})`; src = account?.get('avatar_static');
}
} }
return ( return (
<div <div className={classNames('account__avatar', { 'account__avatar-inline': inline })} onMouseEnter={this.handleMouseEnter} onMouseLeave={this.handleMouseLeave} style={style}>
className={classNames('account__avatar', { 'account__avatar-inline': inline })} <img src={src} alt={account?.get('acct')} />
onMouseEnter={this.handleMouseEnter} </div>
onMouseLeave={this.handleMouseLeave}
style={style}
role='img'
aria-label={account?.get('acct')}
/>
); );
} }

View File

@ -2,6 +2,7 @@ import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePropTypes from 'react-immutable-proptypes';
import { autoPlayGif } from '../initial_state'; import { autoPlayGif } from '../initial_state';
import Avatar from './avatar';
export default class AvatarComposite extends React.PureComponent { export default class AvatarComposite extends React.PureComponent {
@ -74,12 +75,12 @@ export default class AvatarComposite extends React.PureComponent {
bottom: bottom, bottom: bottom,
width: `${width}%`, width: `${width}%`,
height: `${height}%`, height: `${height}%`,
backgroundSize: 'cover',
backgroundImage: `url(${account.get(animate ? 'avatar' : 'avatar_static')})`,
}; };
return ( return (
<div key={account.get('id')} style={style} /> <div key={account.get('id')} style={style}>
<Avatar account={account} animate={animate} />
</div>
); );
} }

View File

@ -2,6 +2,7 @@ import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePropTypes from 'react-immutable-proptypes';
import { autoPlayGif } from '../initial_state'; import { autoPlayGif } from '../initial_state';
import Avatar from './avatar';
export default class AvatarOverlay extends React.PureComponent { export default class AvatarOverlay extends React.PureComponent {
@ -9,27 +10,40 @@ export default class AvatarOverlay extends React.PureComponent {
account: ImmutablePropTypes.map.isRequired, account: ImmutablePropTypes.map.isRequired,
friend: ImmutablePropTypes.map.isRequired, friend: ImmutablePropTypes.map.isRequired,
animate: PropTypes.bool, animate: PropTypes.bool,
size: PropTypes.number,
baseSize: PropTypes.number,
overlaySize: PropTypes.number,
}; };
static defaultProps = { static defaultProps = {
animate: autoPlayGif, animate: autoPlayGif,
size: 46,
baseSize: 36,
overlaySize: 24,
}; };
state = {
hovering: false,
};
handleMouseEnter = () => {
if (this.props.animate) return;
this.setState({ hovering: true });
}
handleMouseLeave = () => {
if (this.props.animate) return;
this.setState({ hovering: false });
}
render() { render() {
const { account, friend, animate } = this.props; const { account, friend, animate, size, baseSize, overlaySize } = this.props;
const { hovering } = this.state;
const baseStyle = {
backgroundImage: `url(${account.get(animate ? 'avatar' : 'avatar_static')})`,
};
const overlayStyle = {
backgroundImage: `url(${friend.get(animate ? 'avatar' : 'avatar_static')})`,
};
return ( return (
<div className='account__avatar-overlay'> <div className='account__avatar-overlay' style={{ width: size, height: size }}>
<div className='account__avatar-overlay-base' style={baseStyle} /> <div className='account__avatar-overlay-base'><Avatar animate={hovering || animate} account={account} size={baseSize} /></div>
<div className='account__avatar-overlay-overlay' style={overlayStyle} /> <div className='account__avatar-overlay-overlay'><Avatar animate={hovering || animate} account={friend} size={overlaySize} /></div>
</div> </div>
); );
} }

View File

@ -1382,6 +1382,14 @@
display: block; display: block;
position: relative; position: relative;
overflow: hidden;
img {
display: block;
width: 100%;
height: 100%;
object-fit: cover;
}
&-inline { &-inline {
display: inline-block; display: inline-block;
@ -1390,8 +1398,6 @@
} }
&-composite { &-composite {
@include avatar-radius;
border-radius: 50%; border-radius: 50%;
overflow: hidden; overflow: hidden;
position: relative; position: relative;
@ -1402,6 +1408,11 @@
box-sizing: border-box; box-sizing: border-box;
} }
.account__avatar {
width: 100% !important;
height: 100% !important;
}
&__label { &__label {
display: block; display: block;
position: absolute; position: absolute;
@ -1421,37 +1432,13 @@ a .account__avatar {
} }
.account__avatar-overlay { .account__avatar-overlay {
@include avatar-size(46px);
position: relative; position: relative;
&-base {
@include avatar-radius;
@include avatar-size(36px);
img {
@include avatar-radius;
width: 100%;
height: 100%;
}
}
&-overlay { &-overlay {
@include avatar-radius;
@include avatar-size(24px);
position: absolute; position: absolute;
bottom: 0; bottom: 0;
right: 0; right: 0;
z-index: 1; z-index: 1;
img {
@include avatar-radius;
width: 100%;
height: 100%;
}
} }
} }