Files
yourpart3/backend/services/friendshipService.js
2024-12-04 19:08:26 +01:00

181 lines
6.8 KiB
JavaScript

import BaseService from './BaseService.js';
import Friendship from '../models/community/friendship.js';
import User from '../models/community/user.js';
import { Op } from 'sequelize';
import UserParam from '../models/community/user_param.js';
import UserParamType from '../models/type/user_param.js';
import UserParamValue from '../models/type/user_param_value.js';
import { notifyUser } from '../utils/socket.js';
class FriendshipService extends BaseService {
genders = {};
async endFriendship(hashedUserId, friendUserId) {
const user = await this.getUserByHashedId(hashedUserId);
const friend = await this.getUserByHashedId(friendUserId);
if (!user) throw new Error('User not found.');
const friendship = await Friendship.findOne({
where: {
[Op.or]: [
{ user1Id: user.id, user2Id: friend.id },
{ user1Id: friend.id, user2Id: user.id },
],
},
});
if (!friendship) throw new Error('Friendship not found.');
await friendship.destroy();
notifyUser(friend.hashedId, 'friendshipChanged', { userId: user.hashedId });
}
async acceptFriendship(hashedUserId, friendUserId) {
const user = await this.getUserByHashedId(hashedUserId);
const friend = await this.getUserByHashedId(friendUserId);
if (!user) throw new Error('User not found.');
const friendship = await Friendship.findOne({
where: { user1Id: friend.id, user2Id: user.id, accepted: false },
});
if (!friendship) throw new Error('Cannot accept this friendship.');
friendship.accepted = true;
await friendship.save();
notifyUser(friend.hashedId, 'friendshipChanged', { userId: user.hashedId });
}
async rejectFriendship(hashedUserId, friendUserId) {
const user = await this.getUserByHashedId(hashedUserId);
const friend = await this.getUserByHashedId(friendUserId);
if (!user) throw new Error('User not found.');
const friendship = await Friendship.findOne({
where: { user1Id: friend.id, user2Id: user.id, accepted: false },
});
if (!friendship) throw new Error('Cannot reject this friendship.');
friendship.denied = true;
await friendship.save();
notifyUser(friend.hashedId, 'friendshipChanged', { userId: user.hashedId });
}
async withdrawRequest(hashedUserId, friendUserId) {
const user = await this.getUserByHashedId(hashedUserId);
const friend = await this.getUserByHashedId(friendUserId);
if (!user) throw new Error('User not found.');
const friendship = await Friendship.findOne({
where: { user1Id: user.id, user2Id: friend.id, accepted: false },
});
if (!friendship) throw new Error('Cannot withdraw this request.');
await friendship.destroy();
notifyUser(friend.hashedId, 'friendshipChanged', { userId: user.hashedId });
}
async getFriendships(hashedUserId, acceptedOnly) {
const user = await this.getUserByHashedId(hashedUserId);
if (!user) throw new Error('User not found.');
const whereCondition = acceptedOnly
? { accepted: true, withdrawn: false, denied: false }
: {};
const friendships = await Friendship.findAll({
where: {
...whereCondition,
[Op.or]: [
{ user1Id: user.id },
{ user2Id: user.id },
],
},
include: [
{
model: User,
as: 'friendSender',
attributes: ['username', 'hashedId'],
include: [
{
model: UserParam,
as: 'user_params',
required: false,
include: [
{
model: UserParamType,
as: 'paramType',
required: true,
where: { description: 'gender' },
attributes: ['description'],
},
],
attributes: ['value'],
},
],
},
{
model: User,
as: 'friendReceiver',
attributes: ['username', 'hashedId'],
include: [
{
model: UserParam,
as: 'user_params',
required: false,
include: [
{
model: UserParamType,
as: 'paramType',
required: true,
where: { description: 'gender' },
attributes: ['description'],
},
],
attributes: ['value'],
},
],
},
],
});
const processedFriendships = await Promise.all(
friendships.map(async (friendship) => {
const isInitiator = friendship.user1Id === user.id;
const otherUser = isInitiator ? friendship.friendReceiver : friendship.friendSender;
const genderParam = otherUser.user_params?.find(param => param.paramType.description === 'gender');
const gender = genderParam ? await this.getGender(genderParam) : null;
return {
id: friendship.id,
user: {
username: otherUser.username,
hashedId: otherUser.hashedId,
gender,
},
accepted: friendship.accepted,
denied: friendship.denied,
withdrawn: friendship.withdrawn,
isInitiator,
};
})
);
return processedFriendships;
}
async getGender(genderParam) {
if (!this.genders) {
this.genders = {};
}
if (this.genders[genderParam.value]) return this.genders[genderParam.value];
const genderObject = await UserParamValue.findOne({
where: { id: genderParam.value },
});
if (genderObject) {
this.genders[genderParam.value] = genderObject.value;
return genderObject.value;
}
return '';
}
}
export default new FriendshipService();