diff --git a/src/api/routes/channels/#channel_id/messages/#message_id/threads.ts b/src/api/routes/channels/#channel_id/messages/#message_id/threads.ts index 488344023..e68a02b3d 100644 --- a/src/api/routes/channels/#channel_id/messages/#message_id/threads.ts +++ b/src/api/routes/channels/#channel_id/messages/#message_id/threads.ts @@ -50,7 +50,6 @@ router.post( where: { id: channel_id }, }); const user = await User.findOneOrFail({ where: { id: req.user_id } }); - const recipient = Recipient.create({ channel_id: message.id, user }); const thread = await Channel.createChannel( { @@ -78,8 +77,6 @@ router.post( { skipPermissionCheck: true, keepId: true, skipEventEmit: true }, ); - recipient.save(); - message.thread = thread; message.flags ||= 1 << 5; await sendMessage({ diff --git a/src/api/routes/channels/#channel_id/messages/index.ts b/src/api/routes/channels/#channel_id/messages/index.ts index 54ef7f3e9..d89d39c65 100644 --- a/src/api/routes/channels/#channel_id/messages/index.ts +++ b/src/api/routes/channels/#channel_id/messages/index.ts @@ -533,16 +533,6 @@ router.post( // no await as it shouldnt block the message send function and silently catch error postHandleMessage(message).catch((e) => console.error("[Message] post-message handler failed", e)); - if (channel.type === ChannelType.GUILD_PUBLIC_THREAD && channel.recipients && !channel.recipients.find((_) => _.user.id === req.user_id)) { - const rec = Recipient.create({ - channel_id: channel.id, - user_id: req.user_id, - }); - channel.recipients.push(rec); - rec.save().then(() => { - channel.save(); - }); - } return res.json( message.withSignedAttachments( diff --git a/src/api/routes/channels/#channel_id/threads.ts b/src/api/routes/channels/#channel_id/threads.ts index 0a320c87c..79392fe66 100644 --- a/src/api/routes/channels/#channel_id/threads.ts +++ b/src/api/routes/channels/#channel_id/threads.ts @@ -17,8 +17,8 @@ */ import { handleMessage, postHandleMessage, route, sendMessage } from "@spacebar/api"; -import { Message, Channel, emitEvent, User, MessageUpdateEvent, Recipient, uploadFile, Attachment, Member, ReadState, MessageCreateEvent } from "@spacebar/util"; -import { MessageThreadCreationSchema, ChannelType, MessageType, ThreadCreationSchema, MessageCreateAttachment, MessageCreateCloudAttachment } from "@spacebar/schemas"; +import { Channel, emitEvent, User, uploadFile, Attachment, Member, ReadState, MessageCreateEvent } from "@spacebar/util"; +import { ChannelType, MessageType, ThreadCreationSchema, MessageCreateAttachment, MessageCreateCloudAttachment } from "@spacebar/schemas"; import { Request, Response, Router } from "express"; import { messageUpload } from "./messages"; @@ -81,9 +81,6 @@ router.post( void 0, { skipPermissionCheck: true, keepId: true, skipEventEmit: true }, ); - const recipient = Recipient.create({ channel_id: channel.id, user }); - - await recipient.save(); await Promise.all([ emitEvent({ diff --git a/src/api/util/handlers/Message.ts b/src/api/util/handlers/Message.ts index bf1f5e969..f79573697 100644 --- a/src/api/util/handlers/Message.ts +++ b/src/api/util/handlers/Message.ts @@ -243,7 +243,7 @@ export async function handleMessage(opts: MessageOptions): Promise { if (opts.message_reference.type != 1) { if (opts.message_reference.guild_id !== channel.guild_id) throw new HTTPError("You can only reference messages from this guild"); - if (opts.message_reference.channel_id !== opts.channel_id && opts.type !== MessageType.THREAD_STARTER_MESSAGE) + if (opts.message_reference.channel_id !== opts.channel_id && opts.type !== MessageType.THREAD_STARTER_MESSAGE && opts.type !== MessageType.THREAD_CREATED) throw new HTTPError("You can only reference messages from this channel"); } diff --git a/src/gateway/opcodes/Identify.ts b/src/gateway/opcodes/Identify.ts index e1c57d552..dacc35ccd 100644 --- a/src/gateway/opcodes/Identify.ts +++ b/src/gateway/opcodes/Identify.ts @@ -419,7 +419,7 @@ export async function onIdentify(this: WebSocket, data: Payload) { const threadMembers = await ThreadMember.find({ where: { member_idx: In(member_idx) }, - relations: { channel: { recipients: { user: true } } }, + relations: { channel: { thread_members: { member: true } } }, }); const threadMemberTime = taskSw.getElapsedAndReset(); diff --git a/src/gateway/opcodes/LazyRequest.ts b/src/gateway/opcodes/LazyRequest.ts index 3a56a0c82..2096503b9 100644 --- a/src/gateway/opcodes/LazyRequest.ts +++ b/src/gateway/opcodes/LazyRequest.ts @@ -218,6 +218,7 @@ export async function onLazyRequest(this: WebSocket, { d }: Payload) { if (!channel_id) return; const permissions = await getPermission(this.user_id, guild_id, channel_id); + console.log(permissions); permissions.hasThrow("VIEW_CHANNEL"); const ranges = channels[channel_id]; diff --git a/src/util/entities/Channel.ts b/src/util/entities/Channel.ts index e3c9c8e87..d57d83614 100644 --- a/src/util/entities/Channel.ts +++ b/src/util/entities/Channel.ts @@ -57,6 +57,12 @@ export class Channel extends BaseClass { }) recipients?: Recipient[]; + @OneToMany(() => ThreadMember, (member: ThreadMember) => member.channel, { + cascade: true, + orphanedRowAction: "delete", + }) + thread_members?: ThreadMember[]; + @Column({ nullable: true }) last_message_id?: string; @@ -676,7 +682,7 @@ export class Channel extends BaseClass { user_limit: this.user_limit || undefined, rate_limit_per_user: this.rate_limit_per_user || undefined, owner_id: this.owner_id || undefined, - ...(this.isThread() && this.recipients ? { member_ids_preview: this.recipients.map((_) => _.user.id) } : {}), + ...(this.isThread() && this.thread_members ? { member_ids_preview: this.thread_members.map((_) => _.member.id) } : {}), }; } } diff --git a/src/util/migration/postgres/1770168396106-threadMembers.ts b/src/util/migration/postgres/1770168396106-threadMembers.ts new file mode 100644 index 000000000..b7df8c814 --- /dev/null +++ b/src/util/migration/postgres/1770168396106-threadMembers.ts @@ -0,0 +1,23 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class ThreadMembers1770168396106 implements MigrationInterface { + name = "ThreadMembers1770168396106"; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "thread_members" DROP CONSTRAINT "FK_606ac45e8756d3440c584477f4e"`); + await queryRunner.query(`DROP INDEX "public"."IDX_bde0970b6a26bdbd83508addd2"`); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_38d4f704373da3f0dc9b352acs9" ON "thread_members" ("id", "member_idx") `); + await queryRunner.query( + `ALTER TABLE "thread_members" ADD CONSTRAINT "FK_4721015b4e24ad29da55dbd2de0" FOREIGN KEY ("member_idx") REFERENCES "members"("index") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "thread_members" DROP CONSTRAINT "FK_4721015b4e24ad29da55dbd2de0"`); + await queryRunner.query(`DROP INDEX "public"."IDX_38d4f704373da3f0dc9b352ac9"`); + await queryRunner.query(`CREATE UNIQUE INDEX "IDX_bde0970b6a26bdbd83508addd2" ON "thread_members" ("id", "member_idx") `); + await queryRunner.query( + `ALTER TABLE "thread_members" ADD CONSTRAINT "FK_606ac45e8756d3440c584477f4e" FOREIGN KEY ("member_idx") REFERENCES "members"("index") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + } +}