Skip to content

Commit

Permalink
Merge pull request #10 from aseerkt/feat/followers
Browse files Browse the repository at this point in the history
Feature Follow Backend Code
  • Loading branch information
aseerkt authored May 25, 2021
2 parents ee72de8 + 2453dcc commit f831679
Show file tree
Hide file tree
Showing 5 changed files with 125 additions and 52 deletions.
4 changes: 1 addition & 3 deletions client/src/routes/Explore.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,9 @@ import { Post, useGetExplorePostsQuery } from '../generated/graphql';

const Explore = () => {
const [observedPost, setObservedPost] = useState('');
const { data, loading, error, fetchMore, variables, networkStatus } =
const { data, loading, error, fetchMore, variables } =
useGetExplorePostsQuery({
variables: { limit: 12 },
notifyOnNetworkStatusChange: true,
});

useEffect(() => {
Expand Down Expand Up @@ -59,7 +58,6 @@ const Explore = () => {
{data?.getExplorePosts.posts && (
<PostsGrid posts={data.getExplorePosts.posts as Post[]} />
)}
{networkStatus === 7 && <Spinner />}
</Container>
);
};
Expand Down
9 changes: 3 additions & 6 deletions client/src/routes/Posts.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,9 @@ import { Link } from 'react-router-dom';

const Posts: React.FC = () => {
const [observedPost, setObservedPost] = React.useState('');
const { data, loading, error, fetchMore, variables, networkStatus } =
useGetPostsQuery({
variables: { limit: 4 },
notifyOnNetworkStatusChange: true,
});
const { data, loading, error, fetchMore, variables } = useGetPostsQuery({
variables: { limit: 4 },
});

React.useEffect(() => {
if (data) {
Expand Down Expand Up @@ -66,7 +64,6 @@ const Posts: React.FC = () => {
{data.getPosts.posts.map((post) => (
<PostCard key={post.id} post={post as Post} />
))}
{networkStatus === 7 && <Spinner />}
</div>
<div className='relative flex-1 hidden md:block md:ml-4'>
{data && data.getPosts.posts.length > 0 && <ProfileRight />}
Expand Down
3 changes: 1 addition & 2 deletions server/src/resolvers/CommentResolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,11 @@ export class CommentResolver {
@Ctx() { res }: MyContext
) {
try {
const comment = await Comment.create({
return await Comment.create({
postId,
text,
username: res.locals.username,
}).save();
return comment;
} catch (err) {
console.log(err);
return false;
Expand Down
107 changes: 82 additions & 25 deletions server/src/resolvers/FollowerResolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
ID,
Mutation,
Query,
registerEnumType,
Resolver,
UseMiddleware,
} from 'type-graphql';
Expand All @@ -13,8 +14,89 @@ import { User } from '../entities/User';
import { isAuth } from '../middlewares/isAuth';
import { MyContext } from '../types';

enum FollowEnum {
Followers,
Followings,
}

registerEnumType(FollowEnum, { name: 'FollowEnum' });

@Resolver()
export class FollowerResolver {
// QUERIES

@Query(() => [User])
@UseMiddleware(isAuth)
async getFollowSuggestions(@Ctx() { res }: MyContext): Promise<User[]> {
const suggestions = await getConnection().query(
`
SELECT
"u"."id",
"u"."username",
"u"."email",
"u"."createdAt",
"u"."updatedAt"
FROM "users" "u"
LEFT JOIN "follows" "f"
ON "f"."followingUsername" = "u"."username"
WHERE ("f"."username" != $1 OR "f"."username" IS NULL) AND "u"."username" != $1
LIMIT 5;
`,
[res.locals.username]
);

// "f"."followingUsername" != "u"."username"

return suggestions;
}

@Query(() => [User])
@UseMiddleware(isAuth)
async getFollows(
@Arg('username') username: string,
@Arg('selector', () => FollowEnum) selector: FollowEnum
) {
if (selector === FollowEnum.Followers) {
const followers = await getConnection().query(
`
SELECT
"u"."id",
"u"."username",
"u"."email",
"u"."createdAt",
"u"."updatedAt"
FROM "users" "u"
LEFT JOIN "follows" "f"
ON "f"."username" = "u"."username"
WHERE "f"."followingUsername" = $1
LIMIT 10
`,
[username]
);
return followers;
} else {
const followings = await getConnection().query(
`
SELECT
"u"."id",
"u"."username",
"u"."email",
"u"."createdAt",
"u"."updatedAt"
FROM "users" "u"
LEFT JOIN "follows" "f"
ON "f"."followingUsername" = "u"."username"
WHERE "f"."username" = $1
LIMIT 10
`,
[username]
);
return followings;
}
}

// MUTATIONS

@Mutation(() => Boolean)
@UseMiddleware(isAuth)
async toggleFollow(
Expand All @@ -39,29 +121,4 @@ export class FollowerResolver {
return false;
}
}

@Query(() => [User])
@UseMiddleware(isAuth)
async getFollowSuggestions(@Ctx() { res }: MyContext): Promise<User[]> {
const suggestions = await getConnection().query(
`
SELECT
"u"."id",
"u"."username",
"u"."email",
"u"."createdAt",
"u"."updatedAt"
FROM "users" "u"
LEFT JOIN "follows" "f"
ON "f"."followingUsername" = "u"."username"
WHERE "u"."username" != $1
LIMIT 5
`,
[res.locals.username]
);

// "f"."followingUsername" != "u"."username"

return suggestions;
}
}
54 changes: 38 additions & 16 deletions server/src/resolvers/PostResolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
Root,
UseMiddleware,
} from 'type-graphql';
import { getConnection } from 'typeorm';
import { CLOUDINARY_ROOT_PATH, __prod__ } from '../constants';
import { Comment } from '../entities/Comment';
import { Like } from '../entities/Like';
Expand Down Expand Up @@ -85,36 +86,55 @@ export class PostResolver {
@Query(() => PaginatedPost)
@UseMiddleware(isAuth)
async getPosts(
@Ctx() { res }: MyContext,
@Arg('limit', () => Int) limit: number,
@Arg('offset', () => Int, { nullable: true }) offset?: number
): Promise<PaginatedPost> {
const params = [res.locals.username, limit + 1];
if (offset) params.push(offset);
// Get posts from followed peoples only
const posts: Post[] = await getConnection().query(
`
SELECT
"p"."id",
"p"."createdAt",
"p"."updatedAt",
"p"."caption",
"p"."imgURL",
"p"."username"
FROM "posts" "p"
LEFT JOIN "follows" "f"
ON "f"."followingUsername" = "p"."username"
WHERE "f"."username" = $1
ORDER BY "p"."createdAt" DESC
LIMIT $2 ${offset ? 'OFFSET $3' : ''};
`,
params
);
return {
posts: posts.slice(0, limit),
hasMore: posts.length === limit + 1,
};
}

@Query(() => PaginatedPost)
@UseMiddleware(isAuth)
async getExplorePosts(
@Arg('limit', () => Int) limit: number,
@Arg('offset', () => Int, { nullable: true }) offset?: number
): Promise<PaginatedPost> {
// TODO: Pagination
const posts = await Post.find({
order: { createdAt: 'DESC' },
skip: offset ? offset : 0,
take: limit + 1,
});

return {
posts: posts.slice(0, limit),
hasMore: posts.length === limit + 1,
};
}

// @Query(() => [Post])
// @UseMiddleware(isAuth)
// async getFeedPosts(@Ctx() { res }: MyContext) {
// const followings = await Follow.find({
// where: { username: res.locals.username },
// select: ['following'],
// relations: ['following.posts'],
// });
// const feedPosts: Post[] = [];
// followings.forEach((f) => {
// feedPosts.push(...f.following.posts);
// });
// return feedPosts;
// }

@Query(() => Post, { nullable: true })
@UseMiddleware(isAuth)
getSinglePost(@Arg('postId') postId: string) {
Expand Down Expand Up @@ -196,3 +216,5 @@ export class PostResolver {
* curl 'http://localhost:5000/graphql' -H 'Accept-Encoding: gzip, deflate, br' -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'Connection: keep-alive' -H 'DNT: 1' -H 'Origin: http://localhost:5000' --data-binary '{"query":"mutation AddPost($file: Upload!){\n addPost(file)\n}"}' --compressed
*
*/

// SELECT "p"."id", "p"."createdAt", "p"."updatedAt", "p"."caption", "p"."imgURL", "p"."username" FROM "posts" "p" LEFT JOIN "follows" "f" ON "f"."followingUsername" = "p"."username" WHERE "f"."username" = 'bob' ORDER BY "p"."createdAt" DESC LIMIT 6 OFFSET 10;

1 comment on commit f831679

@vercel
Copy link

@vercel vercel bot commented on f831679 May 25, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.