mirror of
https://github.com/spacebarchat/server.git
synced 2024-11-23 19:02:37 +01:00
Removed ChannelService, more fixes
This commit is contained in:
parent
97e0c8709b
commit
ada95b6c39
@ -1,4 +1,4 @@
|
||||
import { Channel, ChannelDeleteEvent, ChannelPermissionOverwriteType, ChannelService, ChannelType, ChannelUpdateEvent, emitEvent, Recipient } from "@fosscord/util";
|
||||
import { Channel, ChannelDeleteEvent, ChannelPermissionOverwriteType, ChannelType, ChannelUpdateEvent, emitEvent, Recipient } from "@fosscord/util";
|
||||
import { Request, Response, Router } from "express";
|
||||
import { handleFile, route } from "@fosscord/api";
|
||||
|
||||
@ -28,7 +28,7 @@ router.delete("/", route({ permission: "MANAGE_CHANNELS" }), async (req: Request
|
||||
]);
|
||||
|
||||
} else if (channel.type === ChannelType.GROUP_DM) {
|
||||
await ChannelService.removeRecipientFromChannel(channel, req.user_id)
|
||||
await Channel.removeRecipientFromChannel(channel, req.user_id)
|
||||
} else {
|
||||
//TODO messages in this channel should be deleted before deleting the channel
|
||||
await Promise.all([
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { Router, Response, Request } from "express";
|
||||
import { Attachment, Channel, ChannelType, DmChannelDTO, Embed, emitEvent, getPermission, Message, MessageCreateEvent } from "@fosscord/util";
|
||||
import { Attachment, Channel, ChannelType, DmChannelDTO, Embed, emitEvent, getPermission, Message, MessageCreateEvent, Recipient } from "@fosscord/util";
|
||||
import { HTTPError } from "lambert-server";
|
||||
import { handleMessage, postHandleMessage, route } from "@fosscord/api";
|
||||
import multer from "multer";
|
||||
@ -150,7 +150,6 @@ router.post(
|
||||
return res.status(400).json(error);
|
||||
}
|
||||
}
|
||||
//TODO querying the DB at every message post should be avoided, caching maybe?
|
||||
const channel = await Channel.findOneOrFail({ where: { id: channel_id }, relations: ["recipients", "recipients.user"] })
|
||||
|
||||
const embeds = [];
|
||||
@ -184,7 +183,8 @@ router.post(
|
||||
}
|
||||
}
|
||||
|
||||
await Promise.all(channel.recipients!.map(async r => {
|
||||
//Only one recipients should be closed here, since in group DMs the recipient is deleted not closed
|
||||
await Promise.all(channel.recipients!.filter(r => r.closed).map(async r => {
|
||||
r.closed = false;
|
||||
return await r.save()
|
||||
}));
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { Request, Response, Router } from "express";
|
||||
import { Channel, ChannelRecipientAddEvent, ChannelService, ChannelType, DiscordApiErrors, DmChannelDTO, emitEvent, PublicUserProjection, Recipient, User } from "@fosscord/util";
|
||||
import { Channel, ChannelRecipientAddEvent, ChannelType, DiscordApiErrors, DmChannelDTO, emitEvent, PublicUserProjection, Recipient, User } from "@fosscord/util";
|
||||
|
||||
const router: Router = Router();
|
||||
|
||||
@ -13,7 +13,7 @@ router.put("/:user_id", async (req: Request, res: Response) => {
|
||||
user_id
|
||||
].unique()
|
||||
|
||||
const new_channel = await ChannelService.createDMChannel(recipients, req.user_id)
|
||||
const new_channel = await Channel.createDMChannel(recipients, req.user_id)
|
||||
return res.status(201).json(new_channel);
|
||||
} else {
|
||||
if (channel.recipients!.map(r => r.user_id).includes(user_id)) {
|
||||
@ -49,7 +49,7 @@ router.delete("/:user_id", async (req: Request, res: Response) => {
|
||||
throw DiscordApiErrors.INVALID_RECIPIENT //TODO is this the right error?
|
||||
}
|
||||
|
||||
await ChannelService.removeRecipientFromChannel(channel, user_id)
|
||||
await Channel.removeRecipientFromChannel(channel, user_id)
|
||||
|
||||
return res.sendStatus(204);
|
||||
});
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { Request, Response, Router } from "express";
|
||||
import { Recipient, ChannelService, DmChannelDTO } from "@fosscord/util";
|
||||
import { Recipient, DmChannelDTO, Channel } from "@fosscord/util";
|
||||
import { route } from "@fosscord/api";
|
||||
|
||||
const router: Router = Router();
|
||||
@ -16,7 +16,7 @@ export interface DmChannelCreateSchema {
|
||||
|
||||
router.post("/", route({ body: "DmChannelCreateSchema" }), async (req: Request, res: Response) => {
|
||||
const body = req.body as DmChannelCreateSchema;
|
||||
res.json(await ChannelService.createDMChannel(body.recipients, req.user_id, body.name));
|
||||
res.json(await Channel.createDMChannel(body.recipients, req.user_id, body.name));
|
||||
});
|
||||
|
||||
export default router;
|
||||
|
@ -32,7 +32,7 @@ export async function setupListener(this: WebSocket) {
|
||||
});
|
||||
const guilds = members.map((x) => x.guild);
|
||||
const recipients = await Recipient.find({
|
||||
where: { user_id: this.user_id },
|
||||
where: { user_id: this.user_id, closed: false },
|
||||
relations: ["channel"],
|
||||
});
|
||||
const dm_channels = recipients.map((x) => x.channel);
|
||||
|
@ -1,11 +1,13 @@
|
||||
import { Column, Entity, JoinColumn, ManyToOne, OneToMany, RelationId } from "typeorm";
|
||||
import { BaseClass } from "./BaseClass";
|
||||
import { Guild } from "./Guild";
|
||||
import { User } from "./User";
|
||||
import { PublicUserProjection, User } from "./User";
|
||||
import { HTTPError } from "lambert-server";
|
||||
import { emitEvent, getPermission, Snowflake } from "../util";
|
||||
import { ChannelCreateEvent } from "../interfaces";
|
||||
import { containsAll, emitEvent, getPermission, Snowflake, trimSpecial } from "../util";
|
||||
import { ChannelCreateEvent, ChannelRecipientRemoveEvent } from "../interfaces";
|
||||
import { Recipient } from "./Recipient";
|
||||
import { DmChannelDTO } from "../dtos";
|
||||
import { Message } from "./Message";
|
||||
|
||||
export enum ChannelType {
|
||||
GUILD_TEXT = 0, // a text channel within a server
|
||||
@ -97,7 +99,6 @@ export class Channel extends BaseClass {
|
||||
@Column({ nullable: true })
|
||||
topic?: string;
|
||||
|
||||
// TODO: DM channel
|
||||
static async createChannel(
|
||||
channel: Partial<Channel>,
|
||||
user_id: string = "0",
|
||||
@ -150,16 +151,123 @@ export class Channel extends BaseClass {
|
||||
new Channel(channel).save(),
|
||||
!opts?.skipEventEmit
|
||||
? emitEvent({
|
||||
event: "CHANNEL_CREATE",
|
||||
data: channel,
|
||||
guild_id: channel.guild_id,
|
||||
} as ChannelCreateEvent)
|
||||
event: "CHANNEL_CREATE",
|
||||
data: channel,
|
||||
guild_id: channel.guild_id,
|
||||
} as ChannelCreateEvent)
|
||||
: Promise.resolve(),
|
||||
]);
|
||||
|
||||
return channel;
|
||||
}
|
||||
|
||||
static async createDMChannel(recipients: string[], creator_user_id: string, name?: string) {
|
||||
recipients = recipients.unique().filter((x) => x !== creator_user_id);
|
||||
const otherRecipientsUsers = await User.find({ where: recipients.map((x) => ({ id: x })) });
|
||||
|
||||
// TODO: check config for max number of recipients
|
||||
if (otherRecipientsUsers.length !== recipients.length) {
|
||||
throw new HTTPError("Recipient/s not found");
|
||||
}
|
||||
|
||||
const type = recipients.length === 1 ? ChannelType.DM : ChannelType.GROUP_DM;
|
||||
|
||||
let channel = null;
|
||||
|
||||
const channelRecipients = [...recipients, creator_user_id]
|
||||
|
||||
const userRecipients = await Recipient.find({ where: { user_id: creator_user_id }, relations: ["channel", "channel.recipients"] })
|
||||
|
||||
for (let ur of userRecipients) {
|
||||
let re = ur.channel.recipients!.map(r => r.user_id)
|
||||
if (re.length === channelRecipients.length) {
|
||||
if (containsAll(re, channelRecipients)) {
|
||||
if (channel == null) {
|
||||
channel = ur.channel
|
||||
await ur.assign({ closed: false }).save()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (channel == null) {
|
||||
name = trimSpecial(name);
|
||||
|
||||
channel = await new Channel({
|
||||
name,
|
||||
type,
|
||||
owner_id: (type === ChannelType.DM ? undefined : creator_user_id),
|
||||
created_at: new Date(),
|
||||
last_message_id: null,
|
||||
recipients: channelRecipients.map((x) => new Recipient({ user_id: x, closed: !(type === ChannelType.GROUP_DM || x === creator_user_id) })),
|
||||
}).save();
|
||||
}
|
||||
|
||||
|
||||
const channel_dto = await DmChannelDTO.from(channel)
|
||||
|
||||
if (type === ChannelType.GROUP_DM) {
|
||||
|
||||
for (let recipient of channel.recipients!) {
|
||||
await emitEvent({
|
||||
event: "CHANNEL_CREATE",
|
||||
data: channel_dto.excludedRecipients([recipient.user_id]),
|
||||
user_id: recipient.user_id
|
||||
})
|
||||
}
|
||||
} else {
|
||||
await emitEvent({ event: "CHANNEL_CREATE", data: channel_dto, user_id: creator_user_id });
|
||||
}
|
||||
|
||||
return channel_dto.excludedRecipients([creator_user_id])
|
||||
}
|
||||
|
||||
static async removeRecipientFromChannel(channel: Channel, user_id: string) {
|
||||
await Recipient.delete({ channel_id: channel.id, user_id: user_id })
|
||||
channel.recipients = channel.recipients?.filter(r => r.user_id !== user_id)
|
||||
|
||||
if (channel.recipients?.length === 0) {
|
||||
await Channel.deleteChannel(channel);
|
||||
await emitEvent({
|
||||
event: "CHANNEL_DELETE",
|
||||
data: await DmChannelDTO.from(channel, [user_id]),
|
||||
user_id: user_id
|
||||
});
|
||||
return
|
||||
}
|
||||
|
||||
await emitEvent({
|
||||
event: "CHANNEL_DELETE",
|
||||
data: await DmChannelDTO.from(channel, [user_id]),
|
||||
user_id: user_id
|
||||
});
|
||||
|
||||
//If the owner leave we make the first recipient in the list the new owner
|
||||
if (channel.owner_id === user_id) {
|
||||
channel.owner_id = channel.recipients!.find(r => r.user_id !== user_id)!.user_id //Is there a criteria to choose the new owner?
|
||||
await emitEvent({
|
||||
event: "CHANNEL_UPDATE",
|
||||
data: await DmChannelDTO.from(channel, [user_id]),
|
||||
channel_id: channel.id
|
||||
});
|
||||
}
|
||||
|
||||
await channel.save()
|
||||
|
||||
await emitEvent({
|
||||
event: "CHANNEL_RECIPIENT_REMOVE", data: {
|
||||
channel_id: channel.id,
|
||||
user: await User.findOneOrFail({ where: { id: user_id }, select: PublicUserProjection })
|
||||
}, channel_id: channel.id
|
||||
} as ChannelRecipientRemoveEvent);
|
||||
}
|
||||
|
||||
static async deleteChannel(channel: Channel) {
|
||||
await Message.delete({ channel_id: channel.id }) //TODO we should also delete the attachments from the cdn but to do that we need to move cdn.ts in util
|
||||
//TODO before deleting the channel we should check and delete other relations
|
||||
await Channel.delete({ id: channel.id })
|
||||
}
|
||||
|
||||
isDm() {
|
||||
return this.type === ChannelType.DM || this.type === ChannelType.GROUP_DM
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ import "reflect-metadata";
|
||||
export * from "./util/index";
|
||||
export * from "./interfaces/index";
|
||||
export * from "./entities/index";
|
||||
export * from "./services/index";
|
||||
export * from "./dtos/index";
|
||||
|
||||
// import Config from "../util/Config";
|
||||
|
@ -1,118 +0,0 @@
|
||||
import { Channel, ChannelType, Message, PublicUserProjection, Recipient, User } from "../entities";
|
||||
import { HTTPError } from "lambert-server";
|
||||
import { emitEvent, trimSpecial } from "../util";
|
||||
import { DmChannelDTO } from "../dtos";
|
||||
import { ChannelRecipientRemoveEvent } from "../interfaces";
|
||||
|
||||
export function checker(arr: any[], target: any[]) {
|
||||
return target.every(v => arr.includes(v));
|
||||
}
|
||||
|
||||
export class ChannelService {
|
||||
public static async createDMChannel(recipients: string[], creator_user_id: string, name?: string) {
|
||||
recipients = recipients.unique().filter((x) => x !== creator_user_id);
|
||||
const otherRecipientsUsers = await User.find({ where: recipients.map((x) => ({ id: x })) });
|
||||
|
||||
// TODO: check config for max number of recipients
|
||||
if (otherRecipientsUsers.length !== recipients.length) {
|
||||
throw new HTTPError("Recipient/s not found");
|
||||
}
|
||||
|
||||
const type = recipients.length === 1 ? ChannelType.DM : ChannelType.GROUP_DM;
|
||||
|
||||
let channel = null;
|
||||
|
||||
const channelRecipients = [...recipients, creator_user_id]
|
||||
|
||||
const userRecipients = await Recipient.find({ where: { user_id: creator_user_id }, relations: ["channel", "channel.recipients"] })
|
||||
|
||||
for (let ur of userRecipients) {
|
||||
let re = ur.channel.recipients!.map(r => r.user_id)
|
||||
if (re.length === channelRecipients.length) {
|
||||
if (checker(re, channelRecipients)) {
|
||||
if (channel == null) {
|
||||
channel = ur.channel
|
||||
await ur.assign({ closed: false }).save()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (channel == null) {
|
||||
name = trimSpecial(name);
|
||||
|
||||
channel = await new Channel({
|
||||
name,
|
||||
type,
|
||||
owner_id: (type === ChannelType.DM ? undefined : creator_user_id),
|
||||
created_at: new Date(),
|
||||
last_message_id: null,
|
||||
recipients: channelRecipients.map((x) => new Recipient({ user_id: x, closed: !(type === ChannelType.GROUP_DM || x === creator_user_id) })),
|
||||
}).save();
|
||||
}
|
||||
|
||||
|
||||
const channel_dto = await DmChannelDTO.from(channel)
|
||||
|
||||
if (type === ChannelType.GROUP_DM) {
|
||||
|
||||
for (let recipient of channel.recipients!) {
|
||||
await emitEvent({
|
||||
event: "CHANNEL_CREATE",
|
||||
data: channel_dto.excludedRecipients([recipient.user_id]),
|
||||
user_id: recipient.user_id
|
||||
})
|
||||
}
|
||||
} else {
|
||||
await emitEvent({ event: "CHANNEL_CREATE", data: channel_dto, user_id: creator_user_id });
|
||||
}
|
||||
|
||||
return channel_dto.excludedRecipients([creator_user_id])
|
||||
}
|
||||
|
||||
public static async removeRecipientFromChannel(channel: Channel, user_id: string) {
|
||||
await Recipient.delete({ channel_id: channel.id, user_id: user_id })
|
||||
channel.recipients = channel.recipients?.filter(r => r.user_id !== user_id)
|
||||
|
||||
if (channel.recipients?.length === 0) {
|
||||
await ChannelService.deleteChannel(channel);
|
||||
await emitEvent({
|
||||
event: "CHANNEL_DELETE",
|
||||
data: await DmChannelDTO.from(channel, [user_id]),
|
||||
user_id: user_id
|
||||
});
|
||||
return
|
||||
}
|
||||
|
||||
await emitEvent({
|
||||
event: "CHANNEL_DELETE",
|
||||
data: await DmChannelDTO.from(channel, [user_id]),
|
||||
user_id: user_id
|
||||
});
|
||||
|
||||
//If the owner leave we make the first recipient in the list the new owner
|
||||
if (channel.owner_id === user_id) {
|
||||
channel.owner_id = channel.recipients!.find(r => r.user_id !== user_id)!.user_id //Is there a criteria to choose the new owner?
|
||||
await emitEvent({
|
||||
event: "CHANNEL_UPDATE",
|
||||
data: await DmChannelDTO.from(channel, [user_id]),
|
||||
channel_id: channel.id
|
||||
});
|
||||
}
|
||||
|
||||
await channel.save()
|
||||
|
||||
await emitEvent({
|
||||
event: "CHANNEL_RECIPIENT_REMOVE", data: {
|
||||
channel_id: channel.id,
|
||||
user: await User.findOneOrFail({ where: { id: user_id }, select: PublicUserProjection })
|
||||
}, channel_id: channel.id
|
||||
} as ChannelRecipientRemoveEvent);
|
||||
}
|
||||
|
||||
public static async deleteChannel(channel: Channel) {
|
||||
await Message.delete({ channel_id: channel.id }) //TODO we should also delete the attachments from the cdn but to do that we need to move cdn.ts in util
|
||||
//TODO before deleting the channel we should check and delete other relations
|
||||
await Channel.delete({ id: channel.id })
|
||||
}
|
||||
}
|
@ -1 +0,0 @@
|
||||
export * from "./ChannelService";
|
3
util/src/util/Array.ts
Normal file
3
util/src/util/Array.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export function containsAll(arr: any[], target: any[]) {
|
||||
return target.every(v => arr.includes(v));
|
||||
}
|
@ -12,3 +12,4 @@ export * from "./RabbitMQ";
|
||||
export * from "./Regex";
|
||||
export * from "./Snowflake";
|
||||
export * from "./String";
|
||||
export * from "./Array";
|
||||
|
Loading…
Reference in New Issue
Block a user