Change appearance of account cards in web UI (#17689)
* Change appearance of account cards in web UI * Various fixes and improvements * Various fixes and improvements
This commit is contained in:
		| @@ -7,31 +7,28 @@ import { makeGetAccount } from 'mastodon/selectors'; | ||||
| import Avatar from 'mastodon/components/avatar'; | ||||
| import DisplayName from 'mastodon/components/display_name'; | ||||
| import Permalink from 'mastodon/components/permalink'; | ||||
| import RelativeTimestamp from 'mastodon/components/relative_timestamp'; | ||||
| import IconButton from 'mastodon/components/icon_button'; | ||||
| import Button from 'mastodon/components/button'; | ||||
| import { FormattedMessage, injectIntl, defineMessages } from 'react-intl'; | ||||
| import { autoPlayGif, me, unfollowModal } from 'mastodon/initial_state'; | ||||
| import ShortNumber from 'mastodon/components/short_number'; | ||||
| import { | ||||
|   followAccount, | ||||
|   unfollowAccount, | ||||
|   blockAccount, | ||||
|   unblockAccount, | ||||
|   unmuteAccount, | ||||
| } from 'mastodon/actions/accounts'; | ||||
| import { openModal } from 'mastodon/actions/modal'; | ||||
| import { initMuteModal } from 'mastodon/actions/mutes'; | ||||
| import classNames from 'classnames'; | ||||
|  | ||||
| const messages = defineMessages({ | ||||
|   follow: { id: 'account.follow', defaultMessage: 'Follow' }, | ||||
|   unfollow: { id: 'account.unfollow', defaultMessage: 'Unfollow' }, | ||||
|   requested: { id: 'account.requested', defaultMessage: 'Awaiting approval' }, | ||||
|   unblock: { id: 'account.unblock', defaultMessage: 'Unblock @{name}' }, | ||||
|   unmute: { id: 'account.unmute', defaultMessage: 'Unmute @{name}' }, | ||||
|   unfollowConfirm: { | ||||
|     id: 'confirmations.unfollow.confirm', | ||||
|     defaultMessage: 'Unfollow', | ||||
|   }, | ||||
|   follow: { id: 'account.follow', defaultMessage: 'Follow' }, | ||||
|   cancel_follow_request: { id: 'account.cancel_follow_request', defaultMessage: 'Cancel follow request' }, | ||||
|   requested: { id: 'account.requested', defaultMessage: 'Awaiting approval. Click to cancel follow request' }, | ||||
|   unblock: { id: 'account.unblock_short', defaultMessage: 'Unblock' }, | ||||
|   unmute: { id: 'account.unmute_short', defaultMessage: 'Unmute' }, | ||||
|   unfollowConfirm: { id: 'confirmations.unfollow.confirm', defaultMessage: 'Unfollow' }, | ||||
|   edit_profile: { id: 'account.edit_profile', defaultMessage: 'Edit profile' }, | ||||
| }); | ||||
|  | ||||
| const makeMapStateToProps = () => { | ||||
| @@ -75,18 +72,15 @@ const mapDispatchToProps = (dispatch, { intl }) => ({ | ||||
|   onBlock(account) { | ||||
|     if (account.getIn(['relationship', 'blocking'])) { | ||||
|       dispatch(unblockAccount(account.get('id'))); | ||||
|     } else { | ||||
|       dispatch(blockAccount(account.get('id'))); | ||||
|     } | ||||
|   }, | ||||
|  | ||||
|   onMute(account) { | ||||
|     if (account.getIn(['relationship', 'muting'])) { | ||||
|       dispatch(unmuteAccount(account.get('id'))); | ||||
|     } else { | ||||
|       dispatch(initMuteModal(account)); | ||||
|     } | ||||
|   }, | ||||
|  | ||||
| }); | ||||
|  | ||||
| export default | ||||
| @@ -138,130 +132,92 @@ class AccountCard extends ImmutablePureComponent { | ||||
|  | ||||
|   handleMute = () => { | ||||
|     this.props.onMute(this.props.account); | ||||
|   }; | ||||
|   } | ||||
|  | ||||
|   handleEditProfile = () => { | ||||
|     window.open('/settings/profile', '_blank'); | ||||
|   } | ||||
|  | ||||
|   render() { | ||||
|     const { account, intl } = this.props; | ||||
|  | ||||
|     let buttons; | ||||
|     let actionBtn; | ||||
|  | ||||
|     if ( | ||||
|       account.get('id') !== me && | ||||
|       account.get('relationship', null) !== null | ||||
|     ) { | ||||
|       const following = account.getIn(['relationship', 'following']); | ||||
|       const requested = account.getIn(['relationship', 'requested']); | ||||
|       const blocking = account.getIn(['relationship', 'blocking']); | ||||
|       const muting = account.getIn(['relationship', 'muting']); | ||||
|  | ||||
|       if (requested) { | ||||
|         buttons = ( | ||||
|           <IconButton | ||||
|             disabled | ||||
|             icon='hourglass' | ||||
|             title={intl.formatMessage(messages.requested)} | ||||
|           /> | ||||
|         ); | ||||
|       } else if (blocking) { | ||||
|         buttons = ( | ||||
|           <IconButton | ||||
|             active | ||||
|             icon='unlock' | ||||
|             title={intl.formatMessage(messages.unblock, { | ||||
|               name: account.get('username'), | ||||
|             })} | ||||
|             onClick={this.handleBlock} | ||||
|           /> | ||||
|         ); | ||||
|       } else if (muting) { | ||||
|         buttons = ( | ||||
|           <IconButton | ||||
|             active | ||||
|             icon='volume-up' | ||||
|             title={intl.formatMessage(messages.unmute, { | ||||
|               name: account.get('username'), | ||||
|             })} | ||||
|             onClick={this.handleMute} | ||||
|           /> | ||||
|         ); | ||||
|       } else if (!account.get('moved') || following) { | ||||
|         buttons = ( | ||||
|           <IconButton | ||||
|             icon={following ? 'user-times' : 'user-plus'} | ||||
|             title={intl.formatMessage( | ||||
|               following ? messages.unfollow : messages.follow, | ||||
|             )} | ||||
|             onClick={this.handleFollow} | ||||
|             active={following} | ||||
|           /> | ||||
|         ); | ||||
|     if (me !== account.get('id')) { | ||||
|       if (!account.get('relationship')) { // Wait until the relationship is loaded | ||||
|         actionBtn = ''; | ||||
|       } else if (account.getIn(['relationship', 'requested'])) { | ||||
|         actionBtn = <Button className={classNames('logo-button')} text={intl.formatMessage(messages.cancel_follow_request)} title={intl.formatMessage(messages.requested)} onClick={this.handleFollow} />; | ||||
|       } else if (account.getIn(['relationship', 'muting'])) { | ||||
|         actionBtn = <Button className='logo-button' text={intl.formatMessage(messages.unmute)} onClick={this.handleMute} />; | ||||
|       } else if (!account.getIn(['relationship', 'blocking'])) { | ||||
|         actionBtn = <Button disabled={account.getIn(['relationship', 'blocked_by'])} className={classNames('logo-button', { 'button--destructive': account.getIn(['relationship', 'following']) })} text={intl.formatMessage(account.getIn(['relationship', 'following']) ? messages.unfollow : messages.follow)} onClick={this.handleFollow} />; | ||||
|       } else if (account.getIn(['relationship', 'blocking'])) { | ||||
|         actionBtn = <Button className='logo-button' text={intl.formatMessage(messages.unblock)} onClick={this.handleBlock} />; | ||||
|       } | ||||
|     } else { | ||||
|       actionBtn = <Button className='logo-button' text={intl.formatMessage(messages.edit_profile)} onClick={this.handleEditProfile} />; | ||||
|     } | ||||
|  | ||||
|     return ( | ||||
|       <div className='directory__card'> | ||||
|         <div className='directory__card__img'> | ||||
|           <img | ||||
|             src={ | ||||
|               autoPlayGif ? account.get('header') : account.get('header_static') | ||||
|             } | ||||
|             alt='' | ||||
|           /> | ||||
|         </div> | ||||
|  | ||||
|         <div className='directory__card__bar'> | ||||
|           <Permalink | ||||
|             className='directory__card__bar__name' | ||||
|             href={account.get('url')} | ||||
|             to={`/@${account.get('acct')}`} | ||||
|           > | ||||
|             <Avatar account={account} size={48} /> | ||||
|             <DisplayName account={account} /> | ||||
|           </Permalink> | ||||
|  | ||||
|           <div className='directory__card__bar__relationship account__relationship'> | ||||
|             {buttons} | ||||
|       <div className='account-card'> | ||||
|         <Permalink href={account.get('url')} to={`/@${account.get('acct')}`} className='account-card__permalink'> | ||||
|           <div className='account-card__header'> | ||||
|             <img | ||||
|               src={ | ||||
|                 autoPlayGif ? account.get('header') : account.get('header_static') | ||||
|               } | ||||
|               alt='' | ||||
|             /> | ||||
|           </div> | ||||
|         </div> | ||||
|  | ||||
|         <div className='directory__card__extra' onMouseEnter={this.handleMouseEnter} onMouseLeave={this.handleMouseLeave}> | ||||
|           <div className='account-card__title'> | ||||
|             <div className='account-card__title__avatar'><Avatar account={account} size={56} /></div> | ||||
|             <DisplayName account={account} /> | ||||
|           </div> | ||||
|         </Permalink> | ||||
|  | ||||
|         {account.get('note').length > 0 && ( | ||||
|           <div | ||||
|             className='account__header__content translate' | ||||
|             className='account-card__bio translate' | ||||
|             onMouseEnter={this.handleMouseEnter} | ||||
|             onMouseLeave={this.handleMouseLeave} | ||||
|             dangerouslySetInnerHTML={{ __html: account.get('note_emojified') }} | ||||
|           /> | ||||
|         </div> | ||||
|         )} | ||||
|  | ||||
|         <div className='directory__card__extra'> | ||||
|           <div className='accounts-table__count'> | ||||
|             <ShortNumber value={account.get('statuses_count')} /> | ||||
|             <small> | ||||
|               <FormattedMessage id='account.posts' defaultMessage='Toots' /> | ||||
|             </small> | ||||
|         <div className='account-card__actions'> | ||||
|           <div className='account-card__counters'> | ||||
|             <div className='account-card__counters__item'> | ||||
|               <ShortNumber value={account.get('statuses_count')} /> | ||||
|               <small> | ||||
|                 <FormattedMessage id='account.posts' defaultMessage='Toots' /> | ||||
|               </small> | ||||
|             </div> | ||||
|  | ||||
|             <div className='account-card__counters__item'> | ||||
|               <ShortNumber value={account.get('followers_count')} />{' '} | ||||
|               <small> | ||||
|                 <FormattedMessage | ||||
|                   id='account.followers' | ||||
|                   defaultMessage='Followers' | ||||
|                 /> | ||||
|               </small> | ||||
|             </div> | ||||
|  | ||||
|             <div className='account-card__counters__item'> | ||||
|               <ShortNumber value={account.get('following_count')} />{' '} | ||||
|               <small> | ||||
|                 <FormattedMessage | ||||
|                   id='account.following' | ||||
|                   defaultMessage='Following' | ||||
|                 /> | ||||
|               </small> | ||||
|             </div> | ||||
|           </div> | ||||
|           <div className='accounts-table__count'> | ||||
|             <ShortNumber value={account.get('followers_count')} />{' '} | ||||
|             <small> | ||||
|               <FormattedMessage | ||||
|                 id='account.followers' | ||||
|                 defaultMessage='Followers' | ||||
|               /> | ||||
|             </small> | ||||
|           </div> | ||||
|           <div className='accounts-table__count'> | ||||
|             {account.get('last_status_at') === null ? ( | ||||
|               <FormattedMessage | ||||
|                 id='account.never_active' | ||||
|                 defaultMessage='Never' | ||||
|               /> | ||||
|             ) : ( | ||||
|               <RelativeTimestamp timestamp={account.get('last_status_at')} /> | ||||
|             )}{' '} | ||||
|             <small> | ||||
|               <FormattedMessage | ||||
|                 id='account.last_status' | ||||
|                 defaultMessage='Last active' | ||||
|               /> | ||||
|             </small> | ||||
|  | ||||
|           <div className='account-card__actions__button'> | ||||
|             {actionBtn} | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|   | ||||
| @@ -10,9 +10,9 @@ import { fetchDirectory, expandDirectory } from 'mastodon/actions/directory'; | ||||
| import { List as ImmutableList } from 'immutable'; | ||||
| import AccountCard from './components/account_card'; | ||||
| import RadioButton from 'mastodon/components/radio_button'; | ||||
| import classNames from 'classnames'; | ||||
| import LoadMore from 'mastodon/components/load_more'; | ||||
| import ScrollContainer from 'mastodon/containers/scroll_container'; | ||||
| import LoadingIndicator from 'mastodon/components/loading_indicator'; | ||||
|  | ||||
| const messages = defineMessages({ | ||||
|   title: { id: 'column.directory', defaultMessage: 'Browse profiles' }, | ||||
| @@ -129,7 +129,7 @@ class Directory extends React.PureComponent { | ||||
|     const pinned = !!columnId; | ||||
|  | ||||
|     const scrollableArea = ( | ||||
|       <div className='scrollable' style={{ background: 'transparent' }}> | ||||
|       <div className='scrollable'> | ||||
|         <div className='filter-form'> | ||||
|           <div className='filter-form__column' role='group'> | ||||
|             <RadioButton name='order' value='active' label={intl.formatMessage(messages.recentlyActive)} checked={order === 'active'} onChange={this.handleChangeOrder} /> | ||||
| @@ -142,8 +142,10 @@ class Directory extends React.PureComponent { | ||||
|           </div> | ||||
|         </div> | ||||
|  | ||||
|         <div className={classNames('directory__list', { loading: isLoading })}> | ||||
|           {accountIds.map(accountId => <AccountCard id={accountId} key={accountId} />)} | ||||
|         <div className='directory__list'> | ||||
|           {isLoading ? <LoadingIndicator /> : accountIds.map(accountId => ( | ||||
|             <AccountCard id={accountId} key={accountId} /> | ||||
|           ))} | ||||
|         </div> | ||||
|  | ||||
|         <LoadMore onClick={this.handleLoadMore} visible={!isLoading} /> | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| import React from 'react'; | ||||
| import PropTypes from 'prop-types'; | ||||
| import ImmutablePropTypes from 'react-immutable-proptypes'; | ||||
| import Account from 'mastodon/containers/account_container'; | ||||
| import AccountCard from 'mastodon/features/directory/components/account_card'; | ||||
| import LoadingIndicator from 'mastodon/components/loading_indicator'; | ||||
| import { connect } from 'react-redux'; | ||||
| import { fetchSuggestions } from 'mastodon/actions/suggestions'; | ||||
| @@ -29,9 +29,9 @@ class Suggestions extends React.PureComponent { | ||||
|     const { isLoading, suggestions } = this.props; | ||||
|  | ||||
|     return ( | ||||
|       <div className='explore__links'> | ||||
|         {isLoading ? (<LoadingIndicator />) : suggestions.map(suggestion => ( | ||||
|           <Account key={suggestion.get('account')} id={suggestion.get('account')} /> | ||||
|       <div className='explore__suggestions'> | ||||
|         {isLoading ? <LoadingIndicator /> : suggestions.map(suggestion => ( | ||||
|           <AccountCard key={suggestion.get('account')} id={suggestion.get('account')} /> | ||||
|         ))} | ||||
|       </div> | ||||
|     ); | ||||
|   | ||||
| @@ -40,19 +40,11 @@ html { | ||||
|   background: lighten($ui-base-color, 12%); | ||||
| } | ||||
|  | ||||
| .filter-form, | ||||
| .directory__card__bar { | ||||
| .filter-form { | ||||
|   background: $white; | ||||
|   border-bottom: 1px solid lighten($ui-base-color, 8%); | ||||
| } | ||||
|  | ||||
| .scrollable .directory__list { | ||||
|   width: calc(100% + 2px); | ||||
|   margin-left: -1px; | ||||
|   margin-right: -1px; | ||||
| } | ||||
|  | ||||
| .directory__card, | ||||
| .table-of-contents { | ||||
|   border: 1px solid lighten($ui-base-color, 8%); | ||||
| } | ||||
| @@ -75,8 +67,7 @@ html { | ||||
| .column-header__back-button, | ||||
| .column-header__button, | ||||
| .column-header__button.active, | ||||
| .account__header__bar, | ||||
| .directory__card__extra { | ||||
| .account__header__bar { | ||||
|   background: $white; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -1220,6 +1220,11 @@ a.sparkline { | ||||
|   background: $ui-base-color; | ||||
|   border-radius: 4px; | ||||
|  | ||||
|   &__permalink { | ||||
|     color: inherit; | ||||
|     text-decoration: none; | ||||
|   } | ||||
|  | ||||
|   &__header { | ||||
|     padding: 4px; | ||||
|     border-radius: 4px; | ||||
| @@ -1236,20 +1241,22 @@ a.sparkline { | ||||
|   } | ||||
|  | ||||
|   &__title { | ||||
|     margin-top: -25px; | ||||
|     margin-top: -(15px + 8px); | ||||
|     display: flex; | ||||
|     align-items: flex-end; | ||||
|  | ||||
|     &__avatar { | ||||
|       padding: 15px; | ||||
|       padding: 14px; | ||||
|  | ||||
|       img { | ||||
|       img, | ||||
|       .account__avatar { | ||||
|         display: block; | ||||
|         margin: 0; | ||||
|         width: 56px; | ||||
|         height: 56px; | ||||
|         background: darken($ui-base-color, 8%); | ||||
|         background-color: darken($ui-base-color, 8%); | ||||
|         border-radius: 8px; | ||||
|         border: 1px solid $ui-base-color; | ||||
|       } | ||||
|     } | ||||
|  | ||||
| @@ -1257,30 +1264,34 @@ a.sparkline { | ||||
|       color: $darker-text-color; | ||||
|       padding-bottom: 15px; | ||||
|       font-size: 15px; | ||||
|       line-height: 20px; | ||||
|  | ||||
|       bdi { | ||||
|         display: block; | ||||
|         color: $primary-text-color; | ||||
|         font-weight: 500; | ||||
|         font-weight: 700; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   &__bio { | ||||
|     padding: 0 15px; | ||||
|     margin: 8px 0; | ||||
|     overflow: hidden; | ||||
|     text-overflow: ellipsis; | ||||
|     word-wrap: break-word; | ||||
|     max-height: 18px * 2; | ||||
|     max-height: 21px * 2; | ||||
|     position: relative; | ||||
|     font-size: 15px; | ||||
|     line-height: 21px; | ||||
|  | ||||
|     &::after { | ||||
|       display: block; | ||||
|       content: ""; | ||||
|       width: 50px; | ||||
|       height: 18px; | ||||
|       height: 21px; | ||||
|       position: absolute; | ||||
|       bottom: 0; | ||||
|       bottom: 8px; | ||||
|       right: 15px; | ||||
|       background: linear-gradient(to left, $ui-base-color, transparent); | ||||
|       pointer-events: none; | ||||
| @@ -1293,10 +1304,6 @@ a.sparkline { | ||||
|  | ||||
|       &:hover { | ||||
|         text-decoration: underline; | ||||
|  | ||||
|         .fa { | ||||
|           color: lighten($dark-text-color, 7%); | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       &.mention { | ||||
| @@ -1313,12 +1320,21 @@ a.sparkline { | ||||
|  | ||||
|   &__actions { | ||||
|     display: flex; | ||||
|     justify-content: space-between; | ||||
|     align-items: center; | ||||
|     padding-top: 10px; | ||||
|  | ||||
|     &__button { | ||||
|       flex: 0 0 auto; | ||||
|       flex-shrink: 1; | ||||
|       padding: 0 15px; | ||||
|       overflow: hidden; | ||||
|  | ||||
|       .button { | ||||
|         min-width: 0; | ||||
|         white-space: nowrap; | ||||
|         text-overflow: ellipsis; | ||||
|         overflow: hidden; | ||||
|         max-width: 100%; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
| @@ -1327,19 +1343,23 @@ a.sparkline { | ||||
|     display: grid; | ||||
|     grid-auto-columns: minmax(0, 1fr); | ||||
|     grid-auto-flow: column; | ||||
|     max-width: 340px; | ||||
|     min-width: 65px * 3; | ||||
|  | ||||
|     &__item { | ||||
|       padding: 15px; | ||||
|       padding: 15px 0; | ||||
|       text-align: center; | ||||
|       color: $primary-text-color; | ||||
|       font-weight: 600; | ||||
|       font-size: 15px; | ||||
|       line-height: 21px; | ||||
|  | ||||
|       small { | ||||
|         display: block; | ||||
|         color: $darker-text-color; | ||||
|         font-weight: 400; | ||||
|         font-size: 13px; | ||||
|         line-height: 18px; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|   | ||||
| @@ -50,7 +50,7 @@ | ||||
|   cursor: pointer; | ||||
|   display: inline-block; | ||||
|   font-family: inherit; | ||||
|   font-size: 17px; | ||||
|   font-size: 15px; | ||||
|   font-weight: 500; | ||||
|   letter-spacing: 0; | ||||
|   line-height: 22px; | ||||
| @@ -2333,17 +2333,7 @@ a.account__display-name { | ||||
|     padding: 0; | ||||
|   } | ||||
|  | ||||
|   .directory__list { | ||||
|     display: grid; | ||||
|     grid-gap: 10px; | ||||
|     grid-template-columns: minmax(0, 50%) minmax(0, 50%); | ||||
|  | ||||
|     @media screen and (max-width: $no-gap-breakpoint) { | ||||
|       display: block; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   .directory__card { | ||||
|   .account-card { | ||||
|     margin-bottom: 0; | ||||
|   } | ||||
|  | ||||
| @@ -6219,136 +6209,20 @@ a.status-card.compact:hover { | ||||
|   } | ||||
| } | ||||
|  | ||||
| .directory { | ||||
|   &__list { | ||||
|     width: 100%; | ||||
|     margin: 10px 0; | ||||
|     transition: opacity 100ms ease-in; | ||||
| .scrollable .account-card { | ||||
|   margin: 10px; | ||||
|   background: lighten($ui-base-color, 8%); | ||||
| } | ||||
|  | ||||
|     &.loading { | ||||
|       opacity: 0.7; | ||||
|     } | ||||
|  | ||||
|     @media screen and (max-width: $no-gap-breakpoint) { | ||||
|       margin: 0; | ||||
|     } | ||||
| .scrollable .account-card__title__avatar { | ||||
|   img, | ||||
|   .account__avatar { | ||||
|     border-color: lighten($ui-base-color, 8%); | ||||
|   } | ||||
| } | ||||
|  | ||||
|   &__card { | ||||
|     box-sizing: border-box; | ||||
|     margin-bottom: 10px; | ||||
|  | ||||
|     &__img { | ||||
|       height: 125px; | ||||
|       position: relative; | ||||
|       background: darken($ui-base-color, 12%); | ||||
|       overflow: hidden; | ||||
|  | ||||
|       img { | ||||
|         display: block; | ||||
|         width: 100%; | ||||
|         height: 100%; | ||||
|         margin: 0; | ||||
|         object-fit: cover; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     &__bar { | ||||
|       display: flex; | ||||
|       align-items: center; | ||||
|       background: lighten($ui-base-color, 4%); | ||||
|       padding: 10px; | ||||
|  | ||||
|       &__name { | ||||
|         flex: 1 1 auto; | ||||
|         display: flex; | ||||
|         align-items: center; | ||||
|         text-decoration: none; | ||||
|         overflow: hidden; | ||||
|       } | ||||
|  | ||||
|       &__relationship { | ||||
|         width: 23px; | ||||
|         min-height: 1px; | ||||
|         flex: 0 0 auto; | ||||
|       } | ||||
|  | ||||
|       .avatar { | ||||
|         flex: 0 0 auto; | ||||
|         width: 48px; | ||||
|         height: 48px; | ||||
|         padding-top: 2px; | ||||
|  | ||||
|         img { | ||||
|           width: 100%; | ||||
|           height: 100%; | ||||
|           display: block; | ||||
|           margin: 0; | ||||
|           border-radius: 4px; | ||||
|           background: darken($ui-base-color, 8%); | ||||
|           object-fit: cover; | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       .display-name { | ||||
|         margin-left: 15px; | ||||
|         text-align: left; | ||||
|  | ||||
|         strong { | ||||
|           font-size: 15px; | ||||
|           color: $primary-text-color; | ||||
|           font-weight: 500; | ||||
|           overflow: hidden; | ||||
|           text-overflow: ellipsis; | ||||
|         } | ||||
|  | ||||
|         span { | ||||
|           display: block; | ||||
|           font-size: 14px; | ||||
|           color: $darker-text-color; | ||||
|           font-weight: 400; | ||||
|           overflow: hidden; | ||||
|           text-overflow: ellipsis; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     &__extra { | ||||
|       background: $ui-base-color; | ||||
|       display: flex; | ||||
|       align-items: center; | ||||
|       justify-content: center; | ||||
|  | ||||
|       .accounts-table__count { | ||||
|         width: 33.33%; | ||||
|         flex: 0 0 auto; | ||||
|         padding: 15px 0; | ||||
|       } | ||||
|  | ||||
|       .account__header__content { | ||||
|         box-sizing: border-box; | ||||
|         padding: 15px 10px; | ||||
|         border-bottom: 1px solid lighten($ui-base-color, 8%); | ||||
|         width: 100%; | ||||
|         min-height: 18px + 30px; | ||||
|         white-space: nowrap; | ||||
|         overflow: hidden; | ||||
|         text-overflow: ellipsis; | ||||
|  | ||||
|         p { | ||||
|           display: none; | ||||
|  | ||||
|           &:first-child { | ||||
|             display: inline; | ||||
|           } | ||||
|         } | ||||
|  | ||||
|         br { | ||||
|           display: none; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| .scrollable .account-card__bio::after { | ||||
|   background: linear-gradient(to left, lighten($ui-base-color, 8%), transparent); | ||||
| } | ||||
|  | ||||
| .account-gallery__container { | ||||
| @@ -6452,6 +6326,7 @@ a.status-card.compact:hover { | ||||
|  | ||||
|   &__column { | ||||
|     padding: 10px 15px; | ||||
|     padding-bottom: 0; | ||||
|   } | ||||
|  | ||||
|   .radio-button { | ||||
|   | ||||
| @@ -409,14 +409,6 @@ | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   .directory__card { | ||||
|     border-radius: 4px; | ||||
|  | ||||
|     @media screen and (max-width: $no-gap-breakpoint) { | ||||
|       border-radius: 0; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   .page-header { | ||||
|     @media screen and (max-width: $no-gap-breakpoint) { | ||||
|       border-bottom: 0; | ||||
| @@ -835,19 +827,21 @@ | ||||
|     grid-gap: 10px; | ||||
|     grid-template-columns: minmax(0, 50%) minmax(0, 50%); | ||||
|  | ||||
|     .account-card { | ||||
|       display: flex; | ||||
|       flex-direction: column; | ||||
|     } | ||||
|  | ||||
|     @media screen and (max-width: $no-gap-breakpoint) { | ||||
|       display: block; | ||||
|     } | ||||
|  | ||||
|     .icon-button { | ||||
|       font-size: 18px; | ||||
|       .account-card { | ||||
|         margin-bottom: 10px; | ||||
|         display: block; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   .directory__card { | ||||
|     margin-bottom: 0; | ||||
|   } | ||||
|  | ||||
|   .card-grid { | ||||
|     display: flex; | ||||
|     flex-wrap: wrap; | ||||
|   | ||||
| @@ -12,11 +12,6 @@ body.rtl { | ||||
|     margin-left: 10px; | ||||
|   } | ||||
|  | ||||
|   .directory__card__bar .display-name { | ||||
|     margin-left: 0; | ||||
|     margin-right: 15px; | ||||
|   } | ||||
|  | ||||
|   .display-name, | ||||
|   .announcements__item { | ||||
|     text-align: right; | ||||
|   | ||||
| @@ -19,37 +19,36 @@ | ||||
| - else | ||||
|   .directory__list | ||||
|     - @accounts.each do |account| | ||||
|       .directory__card | ||||
|         .directory__card__img | ||||
|           = image_tag account.header.url, alt: '' | ||||
|         .directory__card__bar | ||||
|           = link_to TagManager.instance.url_for(account), class: 'directory__card__bar__name' do | ||||
|             .avatar | ||||
|               = image_tag account.avatar.url, alt: '', class: 'u-photo' | ||||
|  | ||||
|       .account-card | ||||
|         = link_to TagManager.instance.url_for(account), class: 'account-card__permalink' do | ||||
|           .account-card__header | ||||
|             = image_tag account.header.url, alt: '' | ||||
|           .account-card__title | ||||
|             .account-card__title__avatar | ||||
|               = image_tag account.avatar.url, alt: '' | ||||
|             .display-name | ||||
|               %bdi | ||||
|                 %strong.emojify.p-name= display_name(account, custom_emojify: true) | ||||
|               %span= acct(account) | ||||
|           .directory__card__bar__relationship.account__relationship | ||||
|             = minimal_account_action_button(account) | ||||
|  | ||||
|         .directory__card__extra | ||||
|           .account__header__content.emojify= Formatter.instance.simplified_format(account, custom_emojify: true) | ||||
|  | ||||
|         .directory__card__extra | ||||
|           .accounts-table__count | ||||
|             = friendly_number_to_human account.statuses_count | ||||
|             %small= t('accounts.posts', count: account.statuses_count).downcase | ||||
|           .accounts-table__count | ||||
|             = friendly_number_to_human account.followers_count | ||||
|             %small= t('accounts.followers', count: account.followers_count).downcase | ||||
|           .accounts-table__count | ||||
|             - if account.last_status_at.present? | ||||
|               %time.time-ago{ datetime: account.last_status_at.to_date.iso8601, title: l(account.last_status_at.to_date) }= l account.last_status_at.to_date | ||||
|             - else | ||||
|               = t('accounts.never_active') | ||||
|  | ||||
|             %small= t('accounts.last_active') | ||||
|               %span | ||||
|                 = acct(account) | ||||
|                 = fa_icon('lock') if account.locked? | ||||
|         - if account.note.present? | ||||
|           .account-card__bio.emojify | ||||
|             = Formatter.instance.simplified_format(account, custom_emojify: true) | ||||
|         - else | ||||
|           .flex-spacer | ||||
|         .account-card__actions | ||||
|           .account-card__counters | ||||
|             .account-card__counters__item | ||||
|               = friendly_number_to_human account.statuses_count | ||||
|               %small= t('accounts.posts', count: account.statuses_count).downcase | ||||
|             .account-card__counters__item | ||||
|               = friendly_number_to_human account.followers_count | ||||
|               %small= t('accounts.followers', count: account.followers_count).downcase | ||||
|             .account-card__counters__item | ||||
|               = friendly_number_to_human account.following_count | ||||
|               %small= t('accounts.following', count: account.following_count).downcase | ||||
|           .account-card__actions__button | ||||
|             = account_action_button(account) | ||||
|  | ||||
|   = paginate @accounts | ||||
|   | ||||
| @@ -72,7 +72,6 @@ en: | ||||
|     media: Media | ||||
|     moved_html: "%{name} has moved to %{new_profile_link}:" | ||||
|     network_hidden: This information is not available | ||||
|     never_active: Never | ||||
|     nothing_here: There is nothing here! | ||||
|     people_followed_by: People whom %{name} follows | ||||
|     people_who_follow: People who follow %{name} | ||||
|   | ||||
		Reference in New Issue
	
	Block a user