64 lines
2.6 KiB
TypeScript
64 lines
2.6 KiB
TypeScript
import { Context } from "@/context";
|
|
import { buildUserProfile, UserProfile } from "./type";
|
|
import { db } from "@/storage/db";
|
|
import { RelationshipStatus } from "@prisma/client";
|
|
import { relationshipSet } from "./relationshipSet";
|
|
import { relationshipGet } from "./relationshipGet";
|
|
|
|
export async function friendAdd(ctx: Context, uid: string): Promise<UserProfile | null> {
|
|
// Prevent self-friendship
|
|
if (ctx.uid === uid) {
|
|
return null;
|
|
}
|
|
|
|
// Update relationship status
|
|
return await db.$transaction(async (tx) => {
|
|
|
|
// Read current user objects
|
|
const currentUser = await tx.account.findUnique({
|
|
where: { id: ctx.uid },
|
|
include: { githubUser: true }
|
|
});
|
|
const targetUser = await tx.account.findUnique({
|
|
where: { id: uid },
|
|
include: { githubUser: true }
|
|
});
|
|
if (!currentUser || !targetUser) {
|
|
return null;
|
|
}
|
|
|
|
// Read relationship status
|
|
const currentUserRelationship = await relationshipGet(tx, currentUser.id, targetUser.id);
|
|
const targetUserRelationship = await relationshipGet(tx, targetUser.id, currentUser.id);
|
|
|
|
// Handle cases
|
|
|
|
// Case 1: There's a pending request from the target user - accept it
|
|
if (targetUserRelationship === RelationshipStatus.requested) {
|
|
|
|
// Accept the friend request - update both to friends
|
|
await relationshipSet(tx, targetUser.id, currentUser.id, RelationshipStatus.friend);
|
|
await relationshipSet(tx, currentUser.id, targetUser.id, RelationshipStatus.friend);
|
|
|
|
// Return the target user profile
|
|
return buildUserProfile(targetUser, RelationshipStatus.friend);
|
|
}
|
|
|
|
// Case 2: If status is none or rejected, create a new request (since other side is not in requested state)
|
|
if (currentUserRelationship === RelationshipStatus.none
|
|
|| currentUserRelationship === RelationshipStatus.rejected) {
|
|
await relationshipSet(tx, currentUser.id, targetUser.id, RelationshipStatus.requested);
|
|
|
|
// If other side is in none state, set it to pending, ignore for other states
|
|
if (targetUserRelationship === RelationshipStatus.none) {
|
|
await relationshipSet(tx, targetUser.id, currentUser.id, RelationshipStatus.pending);
|
|
}
|
|
|
|
// Return the target user profile
|
|
return buildUserProfile(targetUser, RelationshipStatus.requested);
|
|
}
|
|
|
|
// Do not change anything and return the target user profile
|
|
return buildUserProfile(targetUser, currentUserRelationship);
|
|
});
|
|
} |