From 00f251b8fe7ee5c1143c880f113237c2fa543664 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 26 Mar 2019 00:36:25 +0100 Subject: [PATCH] [Glitch] Redesign profile column in web UI to match design on public pages Port a96181f16f4ef74ce6a1efc5e893ddd87a127949 to glitch-soc --- .../features/account/components/action_bar.js | 106 +----- .../features/account/components/header.js | 246 ++++++++++---- .../account_timeline/components/header.js | 12 +- .../containers/header_container.js | 1 + .../glitch/styles/components/accounts.scss | 319 ++++++++++-------- .../glitch/styles/components/index.scss | 1 - .../glitch/styles/components/metadata.scss | 45 --- .../flavours/glitch/styles/containers.scss | 1 + .../flavours/glitch/styles/metadata.scss | 56 --- 9 files changed, 365 insertions(+), 422 deletions(-) delete mode 100644 app/javascript/flavours/glitch/styles/metadata.scss diff --git a/app/javascript/flavours/glitch/features/account/components/action_bar.js b/app/javascript/flavours/glitch/features/account/components/action_bar.js index fdacb72983..c76d3688b9 100644 --- a/app/javascript/flavours/glitch/features/account/components/action_bar.js +++ b/app/javascript/flavours/glitch/features/account/components/action_bar.js @@ -3,58 +3,18 @@ import ImmutablePropTypes from 'react-immutable-proptypes'; import PropTypes from 'prop-types'; import DropdownMenuContainer from 'flavours/glitch/containers/dropdown_menu_container'; import { NavLink } from 'react-router-dom'; -import { defineMessages, injectIntl, FormattedMessage, FormattedNumber } from 'react-intl'; +import { injectIntl, FormattedMessage, FormattedNumber } from 'react-intl'; import { me, isStaff } from 'flavours/glitch/util/initial_state'; import { profileLink, accountAdminLink } from 'flavours/glitch/util/backend_links'; -const messages = defineMessages({ - mention: { id: 'account.mention', defaultMessage: 'Mention @{name}' }, - direct: { id: 'account.direct', defaultMessage: 'Direct message @{name}' }, - edit_profile: { id: 'account.edit_profile', defaultMessage: 'Edit profile' }, - unblock: { id: 'account.unblock', defaultMessage: 'Unblock @{name}' }, - unfollow: { id: 'account.unfollow', defaultMessage: 'Unfollow' }, - unmute: { id: 'account.unmute', defaultMessage: 'Unmute @{name}' }, - block: { id: 'account.block', defaultMessage: 'Block @{name}' }, - mute: { id: 'account.mute', defaultMessage: 'Mute @{name}' }, - follow: { id: 'account.follow', defaultMessage: 'Follow' }, - report: { id: 'account.report', defaultMessage: 'Report @{name}' }, - share: { id: 'account.share', defaultMessage: 'Share @{name}\'s profile' }, - media: { id: 'account.media', defaultMessage: 'Media' }, - blockDomain: { id: 'account.block_domain', defaultMessage: 'Hide everything from {domain}' }, - unblockDomain: { id: 'account.unblock_domain', defaultMessage: 'Unhide {domain}' }, - hideReblogs: { id: 'account.hide_reblogs', defaultMessage: 'Hide boosts from @{name}' }, - showReblogs: { id: 'account.show_reblogs', defaultMessage: 'Show boosts from @{name}' }, - endorse: { id: 'account.endorse', defaultMessage: 'Feature on profile' }, - unendorse: { id: 'account.unendorse', defaultMessage: 'Don\'t feature on profile' }, - add_or_remove_from_list: { id: 'account.add_or_remove_from_list', defaultMessage: 'Add or Remove from lists' }, - admin_account: { id: 'status.admin_account', defaultMessage: 'Open moderation interface for @{name}' }, -}); - @injectIntl export default class ActionBar extends React.PureComponent { static propTypes = { account: ImmutablePropTypes.map.isRequired, - onFollow: PropTypes.func, - onBlock: PropTypes.func.isRequired, - onMention: PropTypes.func.isRequired, - onDirect: PropTypes.func.isRequired, - onReblogToggle: PropTypes.func.isRequired, - onReport: PropTypes.func.isRequired, - onMute: PropTypes.func.isRequired, - onBlockDomain: PropTypes.func.isRequired, - onUnblockDomain: PropTypes.func.isRequired, - onEndorseToggle: PropTypes.func.isRequired, - onAddToList: PropTypes.func.isRequired, intl: PropTypes.object.isRequired, }; - handleShare = () => { - navigator.share({ - url: this.props.account.get('url'), - }); - } - isStatusesPageActive = (match, location) => { if (!match) { return false; @@ -65,53 +25,9 @@ export default class ActionBar extends React.PureComponent { render () { const { account, intl } = this.props; - let menu = []; let extraInfo = ''; - menu.push({ text: intl.formatMessage(messages.mention, { name: account.get('username') }), action: this.props.onMention }); - menu.push({ text: intl.formatMessage(messages.direct, { name: account.get('username') }), action: this.props.onDirect }); - - if ('share' in navigator) { - menu.push({ text: intl.formatMessage(messages.share, { name: account.get('username') }), action: this.handleShare }); - } - - menu.push(null); - - if (account.get('id') === me) { - if (profileLink !== undefined) { - menu.push({ text: intl.formatMessage(messages.edit_profile), href: profileLink }); - } - } else { - if (account.getIn(['relationship', 'following'])) { - if (account.getIn(['relationship', 'showing_reblogs'])) { - menu.push({ text: intl.formatMessage(messages.hideReblogs, { name: account.get('username') }), action: this.props.onReblogToggle }); - } else { - menu.push({ text: intl.formatMessage(messages.showReblogs, { name: account.get('username') }), action: this.props.onReblogToggle }); - } - - menu.push({ text: intl.formatMessage(account.getIn(['relationship', 'endorsed']) ? messages.unendorse : messages.endorse), action: this.props.onEndorseToggle }); - menu.push({ text: intl.formatMessage(messages.add_or_remove_from_list), action: this.props.onAddToList }); - menu.push(null); - } - - if (account.getIn(['relationship', 'muting'])) { - menu.push({ text: intl.formatMessage(messages.unmute, { name: account.get('username') }), action: this.props.onMute }); - } else { - menu.push({ text: intl.formatMessage(messages.mute, { name: account.get('username') }), action: this.props.onMute }); - } - - if (account.getIn(['relationship', 'blocking'])) { - menu.push({ text: intl.formatMessage(messages.unblock, { name: account.get('username') }), action: this.props.onBlock }); - } else { - menu.push({ text: intl.formatMessage(messages.block, { name: account.get('username') }), action: this.props.onBlock }); - } - - menu.push({ text: intl.formatMessage(messages.report, { name: account.get('username') }), action: this.props.onReport }); - } - if (account.get('acct') !== account.get('username')) { - const domain = account.get('acct').split('@')[1]; - extraInfo = (
); - - menu.push(null); - - if (account.getIn(['relationship', 'domain_blocking'])) { - menu.push({ text: intl.formatMessage(messages.unblockDomain, { domain }), action: this.props.onUnblockDomain }); - } else { - menu.push({ text: intl.formatMessage(messages.blockDomain, { domain }), action: this.props.onBlockDomain }); - } - } - - if (account.get('id') !== me && isStaff && (accountAdminLink !== undefined)) { - menu.push(null); - menu.push({ - text: intl.formatMessage(messages.admin_account, { name: account.get('username') }), - href: accountAdminLink(account.get('id')), - }); } return ( @@ -147,10 +47,6 @@ export default class ActionBar extends React.PureComponent { {extraInfo}
-
- -
-
diff --git a/app/javascript/flavours/glitch/features/account/components/header.js b/app/javascript/flavours/glitch/features/account/components/header.js index 96696c2a56..1f18986616 100644 --- a/app/javascript/flavours/glitch/features/account/components/header.js +++ b/app/javascript/flavours/glitch/features/account/components/header.js @@ -3,12 +3,14 @@ import ImmutablePropTypes from 'react-immutable-proptypes'; import PropTypes from 'prop-types'; import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; import ImmutablePureComponent from 'react-immutable-pure-component'; - -import Avatar from 'flavours/glitch/components/avatar'; -import IconButton from 'flavours/glitch/components/icon_button'; - -import { autoPlayGif, me } from 'flavours/glitch/util/initial_state'; +import { autoPlayGif, me, isStaff } from 'flavours/glitch/util/initial_state'; import classNames from 'classnames'; +import Icon from 'flavours/glitch/components/icon'; +import Avatar from 'flavours/glitch/components/avatar'; +import Button from 'flavours/glitch/components/button'; +import { shortNumberFormat } from 'flavours/glitch/util/numbers'; +import { NavLink } from 'react-router-dom'; +import DropdownMenuContainer from 'flavours/glitch/containers/dropdown_menu_container'; const messages = defineMessages({ unfollow: { id: 'account.unfollow', defaultMessage: 'Unfollow' }, @@ -16,7 +18,34 @@ const messages = defineMessages({ requested: { id: 'account.requested', defaultMessage: 'Awaiting approval. Click to cancel follow request' }, unblock: { id: 'account.unblock', defaultMessage: 'Unblock @{name}' }, edit_profile: { id: 'account.edit_profile', defaultMessage: 'Edit profile' }, - link_verified_on: { id: 'account.link_verified_on', defaultMessage: 'Ownership of this link was checked on {date}' }, + linkVerifiedOn: { id: 'account.link_verified_on', defaultMessage: 'Ownership of this link was checked on {date}' }, + account_locked: { id: 'account.locked_info', defaultMessage: 'This account privacy status is set to locked. The owner manually reviews who can follow them.' }, + mention: { id: 'account.mention', defaultMessage: 'Mention @{name}' }, + direct: { id: 'account.direct', defaultMessage: 'Direct message @{name}' }, + edit_profile: { id: 'account.edit_profile', defaultMessage: 'Edit profile' }, + unblock: { id: 'account.unblock', defaultMessage: 'Unblock @{name}' }, + unmute: { id: 'account.unmute', defaultMessage: 'Unmute @{name}' }, + block: { id: 'account.block', defaultMessage: 'Block @{name}' }, + mute: { id: 'account.mute', defaultMessage: 'Mute @{name}' }, + report: { id: 'account.report', defaultMessage: 'Report @{name}' }, + share: { id: 'account.share', defaultMessage: 'Share @{name}\'s profile' }, + media: { id: 'account.media', defaultMessage: 'Media' }, + blockDomain: { id: 'account.block_domain', defaultMessage: 'Hide everything from {domain}' }, + unblockDomain: { id: 'account.unblock_domain', defaultMessage: 'Unhide {domain}' }, + hideReblogs: { id: 'account.hide_reblogs', defaultMessage: 'Hide boosts from @{name}' }, + showReblogs: { id: 'account.show_reblogs', defaultMessage: 'Show boosts from @{name}' }, + pins: { id: 'navigation_bar.pins', defaultMessage: 'Pinned toots' }, + preferences: { id: 'navigation_bar.preferences', defaultMessage: 'Preferences' }, + follow_requests: { id: 'navigation_bar.follow_requests', defaultMessage: 'Follow requests' }, + favourites: { id: 'navigation_bar.favourites', defaultMessage: 'Favourites' }, + lists: { id: 'navigation_bar.lists', defaultMessage: 'Lists' }, + blocks: { id: 'navigation_bar.blocks', defaultMessage: 'Blocked users' }, + domain_blocks: { id: 'navigation_bar.domain_blocks', defaultMessage: 'Hidden domains' }, + mutes: { id: 'navigation_bar.mutes', defaultMessage: 'Muted users' }, + endorse: { id: 'account.endorse', defaultMessage: 'Feature on profile' }, + unendorse: { id: 'account.unendorse', defaultMessage: 'Don\'t feature on profile' }, + add_or_remove_from_list: { id: 'account.add_or_remove_from_list', defaultMessage: 'Add or Remove from lists' }, + admin_account: { id: 'status.admin_account', defaultMessage: 'Open moderation interface for @{name}' }, }); const dateFormatOptions = { @@ -28,14 +57,15 @@ const dateFormatOptions = { minute: '2-digit', }; -@injectIntl -export default class Header extends ImmutablePureComponent { +export default @injectIntl +class Header extends ImmutablePureComponent { static propTypes = { account: ImmutablePropTypes.map, onFollow: PropTypes.func.isRequired, onBlock: PropTypes.func.isRequired, intl: PropTypes.object.isRequired, + domain: PropTypes.string.isRequired, }; openEditProfile = () => { @@ -43,109 +73,179 @@ export default class Header extends ImmutablePureComponent { } render () { - const { account, intl } = this.props; + const { account, intl, domain } = this.props; if (!account) { return null; } - let displayName = account.get('display_name_html'); - let fields = account.get('fields'); - let badge = account.get('bot') ? (
) : null; - - let info = ''; - let mutingInfo = ''; + let info = []; let actionBtn = ''; + let lockedIcon = ''; + let menu = []; if (me !== account.get('id') && account.getIn(['relationship', 'followed_by'])) { - info = ; + info.push(); } else if (me !== account.get('id') && account.getIn(['relationship', 'blocking'])) { - info = ; + info.push(); } if (me !== account.get('id') && account.getIn(['relationship', 'muting'])) { - mutingInfo = ; + info.push(); } else if (me !== account.get('id') && account.getIn(['relationship', 'domain_blocking'])) { - mutingInfo = ; + info.push(); } if (me !== account.get('id')) { if (!account.get('relationship')) { // Wait until the relationship is loaded actionBtn = ''; } else if (account.getIn(['relationship', 'requested'])) { - actionBtn = ( -
- -
- ); + actionBtn =