mirror of
https://github.com/fluxerapp/fluxer
synced 2026-10-17 13:05:32 +09:00
fix(threads): announce threads above the latest five messages (#3307)
This commit is contained in:
1 parent
c486c2d3d0
commit
aa42bf13ce
2 files changed
+26
-15
No files matched your search
@@ -76,10 +76,9 @@ import type {
|
||||
} from '@fluxer/schema/src/domains/channel/ForumRequestSchemas';
|
||||
import type {ThreadChannelResponse} from '@fluxer/schema/src/domains/channel/ThreadRequestSchemas';
|
||||
import type {MessageResponse} from '@fluxer/schema/src/domains/message/MessageResponseSchemas';
|
||||
import {snowflakeToDate} from '@fluxer/snowflake/src/Snowflake';
|
||||
import * as BucketUtils from '@fluxer/snowflake/src/SnowflakeBuckets';
|
||||
|
||||
const THREAD_CREATED_MESSAGE_MIN_SOURCE_AGE_MS = 5 * 60 * 1000;
|
||||
const THREAD_CREATED_MESSAGE_RECENT_WINDOW = 5;
|
||||
|
||||
function slowmodeThreadKey(parentId: ChannelID, userId: UserID): string {
|
||||
return `slowmode-thread:${parentId}:${userId}`;
|
||||
@@ -159,13 +158,22 @@ export class ThreadCreationService {
|
||||
}
|
||||
const starter = await this.buildStarterEvent(params.viewer, params.user.id, view, params.requestCache);
|
||||
if (starter) events.push(starter);
|
||||
if (Date.now() - snowflakeToDate(source.id).getTime() >= THREAD_CREATED_MESSAGE_MIN_SOURCE_AGE_MS) {
|
||||
if (!(await this.isAmongRecentMessages(parentAuth.channel.id, source.id))) {
|
||||
events.push(await this.createThreadCreatedMessage(parentAuth.channel, view, params.user.id));
|
||||
}
|
||||
await dispatchThreadEvents(this.ctx.gatewayService, view.state.guildId, events);
|
||||
return mapThreadToResponse(view);
|
||||
}
|
||||
|
||||
private async isAmongRecentMessages(channelId: ChannelID, messageId: MessageID): Promise<boolean> {
|
||||
const recent = await this.ctx.channelRepository.messages.listMessages(
|
||||
channelId,
|
||||
undefined,
|
||||
THREAD_CREATED_MESSAGE_RECENT_WINDOW,
|
||||
);
|
||||
return recent.some((message) => message.id === messageId);
|
||||
}
|
||||
|
||||
async authenticateParent(viewer: ThreadViewer, userId: UserID, channelId: ChannelID): Promise<AuthenticatedChannel> {
|
||||
return this.ctx.channelAuth.getChannelAuthenticated({userId, channelId, viewer});
|
||||
}
|
||||
|
||||
@@ -268,25 +268,28 @@ describe('thread routes', () => {
|
||||
expect(member?.flags).toBe(ThreadMemberFlags.HAS_INTERACTED);
|
||||
});
|
||||
|
||||
it('announces threads started from older messages in the parent without moving its last message', async () => {
|
||||
it('announces threads started from messages above the latest five without moving its last message', async () => {
|
||||
const s = await setup();
|
||||
const message = await sendMessage(harness, s.owner.token, s.channelId, 'old news');
|
||||
const now = Date.now();
|
||||
vi.spyOn(Date, 'now').mockReturnValue(now + 6 * 60 * 1000);
|
||||
const pushedUp = await sendMessage(harness, s.owner.token, s.channelId, 'old news');
|
||||
const nearBottom = await sendMessage(harness, s.owner.token, s.channelId, 'recent news');
|
||||
let latest = nearBottom;
|
||||
for (let i = 0; i < 4; i++) latest = await sendMessage(harness, s.owner.token, s.channelId, `filler ${i}`);
|
||||
const dispatch = vi.spyOn(NoopGatewayService.prototype, 'dispatchGuild');
|
||||
await threadsRequest(harness, s.owner.token)
|
||||
.post(`/channels/${s.channelId}/messages/${message.id}/threads`)
|
||||
.body({name: 'Later'})
|
||||
.expect(201)
|
||||
.execute();
|
||||
for (const message of [nearBottom, pushedUp]) {
|
||||
await threadsRequest(harness, s.owner.token)
|
||||
.post(`/channels/${s.channelId}/messages/${message.id}/threads`)
|
||||
.body({name: message.content})
|
||||
.expect(201)
|
||||
.execute();
|
||||
}
|
||||
const announced = dispatch.mock.calls
|
||||
.map(([params]) => params.data as MessageResponse)
|
||||
.filter((data) => data.type === MessageTypes.THREAD_CREATED);
|
||||
expect(announced).toHaveLength(1);
|
||||
expect(announced[0]).toMatchObject({channel_id: s.channelId, content: 'Later'});
|
||||
expect(announced[0]!.message_reference?.channel_id).toBe(message.id);
|
||||
expect(announced[0]).toMatchObject({channel_id: s.channelId, content: 'old news'});
|
||||
expect(announced[0]!.message_reference?.channel_id).toBe(pushedUp.id);
|
||||
const parent = await repository.findUnique(createChannelID(BigInt(s.channelId)));
|
||||
expect(parent?.lastMessageId?.toString()).toBe(message.id);
|
||||
expect(parent?.lastMessageId?.toString()).toBe(latest.id);
|
||||
});
|
||||
|
||||
it('refuses a second thread on the same message', async () => {
|
||||
|
||||
Reference in new issue
Block a user