wip
This commit is contained in:
		| @@ -222,6 +222,23 @@ const endpoints: Endpoint[] = [ | |||||||
| 		withCredential: true, | 		withCredential: true, | ||||||
| 		kind: 'notification-read' | 		kind: 'notification-read' | ||||||
| 	}, | 	}, | ||||||
|  |  | ||||||
|  | 	{ | ||||||
|  | 		name: 'mute/create', | ||||||
|  | 		withCredential: true, | ||||||
|  | 		kind: 'account/write' | ||||||
|  | 	}, | ||||||
|  | 	{ | ||||||
|  | 		name: 'mute/delete', | ||||||
|  | 		withCredential: true, | ||||||
|  | 		kind: 'account/write' | ||||||
|  | 	}, | ||||||
|  | 	{ | ||||||
|  | 		name: 'mute/list', | ||||||
|  | 		withCredential: true, | ||||||
|  | 		kind: 'account/read' | ||||||
|  | 	}, | ||||||
|  |  | ||||||
| 	{ | 	{ | ||||||
| 		name: 'notifications/get_unread_count', | 		name: 'notifications/get_unread_count', | ||||||
| 		withCredential: true, | 		withCredential: true, | ||||||
|   | |||||||
							
								
								
									
										61
									
								
								src/api/endpoints/mute/create.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								src/api/endpoints/mute/create.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,61 @@ | |||||||
|  | /** | ||||||
|  |  * Module dependencies | ||||||
|  |  */ | ||||||
|  | import $ from 'cafy'; | ||||||
|  | import User from '../../models/user'; | ||||||
|  | import Mute from '../../models/mute'; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Mute a user | ||||||
|  |  * | ||||||
|  |  * @param {any} params | ||||||
|  |  * @param {any} user | ||||||
|  |  * @return {Promise<any>} | ||||||
|  |  */ | ||||||
|  | module.exports = (params, user) => new Promise(async (res, rej) => { | ||||||
|  | 	const muter = user; | ||||||
|  |  | ||||||
|  | 	// Get 'user_id' parameter | ||||||
|  | 	const [userId, userIdErr] = $(params.user_id).id().$; | ||||||
|  | 	if (userIdErr) return rej('invalid user_id param'); | ||||||
|  |  | ||||||
|  | 	// 自分自身 | ||||||
|  | 	if (user._id.equals(userId)) { | ||||||
|  | 		return rej('mutee is yourself'); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Get mutee | ||||||
|  | 	const mutee = await User.findOne({ | ||||||
|  | 		_id: userId | ||||||
|  | 	}, { | ||||||
|  | 		fields: { | ||||||
|  | 			data: false, | ||||||
|  | 			profile: false | ||||||
|  | 		} | ||||||
|  | 	}); | ||||||
|  |  | ||||||
|  | 	if (mutee === null) { | ||||||
|  | 		return rej('user not found'); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Check if already muting | ||||||
|  | 	const exist = await Mute.findOne({ | ||||||
|  | 		muter_id: muter._id, | ||||||
|  | 		mutee_id: mutee._id, | ||||||
|  | 		deleted_at: { $exists: false } | ||||||
|  | 	}); | ||||||
|  |  | ||||||
|  | 	if (exist !== null) { | ||||||
|  | 		return rej('already muting'); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Create mute | ||||||
|  | 	await Mute.insert({ | ||||||
|  | 		created_at: new Date(), | ||||||
|  | 		muter_id: muter._id, | ||||||
|  | 		mutee_id: mutee._id, | ||||||
|  | 	}); | ||||||
|  |  | ||||||
|  | 	// Send response | ||||||
|  | 	res(); | ||||||
|  | }); | ||||||
							
								
								
									
										63
									
								
								src/api/endpoints/mute/delete.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								src/api/endpoints/mute/delete.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,63 @@ | |||||||
|  | /** | ||||||
|  |  * Module dependencies | ||||||
|  |  */ | ||||||
|  | import $ from 'cafy'; | ||||||
|  | import User from '../../models/user'; | ||||||
|  | import Mute from '../../models/mute'; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Unmute a user | ||||||
|  |  * | ||||||
|  |  * @param {any} params | ||||||
|  |  * @param {any} user | ||||||
|  |  * @return {Promise<any>} | ||||||
|  |  */ | ||||||
|  | module.exports = (params, user) => new Promise(async (res, rej) => { | ||||||
|  | 	const muter = user; | ||||||
|  |  | ||||||
|  | 	// Get 'user_id' parameter | ||||||
|  | 	const [userId, userIdErr] = $(params.user_id).id().$; | ||||||
|  | 	if (userIdErr) return rej('invalid user_id param'); | ||||||
|  |  | ||||||
|  | 	// Check if the mutee is yourself | ||||||
|  | 	if (user._id.equals(userId)) { | ||||||
|  | 		return rej('mutee is yourself'); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Get mutee | ||||||
|  | 	const mutee = await User.findOne({ | ||||||
|  | 		_id: userId | ||||||
|  | 	}, { | ||||||
|  | 		fields: { | ||||||
|  | 			data: false, | ||||||
|  | 			profile: false | ||||||
|  | 		} | ||||||
|  | 	}); | ||||||
|  |  | ||||||
|  | 	if (mutee === null) { | ||||||
|  | 		return rej('user not found'); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Check not muting | ||||||
|  | 	const exist = await Mute.findOne({ | ||||||
|  | 		muter_id: muter._id, | ||||||
|  | 		mutee_id: mutee._id, | ||||||
|  | 		deleted_at: { $exists: false } | ||||||
|  | 	}); | ||||||
|  |  | ||||||
|  | 	if (exist === null) { | ||||||
|  | 		return rej('already not muting'); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Delete mute | ||||||
|  | 	await Mute.update({ | ||||||
|  | 		_id: exist._id | ||||||
|  | 	}, { | ||||||
|  | 		$set: { | ||||||
|  | 			deleted_at: new Date() | ||||||
|  | 		} | ||||||
|  | 	}); | ||||||
|  |  | ||||||
|  | 	// Send response | ||||||
|  | 	res(); | ||||||
|  | }); | ||||||
							
								
								
									
										73
									
								
								src/api/endpoints/mute/list.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								src/api/endpoints/mute/list.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,73 @@ | |||||||
|  | /** | ||||||
|  |  * Module dependencies | ||||||
|  |  */ | ||||||
|  | import $ from 'cafy'; | ||||||
|  | import Mute from '../../models/mute'; | ||||||
|  | import serialize from '../../serializers/user'; | ||||||
|  | import getFriends from '../../common/get-friends'; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Get muted users of a user | ||||||
|  |  * | ||||||
|  |  * @param {any} params | ||||||
|  |  * @param {any} me | ||||||
|  |  * @return {Promise<any>} | ||||||
|  |  */ | ||||||
|  | module.exports = (params, me) => new Promise(async (res, rej) => { | ||||||
|  | 	// Get 'iknow' parameter | ||||||
|  | 	const [iknow = false, iknowErr] = $(params.iknow).optional.boolean().$; | ||||||
|  | 	if (iknowErr) return rej('invalid iknow param'); | ||||||
|  |  | ||||||
|  | 	// Get 'limit' parameter | ||||||
|  | 	const [limit = 30, limitErr] = $(params.limit).optional.number().range(1, 100).$; | ||||||
|  | 	if (limitErr) return rej('invalid limit param'); | ||||||
|  |  | ||||||
|  | 	// Get 'cursor' parameter | ||||||
|  | 	const [cursor = null, cursorErr] = $(params.cursor).optional.id().$; | ||||||
|  | 	if (cursorErr) return rej('invalid cursor param'); | ||||||
|  |  | ||||||
|  | 	// Construct query | ||||||
|  | 	const query = { | ||||||
|  | 		muter_id: me._id, | ||||||
|  | 		deleted_at: { $exists: false } | ||||||
|  | 	} as any; | ||||||
|  |  | ||||||
|  | 	if (iknow) { | ||||||
|  | 		// Get my friends | ||||||
|  | 		const myFriends = await getFriends(me._id); | ||||||
|  |  | ||||||
|  | 		query.mutee_id = { | ||||||
|  | 			$in: myFriends | ||||||
|  | 		}; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// カーソルが指定されている場合 | ||||||
|  | 	if (cursor) { | ||||||
|  | 		query._id = { | ||||||
|  | 			$lt: cursor | ||||||
|  | 		}; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Get mutes | ||||||
|  | 	const mutes = await Mute | ||||||
|  | 		.find(query, { | ||||||
|  | 			limit: limit + 1, | ||||||
|  | 			sort: { _id: -1 } | ||||||
|  | 		}); | ||||||
|  |  | ||||||
|  | 	// 「次のページ」があるかどうか | ||||||
|  | 	const inStock = mutes.length === limit + 1; | ||||||
|  | 	if (inStock) { | ||||||
|  | 		mutes.pop(); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Serialize | ||||||
|  | 	const users = await Promise.all(mutes.map(async m => | ||||||
|  | 		await serialize(m.mutee_id, me, { detail: true }))); | ||||||
|  |  | ||||||
|  | 	// Response | ||||||
|  | 	res({ | ||||||
|  | 		users: users, | ||||||
|  | 		next: inStock ? mutes[mutes.length - 1]._id : null, | ||||||
|  | 	}); | ||||||
|  | }); | ||||||
| @@ -4,6 +4,7 @@ | |||||||
| import $ from 'cafy'; | import $ from 'cafy'; | ||||||
| import rap from '@prezzemolo/rap'; | import rap from '@prezzemolo/rap'; | ||||||
| import Post from '../../models/post'; | import Post from '../../models/post'; | ||||||
|  | import Mute from '../../models/mute'; | ||||||
| import ChannelWatching from '../../models/channel-watching'; | import ChannelWatching from '../../models/channel-watching'; | ||||||
| import getFriends from '../../common/get-friends'; | import getFriends from '../../common/get-friends'; | ||||||
| import serialize from '../../serializers/post'; | import serialize from '../../serializers/post'; | ||||||
| @@ -42,15 +43,23 @@ module.exports = async (params, user, app) => { | |||||||
| 		throw 'only one of since_id, until_id, since_date, until_date can be specified'; | 		throw 'only one of since_id, until_id, since_date, until_date can be specified'; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	const { followingIds, watchingChannelIds } = await rap({ | 	const { followingIds, watchingChannelIds, mutedUserIds } = await rap({ | ||||||
| 		// ID list of the user itself and other users who the user follows | 		// ID list of the user itself and other users who the user follows | ||||||
| 		followingIds: getFriends(user._id), | 		followingIds: getFriends(user._id), | ||||||
|  |  | ||||||
| 		// Watchしているチャンネルを取得 | 		// Watchしているチャンネルを取得 | ||||||
| 		watchingChannelIds: ChannelWatching.find({ | 		watchingChannelIds: ChannelWatching.find({ | ||||||
| 			user_id: user._id, | 			user_id: user._id, | ||||||
| 			// 削除されたドキュメントは除く | 			// 削除されたドキュメントは除く | ||||||
| 			deleted_at: { $exists: false } | 			deleted_at: { $exists: false } | ||||||
| 		}).then(watches => watches.map(w => w.channel_id)) | 		}).then(watches => watches.map(w => w.channel_id)), | ||||||
|  |  | ||||||
|  | 		// ミュートしているユーザーを取得 | ||||||
|  | 		mutedUserIds: Mute.find({ | ||||||
|  | 			muter_id: user._id, | ||||||
|  | 			// 削除されたドキュメントは除く | ||||||
|  | 			deleted_at: { $exists: false } | ||||||
|  | 		}).then(ms => ms.map(m => m.mutee_id)) | ||||||
| 	}); | 	}); | ||||||
|  |  | ||||||
| 	//#region Construct query | 	//#region Construct query | ||||||
| @@ -80,13 +89,13 @@ module.exports = async (params, user, app) => { | |||||||
| 		}], | 		}], | ||||||
| 		// mute | 		// mute | ||||||
| 		user_id: { | 		user_id: { | ||||||
| 			$nin: mutes | 			$nin: mutedUserIds | ||||||
| 		}, | 		}, | ||||||
| 		'_reply.user_id': { | 		'_reply.user_id': { | ||||||
| 			$nin: mutes | 			$nin: mutedUserIds | ||||||
| 		}, | 		}, | ||||||
| 		'_repost.user_id': { | 		'_repost.user_id': { | ||||||
| 			$nin: mutes | 			$nin: mutedUserIds | ||||||
| 		}, | 		}, | ||||||
| 	} as any; | 	} as any; | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 syuilo
					syuilo