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_SUCCESS = 'ACCOUNT_UNFOLLOW_SUCCESS'; | ||||||
| export const ACCOUNT_UNFOLLOW_FAIL    = 'ACCOUNT_UNFOLLOW_FAIL'; | 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_REQUEST = 'ACCOUNT_TIMELINE_FETCH_REQUEST'; | ||||||
| export const ACCOUNT_TIMELINE_FETCH_SUCCESS = 'ACCOUNT_TIMELINE_FETCH_SUCCESS'; | export const ACCOUNT_TIMELINE_FETCH_SUCCESS = 'ACCOUNT_TIMELINE_FETCH_SUCCESS'; | ||||||
| export const ACCOUNT_TIMELINE_FETCH_FAIL    = 'ACCOUNT_TIMELINE_FETCH_FAIL'; | export const ACCOUNT_TIMELINE_FETCH_FAIL    = 'ACCOUNT_TIMELINE_FETCH_FAIL'; | ||||||
|  | @ -204,3 +212,69 @@ export function expandAccountTimelineFail(id, error) { | ||||||
|     error: 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> |           <li><a href='#' onClick={this.handleDeleteClick}>Delete</a></li> | ||||||
|         </ul> |         </ul> | ||||||
|       ); |       ); | ||||||
|  |     } else { | ||||||
|  |       menu = <ul />; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     return ( |     return ( | ||||||
|  |  | ||||||
|  | @ -7,7 +7,8 @@ const ActionBar = React.createClass({ | ||||||
|   propTypes: { |   propTypes: { | ||||||
|     account: ImmutablePropTypes.map.isRequired, |     account: ImmutablePropTypes.map.isRequired, | ||||||
|     me: React.PropTypes.number.isRequired, |     me: React.PropTypes.number.isRequired, | ||||||
|     onFollow: React.PropTypes.func.isRequired |     onFollow: React.PropTypes.func.isRequired, | ||||||
|  |     onBlock: React.PropTypes.func.isRequired | ||||||
|   }, |   }, | ||||||
| 
 | 
 | ||||||
|   mixins: [PureRenderMixin], |   mixins: [PureRenderMixin], | ||||||
|  | @ -16,25 +17,46 @@ const ActionBar = React.createClass({ | ||||||
|     const { account, me } = this.props; |     const { account, me } = this.props; | ||||||
| 
 | 
 | ||||||
|     let infoText     = ''; |     let infoText     = ''; | ||||||
|  |     let follow       = ''; | ||||||
|     let buttonText   = ''; |     let buttonText   = ''; | ||||||
|  |     let block        = ''; | ||||||
|  |     let disabled     = false; | ||||||
| 
 | 
 | ||||||
|     if (account.get('id') === me) { |     if (account.get('id') === me) { | ||||||
|       buttonText = 'This is you!'; |       buttonText = 'This is you!'; | ||||||
|  |       disabled   = true; | ||||||
|     } else { |     } else { | ||||||
|       if (account.getIn(['relationship', 'following'])) { |       let blockText = ''; | ||||||
|         buttonText = 'Unfollow'; | 
 | ||||||
|  |       if (account.getIn(['relationship', 'blocking'])) { | ||||||
|  |         buttonText = 'Blocked'; | ||||||
|  |         disabled   = true; | ||||||
|  |         blockText  = 'Unblock'; | ||||||
|       } else { |       } else { | ||||||
|         buttonText = 'Follow'; |         if (account.getIn(['relationship', 'following'])) { | ||||||
|  |           buttonText = 'Unfollow'; | ||||||
|  |         } else { | ||||||
|  |           buttonText = 'Follow'; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         if (account.getIn(['relationship', 'followed_by'])) { | ||||||
|  |           infoText = 'Follows you!'; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         blockText = 'Block'; | ||||||
|       } |       } | ||||||
| 
 | 
 | ||||||
|       if (account.getIn(['relationship', 'followed_by'])) { |       block = <Button text={blockText} onClick={this.props.onBlock} />; | ||||||
|         infoText = 'Follows you!'; |     } | ||||||
|       } | 
 | ||||||
|  |     if (!account.getIn(['relationship', 'blocking'])) { | ||||||
|  |       follow = <Button text={buttonText} onClick={this.props.onFollow} disabled={disabled} />; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     return ( |     return ( | ||||||
|       <div style={{ borderTop: '1px solid #363c4b', borderBottom: '1px solid #363c4b', padding: '10px', lineHeight: '36px', overflow: 'hidden', flex: '0 0 auto' }}> |       <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> |       </div> | ||||||
|     ); |     ); | ||||||
|   }, |   }, | ||||||
|  |  | ||||||
|  | @ -5,6 +5,8 @@ import { | ||||||
|   fetchAccount, |   fetchAccount, | ||||||
|   followAccount, |   followAccount, | ||||||
|   unfollowAccount, |   unfollowAccount, | ||||||
|  |   blockAccount, | ||||||
|  |   unblockAccount, | ||||||
|   fetchAccountTimeline, |   fetchAccountTimeline, | ||||||
|   expandAccountTimeline |   expandAccountTimeline | ||||||
| }                            from '../../actions/accounts'; | }                            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) { |   handleReply (status) { | ||||||
|     this.props.dispatch(replyCompose(status)); |     this.props.dispatch(replyCompose(status)); | ||||||
|   }, |   }, | ||||||
|  | @ -104,7 +114,7 @@ const Account = React.createClass({ | ||||||
|     return ( |     return ( | ||||||
|       <div style={{ display: 'flex', flexDirection: 'column', 'flex': '0 0 auto', height: '100%' }}> |       <div style={{ display: 'flex', flexDirection: 'column', 'flex': '0 0 auto', height: '100%' }}> | ||||||
|         <Header account={account} /> |         <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} /> |         <StatusList statuses={statuses} me={me} onScrollToBottom={this.handleScrollToBottom} onReply={this.handleReply} onReblog={this.handleReblog} onFavourite={this.handleFavourite} /> | ||||||
|       </div> |       </div> | ||||||
|     ); |     ); | ||||||
|  |  | ||||||
|  | @ -15,6 +15,8 @@ import { | ||||||
|   ACCOUNT_FETCH_SUCCESS, |   ACCOUNT_FETCH_SUCCESS, | ||||||
|   ACCOUNT_FOLLOW_SUCCESS, |   ACCOUNT_FOLLOW_SUCCESS, | ||||||
|   ACCOUNT_UNFOLLOW_SUCCESS, |   ACCOUNT_UNFOLLOW_SUCCESS, | ||||||
|  |   ACCOUNT_BLOCK_SUCCESS, | ||||||
|  |   ACCOUNT_UNBLOCK_SUCCESS, | ||||||
|   ACCOUNT_TIMELINE_FETCH_SUCCESS, |   ACCOUNT_TIMELINE_FETCH_SUCCESS, | ||||||
|   ACCOUNT_TIMELINE_EXPAND_SUCCESS |   ACCOUNT_TIMELINE_EXPAND_SUCCESS | ||||||
| }                                from '../actions/accounts'; | }                                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)); |       return normalizeAccount(state, Immutable.fromJS(action.account), Immutable.fromJS(action.relationship)); | ||||||
|     case ACCOUNT_FOLLOW_SUCCESS: |     case ACCOUNT_FOLLOW_SUCCESS: | ||||||
|     case ACCOUNT_UNFOLLOW_SUCCESS: |     case ACCOUNT_UNFOLLOW_SUCCESS: | ||||||
|  |     case ACCOUNT_UNBLOCK_SUCCESS: | ||||||
|  |     case ACCOUNT_BLOCK_SUCCESS: | ||||||
|       return normalizeRelationship(state, Immutable.fromJS(action.relationship)); |       return normalizeRelationship(state, Immutable.fromJS(action.relationship)); | ||||||
|     case STATUS_FETCH_SUCCESS: |     case STATUS_FETCH_SUCCESS: | ||||||
|       return normalizeContext(state, Immutable.fromJS(action.status), Immutable.fromJS(action.context.ancestors), Immutable.fromJS(action.context.descendants)); |       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 { | .dropdown--active .dropdown__content { | ||||||
|   display: block; |   display: block; | ||||||
|   z-index: 9999; |   z-index: 9999; | ||||||
|   box-shadow: 0 0 15px rgba(0, 0, 0, 0.4); |  | ||||||
| 
 | 
 | ||||||
|   &:before { |   &:before { | ||||||
|     content: ""; |     content: ""; | ||||||
|  | @ -187,20 +186,11 @@ | ||||||
| 
 | 
 | ||||||
|   ul { |   ul { | ||||||
|     list-style: none; |     list-style: none; | ||||||
|   } |     background: #d9e1e8; | ||||||
| 
 |     padding: 4px 0; | ||||||
|   li { |     border-radius: 4px; | ||||||
|     &:first-child a { |     box-shadow: 0 0 15px rgba(0, 0, 0, 0.4); | ||||||
|       border-radius: 4px 4px 0 0; |     min-width: 100px; | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     &:last-child a { |  | ||||||
|       border-radius: 0 0 4px 4px; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     &:first-child:last-child a { |  | ||||||
|       border-radius: 4px; |  | ||||||
|     } |  | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   a { |   a { | ||||||
|  |  | ||||||
|  | @ -8,7 +8,7 @@ class FavouriteService < BaseService | ||||||
|     account.ping!(account_url(account, format: 'atom'), [Rails.configuration.x.hub_url]) |     account.ping!(account_url(account, format: 'atom'), [Rails.configuration.x.hub_url]) | ||||||
| 
 | 
 | ||||||
|     if status.local? |     if status.local? | ||||||
|       NotificationMailer.favourite(status, account).deliver_later |       NotificationMailer.favourite(status, account).deliver_later unless status.account.blocking?(account) | ||||||
|     else |     else | ||||||
|       NotificationWorker.perform_async(favourite.stream_entry.id, status.account_id) |       NotificationWorker.perform_async(favourite.stream_entry.id, status.account_id) | ||||||
|     end |     end | ||||||
|  |  | ||||||
|  | @ -10,7 +10,7 @@ class FollowService < BaseService | ||||||
|     follow = source_account.follow!(target_account) |     follow = source_account.follow!(target_account) | ||||||
| 
 | 
 | ||||||
|     if target_account.local? |     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 |     else | ||||||
|       subscribe_service.call(target_account) |       subscribe_service.call(target_account) | ||||||
|       NotificationWorker.perform_async(follow.stream_entry.id, target_account.id) |       NotificationWorker.perform_async(follow.stream_entry.id, target_account.id) | ||||||
|  |  | ||||||
|  | @ -69,7 +69,7 @@ class ProcessFeedService < BaseService | ||||||
| 
 | 
 | ||||||
|         unless mentioned_account.nil? |         unless mentioned_account.nil? | ||||||
|           mentioned_account.mentions.where(status: status).first_or_create(status: status) |           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 |         end | ||||||
|       else |       else | ||||||
|         # What to do about remote user? |         # What to do about remote user? | ||||||
|  | @ -114,7 +114,7 @@ class ProcessFeedService < BaseService | ||||||
| 
 | 
 | ||||||
|     if !status.reblog.nil? |     if !status.reblog.nil? | ||||||
|       status.save! |       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 | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -58,7 +58,7 @@ class ProcessInteractionService < BaseService | ||||||
| 
 | 
 | ||||||
|   def follow!(account, target_account) |   def follow!(account, target_account) | ||||||
|     account.follow!(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 |   end | ||||||
| 
 | 
 | ||||||
|   def unfollow!(account, target_account) |   def unfollow!(account, target_account) | ||||||
|  | @ -78,7 +78,7 @@ class ProcessInteractionService < BaseService | ||||||
|   def favourite!(xml, from_account) |   def favourite!(xml, from_account) | ||||||
|     current_status = status(xml) |     current_status = status(xml) | ||||||
|     current_status.favourites.where(account: from_account).first_or_create!(account: from_account) |     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 |   end | ||||||
| 
 | 
 | ||||||
|   def add_post!(body, account) |   def add_post!(body, account) | ||||||
|  |  | ||||||
|  | @ -27,7 +27,7 @@ class ProcessMentionsService < BaseService | ||||||
|       mentioned_account = mention.account |       mentioned_account = mention.account | ||||||
| 
 | 
 | ||||||
|       if mentioned_account.local? |       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 |       else | ||||||
|         NotificationWorker.perform_async(status.stream_entry.id, mentioned_account.id) |         NotificationWorker.perform_async(status.stream_entry.id, mentioned_account.id) | ||||||
|       end |       end | ||||||
|  |  | ||||||
|  | @ -9,7 +9,7 @@ class ReblogService < BaseService | ||||||
|     account.ping!(account_url(account, format: 'atom'), [Rails.configuration.x.hub_url]) |     account.ping!(account_url(account, format: 'atom'), [Rails.configuration.x.hub_url]) | ||||||
| 
 | 
 | ||||||
|     if reblogged_status.local? |     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 |     else | ||||||
|       NotificationWorker.perform_async(reblog.stream_entry.id, reblogged_status.account_id) |       NotificationWorker.perform_async(reblog.stream_entry.id, reblogged_status.account_id) | ||||||
|     end |     end | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue