Merge pull request #1382 from akihikodaki/unfollow
Implement remote account unfollow
This commit is contained in:
		
						commit
						c666a2b26e
					
				
					 6 changed files with 81 additions and 47 deletions
				
			
		| 
						 | 
				
			
			@ -3,6 +3,7 @@ import follow from './follow';
 | 
			
		|||
import performActivityPub from './perform-activitypub';
 | 
			
		||||
import processInbox from './process-inbox';
 | 
			
		||||
import reportGitHubFailure from './report-github-failure';
 | 
			
		||||
import unfollow from './unfollow';
 | 
			
		||||
 | 
			
		||||
const handlers = {
 | 
			
		||||
  deliverPost,
 | 
			
		||||
| 
						 | 
				
			
			@ -10,6 +11,7 @@ const handlers = {
 | 
			
		|||
  performActivityPub,
 | 
			
		||||
  processInbox,
 | 
			
		||||
  reportGitHubFailure,
 | 
			
		||||
  unfollow
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export default (job, done) => handlers[job.data.type](job).then(() => done(), done);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										54
									
								
								src/processor/http/unfollow.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								src/processor/http/unfollow.ts
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,54 @@
 | 
			
		|||
import FollowedLog from '../../models/followed-log';
 | 
			
		||||
import Following from '../../models/following';
 | 
			
		||||
import FollowingLog from '../../models/following-log';
 | 
			
		||||
import User, { isRemoteUser, pack as packUser } from '../../models/user';
 | 
			
		||||
import stream from '../../publishers/stream';
 | 
			
		||||
import renderFollow from '../../remote/activitypub/renderer/follow';
 | 
			
		||||
import renderUndo from '../../remote/activitypub/renderer/undo';
 | 
			
		||||
import context from '../../remote/activitypub/renderer/context';
 | 
			
		||||
import request from '../../remote/request';
 | 
			
		||||
 | 
			
		||||
export default async ({ data }) => {
 | 
			
		||||
	// Delete following
 | 
			
		||||
	const following = await Following.findOneAndDelete({ _id: data.id });
 | 
			
		||||
	if (following === null) {
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	const promisedFollower = User.findOne({ _id: following.followerId });
 | 
			
		||||
	const promisedFollowee = User.findOne({ _id: following.followeeId });
 | 
			
		||||
 | 
			
		||||
	await Promise.all([
 | 
			
		||||
		// Decrement following count
 | 
			
		||||
		User.update({ _id: following.followerId }, { $inc: { followingCount: -1 } }),
 | 
			
		||||
		promisedFollower.then(({ followingCount }) => FollowingLog.insert({
 | 
			
		||||
			userId: following.followerId,
 | 
			
		||||
			count: followingCount - 1
 | 
			
		||||
		})),
 | 
			
		||||
 | 
			
		||||
		// Decrement followers count
 | 
			
		||||
		User.update({ _id: following.followeeId }, { $inc: { followersCount: -1 } }),
 | 
			
		||||
		promisedFollowee.then(({ followersCount }) => FollowedLog.insert({
 | 
			
		||||
			userId: following.followeeId,
 | 
			
		||||
			count: followersCount - 1
 | 
			
		||||
		})),
 | 
			
		||||
 | 
			
		||||
		// Publish follow event
 | 
			
		||||
		Promise.all([promisedFollower, promisedFollowee]).then(async ([follower, followee]) => {
 | 
			
		||||
			if (isRemoteUser(follower)) {
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			const promisedPackedUser = packUser(followee, follower);
 | 
			
		||||
 | 
			
		||||
			if (isRemoteUser(followee)) {
 | 
			
		||||
				const undo = renderUndo(renderFollow(follower, followee));
 | 
			
		||||
				undo['@context'] = context;
 | 
			
		||||
 | 
			
		||||
				await request(follower, followee.account.inbox, undo);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			stream(follower._id, 'unfollow', promisedPackedUser);
 | 
			
		||||
		})
 | 
			
		||||
	]);
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -15,7 +15,7 @@ export default async (resolver, actor, activity) => {
 | 
			
		|||
 | 
			
		||||
		switch (result.object.$ref) {
 | 
			
		||||
		case 'following':
 | 
			
		||||
			await unfollow(result.resolver, result.object);
 | 
			
		||||
			await unfollow(result.object);
 | 
			
		||||
		}
 | 
			
		||||
	}));
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,24 +1,11 @@
 | 
			
		|||
import FollowedLog from '../../../../models/followed-log';
 | 
			
		||||
import Following from '../../../../models/following';
 | 
			
		||||
import FollowingLog from '../../../../models/following-log';
 | 
			
		||||
import User from '../../../../models/user';
 | 
			
		||||
import queue from '../../../../queue';
 | 
			
		||||
 | 
			
		||||
export default async (resolver, { $id }) => {
 | 
			
		||||
	const following = await Following.findOneAndDelete({ _id: $id });
 | 
			
		||||
	if (following === null) {
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	await Promise.all([
 | 
			
		||||
		User.update({ _id: following.followerId }, { $inc: { followingCount: -1 } }),
 | 
			
		||||
		User.findOne({ _id: following.followerId }).then(({ followingCount }) => FollowingLog.insert({
 | 
			
		||||
			userId: following.followerId,
 | 
			
		||||
			count: followingCount - 1
 | 
			
		||||
		})),
 | 
			
		||||
		User.update({ _id: following.followeeId }, { $inc: { followersCount: -1 } }),
 | 
			
		||||
		User.findOne({ _id: following.followeeId }).then(({ followersCount }) => FollowedLog.insert({
 | 
			
		||||
			userId: following.followeeId,
 | 
			
		||||
			count: followersCount - 1
 | 
			
		||||
		})),
 | 
			
		||||
	]);
 | 
			
		||||
};
 | 
			
		||||
export default ({ $id }) => new Promise((resolve, reject) => {
 | 
			
		||||
	queue.create('http', { type: 'unfollow', id: $id }).save(error => {
 | 
			
		||||
		if (error) {
 | 
			
		||||
			reject(error);
 | 
			
		||||
		} else {
 | 
			
		||||
			resolve();
 | 
			
		||||
		}
 | 
			
		||||
	});
 | 
			
		||||
});
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										4
									
								
								src/remote/activitypub/renderer/undo.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								src/remote/activitypub/renderer/undo.ts
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,4 @@
 | 
			
		|||
export default object => ({
 | 
			
		||||
	type: 'Undo',
 | 
			
		||||
	object
 | 
			
		||||
});
 | 
			
		||||
| 
						 | 
				
			
			@ -2,9 +2,9 @@
 | 
			
		|||
 * Module dependencies
 | 
			
		||||
 */
 | 
			
		||||
import $ from 'cafy';
 | 
			
		||||
import User, { pack as packUser } from '../../../../models/user';
 | 
			
		||||
import User from '../../../../models/user';
 | 
			
		||||
import Following from '../../../../models/following';
 | 
			
		||||
import event from '../../../../publishers/stream';
 | 
			
		||||
import queue from '../../../../queue';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Unfollow a user
 | 
			
		||||
| 
						 | 
				
			
			@ -49,28 +49,15 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 | 
			
		|||
		return rej('already not following');
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Delete following
 | 
			
		||||
	await Following.findOneAndDelete({
 | 
			
		||||
		_id: exist._id
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	// Send response
 | 
			
		||||
	res();
 | 
			
		||||
 | 
			
		||||
	// Decrement following count
 | 
			
		||||
	User.update({ _id: follower._id }, {
 | 
			
		||||
		$inc: {
 | 
			
		||||
			followingCount: -1
 | 
			
		||||
	queue.create('http', {
 | 
			
		||||
		type: 'unfollow',
 | 
			
		||||
		id: exist._id
 | 
			
		||||
	}).save(error => {
 | 
			
		||||
		if (error) {
 | 
			
		||||
			return rej('unfollow failed');
 | 
			
		||||
		}
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	// Decrement followers count
 | 
			
		||||
	User.update({ _id: followee._id }, {
 | 
			
		||||
		$inc: {
 | 
			
		||||
			followersCount: -1
 | 
			
		||||
		}
 | 
			
		||||
		// Send response
 | 
			
		||||
		res();
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	// Publish follow event
 | 
			
		||||
	event(follower._id, 'unfollow', await packUser(followee, follower));
 | 
			
		||||
});
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue