From 26b40d8886ccf87eed5cce2868b14994c29752b9 Mon Sep 17 00:00:00 2001
From: syuilo <syuilotan@yahoo.co.jp>
Date: Fri, 22 Dec 2017 06:38:48 +0900
Subject: [PATCH] wip

---
 src/api/endpoints/posts/search.ts | 89 +++++++++++++++++++++++++++++--
 src/web/docs/search.ja.pug        | 16 ++++++
 2 files changed, 102 insertions(+), 3 deletions(-)

diff --git a/src/api/endpoints/posts/search.ts b/src/api/endpoints/posts/search.ts
index ac25652a0b..f722231d4c 100644
--- a/src/api/endpoints/posts/search.ts
+++ b/src/api/endpoints/posts/search.ts
@@ -6,6 +6,7 @@ import $ from 'cafy';
 const escapeRegexp = require('escape-regexp');
 import Post from '../../models/post';
 import User from '../../models/user';
+import Mute from '../../models/mute';
 import getFriends from '../../common/get-friends';
 import serialize from '../../serializers/post';
 import config from '../../../conf';
@@ -34,6 +35,10 @@ module.exports = (params, me) => new Promise(async (res, rej) => {
 	const [following = null, followingErr] = $(params.following).optional.nullable.boolean().$;
 	if (followingErr) return rej('invalid following param');
 
+	// Get 'mute' parameter
+	const [mute = 'mute_all', muteErr] = $(params.mute).optional.string().$;
+	if (muteErr) return rej('invalid mute param');
+
 	// Get 'reply' parameter
 	const [reply = null, replyErr] = $(params.reply).optional.nullable.boolean().$;
 	if (replyErr) return rej('invalid reply param');
@@ -80,11 +85,11 @@ module.exports = (params, me) => new Promise(async (res, rej) => {
 	// If Elasticsearch is available, search by it
 	// If not, search by MongoDB
 	(config.elasticsearch.enable ? byElasticsearch : byNative)
-		(res, rej, me, text, user, following, reply, repost, media, poll, sinceDate, untilDate, offset, limit);
+		(res, rej, me, text, user, following, mute, reply, repost, media, poll, sinceDate, untilDate, offset, limit);
 });
 
 // Search by MongoDB
-async function byNative(res, rej, me, text, userId, following, reply, repost, media, poll, sinceDate, untilDate, offset, max) {
+async function byNative(res, rej, me, text, userId, following, mute, reply, repost, media, poll, sinceDate, untilDate, offset, max) {
 	let q: any = {
 		$and: []
 	};
@@ -116,6 +121,84 @@ async function byNative(res, rej, me, text, userId, following, reply, repost, me
 		});
 	}
 
+	if (me != null) {
+		const mutes = await Mute.find({
+			muter_id: me._id,
+			deleted_at: { $exists: false }
+		});
+		const mutedUserIds = mutes.map(m => m.mutee_id);
+
+		switch (mute) {
+			case 'mute_all':
+				push({
+					user_id: {
+						$nin: mutedUserIds
+					},
+					'_reply.user_id': {
+						$nin: mutedUserIds
+					},
+					'_repost.user_id': {
+						$nin: mutedUserIds
+					}
+				});
+				break;
+			case 'mute_related':
+				push({
+					'_reply.user_id': {
+						$nin: mutedUserIds
+					},
+					'_repost.user_id': {
+						$nin: mutedUserIds
+					}
+				});
+				break;
+			case 'mute_direct':
+				push({
+					user_id: {
+						$nin: mutedUserIds
+					}
+				});
+				break;
+			case 'direct_only':
+				push({
+					user_id: {
+						$in: mutedUserIds
+					}
+				});
+				break;
+			case 'related_only':
+				push({
+					$or: [{
+						'_reply.user_id': {
+							$in: mutedUserIds
+						}
+					}, {
+						'_repost.user_id': {
+							$in: mutedUserIds
+						}
+					}]
+				});
+				break;
+			case 'all_only':
+				push({
+					$or: [{
+						user_id: {
+							$in: mutedUserIds
+						}
+					}, {
+						'_reply.user_id': {
+							$in: mutedUserIds
+						}
+					}, {
+						'_repost.user_id': {
+							$in: mutedUserIds
+						}
+					}]
+				});
+				break;
+		}
+	}
+
 	if (reply != null) {
 		if (reply) {
 			push({
@@ -236,7 +319,7 @@ async function byNative(res, rej, me, text, userId, following, reply, repost, me
 }
 
 // Search by Elasticsearch
-async function byElasticsearch(res, rej, me, text, userId, following, reply, repost, media, poll, sinceDate, untilDate, offset, max) {
+async function byElasticsearch(res, rej, me, text, userId, following, mute, reply, repost, media, poll, sinceDate, untilDate, offset, max) {
 	const es = require('../../db/elasticsearch');
 
 	es.search({
diff --git a/src/web/docs/search.ja.pug b/src/web/docs/search.ja.pug
index 41e443d746..552f95c60f 100644
--- a/src/web/docs/search.ja.pug
+++ b/src/web/docs/search.ja.pug
@@ -29,6 +29,22 @@ section
 					| false ... フォローしていないユーザーに限定。
 					br
 					| null ... 特に限定しない(デフォルト)
+			tr
+				td mute
+				td
+					| mute_all ... ミュートしているユーザーの投稿とその投稿に対する返信やRepostを除外する(デフォルト)
+					br
+					| mute_related ... ミュートしているユーザーの投稿に対する返信やRepostだけ除外する
+					br
+					| mute_direct ... ミュートしているユーザーの投稿だけ除外する
+					br
+					| disabled ... ミュートしているユーザーの投稿とその投稿に対する返信やRepostも含める
+					br
+					| direct_only ... ミュートしているユーザーの投稿だけに限定
+					br
+					| related_only ... ミュートしているユーザーの投稿に対する返信やRepostだけに限定
+					br
+					| all_only ... ミュートしているユーザーの投稿とその投稿に対する返信やRepostに限定
 			tr
 				td reply
 				td