parent
							
								
									d403869945
								
							
						
					
					
						commit
						0d5bc3be66
					
				
					 22 changed files with 310 additions and 80 deletions
				
			
		|  | @ -419,6 +419,9 @@ desktop/views/pages/user/user.photos.vue: | |||
| 
 | ||||
| desktop/views/pages/user/user.profile.vue: | ||||
|   follows-you: "Follows you" | ||||
|   stalk: "Stalk" | ||||
|   stalking: "Stalking" | ||||
|   unstalk: "Unstalk" | ||||
|   mute: "Mute" | ||||
|   muted: "Muting" | ||||
|   unmute: "Unmute" | ||||
|  |  | |||
|  | @ -419,6 +419,9 @@ desktop/views/pages/user/user.photos.vue: | |||
| 
 | ||||
| desktop/views/pages/user/user.profile.vue: | ||||
|   follows-you: "Vous suis" | ||||
|   stalk: "ストークする" | ||||
|   stalking: "ストーキングしています" | ||||
|   unstalk: "ストーク解除" | ||||
|   mute: "Mettre en sourdine" | ||||
|   muted: "Muting" | ||||
|   unmute: "Enlever la sourdine" | ||||
|  |  | |||
|  | @ -419,6 +419,9 @@ desktop/views/pages/user/user.photos.vue: | |||
| 
 | ||||
| desktop/views/pages/user/user.profile.vue: | ||||
|   follows-you: "フォローされています" | ||||
|   stalk: "ストークする" | ||||
|   stalking: "ストーキングしています" | ||||
|   unstalk: "ストーク解除" | ||||
|   mute: "ミュートする" | ||||
|   muted: "ミュートしています" | ||||
|   unmute: "ミュート解除" | ||||
|  |  | |||
							
								
								
									
										49
									
								
								migration/2018-04-19.js
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								migration/2018-04-19.js
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,49 @@ | |||
| // for Node.js interpret
 | ||||
| 
 | ||||
| const { default: User } = require('../built/models/user'); | ||||
| const { default: Following } = require('../built/models/following'); | ||||
| const { default: zip } = require('@prezzemolo/zip') | ||||
| 
 | ||||
| const migrate = async (following) => { | ||||
| 	const follower = await User.findOne({ _id: following.followerId }); | ||||
| 	const followee = await User.findOne({ _id: following.followeeId }); | ||||
| 	const result = await Following.update(following._id, { | ||||
| 		$set: { | ||||
| 			stalk: true, | ||||
| 			_follower: { | ||||
| 				host: follower.host, | ||||
| 				inbox: follower.host != null ? follower.inbox : undefined | ||||
| 			}, | ||||
| 			_followee: { | ||||
| 				host: followee.host, | ||||
| 				inbox: followee.host != null ? followee.inbox : undefined | ||||
| 			} | ||||
| 		} | ||||
| 	}); | ||||
| 	return result.ok === 1; | ||||
| } | ||||
| 
 | ||||
| async function main() { | ||||
| 	const count = await Following.count({}); | ||||
| 
 | ||||
| 	const dop = Number.parseInt(process.argv[2]) || 5 | ||||
| 	const idop = ((count - (count % dop)) / dop) + 1 | ||||
| 
 | ||||
| 	return zip( | ||||
| 		1, | ||||
| 		async (time) => { | ||||
| 			console.log(`${time} / ${idop}`) | ||||
| 			const doc = await Following.find({}, { | ||||
| 				limit: dop, skip: time * dop | ||||
| 			}) | ||||
| 			return Promise.all(doc.map(migrate)) | ||||
| 		}, | ||||
| 		idop | ||||
| 	).then(a => { | ||||
| 		const rv = [] | ||||
| 		a.forEach(e => rv.push(...e)) | ||||
| 		return rv | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| main().then(console.dir).catch(console.error) | ||||
|  | @ -3,8 +3,14 @@ | |||
| 	<div class="friend-form" v-if="os.isSignedIn && os.i.id != user.id"> | ||||
| 		<mk-follow-button :user="user" size="big"/> | ||||
| 		<p class="followed" v-if="user.isFollowed">%i18n:@follows-you%</p> | ||||
| 		<p v-if="user.isMuted">%i18n:@muted% <a @click="unmute">%i18n:@unmute%</a></p> | ||||
| 		<p v-if="!user.isMuted"><a @click="mute">%i18n:@mute%</a></p> | ||||
| 		<p class="stalk"> | ||||
| 			<span v-if="user.isStalking">%i18n:@stalking% <a @click="unstalk">%i18n:@unstalk%</a></span> | ||||
| 			<span v-if="!user.isStalking"><a @click="stalk">%i18n:@stalk%</a></span> | ||||
| 		</p> | ||||
| 		<p class="mute"> | ||||
| 			<span v-if="user.isMuted">%i18n:@muted% <a @click="unmute">%i18n:@unmute%</a></span> | ||||
| 			<span v-if="!user.isMuted"><a @click="mute">%i18n:@mute%</a></span> | ||||
| 		</p> | ||||
| 	</div> | ||||
| 	<div class="description" v-if="user.description">{{ user.description }}</div> | ||||
| 	<div class="birthday" v-if="user.host === null && user.profile.birthday"> | ||||
|  | @ -47,6 +53,26 @@ export default Vue.extend({ | |||
| 			}); | ||||
| 		}, | ||||
| 
 | ||||
| 		stalk() { | ||||
| 			(this as any).api('following/stalk', { | ||||
| 				userId: this.user.id | ||||
| 			}).then(() => { | ||||
| 				this.user.isStalking = true; | ||||
| 			}, () => { | ||||
| 				alert('error'); | ||||
| 			}); | ||||
| 		}, | ||||
| 
 | ||||
| 		unstalk() { | ||||
| 			(this as any).api('following/unstalk', { | ||||
| 				userId: this.user.id | ||||
| 			}).then(() => { | ||||
| 				this.user.isStalking = false; | ||||
| 			}, () => { | ||||
| 				alert('error'); | ||||
| 			}); | ||||
| 		}, | ||||
| 
 | ||||
| 		mute() { | ||||
| 			(this as any).api('mute/create', { | ||||
| 				userId: this.user.id | ||||
|  |  | |||
|  | @ -10,6 +10,17 @@ export type IFollowing = { | |||
| 	createdAt: Date; | ||||
| 	followeeId: mongo.ObjectID; | ||||
| 	followerId: mongo.ObjectID; | ||||
| 	stalk: boolean; | ||||
| 
 | ||||
| 	// 非正規化
 | ||||
| 	_followee: { | ||||
| 		host: string; | ||||
| 		inbox?: string; | ||||
| 	}, | ||||
| 	_follower: { | ||||
| 		host: string; | ||||
| 		inbox?: string; | ||||
| 	} | ||||
| }; | ||||
| 
 | ||||
| /** | ||||
|  |  | |||
|  | @ -58,6 +58,7 @@ export type INote = { | |||
| 	}; | ||||
| 	uri: string; | ||||
| 
 | ||||
| 	// 非正規化
 | ||||
| 	_reply?: { | ||||
| 		userId: mongo.ObjectID; | ||||
| 	}; | ||||
|  | @ -66,11 +67,9 @@ export type INote = { | |||
| 	}; | ||||
| 	_user: { | ||||
| 		host: string; | ||||
| 		account: { | ||||
| 		inbox?: string; | ||||
| 	}; | ||||
| }; | ||||
| }; | ||||
| 
 | ||||
| /** | ||||
|  * Noteを物理削除します | ||||
|  |  | |||
|  | @ -5,7 +5,7 @@ import db from '../db/mongodb'; | |||
| import Note, { pack as packNote, deleteNote } from './note'; | ||||
| import Following, { deleteFollowing } from './following'; | ||||
| import Mute, { deleteMute } from './mute'; | ||||
| import getFriends from '../server/api/common/get-friends'; | ||||
| import { getFriendIds } from '../server/api/common/get-friends'; | ||||
| import config from '../config'; | ||||
| import AccessToken, { deleteAccessToken } from './access-token'; | ||||
| import NoteWatching, { deleteNoteWatching } from './note-watching'; | ||||
|  | @ -375,33 +375,30 @@ export const pack = ( | |||
| 	} | ||||
| 
 | ||||
| 	if (meId && !meId.equals(_user.id)) { | ||||
| 		// Whether the user is following
 | ||||
| 		_user.isFollowing = (async () => { | ||||
| 			const follow = await Following.findOne({ | ||||
| 		const [following1, following2, mute] = await Promise.all([ | ||||
| 			Following.findOne({ | ||||
| 				followerId: meId, | ||||
| 				followeeId: _user.id | ||||
| 			}); | ||||
| 			return follow !== null; | ||||
| 		})(); | ||||
| 
 | ||||
| 		// Whether the user is followed
 | ||||
| 		_user.isFollowed = (async () => { | ||||
| 			const follow2 = await Following.findOne({ | ||||
| 			}), | ||||
| 			Following.findOne({ | ||||
| 				followerId: _user.id, | ||||
| 				followeeId: meId | ||||
| 			}); | ||||
| 			return follow2 !== null; | ||||
| 		})(); | ||||
| 			}), | ||||
| 			Mute.findOne({ | ||||
| 				muterId: meId, | ||||
| 				muteeId: _user.id | ||||
| 			}) | ||||
| 		]); | ||||
| 
 | ||||
| 		// Whether the user is following
 | ||||
| 		_user.isFollowing = following1 !== null; | ||||
| 		_user.isStalking = following1 && following1.stalk; | ||||
| 
 | ||||
| 		// Whether the user is followed
 | ||||
| 		_user.isFollowed = following2 !== null; | ||||
| 
 | ||||
| 		// Whether the user is muted
 | ||||
| 		_user.isMuted = (async () => { | ||||
| 			const mute = await Mute.findOne({ | ||||
| 				muterId: meId, | ||||
| 				muteeId: _user.id, | ||||
| 				deletedAt: { $exists: false } | ||||
| 			}); | ||||
| 			return mute !== null; | ||||
| 		})(); | ||||
| 		_user.isMuted = mute !== null; | ||||
| 	} | ||||
| 
 | ||||
| 	if (opts.detail) { | ||||
|  | @ -413,7 +410,7 @@ export const pack = ( | |||
| 		} | ||||
| 
 | ||||
| 		if (meId && !meId.equals(_user.id)) { | ||||
| 			const myFollowingIds = await getFriends(meId); | ||||
| 			const myFollowingIds = await getFriendIds(meId); | ||||
| 
 | ||||
| 			// Get following you know count
 | ||||
| 			_user.followingYouKnowCount = Following.count({ | ||||
|  |  | |||
|  | @ -1,10 +1,10 @@ | |||
| import * as mongodb from 'mongodb'; | ||||
| import Following from '../../../models/following'; | ||||
| 
 | ||||
| export default async (me: mongodb.ObjectID, includeMe: boolean = true) => { | ||||
| export const getFriendIds = async (me: mongodb.ObjectID, includeMe = true) => { | ||||
| 	// Fetch relation to other users who the I follows
 | ||||
| 	// SELECT followee
 | ||||
| 	const myfollowing = await Following | ||||
| 	const followings = await Following | ||||
| 		.find({ | ||||
| 			followerId: me | ||||
| 		}, { | ||||
|  | @ -14,7 +14,7 @@ export default async (me: mongodb.ObjectID, includeMe: boolean = true) => { | |||
| 		}); | ||||
| 
 | ||||
| 	// ID list of other users who the I follows
 | ||||
| 	const myfollowingIds = myfollowing.map(follow => follow.followeeId); | ||||
| 	const myfollowingIds = followings.map(following => following.followeeId); | ||||
| 
 | ||||
| 	if (includeMe) { | ||||
| 		myfollowingIds.push(me); | ||||
|  | @ -22,3 +22,26 @@ export default async (me: mongodb.ObjectID, includeMe: boolean = true) => { | |||
| 
 | ||||
| 	return myfollowingIds; | ||||
| }; | ||||
| 
 | ||||
| export const getFriends = async (me: mongodb.ObjectID, includeMe = true) => { | ||||
| 	// Fetch relation to other users who the I follows
 | ||||
| 	const followings = await Following | ||||
| 		.find({ | ||||
| 			followerId: me | ||||
| 		}); | ||||
| 
 | ||||
| 	// ID list of other users who the I follows
 | ||||
| 	const myfollowings = followings.map(following => ({ | ||||
| 		id: following.followeeId, | ||||
| 		stalk: following.stalk | ||||
| 	})); | ||||
| 
 | ||||
| 	if (includeMe) { | ||||
| 		myfollowings.push({ | ||||
| 			id: me, | ||||
| 			stalk: true | ||||
| 		}); | ||||
| 	} | ||||
| 
 | ||||
| 	return myfollowings; | ||||
| }; | ||||
|  |  | |||
|  | @ -426,6 +426,24 @@ const endpoints: Endpoint[] = [ | |||
| 		}, | ||||
| 		kind: 'following-write' | ||||
| 	}, | ||||
| 	{ | ||||
| 		name: 'following/stalk', | ||||
| 		withCredential: true, | ||||
| 		limit: { | ||||
| 			duration: ms('1hour'), | ||||
| 			max: 100 | ||||
| 		}, | ||||
| 		kind: 'following-write' | ||||
| 	}, | ||||
| 	{ | ||||
| 		name: 'following/unstalk', | ||||
| 		withCredential: true, | ||||
| 		limit: { | ||||
| 			duration: ms('1hour'), | ||||
| 			max: 100 | ||||
| 		}, | ||||
| 		kind: 'following-write' | ||||
| 	}, | ||||
| 
 | ||||
| 	{ | ||||
| 		name: 'notes' | ||||
|  |  | |||
							
								
								
									
										36
									
								
								src/server/api/endpoints/following/stalk.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								src/server/api/endpoints/following/stalk.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,36 @@ | |||
| import $ from 'cafy'; | ||||
| import Following from '../../../../models/following'; | ||||
| import { isLocalUser } from '../../../../models/user'; | ||||
| 
 | ||||
| /** | ||||
|  * Stalk a user | ||||
|  */ | ||||
| module.exports = (params, user) => new Promise(async (res, rej) => { | ||||
| 	const follower = user; | ||||
| 
 | ||||
| 	// Get 'userId' parameter
 | ||||
| 	const [userId, userIdErr] = $(params.userId).id().$; | ||||
| 	if (userIdErr) return rej('invalid userId param'); | ||||
| 
 | ||||
| 	// Fetch following
 | ||||
| 	const following = await Following.findOne({ | ||||
| 		followerId: follower._id, | ||||
| 		followeeId: userId | ||||
| 	}); | ||||
| 
 | ||||
| 	if (following === null) { | ||||
| 		return rej('following not found'); | ||||
| 	} | ||||
| 
 | ||||
| 	// Stalk
 | ||||
| 	await Following.update({ _id: following._id }, { | ||||
| 		$set: { | ||||
| 			stalk: true | ||||
| 		} | ||||
| 	}); | ||||
| 
 | ||||
| 	// Send response
 | ||||
| 	res(); | ||||
| 
 | ||||
| 	// TODO: イベント
 | ||||
| }); | ||||
							
								
								
									
										35
									
								
								src/server/api/endpoints/following/unstalk.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								src/server/api/endpoints/following/unstalk.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,35 @@ | |||
| import $ from 'cafy'; | ||||
| import Following from '../../../../models/following'; | ||||
| 
 | ||||
| /** | ||||
|  * Unstalk a user | ||||
|  */ | ||||
| module.exports = (params, user) => new Promise(async (res, rej) => { | ||||
| 	const follower = user; | ||||
| 
 | ||||
| 	// Get 'userId' parameter
 | ||||
| 	const [userId, userIdErr] = $(params.userId).id().$; | ||||
| 	if (userIdErr) return rej('invalid userId param'); | ||||
| 
 | ||||
| 	// Fetch following
 | ||||
| 	const following = await Following.findOne({ | ||||
| 		followerId: follower._id, | ||||
| 		followeeId: userId | ||||
| 	}); | ||||
| 
 | ||||
| 	if (following === null) { | ||||
| 		return rej('following not found'); | ||||
| 	} | ||||
| 
 | ||||
| 	// Stalk
 | ||||
| 	await Following.update({ _id: following._id }, { | ||||
| 		$set: { | ||||
| 			stalk: false | ||||
| 		} | ||||
| 	}); | ||||
| 
 | ||||
| 	// Send response
 | ||||
| 	res(); | ||||
| 
 | ||||
| 	// TODO: イベント
 | ||||
| }); | ||||
|  | @ -5,7 +5,7 @@ import $ from 'cafy'; | |||
| import Notification from '../../../../models/notification'; | ||||
| import Mute from '../../../../models/mute'; | ||||
| import { pack } from '../../../../models/notification'; | ||||
| import getFriends from '../../common/get-friends'; | ||||
| import { getFriendIds } from '../../common/get-friends'; | ||||
| import read from '../../common/read-notification'; | ||||
| 
 | ||||
| /** | ||||
|  | @ -62,7 +62,7 @@ module.exports = (params, user) => new Promise(async (res, rej) => { | |||
| 
 | ||||
| 	if (following) { | ||||
| 		// ID list of the user itself and other users who the user follows
 | ||||
| 		const followingIds = await getFriends(user._id); | ||||
| 		const followingIds = await getFriendIds(user._id); | ||||
| 
 | ||||
| 		query.$and.push({ | ||||
| 			notifierId: { | ||||
|  |  | |||
|  | @ -4,7 +4,7 @@ | |||
| import $ from 'cafy'; | ||||
| import Mute from '../../../../models/mute'; | ||||
| import { pack } from '../../../../models/user'; | ||||
| import getFriends from '../../common/get-friends'; | ||||
| import { getFriendIds } from '../../common/get-friends'; | ||||
| 
 | ||||
| /** | ||||
|  * Get muted users of a user | ||||
|  | @ -34,7 +34,7 @@ module.exports = (params, me) => new Promise(async (res, rej) => { | |||
| 
 | ||||
| 	if (iknow) { | ||||
| 		// Get my friends
 | ||||
| 		const myFriends = await getFriends(me._id); | ||||
| 		const myFriends = await getFriendIds(me._id); | ||||
| 
 | ||||
| 		query.muteeId = { | ||||
| 			$in: myFriends | ||||
|  |  | |||
|  | @ -3,7 +3,7 @@ | |||
|  */ | ||||
| import $ from 'cafy'; | ||||
| import Note from '../../../../models/note'; | ||||
| import getFriends from '../../common/get-friends'; | ||||
| import { getFriendIds } from '../../common/get-friends'; | ||||
| import { pack } from '../../../../models/note'; | ||||
| 
 | ||||
| /** | ||||
|  | @ -46,7 +46,7 @@ module.exports = (params, user) => new Promise(async (res, rej) => { | |||
| 	}; | ||||
| 
 | ||||
| 	if (following) { | ||||
| 		const followingIds = await getFriends(user._id); | ||||
| 		const followingIds = await getFriendIds(user._id); | ||||
| 
 | ||||
| 		query.userId = { | ||||
| 			$in: followingIds | ||||
|  |  | |||
|  | @ -6,7 +6,7 @@ const escapeRegexp = require('escape-regexp'); | |||
| import Note from '../../../../models/note'; | ||||
| import User from '../../../../models/user'; | ||||
| import Mute from '../../../../models/mute'; | ||||
| import getFriends from '../../common/get-friends'; | ||||
| import { getFriendIds } from '../../common/get-friends'; | ||||
| import { pack } from '../../../../models/note'; | ||||
| 
 | ||||
| /** | ||||
|  | @ -156,7 +156,7 @@ async function search( | |||
| 	} | ||||
| 
 | ||||
| 	if (following != null && me != null) { | ||||
| 		const ids = await getFriends(me._id, false); | ||||
| 		const ids = await getFriendIds(me._id, false); | ||||
| 		push({ | ||||
| 			userId: following ? { | ||||
| 				$in: ids | ||||
|  |  | |||
|  | @ -2,11 +2,10 @@ | |||
|  * Module dependencies | ||||
|  */ | ||||
| import $ from 'cafy'; | ||||
| import rap from '@prezzemolo/rap'; | ||||
| import Note from '../../../../models/note'; | ||||
| import Mute from '../../../../models/mute'; | ||||
| import ChannelWatching from '../../../../models/channel-watching'; | ||||
| import getFriends from '../../common/get-friends'; | ||||
| import { getFriends } from '../../common/get-friends'; | ||||
| import { pack } from '../../../../models/note'; | ||||
| 
 | ||||
| /** | ||||
|  | @ -38,34 +37,58 @@ module.exports = async (params, user, app) => { | |||
| 		throw 'only one of sinceId, untilId, sinceDate, untilDate can be specified'; | ||||
| 	} | ||||
| 
 | ||||
| 	const { followingIds, watchingChannelIds, mutedUserIds } = await rap({ | ||||
| 		// ID list of the user itself and other users who the user follows
 | ||||
| 		followingIds: getFriends(user._id), | ||||
| 	const [followings, watchingChannelIds, mutedUserIds] = await Promise.all([ | ||||
| 		// フォローを取得
 | ||||
| 		// Fetch following
 | ||||
| 		getFriends(user._id), | ||||
| 
 | ||||
| 		// Watchしているチャンネルを取得
 | ||||
| 		watchingChannelIds: ChannelWatching.find({ | ||||
| 		ChannelWatching.find({ | ||||
| 			userId: user._id, | ||||
| 			// 削除されたドキュメントは除く
 | ||||
| 			deletedAt: { $exists: false } | ||||
| 		}).then(watches => watches.map(w => w.channelId)), | ||||
| 
 | ||||
| 		// ミュートしているユーザーを取得
 | ||||
| 		mutedUserIds: Mute.find({ | ||||
| 		Mute.find({ | ||||
| 			muterId: user._id | ||||
| 		}).then(ms => ms.map(m => m.muteeId)) | ||||
| 	}); | ||||
| 	]); | ||||
| 
 | ||||
| 	//#region Construct query
 | ||||
| 	const sort = { | ||||
| 		_id: -1 | ||||
| 	}; | ||||
| 
 | ||||
| 	const followQuery = followings.map(f => f.stalk ? { | ||||
| 		userId: f.id | ||||
| 	} : { | ||||
| 		userId: f.id, | ||||
| 
 | ||||
| 		// ストーキングしてないならリプライは含めない(ただし投稿者自身の投稿へのリプライ、自分の投稿へのリプライ、自分のリプライは含める)
 | ||||
| 		$or: [{ | ||||
| 			// リプライでない
 | ||||
| 			replyId: null | ||||
| 		}, { // または
 | ||||
| 			// リプライだが返信先が投稿者自身の投稿
 | ||||
| 			$expr: { | ||||
| 				'$_reply.userId': '$userId' | ||||
| 			} | ||||
| 		}, { // または
 | ||||
| 			// リプライだが返信先が自分(フォロワー)の投稿
 | ||||
| 			'_reply.userId': user._id | ||||
| 		}, { // または
 | ||||
| 			// 自分(フォロワー)が送信したリプライ
 | ||||
| 			userId: user._id | ||||
| 		}] | ||||
| 	}); | ||||
| 
 | ||||
| 	const query = { | ||||
| 		$or: [{ | ||||
| 			$and: [{ | ||||
| 				// フォローしている人のタイムラインへの投稿
 | ||||
| 			userId: { | ||||
| 				$in: followingIds | ||||
| 			}, | ||||
| 				$or: followQuery | ||||
| 			}, { | ||||
| 				// 「タイムラインへの」投稿に限定するためにチャンネルが指定されていないもののみに限る
 | ||||
| 				$or: [{ | ||||
| 					channelId: { | ||||
|  | @ -74,6 +97,7 @@ module.exports = async (params, user, app) => { | |||
| 				}, { | ||||
| 					channelId: null | ||||
| 				}] | ||||
| 			}] | ||||
| 		}, { | ||||
| 			// Watchしているチャンネルへの投稿
 | ||||
| 			channelId: { | ||||
|  |  | |||
|  | @ -5,7 +5,7 @@ import $ from 'cafy'; | |||
| import User from '../../../../models/user'; | ||||
| import Following from '../../../../models/following'; | ||||
| import { pack } from '../../../../models/user'; | ||||
| import getFriends from '../../common/get-friends'; | ||||
| import { getFriendIds } from '../../common/get-friends'; | ||||
| 
 | ||||
| /** | ||||
|  * Get followers of a user | ||||
|  | @ -52,7 +52,7 @@ module.exports = (params, me) => new Promise(async (res, rej) => { | |||
| 	// ログインしていてかつ iknow フラグがあるとき
 | ||||
| 	if (me && iknow) { | ||||
| 		// Get my friends
 | ||||
| 		const myFriends = await getFriends(me._id); | ||||
| 		const myFriends = await getFriendIds(me._id); | ||||
| 
 | ||||
| 		query.followerId = { | ||||
| 			$in: myFriends | ||||
|  |  | |||
|  | @ -5,7 +5,7 @@ import $ from 'cafy'; | |||
| import User from '../../../../models/user'; | ||||
| import Following from '../../../../models/following'; | ||||
| import { pack } from '../../../../models/user'; | ||||
| import getFriends from '../../common/get-friends'; | ||||
| import { getFriendIds } from '../../common/get-friends'; | ||||
| 
 | ||||
| /** | ||||
|  * Get following users of a user | ||||
|  | @ -52,7 +52,7 @@ module.exports = (params, me) => new Promise(async (res, rej) => { | |||
| 	// ログインしていてかつ iknow フラグがあるとき
 | ||||
| 	if (me && iknow) { | ||||
| 		// Get my friends
 | ||||
| 		const myFriends = await getFriends(me._id); | ||||
| 		const myFriends = await getFriendIds(me._id); | ||||
| 
 | ||||
| 		query.followeeId = { | ||||
| 			$in: myFriends | ||||
|  |  | |||
|  | @ -4,7 +4,7 @@ | |||
| const ms = require('ms'); | ||||
| import $ from 'cafy'; | ||||
| import User, { pack } from '../../../../models/user'; | ||||
| import getFriends from '../../common/get-friends'; | ||||
| import { getFriendIds } from '../../common/get-friends'; | ||||
| import Mute from '../../../../models/mute'; | ||||
| 
 | ||||
| /** | ||||
|  | @ -24,7 +24,7 @@ module.exports = (params, me) => new Promise(async (res, rej) => { | |||
| 	if (offsetErr) return rej('invalid offset param'); | ||||
| 
 | ||||
| 	// ID list of the user itself and other users who the user follows
 | ||||
| 	const followingIds = await getFriends(me._id); | ||||
| 	const followingIds = await getFriendIds(me._id); | ||||
| 
 | ||||
| 	// ミュートしているユーザーを取得
 | ||||
| 	const mutedUserIds = (await Mute.find({ | ||||
|  |  | |||
|  | @ -13,7 +13,18 @@ export default async function(follower: IUser, followee: IUser, activity?) { | |||
| 	const following = await Following.insert({ | ||||
| 		createdAt: new Date(), | ||||
| 		followerId: follower._id, | ||||
| 		followeeId: followee._id | ||||
| 		followeeId: followee._id, | ||||
| 		stalk: true, | ||||
| 
 | ||||
| 		// 非正規化
 | ||||
| 		_follower: { | ||||
| 			host: follower.host, | ||||
| 			inbox: isRemoteUser(follower) ? follower.inbox : undefined | ||||
| 		}, | ||||
| 		_followee: { | ||||
| 			host: followee.host, | ||||
| 			inbox: isRemoteUser(followee) ? followee.inbox : undefined | ||||
| 		} | ||||
| 	}); | ||||
| 
 | ||||
| 	//#region Increment following count
 | ||||
|  |  | |||
|  | @ -124,19 +124,8 @@ export default async (user: IUser, data: { | |||
| 		publishGlobalTimelineStream(noteObj); | ||||
| 
 | ||||
| 		// Fetch all followers
 | ||||
| 		const followers = await Following.aggregate([{ | ||||
| 			$lookup: { | ||||
| 				from: 'users', | ||||
| 				localField: 'followerId', | ||||
| 				foreignField: '_id', | ||||
| 				as: 'user' | ||||
| 			} | ||||
| 		}, { | ||||
| 			$match: { | ||||
| 		const followers = await Following.find({ | ||||
| 			followeeId: note.userId | ||||
| 			} | ||||
| 		}], { | ||||
| 			_id: false | ||||
| 		}); | ||||
| 
 | ||||
| 		if (!silent) { | ||||
|  | @ -157,12 +146,15 @@ export default async (user: IUser, data: { | |||
| 				deliver(user, await render(), data.renote._user.inbox); | ||||
| 			} | ||||
| 
 | ||||
| 			Promise.all(followers.map(async follower => { | ||||
| 				follower = follower.user[0]; | ||||
| 			Promise.all(followers.map(async following => { | ||||
| 				const follower = following._follower; | ||||
| 
 | ||||
| 				if (isLocalUser(follower)) { | ||||
| 					// この投稿が返信かつstalkフォローでないならスキップ
 | ||||
| 					if (note.replyId && !following.stalk) return; | ||||
| 
 | ||||
| 					// Publish event to followers stream
 | ||||
| 					stream(follower._id, 'note', noteObj); | ||||
| 					stream(following.followerId, 'note', noteObj); | ||||
| 				} else { | ||||
| 					// フォロワーがリモートユーザーかつ投稿者がローカルユーザーなら投稿を配信
 | ||||
| 					if (isLocalUser(user)) { | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue