@ -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,41 +37,66 @@ 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: [{
|
||||
// フォローしている人のタイムラインへの投稿
|
||||
userId: {
|
||||
$in: followingIds
|
||||
},
|
||||
// 「タイムラインへの」投稿に限定するためにチャンネルが指定されていないもののみに限る
|
||||
$or: [{
|
||||
channelId: {
|
||||
$exists: false
|
||||
}
|
||||
$and: [{
|
||||
// フォローしている人のタイムラインへの投稿
|
||||
$or: followQuery
|
||||
}, {
|
||||
channelId: null
|
||||
// 「タイムラインへの」投稿に限定するためにチャンネルが指定されていないもののみに限る
|
||||
$or: [{
|
||||
channelId: {
|
||||
$exists: false
|
||||
}
|
||||
}, {
|
||||
channelId: null
|
||||
}]
|
||||
}]
|
||||
}, {
|
||||
// Watchしているチャンネルへの投稿
|
||||
|
@ -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({
|
||||
|
Reference in New Issue
Block a user