Blocking will prevent e-mail notifications from blocked user, blocks in UI
This commit is contained in:
		
					parent
					
						
							
								7b9a4af311
							
						
					
				
			
			
				commit
				
					
						70e9dd0b5b
					
				
			
		
					 12 changed files with 134 additions and 32 deletions
				
			
		|  | @ -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 | ||||
|   }; | ||||
| }; | ||||
|  |  | |||
|  | @ -41,6 +41,8 @@ const StatusActionBar = React.createClass({ | |||
|           <li><a href='#' onClick={this.handleDeleteClick}>Delete</a></li> | ||||
|         </ul> | ||||
|       ); | ||||
|     } else { | ||||
|       menu = <ul />; | ||||
|     } | ||||
| 
 | ||||
|     return ( | ||||
|  |  | |||
|  | @ -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,10 +17,21 @@ 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 { | ||||
|       let blockText = ''; | ||||
| 
 | ||||
|       if (account.getIn(['relationship', 'blocking'])) { | ||||
|         buttonText = 'Blocked'; | ||||
|         disabled   = true; | ||||
|         blockText  = 'Unblock'; | ||||
|       } else { | ||||
|         if (account.getIn(['relationship', 'following'])) { | ||||
|           buttonText = 'Unfollow'; | ||||
|  | @ -30,11 +42,21 @@ const ActionBar = React.createClass({ | |||
|         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> | ||||
|     ); | ||||
|   }, | ||||
|  |  | |||
|  | @ -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> | ||||
|     ); | ||||
|  |  | |||
|  | @ -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)); | ||||
|  |  | |||
|  | @ -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 { | ||||
|     background: #d9e1e8; | ||||
|     padding: 4px 0; | ||||
|     border-radius: 4px; | ||||
|     } | ||||
|     box-shadow: 0 0 15px rgba(0, 0, 0, 0.4); | ||||
|     min-width: 100px; | ||||
|   } | ||||
| 
 | ||||
|   a { | ||||
|  |  | |||
|  | @ -8,7 +8,7 @@ class FavouriteService < BaseService | |||
|     account.ping!(account_url(account, format: 'atom'), [Rails.configuration.x.hub_url]) | ||||
| 
 | ||||
|     if status.local? | ||||
|       NotificationMailer.favourite(status, account).deliver_later | ||||
|       NotificationMailer.favourite(status, account).deliver_later unless status.account.blocking?(account) | ||||
|     else | ||||
|       NotificationWorker.perform_async(favourite.stream_entry.id, status.account_id) | ||||
|     end | ||||
|  |  | |||
|  | @ -10,7 +10,7 @@ class FollowService < BaseService | |||
|     follow = source_account.follow!(target_account) | ||||
| 
 | ||||
|     if target_account.local? | ||||
|       NotificationMailer.follow(target_account, source_account).deliver_later | ||||
|       NotificationMailer.follow(target_account, source_account).deliver_later unless target_account.blocking?(source_account) | ||||
|     else | ||||
|       subscribe_service.call(target_account) | ||||
|       NotificationWorker.perform_async(follow.stream_entry.id, target_account.id) | ||||
|  |  | |||
|  | @ -69,7 +69,7 @@ class ProcessFeedService < BaseService | |||
| 
 | ||||
|         unless mentioned_account.nil? | ||||
|           mentioned_account.mentions.where(status: status).first_or_create(status: status) | ||||
|           NotificationMailer.mention(mentioned_account, status).deliver_later | ||||
|           NotificationMailer.mention(mentioned_account, status).deliver_later unless mentioned_account.blocking?(status.account) | ||||
|         end | ||||
|       else | ||||
|         # What to do about remote user? | ||||
|  | @ -114,7 +114,7 @@ class ProcessFeedService < BaseService | |||
| 
 | ||||
|     if !status.reblog.nil? | ||||
|       status.save! | ||||
|       NotificationMailer.reblog(status.reblog, status.account).deliver_later if status.reblog.local? | ||||
|       NotificationMailer.reblog(status.reblog, status.account).deliver_later if status.reblog.local? && !status.reblog.account.blocking?(status.account) | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|  |  | |||
|  | @ -58,7 +58,7 @@ class ProcessInteractionService < BaseService | |||
| 
 | ||||
|   def follow!(account, target_account) | ||||
|     account.follow!(target_account) | ||||
|     NotificationMailer.follow(target_account, account).deliver_later | ||||
|     NotificationMailer.follow(target_account, account).deliver_later unless target_account.blocking?(account) | ||||
|   end | ||||
| 
 | ||||
|   def unfollow!(account, target_account) | ||||
|  | @ -78,7 +78,7 @@ class ProcessInteractionService < BaseService | |||
|   def favourite!(xml, from_account) | ||||
|     current_status = status(xml) | ||||
|     current_status.favourites.where(account: from_account).first_or_create!(account: from_account) | ||||
|     NotificationMailer.favourite(current_status, from_account).deliver_later | ||||
|     NotificationMailer.favourite(current_status, from_account).deliver_later unless current_status.account.blocking?(from_account) | ||||
|   end | ||||
| 
 | ||||
|   def add_post!(body, account) | ||||
|  |  | |||
|  | @ -27,7 +27,7 @@ class ProcessMentionsService < BaseService | |||
|       mentioned_account = mention.account | ||||
| 
 | ||||
|       if mentioned_account.local? | ||||
|         NotificationMailer.mention(mentioned_account, status).deliver_later | ||||
|         NotificationMailer.mention(mentioned_account, status).deliver_later unless mentioned_account.blocking?(status.account) | ||||
|       else | ||||
|         NotificationWorker.perform_async(status.stream_entry.id, mentioned_account.id) | ||||
|       end | ||||
|  |  | |||
|  | @ -9,7 +9,7 @@ class ReblogService < BaseService | |||
|     account.ping!(account_url(account, format: 'atom'), [Rails.configuration.x.hub_url]) | ||||
| 
 | ||||
|     if reblogged_status.local? | ||||
|       NotificationMailer.reblog(reblogged_status, account).deliver_later | ||||
|       NotificationMailer.reblog(reblogged_status, account).deliver_later unless reblogged_status.account.blocking?(account) | ||||
|     else | ||||
|       NotificationWorker.perform_async(reblog.stream_entry.id, reblogged_status.account_id) | ||||
|     end | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue