mirror of
https://github.com/fluxerapp/fluxer
synced 2026-10-17 13:05:32 +09:00
fix(app): ignore leftover mentions in unseen channels (#3290)
This commit is contained in:
1 parent
d6e3254a16
commit
4da8dec4ac
2 files changed
+77
-12
No files matched your search
@@ -97,6 +97,51 @@ describe('background read state reducer', () => {
|
||||
expect(recorder.total).toBe(1);
|
||||
});
|
||||
|
||||
test('a leftover mention in a channel the account can no longer see is not counted, as in the foreground', () => {
|
||||
reducer.applyReady(
|
||||
readyPayload({
|
||||
private_channels: [{id: 'dm-open', type: ChannelTypes.DM}],
|
||||
read_states: [
|
||||
{id: 'dm-closed', mention_count: 1},
|
||||
{id: 'left-guild-channel', mention_count: 1},
|
||||
{id: 'dm-open', mention_count: 2},
|
||||
],
|
||||
}),
|
||||
);
|
||||
|
||||
expect([...recorder.counts]).toEqual([['dm-open', 2]]);
|
||||
});
|
||||
|
||||
test('a leftover mention appears once its guild arrives and its channel is known', () => {
|
||||
reducer.applyReady(
|
||||
readyPayload({
|
||||
guilds: [{id: 'guild-9', unavailable: true}],
|
||||
read_states: [{id: 'late-1', mention_count: 2}],
|
||||
}),
|
||||
);
|
||||
expect(recorder.total).toBe(0);
|
||||
|
||||
reducer.applyDispatch('GUILD_CREATE', {id: 'guild-9', channels: [{id: 'late-1'}], members: []});
|
||||
|
||||
expect(recorder.counts.get('late-1')).toBe(2);
|
||||
});
|
||||
|
||||
test('a reopened direct message brings its leftover mention back', () => {
|
||||
reducer.applyReady(readyPayload({read_states: [{id: 'dm-closed', mention_count: 1}]}));
|
||||
|
||||
reducer.applyDispatch('CHANNEL_CREATE', {id: 'dm-closed', type: ChannelTypes.DM});
|
||||
|
||||
expect(recorder.counts.get('dm-closed')).toBe(1);
|
||||
});
|
||||
|
||||
test('an acknowledgement for a channel the account cannot see is not counted', () => {
|
||||
reducer.applyReady(readyPayload());
|
||||
|
||||
reducer.applyDispatch('MESSAGE_ACK', {channel_id: 'gone', message_id: 'm', mention_count: 1});
|
||||
|
||||
expect(recorder.total).toBe(0);
|
||||
});
|
||||
|
||||
test('a muted guild still contributes an explicit mention, exactly as the foreground badge does', () => {
|
||||
reducer.applyReady(readyPayload({user_guild_settings: [{guild_id: 'guild-1', muted: true}]}));
|
||||
|
||||
|
||||
@@ -258,7 +258,13 @@ export class BackgroundReadStateReducer implements BackgroundSnapshotSink {
|
||||
this.storeMentionCount(channelId, mentionCount);
|
||||
}
|
||||
}
|
||||
this.observeMentionCounts(new Map(this.mentionCounts), BackgroundMentionCountMode.REPLACE);
|
||||
const visible = new Map<string, number>();
|
||||
for (const [channelId, mentionCount] of this.mentionCounts) {
|
||||
if (this.channelDetails.has(channelId)) {
|
||||
visible.set(channelId, mentionCount);
|
||||
}
|
||||
}
|
||||
this.observeMentionCounts(visible, BackgroundMentionCountMode.REPLACE);
|
||||
}
|
||||
|
||||
applyDispatch(type: string, data: unknown): void {
|
||||
@@ -339,21 +345,20 @@ export class BackgroundReadStateReducer implements BackgroundSnapshotSink {
|
||||
return;
|
||||
}
|
||||
this.storeGuildDetails(guild);
|
||||
for (const entry of asArray(guild.channels)) {
|
||||
const revealed = new Map<string, number>();
|
||||
for (const entry of [...asArray(guild.channels), ...asArray(guild.threads)]) {
|
||||
const channel = asRecord(entry);
|
||||
const channelId = asString(channel?.id);
|
||||
if (channel !== null && channelId !== null) {
|
||||
this.linkChannel(guildId, channelId);
|
||||
this.storeChannelDetails(channelId, channel);
|
||||
const mentionCount = this.storeChannelDetails(channelId, channel);
|
||||
if (mentionCount > 0) {
|
||||
revealed.set(channelId, mentionCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (const entry of asArray(guild.threads)) {
|
||||
const thread = asRecord(entry);
|
||||
const threadId = asString(thread?.id);
|
||||
if (thread !== null && threadId !== null) {
|
||||
this.linkChannel(guildId, threadId);
|
||||
this.storeChannelDetails(threadId, thread);
|
||||
}
|
||||
if (revealed.size > 0) {
|
||||
this.observeMentionCounts(revealed, BackgroundMentionCountMode.MERGE);
|
||||
}
|
||||
for (const entry of asArray(guild.members)) {
|
||||
const member = asRecord(entry);
|
||||
@@ -402,12 +407,21 @@ export class BackgroundReadStateReducer implements BackgroundSnapshotSink {
|
||||
if (guildId !== null) {
|
||||
this.linkChannel(guildId, channelId);
|
||||
}
|
||||
this.storeChannelDetails(channelId, channel);
|
||||
this.revealChannel(channelId, channel);
|
||||
}
|
||||
|
||||
private storeChannelDetails(channelId: string, channel: Record<string, unknown>): void {
|
||||
private revealChannel(channelId: string, channel: Record<string, unknown>): void {
|
||||
const mentionCount = this.storeChannelDetails(channelId, channel);
|
||||
if (mentionCount > 0) {
|
||||
this.observeMentionCounts(new Map([[channelId, mentionCount]]), BackgroundMentionCountMode.MERGE);
|
||||
}
|
||||
}
|
||||
|
||||
private storeChannelDetails(channelId: string, channel: Record<string, unknown>): number {
|
||||
this.assertChannelCapacity(this.channelDetails, channelId);
|
||||
const known = this.channelDetails.has(channelId);
|
||||
this.channelDetails.set(channelId, readChannelDetails(channel));
|
||||
return known ? 0 : (this.mentionCounts.get(channelId) ?? 0);
|
||||
}
|
||||
|
||||
private storeRelationship(value: unknown): void {
|
||||
@@ -448,6 +462,9 @@ export class BackgroundReadStateReducer implements BackgroundSnapshotSink {
|
||||
if (guildId !== null) {
|
||||
this.linkChannel(guildId, channelId);
|
||||
}
|
||||
if (!this.channelDetails.has(channelId)) {
|
||||
this.revealChannel(channelId, {});
|
||||
}
|
||||
const muted = this.isGuildOrChannelMuted(guildId, channelId);
|
||||
const authorBlocked = authorId !== null && this.blockedUserIds.has(authorId);
|
||||
const mentioned = this.messageMentionsUser(message, guildId, muted, authorBlocked);
|
||||
@@ -637,6 +654,9 @@ export class BackgroundReadStateReducer implements BackgroundSnapshotSink {
|
||||
} else {
|
||||
this.mentionCounts.delete(channelId);
|
||||
}
|
||||
if (mentionCount > 0 && !this.channelDetails.has(channelId)) {
|
||||
return;
|
||||
}
|
||||
this.observeMentionCounts(new Map([[channelId, mentionCount]]), BackgroundMentionCountMode.MERGE);
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user