From 3f9708edc4cd799afb68000adc35036dd8b8faa5 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Fri, 23 Sep 2016 20:23:26 +0200 Subject: [PATCH] Change output of api/accounts/:id/follow and unfollow to return relationship Track relationship in redux state. Display follow/unfollow and following-back information on account view (unstyled) --- .../components/actions/accounts.jsx | 8 ++-- .../components/components/status_content.jsx | 27 ++++++++--- .../account/components/action_bar.jsx | 48 +++++++++++++++++++ .../features/account/components/header.jsx | 5 +- .../components/features/account/index.jsx | 18 +++---- .../components/reducers/timelines.jsx | 25 ++++++++-- app/controllers/api/accounts_controller.rb | 14 ++++-- app/views/api/accounts/relationship.rabl | 5 ++ app/views/api/accounts/relationships.rabl | 5 +- 9 files changed, 122 insertions(+), 33 deletions(-) create mode 100644 app/assets/javascripts/components/features/account/components/action_bar.jsx create mode 100644 app/views/api/accounts/relationship.rabl diff --git a/app/assets/javascripts/components/actions/accounts.jsx b/app/assets/javascripts/components/actions/accounts.jsx index ac9f5962f..b4183bbee 100644 --- a/app/assets/javascripts/components/actions/accounts.jsx +++ b/app/assets/javascripts/components/actions/accounts.jsx @@ -124,10 +124,10 @@ export function followAccountRequest(id) { }; }; -export function followAccountSuccess(account) { +export function followAccountSuccess(relationship) { return { type: ACCOUNT_FOLLOW_SUCCESS, - account: account + relationship: relationship }; }; @@ -145,10 +145,10 @@ export function unfollowAccountRequest(id) { }; }; -export function unfollowAccountSuccess(account) { +export function unfollowAccountSuccess(relationship) { return { type: ACCOUNT_UNFOLLOW_SUCCESS, - account: account + relationship: relationship }; }; diff --git a/app/assets/javascripts/components/components/status_content.jsx b/app/assets/javascripts/components/components/status_content.jsx index 98d914514..285945fa8 100644 --- a/app/assets/javascripts/components/components/status_content.jsx +++ b/app/assets/javascripts/components/components/status_content.jsx @@ -14,15 +14,24 @@ const StatusContent = React.createClass({ mixins: [PureRenderMixin], componentDidMount () { - const node = ReactDOM.findDOMNode(this); - - this.props.status.get('mentions').forEach(mention => { - const links = node.querySelector(`a[href="${mention.get('url')}"]`); - links.addEventListener('click', this.onLinkClick.bind(this, mention)); - }); + const node = ReactDOM.findDOMNode(this); + const links = node.querySelectorAll('a'); + + for (var i = 0; i < links.length; ++i) { + let link = links[i]; + let mention = this.props.status.get('mentions').find(item => link.href === item.get('url')); + + if (mention) { + link.addEventListener('click', this.onMentionClick.bind(this, mention)); + } else { + link.setAttribute('target', '_blank'); + link.setAttribute('rel', 'noopener'); + link.addEventListener('click', this.onNormalClick); + } + } }, - onLinkClick (mention, e) { + onMentionClick (mention, e) { if (e.button === 0) { e.preventDefault(); this.context.router.push(`/accounts/${mention.get('id')}`); @@ -31,6 +40,10 @@ const StatusContent = React.createClass({ e.stopPropagation(); }, + onNormalClick (e) { + e.stopPropagation(); + }, + render () { const content = { __html: this.props.status.get('content') }; return
; diff --git a/app/assets/javascripts/components/features/account/components/action_bar.jsx b/app/assets/javascripts/components/features/account/components/action_bar.jsx new file mode 100644 index 000000000..a6eb01d61 --- /dev/null +++ b/app/assets/javascripts/components/features/account/components/action_bar.jsx @@ -0,0 +1,48 @@ +import PureRenderMixin from 'react-addons-pure-render-mixin'; +import ImmutablePropTypes from 'react-immutable-proptypes'; +import Button from '../../../components/button'; + +const ActionBar = React.createClass({ + + propTypes: { + account: ImmutablePropTypes.map.isRequired, + me: React.PropTypes.number.isRequired, + onFollow: React.PropTypes.func.isRequired, + onUnfollow: React.PropTypes.func.isRequired + }, + + mixins: [PureRenderMixin], + + render () { + const { account, me } = this.props; + + let followBack = ''; + let actionButton = ''; + + if (account.get('id') === me) { + actionButton = 'This is you!'; + } else { + if (account.getIn(['relationship', 'following'])) { + actionButton =