about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEugen Rochko <eugen@zeonfederated.com>2022-10-28 00:48:45 +0200
committerGitHub <noreply@github.com>2022-10-28 00:48:45 +0200
commit8dfe5179ee7186e549dbe1186a151ffa848fe8ab (patch)
tree9b2ec70b5330372ea02e8d14e5f9dc3f402ea2d9
parent07cc201accd4a04c8c11cda21eecded4e7875d55 (diff)
Fix avatars not using image tags in web UI (#19488)
Fix #19483
-rw-r--r--app/javascript/mastodon/components/__tests__/__snapshots__/avatar-test.js.snap22
-rw-r--r--app/javascript/mastodon/components/__tests__/__snapshots__/avatar_overlay-test.js.snap50
-rw-r--r--app/javascript/mastodon/components/avatar.js26
-rw-r--r--app/javascript/mastodon/components/avatar_composite.js7
-rw-r--r--app/javascript/mastodon/components/avatar_overlay.js36
-rw-r--r--app/javascript/styles/mastodon/components.scss39
6 files changed, 102 insertions, 78 deletions
diff --git a/app/javascript/mastodon/components/__tests__/__snapshots__/avatar-test.js.snap b/app/javascript/mastodon/components/__tests__/__snapshots__/avatar-test.js.snap
index f5c10aa37..7fbdedeb2 100644
--- a/app/javascript/mastodon/components/__tests__/__snapshots__/avatar-test.js.snap
+++ b/app/javascript/mastodon/components/__tests__/__snapshots__/avatar-test.js.snap
@@ -2,36 +2,38 @@
 
 exports[`<Avatar /> Autoplay renders a animated avatar 1`] = `
 <div
-  aria-label="alice"
   className="account__avatar"
   onMouseEnter={[Function]}
   onMouseLeave={[Function]}
-  role="img"
   style={
     {
-      "backgroundImage": "url(/animated/alice.gif)",
-      "backgroundSize": "100px 100px",
       "height": "100px",
       "width": "100px",
     }
   }
-/>
+>
+  <img
+    alt="alice"
+    src="/animated/alice.gif"
+  />
+</div>
 `;
 
 exports[`<Avatar /> Still renders a still avatar 1`] = `
 <div
-  aria-label="alice"
   className="account__avatar"
   onMouseEnter={[Function]}
   onMouseLeave={[Function]}
-  role="img"
   style={
     {
-      "backgroundImage": "url(/static/alice.jpg)",
-      "backgroundSize": "100px 100px",
       "height": "100px",
       "width": "100px",
     }
   }
-/>
+>
+  <img
+    alt="alice"
+    src="/static/alice.jpg"
+  />
+</div>
 `;
diff --git a/app/javascript/mastodon/components/__tests__/__snapshots__/avatar_overlay-test.js.snap b/app/javascript/mastodon/components/__tests__/__snapshots__/avatar_overlay-test.js.snap
index 58f27a321..f8385357a 100644
--- a/app/javascript/mastodon/components/__tests__/__snapshots__/avatar_overlay-test.js.snap
+++ b/app/javascript/mastodon/components/__tests__/__snapshots__/avatar_overlay-test.js.snap
@@ -3,22 +3,52 @@
 exports[`<AvatarOverlay renders a overlay avatar 1`] = `
 <div
   className="account__avatar-overlay"
+  style={
+    {
+      "height": 46,
+      "width": 46,
+    }
+  }
 >
   <div
     className="account__avatar-overlay-base"
-    style={
-      {
-        "backgroundImage": "url(/static/alice.jpg)",
+  >
+    <div
+      className="account__avatar"
+      onMouseEnter={[Function]}
+      onMouseLeave={[Function]}
+      style={
+        {
+          "height": "36px",
+          "width": "36px",
+        }
       }
-    }
-  />
+    >
+      <img
+        alt="alice"
+        src="/static/alice.jpg"
+      />
+    </div>
+  </div>
   <div
     className="account__avatar-overlay-overlay"
-    style={
-      {
-        "backgroundImage": "url(/static/eve.jpg)",
+  >
+    <div
+      className="account__avatar"
+      onMouseEnter={[Function]}
+      onMouseLeave={[Function]}
+      style={
+        {
+          "height": "24px",
+          "width": "24px",
+        }
       }
-    }
-  />
+    >
+      <img
+        alt="eve@blackhat.lair"
+        src="/static/eve.jpg"
+      />
+    </div>
+  </div>
 </div>
 `;
diff --git a/app/javascript/mastodon/components/avatar.js b/app/javascript/mastodon/components/avatar.js
index dd3932ae6..207b26691 100644
--- a/app/javascript/mastodon/components/avatar.js
+++ b/app/javascript/mastodon/components/avatar.js
@@ -42,30 +42,20 @@ export default class Avatar extends React.PureComponent {
       ...this.props.style,
       width: `${size}px`,
       height: `${size}px`,
-      backgroundSize: `${size}px ${size}px`,
     };
 
-    if (account) {
-      const src = account.get('avatar');
-      const staticSrc = account.get('avatar_static');
+    let src;
 
-      if (hovering || animate) {
-        style.backgroundImage = `url(${src})`;
-      } else {
-        style.backgroundImage = `url(${staticSrc})`;
-      }
+    if (hovering || animate) {
+      src = account?.get('avatar');
+    } else {
+      src = account?.get('avatar_static');
     }
 
-
     return (
-      <div
-        className={classNames('account__avatar', { 'account__avatar-inline': inline })}
-        onMouseEnter={this.handleMouseEnter}
-        onMouseLeave={this.handleMouseLeave}
-        style={style}
-        role='img'
-        aria-label={account?.get('acct')}
-      />
+      <div className={classNames('account__avatar', { 'account__avatar-inline': inline })} onMouseEnter={this.handleMouseEnter} onMouseLeave={this.handleMouseLeave} style={style}>
+        <img src={src} alt={account?.get('acct')} />
+      </div>
     );
   }
 
diff --git a/app/javascript/mastodon/components/avatar_composite.js b/app/javascript/mastodon/components/avatar_composite.js
index 5d5b89749..220bf5b4f 100644
--- a/app/javascript/mastodon/components/avatar_composite.js
+++ b/app/javascript/mastodon/components/avatar_composite.js
@@ -2,6 +2,7 @@ import React from 'react';
 import PropTypes from 'prop-types';
 import ImmutablePropTypes from 'react-immutable-proptypes';
 import { autoPlayGif } from '../initial_state';
+import Avatar from './avatar';
 
 export default class AvatarComposite extends React.PureComponent {
 
@@ -74,12 +75,12 @@ export default class AvatarComposite extends React.PureComponent {
       bottom: bottom,
       width: `${width}%`,
       height: `${height}%`,
-      backgroundSize: 'cover',
-      backgroundImage: `url(${account.get(animate ? 'avatar' : 'avatar_static')})`,
     };
 
     return (
-      <div key={account.get('id')} style={style} />
+      <div key={account.get('id')} style={style}>
+        <Avatar account={account} animate={animate} />
+      </div>
     );
   }
 
diff --git a/app/javascript/mastodon/components/avatar_overlay.js b/app/javascript/mastodon/components/avatar_overlay.js
index 3ec1d7730..8d5d44ea5 100644
--- a/app/javascript/mastodon/components/avatar_overlay.js
+++ b/app/javascript/mastodon/components/avatar_overlay.js
@@ -2,6 +2,7 @@ import React from 'react';
 import PropTypes from 'prop-types';
 import ImmutablePropTypes from 'react-immutable-proptypes';
 import { autoPlayGif } from '../initial_state';
+import Avatar from './avatar';
 
 export default class AvatarOverlay extends React.PureComponent {
 
@@ -9,27 +10,40 @@ export default class AvatarOverlay extends React.PureComponent {
     account: ImmutablePropTypes.map.isRequired,
     friend: ImmutablePropTypes.map.isRequired,
     animate: PropTypes.bool,
+    size: PropTypes.number,
+    baseSize: PropTypes.number,
+    overlaySize: PropTypes.number,
   };
 
   static defaultProps = {
     animate: autoPlayGif,
+    size: 46,
+    baseSize: 36,
+    overlaySize: 24,
   };
 
-  render() {
-    const { account, friend, animate } = this.props;
+  state = {
+    hovering: false,
+  };
+
+  handleMouseEnter = () => {
+    if (this.props.animate) return;
+    this.setState({ hovering: true });
+  }
 
-    const baseStyle = {
-      backgroundImage: `url(${account.get(animate ? 'avatar' : 'avatar_static')})`,
-    };
+  handleMouseLeave = () => {
+    if (this.props.animate) return;
+    this.setState({ hovering: false });
+  }
 
-    const overlayStyle = {
-      backgroundImage: `url(${friend.get(animate ? 'avatar' : 'avatar_static')})`,
-    };
+  render() {
+    const { account, friend, animate, size, baseSize, overlaySize } = this.props;
+    const { hovering } = this.state;
 
     return (
-      <div className='account__avatar-overlay'>
-        <div className='account__avatar-overlay-base' style={baseStyle} />
-        <div className='account__avatar-overlay-overlay' style={overlayStyle} />
+      <div className='account__avatar-overlay' style={{ width: size, height: size }}>
+        <div className='account__avatar-overlay-base'><Avatar animate={hovering || animate} account={account} size={baseSize} /></div>
+        <div className='account__avatar-overlay-overlay'><Avatar animate={hovering || animate} account={friend} size={overlaySize} /></div>
       </div>
     );
   }
diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss
index 633b9ed70..69301fb05 100644
--- a/app/javascript/styles/mastodon/components.scss
+++ b/app/javascript/styles/mastodon/components.scss
@@ -1382,6 +1382,14 @@
 
   display: block;
   position: relative;
+  overflow: hidden;
+
+  img {
+    display: block;
+    width: 100%;
+    height: 100%;
+    object-fit: cover;
+  }
 
   &-inline {
     display: inline-block;
@@ -1390,8 +1398,6 @@
   }
 
   &-composite {
-    @include avatar-radius;
-
     border-radius: 50%;
     overflow: hidden;
     position: relative;
@@ -1402,6 +1408,11 @@
       box-sizing: border-box;
     }
 
+    .account__avatar {
+      width: 100% !important;
+      height: 100% !important;
+    }
+
     &__label {
       display: block;
       position: absolute;
@@ -1421,37 +1432,13 @@ a .account__avatar {
 }
 
 .account__avatar-overlay {
-  @include avatar-size(46px);
-
   position: relative;
 
-  &-base {
-    @include avatar-radius;
-    @include avatar-size(36px);
-
-    img {
-      @include avatar-radius;
-
-      width: 100%;
-      height: 100%;
-    }
-  }
-
   &-overlay {
-    @include avatar-radius;
-    @include avatar-size(24px);
-
     position: absolute;
     bottom: 0;
     right: 0;
     z-index: 1;
-
-    img {
-      @include avatar-radius;
-
-      width: 100%;
-      height: 100%;
-    }
   }
 }