about summary refs log tree commit diff
path: root/app/assets/javascripts
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts')
-rw-r--r--app/assets/javascripts/components/actions/accounts.jsx74
-rw-r--r--app/assets/javascripts/components/components/status_action_bar.jsx2
-rw-r--r--app/assets/javascripts/components/features/account/components/action_bar.jsx38
-rw-r--r--app/assets/javascripts/components/features/account/index.jsx12
-rw-r--r--app/assets/javascripts/components/reducers/timelines.jsx4
5 files changed, 121 insertions, 9 deletions
diff --git a/app/assets/javascripts/components/actions/accounts.jsx b/app/assets/javascripts/components/actions/accounts.jsx
index c4aa2d80c..eeec405d1 100644
--- a/app/assets/javascripts/components/actions/accounts.jsx
+++ b/app/assets/javascripts/components/actions/accounts.jsx
@@ -15,6 +15,14 @@ export const ACCOUNT_UNFOLLOW_REQUEST = 'ACCOUNT_UNFOLLOW_REQUEST';
 export const ACCOUNT_UNFOLLOW_SUCCESS = 'ACCOUNT_UNFOLLOW_SUCCESS';
 export const ACCOUNT_UNFOLLOW_FAIL    = 'ACCOUNT_UNFOLLOW_FAIL';
 
+export const ACCOUNT_BLOCK_REQUEST = 'ACCOUNT_BLOCK_REQUEST';
+export const ACCOUNT_BLOCK_SUCCESS = 'ACCOUNT_BLOCK_SUCCESS';
+export const ACCOUNT_BLOCK_FAIL    = 'ACCOUNT_BLOCK_FAIL';
+
+export const ACCOUNT_UNBLOCK_REQUEST = 'ACCOUNT_UNBLOCK_REQUEST';
+export const ACCOUNT_UNBLOCK_SUCCESS = 'ACCOUNT_UNBLOCK_SUCCESS';
+export const ACCOUNT_UNBLOCK_FAIL    = 'ACCOUNT_UNBLOCK_FAIL';
+
 export const ACCOUNT_TIMELINE_FETCH_REQUEST = 'ACCOUNT_TIMELINE_FETCH_REQUEST';
 export const ACCOUNT_TIMELINE_FETCH_SUCCESS = 'ACCOUNT_TIMELINE_FETCH_SUCCESS';
 export const ACCOUNT_TIMELINE_FETCH_FAIL    = 'ACCOUNT_TIMELINE_FETCH_FAIL';
@@ -204,3 +212,69 @@ export function expandAccountTimelineFail(id, error) {
     error: error
   };
 };
+
+export function blockAccount(id) {
+  return (dispatch, getState) => {
+    dispatch(blockAccountRequest(id));
+
+    api(getState).post(`/api/v1/accounts/${id}/block`).then(response => {
+      dispatch(blockAccountSuccess(response.data));
+    }).catch(error => {
+      dispatch(blockAccountFail(id, error));
+    });
+  };
+};
+
+export function unblockAccount(id) {
+  return (dispatch, getState) => {
+    dispatch(unblockAccountRequest(id));
+
+    api(getState).post(`/api/v1/accounts/${id}/unblock`).then(response => {
+      dispatch(unblockAccountSuccess(response.data));
+    }).catch(error => {
+      dispatch(unblockAccountFail(id, error));
+    });
+  };
+};
+
+export function blockAccountRequest(id) {
+  return {
+    type: ACCOUNT_BLOCK_REQUEST,
+    id: id
+  };
+};
+
+export function blockAccountSuccess(relationship) {
+  return {
+    type: ACCOUNT_BLOCK_SUCCESS,
+    relationship: relationship
+  };
+};
+
+export function blockAccountFail(error) {
+  return {
+    type: ACCOUNT_BLOCK_FAIL,
+    error: error
+  };
+};
+
+export function unblockAccountRequest(id) {
+  return {
+    type: ACCOUNT_UNBLOCK_REQUEST,
+    id: id
+  };
+};
+
+export function unblockAccountSuccess(relationship) {
+  return {
+    type: ACCOUNT_UNBLOCK_SUCCESS,
+    relationship: relationship
+  };
+};
+
+export function unblockAccountFail(error) {
+  return {
+    type: ACCOUNT_UNBLOCK_FAIL,
+    error: error
+  };
+};
diff --git a/app/assets/javascripts/components/components/status_action_bar.jsx b/app/assets/javascripts/components/components/status_action_bar.jsx
index 76f0ac5f1..3e826d68a 100644
--- a/app/assets/javascripts/components/components/status_action_bar.jsx
+++ b/app/assets/javascripts/components/components/status_action_bar.jsx
@@ -41,6 +41,8 @@ const StatusActionBar = React.createClass({
           <li><a href='#' onClick={this.handleDeleteClick}>Delete</a></li>
         </ul>
       );
+    } else {
+      menu = <ul />;
     }
 
     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
