Skip to content

Commit

Permalink
[API] Implement users/relation
Browse files Browse the repository at this point in the history
  • Loading branch information
syuilo committed Oct 31, 2018
1 parent c15148b commit 6491779
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 49 deletions.
103 changes: 54 additions & 49 deletions src/models/user.ts
Expand Up @@ -155,6 +155,50 @@ export function isValidBirthday(birthday: string): boolean {
}
//#endregion

export async function getRelation(me: mongo.ObjectId, target: mongo.ObjectId) {

This comment has been minimized.

Copy link
@tateisu

tateisu Nov 1, 2018

今の実装はユーザごと、フラグごとにクエリを行っていますが、

  • フラグごとに1回ずつクエリ ( ユーザIDのリストを渡して {ユーザIDとフラグの値} のリストを得る)して
  • 後からリレーションのリストの形に変換する

とクエリ回数を減らせるのではないでしょうか。mongoDBだとどうなのか分かりませんが…

const [following1, following2, followReq1, followReq2, toBlocking, fromBlocked, mute] = await Promise.all([
Following.findOne({
followerId: me,
followeeId: target
}),
Following.findOne({
followerId: target,
followeeId: me
}),
FollowRequest.findOne({
followerId: me,
followeeId: target
}),
FollowRequest.findOne({
followerId: target,
followeeId: me
}),
Blocking.findOne({
blockerId: me,
blockeeId: target
}),
Blocking.findOne({

This comment has been minimized.

Copy link
@tateisu

tateisu Nov 1, 2018

「相手が自分をブロックしている」状態表示は必要なのでしょうか?
もし不要とおもわれるならこの情報を減らした方がクエリ負荷を下げられると思います

blockerId: target,
blockeeId: me
}),
Mute.findOne({
muterId: me,
muteeId: target
})
]);

return {
isFollowing: following1 !== null,
isStalking: following1 && following1.stalk,
hasPendingFollowRequestFromYou: followReq1 !== null,
hasPendingFollowRequestToYou: followReq2 !== null,
isFollowed: following2 !== null,
isBlocking: toBlocking !== null,
isBlocked: fromBlocked !== null,
isMuted: mute !== null
};
}

/**
* Pack a user for API response
*
Expand Down Expand Up @@ -271,55 +315,16 @@ export const pack = (
}

if (meId && !meId.equals(_user.id) && opts.detail) {
const [following1, following2, followReq1, followReq2, toBlocking, fromBlocked, mute] = await Promise.all([
Following.findOne({
followerId: meId,
followeeId: _user.id
}),
Following.findOne({
followerId: _user.id,
followeeId: meId
}),
FollowRequest.findOne({
followerId: meId,
followeeId: _user.id
}),
FollowRequest.findOne({
followerId: _user.id,
followeeId: meId
}),
Blocking.findOne({
blockerId: meId,
blockeeId: _user.id
}),
Blocking.findOne({
blockerId: _user.id,
blockeeId: meId
}),
Mute.findOne({
muterId: meId,
muteeId: _user.id
})
]);

// Whether the user is following
_user.isFollowing = following1 !== null;
_user.isStalking = following1 && following1.stalk;

_user.hasPendingFollowRequestFromYou = followReq1 !== null;
_user.hasPendingFollowRequestToYou = followReq2 !== null;

// Whether the user is followed
_user.isFollowed = following2 !== null;

// Whether the user is blocking
_user.isBlocking = toBlocking !== null;

// Whether the user is blocked
_user.isBlocked = fromBlocked !== null;

// Whether the user is muted
_user.isMuted = mute !== null;
const relation = await getRelation(meId, _user.id);

_user.isFollowing = relation.isFollowing;
_user.isFollowed = relation.isFollowed;
_user.isStalking = relation.isStalking;
_user.hasPendingFollowRequestFromYou = relation.hasPendingFollowRequestFromYou;
_user.hasPendingFollowRequestToYou = relation.hasPendingFollowRequestToYou;
_user.isBlocking = relation.isBlocking;
_user.isBlocked = relation.isBlocked;
_user.isMuted = relation.isMuted;
}

if (opts.detail) {
Expand Down
28 changes: 28 additions & 0 deletions src/server/api/endpoints/users/relation.ts
@@ -0,0 +1,28 @@
import $ from 'cafy'; import ID from '../../../../misc/cafy-id';
import { ILocalUser, getRelation } from '../../../../models/user';
import getParams from '../../get-params';

export const meta = {
desc: {
'ja-JP': 'ユーザー間のリレーションを取得します。'
},

params: {
userId: $.or($.type(ID), $.arr($.type(ID)).unique()).note({
desc: {
'ja-JP': 'ユーザーID (配列でも可)'
}
})
}
};

export default (params: any, me: ILocalUser) => new Promise(async (res, rej) => {
const [ps, psErr] = getParams(meta, params);
if (psErr) return rej(psErr);

const ids = Array.isArray(ps.userId) ? ps.userId : [ps.userId];

const relations = await Promise.all(ids.map(id => getRelation(me._id, id)));

res(Array.isArray(ps.userId) ? relations : relations[0]);
});

0 comments on commit 6491779

Please sign in to comment.