forked from cybrespace/mastodon
		
	Make "unfollow" undo pending outgoing follow request too (#4781)
* Make "unfollow" undo pending outgoing follow request too * Add cancel button to web UI when awaiting follow request approval * Make the hourglass button do the cancelling
This commit is contained in:
		
							parent
							
								
									2a5d1d5a1b
								
							
						
					
					
						commit
						d3b6746173
					
				
					 8 changed files with 37 additions and 11 deletions
				
			
		| 
						 | 
					@ -32,7 +32,7 @@ const makeMapStateToProps = () => {
 | 
				
			||||||
const mapDispatchToProps = (dispatch, { intl }) => ({
 | 
					const mapDispatchToProps = (dispatch, { intl }) => ({
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  onFollow (account) {
 | 
					  onFollow (account) {
 | 
				
			||||||
    if (account.getIn(['relationship', 'following'])) {
 | 
					    if (account.getIn(['relationship', 'following']) || account.getIn(['relationship', 'requested'])) {
 | 
				
			||||||
      if (this.unfollowModal) {
 | 
					      if (this.unfollowModal) {
 | 
				
			||||||
        dispatch(openModal('CONFIRM', {
 | 
					        dispatch(openModal('CONFIRM', {
 | 
				
			||||||
          message: <FormattedMessage id='confirmations.unfollow.message' defaultMessage='Are you sure you want to unfollow {name}?' values={{ name: <strong>@{account.get('acct')}</strong> }} />,
 | 
					          message: <FormattedMessage id='confirmations.unfollow.message' defaultMessage='Are you sure you want to unfollow {name}?' values={{ name: <strong>@{account.get('acct')}</strong> }} />,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,7 +11,7 @@ import ImmutablePureComponent from 'react-immutable-pure-component';
 | 
				
			||||||
const messages = defineMessages({
 | 
					const messages = defineMessages({
 | 
				
			||||||
  unfollow: { id: 'account.unfollow', defaultMessage: 'Unfollow' },
 | 
					  unfollow: { id: 'account.unfollow', defaultMessage: 'Unfollow' },
 | 
				
			||||||
  follow: { id: 'account.follow', defaultMessage: 'Follow' },
 | 
					  follow: { id: 'account.follow', defaultMessage: 'Follow' },
 | 
				
			||||||
  requested: { id: 'account.requested', defaultMessage: 'Awaiting approval' },
 | 
					  requested: { id: 'account.requested', defaultMessage: 'Awaiting approval. Click to cancel follow request' },
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const makeMapStateToProps = () => {
 | 
					const makeMapStateToProps = () => {
 | 
				
			||||||
| 
						 | 
					@ -102,7 +102,7 @@ export default class Header extends ImmutablePureComponent {
 | 
				
			||||||
      if (account.getIn(['relationship', 'requested'])) {
 | 
					      if (account.getIn(['relationship', 'requested'])) {
 | 
				
			||||||
        actionBtn = (
 | 
					        actionBtn = (
 | 
				
			||||||
          <div className='account--action-button'>
 | 
					          <div className='account--action-button'>
 | 
				
			||||||
            <IconButton size={26} disabled icon='hourglass' title={intl.formatMessage(messages.requested)} />
 | 
					            <IconButton size={26} active icon='hourglass' title={intl.formatMessage(messages.requested)} onClick={this.props.onFollow} />
 | 
				
			||||||
          </div>
 | 
					          </div>
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
      } else if (!account.getIn(['relationship', 'blocking'])) {
 | 
					      } else if (!account.getIn(['relationship', 'blocking'])) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -38,7 +38,7 @@ const makeMapStateToProps = () => {
 | 
				
			||||||
const mapDispatchToProps = (dispatch, { intl }) => ({
 | 
					const mapDispatchToProps = (dispatch, { intl }) => ({
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  onFollow (account) {
 | 
					  onFollow (account) {
 | 
				
			||||||
    if (account.getIn(['relationship', 'following'])) {
 | 
					    if (account.getIn(['relationship', 'following']) || account.getIn(['relationship', 'requested'])) {
 | 
				
			||||||
      if (this.unfollowModal) {
 | 
					      if (this.unfollowModal) {
 | 
				
			||||||
        dispatch(openModal('CONFIRM', {
 | 
					        dispatch(openModal('CONFIRM', {
 | 
				
			||||||
          message: <FormattedMessage id='confirmations.unfollow.message' defaultMessage='Are you sure you want to unfollow {name}?' values={{ name: <strong>@{account.get('acct')}</strong> }} />,
 | 
					          message: <FormattedMessage id='confirmations.unfollow.message' defaultMessage='Are you sure you want to unfollow {name}?' values={{ name: <strong>@{account.get('acct')}</strong> }} />,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -436,7 +436,7 @@
 | 
				
			||||||
        "id": "account.follow"
 | 
					        "id": "account.follow"
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      {
 | 
					      {
 | 
				
			||||||
        "defaultMessage": "Awaiting approval",
 | 
					        "defaultMessage": "Awaiting approval. Click to cancel follow request",
 | 
				
			||||||
        "id": "account.requested"
 | 
					        "id": "account.requested"
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      {
 | 
					      {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -12,7 +12,7 @@
 | 
				
			||||||
  "account.mute": "Mute @{name}",
 | 
					  "account.mute": "Mute @{name}",
 | 
				
			||||||
  "account.posts": "Posts",
 | 
					  "account.posts": "Posts",
 | 
				
			||||||
  "account.report": "Report @{name}",
 | 
					  "account.report": "Report @{name}",
 | 
				
			||||||
  "account.requested": "Awaiting approval",
 | 
					  "account.requested": "Awaiting approval. Click to cancel follow request",
 | 
				
			||||||
  "account.share": "Share @{name}'s profile",
 | 
					  "account.share": "Share @{name}'s profile",
 | 
				
			||||||
  "account.unblock": "Unblock @{name}",
 | 
					  "account.unblock": "Unblock @{name}",
 | 
				
			||||||
  "account.unblock_domain": "Unhide {domain}",
 | 
					  "account.unblock_domain": "Unhide {domain}",
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -33,6 +33,8 @@ class ActivityPub::Activity::Undo < ActivityPub::Activity
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if @account.following?(target_account)
 | 
					    if @account.following?(target_account)
 | 
				
			||||||
      @account.unfollow!(target_account)
 | 
					      @account.unfollow!(target_account)
 | 
				
			||||||
 | 
					    elsif @account.requested?(target_account)
 | 
				
			||||||
 | 
					      FollowRequest.find_by(account: @account, target_account: target_account)&.destroy
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
      delete_later!(object_uri)
 | 
					      delete_later!(object_uri)
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -67,10 +67,13 @@ class ProcessInteractionService < BaseService
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def follow!(account, target_account)
 | 
					  def follow!(account, target_account)
 | 
				
			||||||
    follow = account.follow!(target_account)
 | 
					    follow = account.follow!(target_account)
 | 
				
			||||||
 | 
					    FollowRequest.find_by(account: account, target_account: target_account)&.destroy
 | 
				
			||||||
    NotifyService.new.call(target_account, follow)
 | 
					    NotifyService.new.call(target_account, follow)
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def follow_request!(account, target_account)
 | 
					  def follow_request!(account, target_account)
 | 
				
			||||||
 | 
					    return if account.requested?(target_account)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    follow_request = FollowRequest.create!(account: account, target_account: target_account)
 | 
					    follow_request = FollowRequest.create!(account: account, target_account: target_account)
 | 
				
			||||||
    NotifyService.new.call(target_account, follow_request)
 | 
					    NotifyService.new.call(target_account, follow_request)
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
| 
						 | 
					@ -88,6 +91,7 @@ class ProcessInteractionService < BaseService
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def unfollow!(account, target_account)
 | 
					  def unfollow!(account, target_account)
 | 
				
			||||||
    account.unfollow!(target_account)
 | 
					    account.unfollow!(target_account)
 | 
				
			||||||
 | 
					    FollowRequest.find_by(account: account, target_account: target_account)&.destroy
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def reflect_block!(account, target_account)
 | 
					  def reflect_block!(account, target_account)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,15 +5,35 @@ class UnfollowService < BaseService
 | 
				
			||||||
  # @param [Account] source_account Where to unfollow from
 | 
					  # @param [Account] source_account Where to unfollow from
 | 
				
			||||||
  # @param [Account] target_account Which to unfollow
 | 
					  # @param [Account] target_account Which to unfollow
 | 
				
			||||||
  def call(source_account, target_account)
 | 
					  def call(source_account, target_account)
 | 
				
			||||||
    follow = source_account.unfollow!(target_account)
 | 
					    @source_account = source_account
 | 
				
			||||||
    return unless follow
 | 
					    @target_account = target_account
 | 
				
			||||||
    create_notification(follow) unless target_account.local?
 | 
					
 | 
				
			||||||
    UnmergeWorker.perform_async(target_account.id, source_account.id)
 | 
					    unfollow! || undo_follow_request!
 | 
				
			||||||
    follow
 | 
					 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private
 | 
					  private
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def unfollow!
 | 
				
			||||||
 | 
					    follow = Follow.find_by(account: @source_account, target_account: @target_account)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return unless follow
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    follow.destroy!
 | 
				
			||||||
 | 
					    create_notification(follow) unless @target_account.local?
 | 
				
			||||||
 | 
					    UnmergeWorker.perform_async(@target_account.id, @source_account.id)
 | 
				
			||||||
 | 
					    follow
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def undo_follow_request!
 | 
				
			||||||
 | 
					    follow_request = FollowRequest.find_by(account: @source_account, target_account: @target_account)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return unless follow_request
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    follow_request.destroy!
 | 
				
			||||||
 | 
					    create_notification(follow_request) unless @target_account.local?
 | 
				
			||||||
 | 
					    follow_request
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def create_notification(follow)
 | 
					  def create_notification(follow)
 | 
				
			||||||
    if follow.target_account.ostatus?
 | 
					    if follow.target_account.ostatus?
 | 
				
			||||||
      NotificationWorker.perform_async(build_xml(follow), follow.account_id, follow.target_account_id)
 | 
					      NotificationWorker.perform_async(build_xml(follow), follow.account_id, follow.target_account_id)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue