Skip to content

Commit d526d10

Browse files
authored
Merge pull request velopert#154 from velopert/feature/follow
Feature/follow
2 parents 278b468 + cc0a6e8 commit d526d10

File tree

6 files changed

+51
-67
lines changed

6 files changed

+51
-67
lines changed

src/cache.ts

+14-14
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,5 @@
11
import Redis from 'ioredis';
22

3-
type GenerateCacheKey = {
4-
recommendedPostKey: (postId: string) => string;
5-
postCacheKey: (username: string, postUrlSlug: string) => string;
6-
userCacheKey: (username: string) => string;
7-
postSeriesKey: (username: string, seriesUrlSlug: string) => string;
8-
changeEmailKey: (code: string) => string;
9-
};
10-
11-
type QueueName = 'feed';
12-
133
class Cache {
144
client: Redis.Redis | null = null;
155

@@ -46,15 +36,25 @@ class Cache {
4636
changeEmailKey: (code: string) => `changeEmailCode:${code}`,
4737
};
4838
}
49-
getQueueName(name: QueueName): string {
50-
const mapper = {
51-
feed: 'feedQueue',
39+
40+
get queueName() {
41+
return {
42+
feed: 'queue:feed',
5243
};
53-
return mapper[name];
5444
}
5545
}
5646

5747
const cache = new Cache();
5848
cache.connect();
5949

6050
export default cache;
51+
52+
type GenerateCacheKey = {
53+
recommendedPostKey: (postId: string) => string;
54+
postCacheKey: (username: string, postUrlSlug: string) => string;
55+
userCacheKey: (username: string) => string;
56+
postSeriesKey: (username: string, seriesUrlSlug: string) => string;
57+
changeEmailKey: (code: string) => string;
58+
};
59+
60+
type QueueName = 'feed';

src/graphql/post.ts

+5-22
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,7 @@
11
import { ApolloContext } from './../app';
22
import { gql, IResolvers, ApolloError, AuthenticationError } from 'apollo-server-koa';
33
import Post from '../entity/Post';
4-
import {
5-
getRepository,
6-
getManager,
7-
LessThan,
8-
Not,
9-
MoreThan,
10-
UsingJoinColumnIsNotAllowedError,
11-
} from 'typeorm';
12-
import PostScore from '../entity/PostScore';
4+
import { getRepository, getManager, LessThan, Not, MoreThan } from 'typeorm';
135
import { normalize, escapeForUrl, checkEmpty } from '../lib/utils';
146
import removeMd from 'remove-markdown';
157
import PostsTags from '../entity/PostsTags';
@@ -35,15 +27,11 @@ import { createLikeLog, createReadLog } from '../lib/bigQuery';
3527
import esClient from '../search/esClient';
3628
import { buildFallbackRecommendedPosts, buildRecommendedPostsQuery } from '../search/buildQuery';
3729
import { pickRandomItems } from '../etc/pickRandomItems';
38-
import { shuffleArray } from '../etc/shuffleArray';
39-
import checkUnscore from '../etc/checkUnscore';
4030
import geoipCountry from 'geoip-country';
4131
import { purgeRecentPosts, purgeUser, purgePost } from '../lib/graphcdn';
4232
import imageService from '../services/imageService';
43-
import { sendSlackMessage } from '../lib/sendSlackMessage';
4433
import externalInterationService from '../services/externalIntegrationService';
4534
import postService from '../services/postService';
46-
import userFollowService from '../services/userFollowService';
4735
import { checkBlockList } from '../lib/checkBlockList';
4836

4937
const lruCache = new LRU<string, string[]>({
@@ -100,7 +88,6 @@ export const typeDef = gql`
10088
linked_posts: LinkedPosts
10189
last_read_at: Date
10290
recommended_posts: [Post]
103-
followed: Boolean
10491
}
10592
type SearchResult {
10693
count: Int
@@ -392,10 +379,6 @@ export const resolvers: IResolvers<any, ApolloContext> = {
392379
next,
393380
};
394381
},
395-
followed: async (parent: Post, _, ctx) => {
396-
if (!ctx.user_id) return false;
397-
return await userFollowService.isFollowed(ctx.user_id, parent.fk_user_id);
398-
},
399382
},
400383
Query: {
401384
post: async (parent: any, { id, username, url_slug }: any, ctx: any) => {
@@ -903,12 +886,12 @@ export const resolvers: IResolvers<any, ApolloContext> = {
903886
});
904887
});
905888

906-
const queueName = cache.getQueueName('feed');
907-
const queueInfo = {
908-
fk_follower_id: ctx.user_id,
889+
const queueName = cache.queueName.feed;
890+
const queueData = {
891+
fk_following_id: ctx.user_id,
909892
fk_post_id: post.id,
910893
};
911-
cache.client!.lpush(queueName, JSON.stringify(queueInfo));
894+
cache.client!.lpush(queueName, JSON.stringify(queueData));
912895
}
913896

914897
purgeRecentPosts();

src/graphql/user.ts

+11-6
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ export const typeDef = gql`
2323
velog_config: VelogConfig
2424
series_list: [Series]
2525
user_meta: UserMeta
26+
is_followed: Boolean
2627
}
2728
type UserProfile {
2829
id: ID!
@@ -63,8 +64,8 @@ export const typeDef = gql`
6364
acceptIntegration: String!
6465
initiateChangeEmail(email: String!): Boolean
6566
confirmChangeEmail(code: String!): Boolean
66-
follow(follow_user_id: ID!): Boolean
67-
unfollow(follow_user_id: ID!): Boolean
67+
follow(following_user_id: ID!): Boolean
68+
unfollow(following_user_id: ID!): Boolean
6869
}
6970
`;
7071

@@ -117,6 +118,10 @@ export const resolvers: IResolvers<any, ApolloContext> = {
117118
const userMetaRepo = getRepository(UserMeta);
118119
return userMetaRepo.findOne({ fk_user_id: user_id });
119120
},
121+
is_followed: async (parent: User, _, ctx) => {
122+
if (!ctx.user_id) return false;
123+
return await userService.isFollowed(parent.id, ctx.user_id);
124+
},
120125
},
121126
Query: {
122127
user: async (parent: any, { id, username }: any) => {
@@ -295,13 +300,13 @@ export const resolvers: IResolvers<any, ApolloContext> = {
295300
if (!ctx.user_id) throw new AuthenticationError('Not Logged In');
296301
return await userService.confirmChangeEmail(ctx.user_id, args.code);
297302
},
298-
follow: async (_, args: { follow_user_id: string }, ctx) => {
303+
follow: async (_, args: { following_user_id: string }, ctx) => {
299304
if (!ctx.user_id) throw new AuthenticationError('Not Logged In');
300-
return await userService.followUser(args.follow_user_id, ctx.cookies);
305+
return await userService.follow(args.following_user_id, ctx.cookies);
301306
},
302-
unfollow: async (_, args: { follow_user_id: string }, ctx) => {
307+
unfollow: async (_, args: { following_user_id: string }, ctx) => {
303308
if (!ctx.user_id) throw new AuthenticationError('Not Logged In');
304-
return await userService.unfollowUser(args.follow_user_id, ctx.cookies);
309+
return await userService.unfollow(args.following_user_id, ctx.cookies);
305310
},
306311
},
307312
};

src/services/postService.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ const postService = {
193193
mutation LikePost {
194194
likePost(input: { postId: "${postId}"}) {
195195
id
196-
liked
196+
is_liked
197197
likes
198198
}
199199
}
@@ -227,7 +227,7 @@ const postService = {
227227
mutation UnLikePost {
228228
unlikePost(input: { postId: "${postId}"}) {
229229
id
230-
liked
230+
is_liked
231231
likes
232232
}
233233
}

src/services/userFollowService.ts

-18
This file was deleted.

src/services/userService.ts

+19-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import Joi from 'joi';
2-
import type { User, Prisma } from '@prisma/client';
2+
import type { User, Prisma, FollowUser } from '@prisma/client';
33
import db from '../lib/db';
44
import { validateArgs } from '../lib/utils';
55
import { ApolloError, AuthenticationError } from 'apollo-server-koa';
@@ -140,7 +140,7 @@ const userService = {
140140
cache.client?.del(key);
141141
return true;
142142
},
143-
async followUser(followUserId: string, cookies: Cookies) {
143+
async follow(followingUserId: string, cookies: Cookies) {
144144
try {
145145
const query = 'mutation Follow ($input: FollowInput!) {\n\tfollow(input: $input) \n}';
146146

@@ -156,7 +156,7 @@ const userService = {
156156
{
157157
operationName: 'Follow',
158158
query: query,
159-
variables: { input: { followUserId: followUserId } },
159+
variables: { input: { followingUserId: followingUserId } },
160160
},
161161
{
162162
headers: {
@@ -172,7 +172,7 @@ const userService = {
172172
return false;
173173
}
174174
},
175-
async unfollowUser(followUserId: string, cookies: Cookies) {
175+
async unfollow(followingUserId: string, cookies: Cookies) {
176176
try {
177177
const query = 'mutation Unfollow ($input: UnfollowInput!) {\n\tunfollow(input: $input) \n}';
178178

@@ -188,7 +188,7 @@ const userService = {
188188
{
189189
operationName: 'Unfollow',
190190
query: query,
191-
variables: { input: { followUserId: followUserId } },
191+
variables: { input: { followingUserId: followingUserId } },
192192
},
193193
{
194194
headers: {
@@ -204,6 +204,20 @@ const userService = {
204204
return false;
205205
}
206206
},
207+
async findFollowRelationship(
208+
followingUserId: string,
209+
signedUserId: string
210+
): Promise<FollowUser | null> {
211+
return await db.followUser.findFirst({
212+
where: {
213+
fk_following_user_id: followingUserId,
214+
fk_follower_user_id: signedUserId,
215+
},
216+
});
217+
},
218+
async isFollowed(followingUserId: string, signedUserId: string): Promise<boolean> {
219+
return !!(await this.findFollowRelationship(followingUserId, signedUserId));
220+
},
207221
};
208222

209223
export default userService;

0 commit comments

Comments
 (0)