]> cat aescling's git repositories - mastodon.git/commitdiff
Refactor Avatar and AvatarOverlay to have 'account' as prop instead of src and static...
authorOndřej Hruška <ondra@ondrovo.com>
Mon, 7 Aug 2017 17:44:55 +0000 (19:44 +0200)
committerEugen Rochko <eugen@zeonfederated.com>
Mon, 7 Aug 2017 17:44:55 +0000 (19:44 +0200)
* Refactored Avatar and AvatarOverlay (DRY) to have 'account' as prop.
Also removed animate attribute from compose navigation bar, which should
have never been there. Added test for avatar overlay.

* fix broken tests

* god dammit another bug in tests! travis please let this pass

* formatting in avatar overlay

13 files changed:
app/javascript/mastodon/components/account.js
app/javascript/mastodon/components/avatar.js
app/javascript/mastodon/components/avatar_overlay.js
app/javascript/mastodon/components/status.js
app/javascript/mastodon/features/compose/components/autosuggest_account.js
app/javascript/mastodon/features/compose/components/navigation_bar.js
app/javascript/mastodon/features/compose/components/reply_indicator.js
app/javascript/mastodon/features/follow_requests/components/account_authorize.js
app/javascript/mastodon/features/status/components/detailed_status.js
app/javascript/mastodon/features/ui/components/actions_modal.js
app/javascript/mastodon/features/ui/components/boost_modal.js
spec/javascript/components/avatar.test.js
spec/javascript/components/avatar_overlay.test.js [new file with mode: 0644]