index 309471dd2..aadf168b2 100644
--- a/app/assets/javascripts/components/features/account/components/action_bar.jsx
+++ b/app/assets/javascripts/components/features/account/components/action_bar.jsx
@@ -7,7 +7,8 @@ const ActionBar = React.createClass({
   propTypes: {
     account: ImmutablePropTypes.map.isRequired,
     me: React.PropTypes.number.isRequired,
-    onFollow: React.PropTypes.func.isRequired
+    onFollow: React.PropTypes.func.isRequired,
+    onBlock: React.PropTypes.func.isRequired
   },
 
   mixins: [PureRenderMixin],
@@ -16,25 +17,46 @@ const ActionBar = React.createClass({
     const { account, me } = this.props;
 
     let infoText     = '';
+    let follow       = '';
     let buttonText   = '';
+    let block        = '';
+    let disabled     = false;
 
     if (account.get('id') === me) {
       buttonText = 'This is you!';
+      disabled   = true;
     } else {
-      if (account.getIn(['relationship', 'following'])) {
-        buttonText = 'Unfollow';
+      let blockText = '';
+
+      if (account.getIn(['relationship', 'blocking'])) {
+        buttonText = 'Blocked';
+        disabled   = true;
+        blockText  = 'Unblock';
       } else {
-        buttonText = 'Follow';
-      }
+        if (account.getIn(['relationship', 'following'])) {
+          buttonText = 'Unfollow';
+        } else {
+          buttonText = 'Follow';
+        }
+
+        if (account.getIn(['relationship', 'followed_by'])) {
+          infoText = 'Follows you!';
+        }
 
-      if (account.getIn(['relationship', 'followed_by'])) {
-        infoText = 'Follows you!';
+        blockText = 'Block';
       }
+
+      block = <Button text={blockText} onClick={this.props.onBlock} />;
+    }
+
+    if (!account.getIn(['relationship', 'blocking'])) {
+      follow = <Button text={buttonText} onClick={this.props.onFollow} disabled={disabled} />;
     }
 
     return (
       <div style={{ borderTop: '1px solid #363c4b', borderBottom: '1px solid #363c4b', padding: '10px', lineHeight: '36px', overflow: 'hidden', flex: '0 0 auto' }}>
-        <Button text={buttonText} onClick={this.props.onFollow} disabled={account.get('id') === me} /> <span style={{ color: '#616b86', fontWeight: '500', textTransform: 'uppercase', float: 'right', display: 'block' }}>{infoText}</span>
+        {follow} {block}
+        <span style={{ color: '#616b86', fontWeight: '500', textTransform: 'uppercase', float: 'right', display: 'block' }}>{infoText}</span>
       </div>
     );
   },
diff --git a/app/assets/javascripts/components/features/account/index.jsx b/app/assets/javascripts/components/features/account/index.jsx
index 40c06c545..c2389af2e 100644
--- a/app/assets/javascripts/components/features/account/index.jsx
+++ b/app/assets/javascripts/components/features/account/index.jsx
@@ -5,6 +5,8 @@ import {
   fetchAccount,
   followAccount,
   unfollowAccount,
+  blockAccount,
+  unblockAccount,
   fetchAccountTimeline,
   expandAccountTimeline
 }                            from '../../actions/accounts';
@@ -66,6 +68,14 @@ const Account = React.createClass({
     }
   },
 
+  handleBlock () {
+    if (this.props.account.getIn(['relationship', 'blocking'])) {
+      this.props.dispatch(unblockAccount(this.props.account.get('id')));
+    } else {
+      this.props.dispatch(blockAccount(this.props.account.get('id')));
+    }
+  },
+
   handleReply (status) {
     this.props.dispatch(replyCompose(status));
   },
@@ -104,7 +114,7 @@ const Account = React.createClass({
     return (
       <div style={{ display: 'flex', flexDirection: 'column', 'flex': '0 0 auto', height: '100%' }}>
         <Header account={account} />
-        <ActionBar account={account} me={me} onFollow={this.handleFollow} onUnfollow={this.handleUnfollow} />
+        <ActionBar account={account} me={me} onFollow={this.handleFollow} onBlock={this.handleBlock} />
         <StatusList statuses={statuses} me={me} onScrollToBottom={this.handleScrollToBottom} onReply={this.handleReply} onReblog={this.handleReblog} onFavourite={this.handleFavourite} />
       </div>
     );
diff --git a/app/assets/javascripts/components/reducers/timelines.jsx b/app/assets/javascripts/components/reducers/timelines.jsx
index ec42b7825..392683150 100644
--- a/app/assets/javascripts/components/reducers/timelines.jsx
+++ b/app/assets/javascripts/components/reducers/timelines.jsx
@@ -15,6 +15,8 @@ import {
   ACCOUNT_FETCH_SUCCESS,
   ACCOUNT_FOLLOW_SUCCESS,
   ACCOUNT_UNFOLLOW_SUCCESS,
+  ACCOUNT_BLOCK_SUCCESS,
+  ACCOUNT_UNBLOCK_SUCCESS,
   ACCOUNT_TIMELINE_FETCH_SUCCESS,
   ACCOUNT_TIMELINE_EXPAND_SUCCESS
 }                                from '../actions/accounts';
@@ -231,6 +233,8 @@ export default function timelines(state = initialState, action) {
       return normalizeAccount(state, Immutable.fromJS(action.account), Immutable.fromJS(action.relationship));
     case ACCOUNT_FOLLOW_SUCCESS:
     case ACCOUNT_UNFOLLOW_SUCCESS:
+    case ACCOUNT_UNBLOCK_SUCCESS:
+    case ACCOUNT_BLOCK_SUCCESS:
       return normalizeRelationship(state, Immutable.fromJS(action.relationship));
     case STATUS_FETCH_SUCCESS:
       return normalizeContext(state, Immutable.fromJS(action.status), Immutable.fromJS(action.context.ancestors), Immutable.fromJS(action.context.descendants));