about summary refs log tree commit diff
path: root/app/assets
diff options
context:
space:
mode:
authorEugen Rochko <eugen@zeonfederated.com>2016-10-03 18:49:52 +0200
committerEugen Rochko <eugen@zeonfederated.com>2016-10-03 18:49:52 +0200
commit70e9dd0b5b2c4b2d695334d8b63c6d58cb1619d8 (patch)
treed1ff421300703d4b690e111dd8b5b5da665aab5b /app/assets
parent7b9a4af3112dc4edcd378dc94190e2eb8e041f56 (diff)
Blocking will prevent e-mail notifications from blocked user, blocks in UI
Diffstat (limited to 'app/assets')
-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
-rw-r--r--app/assets/stylesheets/components.scss20
6 files changed, 126 insertions, 24 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));
diff --git a/app/assets/stylesheets/components.scss b/app/assets/stylesheets/components.scss
index 7c111e04a..155517362 100644
--- a/app/assets/stylesheets/components.scss
+++ b/app/assets/stylesheets/components.scss
@@ -170,7 +170,6 @@
 .dropdown--active .dropdown__content {
   display: block;
   z-index: 9999;
-  box-shadow: 0 0 15px rgba(0, 0, 0, 0.4);
 
   &:before {
     content: "";
@@ -187,20 +186,11 @@
 
   ul {
     list-style: none;
-  }
-
-  li {
-    &:first-child a {
-      border-radius: 4px 4px 0 0;
-    }
-
-    &:last-child a {
-      border-radius: 0 0 4px 4px;
-    }
-
-    &:first-child:last-child a {
-      border-radius: 4px;
-    }
+    background: #d9e1e8;
+    padding: 4px 0;
+    border-radius: 4px;
+    box-shadow: 0 0 15px rgba(0, 0, 0, 0.4);
+    min-width: 100px;
   }
 
   a {