index b6ca0661fb154a6ba03bda268e11e8db7c887ac7..69cc63d106e428252b85e0d60bebdc7038d54807 100644 (file)
@@ -70,7 +70,7 @@ export default class Account extends ImmutablePureComponent {
       <div className='account'>
         <div className='account__wrapper'>
           <Permalink key={account.get('id')} className='account__display-name' href={account.get('url')} to={`/accounts/${account.get('id')}`}>
-            <div className='account__avatar-wrapper'><Avatar src={account.get('avatar')} staticSrc={account.get('avatar_static')} size={36} /></div>
+            <div className='account__avatar-wrapper'><Avatar account={account} size={36} /></div>
             <DisplayName account={account} />
           </Permalink>
 
index 4f8170657610afc81ec04ad73f9a9401e8817514..f7c484ee3a71d0bff9054bbe695628f5f751dde4 100644 (file)
@@ -1,11 +1,11 @@
 import React from 'react';
 import PropTypes from 'prop-types';
+import ImmutablePropTypes from 'react-immutable-proptypes';
 
 export default class Avatar extends React.PureComponent {
 
   static propTypes = {
-    src: PropTypes.string.isRequired,
-    staticSrc: PropTypes.string,
+    account: ImmutablePropTypes.map.isRequired,
     size: PropTypes.number.isRequired,
     style: PropTypes.object,
     animate: PropTypes.bool,
@@ -33,9 +33,12 @@ export default class Avatar extends React.PureComponent {
   }
 
   render () {
-    const { src, size, staticSrc, animate, inline } = this.props;
+    const { account, size, animate, inline } = this.props;
     const { hovering } = this.state;
 
+    const src = account.get('avatar');
+    const staticSrc = account.get('avatar_static');
+
     let className = 'account__avatar';
 
     if (inline) {
index de43e0ef5150a234ee0fd232d6dc5051034116c9..f5d67b34e8b476b63474d8746fd80a1ee12f621e 100644 (file)
@@ -1,22 +1,22 @@
 import React from 'react';
-import PropTypes from 'prop-types';
+import ImmutablePropTypes from 'react-immutable-proptypes';
 
 export default class AvatarOverlay extends React.PureComponent {
 
   static propTypes = {
-    staticSrc: PropTypes.string.isRequired,
-    overlaySrc: PropTypes.string.isRequired,
+    account: ImmutablePropTypes.map.isRequired,
+    friend: ImmutablePropTypes.map.isRequired,
   };
 
   render() {
-    const { staticSrc, overlaySrc } = this.props;
+    const { account, friend } = this.props;
 
     const baseStyle = {
-      backgroundImage: `url(${staticSrc})`,
+      backgroundImage: `url(${account.get('avatar_static')})`,
     };
 
     const overlayStyle = {
-      backgroundImage: `url(${overlaySrc})`,
+      backgroundImage: `url(${friend.get('avatar_static')})`,
     };
 
     return (
index ceb512d96080209e331efb6b53ed3ea4b3c0032f..25879c497325b9cc065fe57112c54985afa884dd 100644 (file)
@@ -228,9 +228,9 @@ export default class Status extends ImmutablePureComponent {
     }
 
     if (account === undefined || account === null) {
-      statusAvatar = <Avatar src={status.getIn(['account', 'avatar'])} staticSrc={status.getIn(['account', 'avatar_static'])} size={48} />;
+      statusAvatar = <Avatar account={status.get('account')} size={48} />;
     }else{
-      statusAvatar = <AvatarOverlay staticSrc={status.getIn(['account', 'avatar_static'])} overlaySrc={account.get('avatar_static')} />;
+      statusAvatar = <AvatarOverlay account={status.get('account')} friend={account} />;
     }
 
     return (
index ebfa3c247bd2ce4879b5335c0d861f6b068f45ee..e7de3716ba395dc2032107914c26e4de38ea34c1 100644 (file)
@@ -15,7 +15,7 @@ export default class AutosuggestAccount extends ImmutablePureComponent {
 
     return (
       <div className='autosuggest-account'>
-        <div className='autosuggest-account-icon'><Avatar src={account.get('avatar')} staticSrc={account.get('avatar_static')} size={18} /></div>
+        <div className='autosuggest-account-icon'><Avatar account={account} size={18} /></div>
         <DisplayName account={account} />
       </div>
     );
index cd2dd8f6161dcb2cc91d1d87e53d45caa62d9c9c..7f346854ce420917921d061abaaa9d6aa37f4807 100644 (file)
@@ -19,7 +19,7 @@ export default class NavigationBar extends ImmutablePureComponent {
       <div className='navigation-bar'>
         <Permalink href={this.props.account.get('url')} to={`/accounts/${this.props.account.get('id')}`}>
           <span style={{ display: 'none' }}>{this.props.account.get('acct')}</span>
-          <Avatar src={this.props.account.get('avatar')} animate size={40} />
+          <Avatar account={this.props.account} size={40} />
         </Permalink>
 
         <div className='navigation-bar__profile'>
index da00e46c51e7026184b43d99f36d70abedb40bc9..35a9b4b1b4abbad92cb7bcff823b335a10263e09 100644 (file)
@@ -51,7 +51,7 @@ export default class ReplyIndicator extends ImmutablePureComponent {
           <div className='reply-indicator__cancel'><IconButton title={intl.formatMessage(messages.cancel)} icon='times' onClick={this.handleClick} /></div>
 
           <a href={status.getIn(['account', 'url'])} onClick={this.handleAccountClick} className='reply-indicator__display-name'>
-            <div className='reply-indicator__display-avatar'><Avatar size={24} src={status.getIn(['account', 'avatar'])} staticSrc={status.getIn(['account', 'avatar_static'])} /></div>
+            <div className='reply-indicator__display-avatar'><Avatar account={status.get('account')} size={24} /></div>
             <DisplayName account={status.get('account')} />
           </a>
         </div>
index 566953ddd604354305aed80440239bd8c4d72c46..66fa5c235c677ab322a3256caf38ca07c67acdb7 100644 (file)
@@ -32,7 +32,7 @@ export default class AccountAuthorize extends ImmutablePureComponent {
       <div className='account-authorize__wrapper'>
         <div className='account-authorize'>
           <Permalink href={account.get('url')} to={`/accounts/${account.get('id')}`} className='detailed-status__display-name'>
-            <div className='account-authorize__avatar'><Avatar src={account.get('avatar')} staticSrc={account.get('avatar_static')} size={48} /></div>
+            <div className='account-authorize__avatar'><Avatar account={account} size={48} /></div>
             <DisplayName account={account} />
           </Permalink>
 
index 619957dbe7d2a4821c8b30f0a2baffffb2197a7a..940a2699b730a3da91088d205c31ee6d2c0303ea 100644 (file)
@@ -59,7 +59,7 @@ export default class DetailedStatus extends ImmutablePureComponent {
     return (
       <div className='detailed-status'>
         <a href={status.getIn(['account', 'url'])} onClick={this.handleAccountClick} className='detailed-status__display-name'>
-          <div className='detailed-status__display-avatar'><Avatar src={status.getIn(['account', 'avatar'])} staticSrc={status.getIn(['account', 'avatar_static'])} size={48} /></div>
+          <div className='detailed-status__display-avatar'><Avatar account={status.get('account')} size={48} /></div>
           <DisplayName account={status.get('account')} />
         </a>
 
index cc0620d1c4754a7c64f8078169e707a471eedceb..3d40033be1fc8be89421b7b33823da3830591e0a 100644 (file)
@@ -46,7 +46,7 @@ export default class ActionsModal extends ImmutablePureComponent {
 
           <a href={this.props.status.getIn(['account', 'url'])} className='status__display-name'>
             <div className='status__avatar'>
-              <Avatar src={this.props.status.getIn(['account', 'avatar'])} staticSrc={this.props.status.getIn(['account', 'avatar_static'])} size={48} />
+              <Avatar account={this.props.status.get('account')} size={48} />
             </div>
 
             <DisplayName account={this.props.status.get('account')} />
index 6c80a10844a7e105cf77a48813d31c64b7558abd..0e9592c977fdefc26021b11c153166a252f275de 100644 (file)
@@ -62,7 +62,7 @@ export default class BoostModal extends ImmutablePureComponent {
 
               <a onClick={this.handleAccountClick} href={status.getIn(['account', 'url'])} className='status__display-name'>
                 <div className='status__avatar'>
-                  <Avatar src={status.getIn(['account', 'avatar'])} staticSrc={status.getIn(['account', 'avatar_static'])} size={48} />
+                  <Avatar account={status.get('account')} size={48} />
                 </div>
 
                 <DisplayName account={status.get('account')} />
index 03b71dc9d92eb716f5e22739c5e9313f5b5bff60..ee40812caf1828deff4294ff2ed4edccd0883780 100644 (file)
@@ -1,20 +1,42 @@
 import { expect } from 'chai';
 import { render } from 'enzyme';
+import { fromJS }  from 'immutable';
 import React from 'react';
 import Avatar from '../../../app/javascript/mastodon/components/avatar';
 
 describe('<Avatar />', () => {
-  const src = '/path/to/image.jpg';
+  const account = fromJS({
+    username: 'alice',
+    acct: 'alice',
+    display_name: 'Alice',
+    avatar: '/animated/alice.gif',
+    avatar_static: '/static/alice.jpg',
+  });
   const size = 100;
-  const wrapper = render(<Avatar src={src} animate size={size} />);
+  const animated = render(<Avatar account={account} animate size={size} />);
+  const still = render(<Avatar account={account} size={size} />);
 
+  // Autoplay
   it('renders a div element with the given src as background', () => {
-    expect(wrapper.find('div')).to.have.style('background-image', `url(${src})`);
+    expect(animated.find('div')).to.have.style('background-image', `url(${account.get('avatar')})`);
   });
 
   it('renders a div element of the given size', () => {
     ['width', 'height'].map((attr) => {
-      expect(wrapper.find('div')).to.have.style(attr, `${size}px`);
+      expect(animated.find('div')).to.have.style(attr, `${size}px`);
+    });
+  });
+
+  // Still
+  it('renders a div element with the given static src as background if not autoplay', () => {
+    expect(still.find('div')).to.have.style('background-image', `url(${account.get('avatar_static')})`);
+  });
+
+  it('renders a div element of the given size if not autoplay', () => {
+    ['width', 'height'].map((attr) => {
+      expect(still.find('div')).to.have.style(attr, `${size}px`);
     });
   });
+
+  // TODO add autoplay test if possible
 });
diff --git a/spec/javascript/components/avatar_overlay.test.js b/spec/javascript/components/avatar_overlay.test.js
new file mode 100644 (file)
index 0000000..a8f0e13
--- /dev/null
@@ -0,0 +1,34 @@
+import { expect } from 'chai';
+import { render } from 'enzyme';
+import { fromJS }  from 'immutable';
+import React from 'react';
+import AvatarOverlay from '../../../app/javascript/mastodon/components/avatar_overlay';
+
+describe('<Avatar />', () => {
+  const account = fromJS({
+    username: 'alice',
+    acct: 'alice',
+    display_name: 'Alice',
+    avatar: '/animated/alice.gif',
+    avatar_static: '/static/alice.jpg',
+  });
+  const friend = fromJS({
+    username: 'eve',
+    acct: 'eve@blackhat.lair',
+    display_name: 'Evelyn',
+    avatar: '/animated/eve.gif',
+    avatar_static: '/static/eve.jpg',
+  });
+
+  const overlay = render(<AvatarOverlay account={account} friend={friend} />);
+
+  it('renders account static src as base of overlay avatar', () => {
+    expect(overlay.find('.account__avatar-overlay-base'))
+      .to.have.style('background-image', `url(${account.get('avatar_static')})`);
+  });
+
+  it('renders friend static src as overlay of overlay avatar', () => {
+    expect(overlay.find('.account__avatar-overlay-overlay'))
+      .to.have.style('background-image', `url(${friend.get('avatar_static')})`);
+  });
+});