181 lines
6.8 KiB
JavaScript
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();
|