feat: add ability to follow and unfollow a user on their profile page
This commit is contained in:
Vendored
+2
@@ -14,6 +14,7 @@ import type {
|
||||
FilterApi,
|
||||
FunctionReference,
|
||||
} from "convex/server";
|
||||
import type * as follows from "../follows";
|
||||
import type * as http from "../http";
|
||||
import type * as likes from "../likes";
|
||||
import type * as posts from "../posts";
|
||||
@@ -28,6 +29,7 @@ import type * as users from "../users";
|
||||
* ```
|
||||
*/
|
||||
declare const fullApi: ApiFromModules<{
|
||||
follows: typeof follows;
|
||||
http: typeof http;
|
||||
likes: typeof likes;
|
||||
posts: typeof posts;
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
import { v } from 'convex/values';
|
||||
import { mutation, query } from './_generated/server';
|
||||
import { userQuery } from './users';
|
||||
|
||||
export const addFollow = mutation({
|
||||
args: { followingId: v.id('users') },
|
||||
handler: async (ctx, args) => {
|
||||
const clerkUser = await ctx.auth.getUserIdentity();
|
||||
|
||||
if (clerkUser === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
const user = await userQuery(ctx, clerkUser.subject);
|
||||
|
||||
if (user === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
const existingFollow = await ctx.db
|
||||
.query('follows')
|
||||
.withIndex('by_following_follower_id', q =>
|
||||
q.eq('following', args.followingId).eq('follower', user._id)
|
||||
)
|
||||
.unique();
|
||||
|
||||
if (existingFollow !== null) {
|
||||
return;
|
||||
}
|
||||
|
||||
await ctx.db.insert('follows', {
|
||||
following: args.followingId,
|
||||
follower: user._id,
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
export const removeFollow = mutation({
|
||||
args: { followingId: v.id('users') },
|
||||
handler: async (ctx, args) => {
|
||||
const clerkUser = await ctx.auth.getUserIdentity();
|
||||
|
||||
if (clerkUser === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
const user = await userQuery(ctx, clerkUser.subject);
|
||||
|
||||
if (user === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
const existingFollow = await ctx.db
|
||||
.query('follows')
|
||||
.withIndex('by_following_follower_id', q =>
|
||||
q.eq('following', args.followingId).eq('follower', user._id)
|
||||
)
|
||||
.unique();
|
||||
|
||||
if (existingFollow === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
await ctx.db.delete(existingFollow._id);
|
||||
},
|
||||
});
|
||||
|
||||
export const getUserFollowerCount = query({
|
||||
args: { userId: v.id('users') },
|
||||
handler: async (ctx, args) => {
|
||||
const followers = await ctx.db
|
||||
.query('follows')
|
||||
.withIndex('by_following', q => q.eq('following', args.userId))
|
||||
.collect();
|
||||
|
||||
return followers.length;
|
||||
},
|
||||
});
|
||||
|
||||
export const getUserFollowingCount = query({
|
||||
args: { userId: v.id('users') },
|
||||
handler: async (ctx, args) => {
|
||||
const followings = await ctx.db
|
||||
.query('follows')
|
||||
.withIndex('by_follower', q => q.eq('follower', args.userId))
|
||||
.collect();
|
||||
|
||||
return followings.length;
|
||||
},
|
||||
});
|
||||
|
||||
export const getFollowing = query({
|
||||
args: { followingId: v.id('users') },
|
||||
handler: async (ctx, args) => {
|
||||
const currentClerkUser = await ctx.auth.getUserIdentity();
|
||||
|
||||
if (currentClerkUser == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const user = await userQuery(ctx, currentClerkUser.subject);
|
||||
|
||||
if (user == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const following = await ctx.db
|
||||
.query('follows')
|
||||
.withIndex('by_following_follower_id', q =>
|
||||
q.eq('following', args.followingId).eq('follower', user._id)
|
||||
)
|
||||
.unique();
|
||||
|
||||
return following !== null;
|
||||
},
|
||||
});
|
||||
@@ -147,3 +147,15 @@ export const getPostReplyCount = query({
|
||||
return replies.length;
|
||||
},
|
||||
});
|
||||
|
||||
export const getUserPostCount = query({
|
||||
args: { userId: v.id('users') },
|
||||
handler: async (ctx, args) => {
|
||||
const posts = await ctx.db
|
||||
.query('posts')
|
||||
.withIndex('by_user_id', q => q.eq('userId', args.userId))
|
||||
.collect();
|
||||
|
||||
return posts.length;
|
||||
},
|
||||
});
|
||||
|
||||
+2
-1
@@ -53,7 +53,8 @@ export default defineSchema(
|
||||
follower: v.id('users'), // person following
|
||||
})
|
||||
.index('by_following', ['following'])
|
||||
.index('by_follower', ['follower']),
|
||||
.index('by_follower', ['follower'])
|
||||
.index('by_following_follower_id', ['following', 'follower']),
|
||||
},
|
||||
{ schemaValidation: false }
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user