feat(app): restyle the inbox and message preview surfaces (#1706)

This commit is contained in:
Hampus authored and GitHub committed 2026-08-18 00:43:18 +02:00
1 parent 41c7acdd8f
commit cc105883a5
55 files changed
+10669 -10576

No files matched your search

@@ -0,0 +1,62 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {MessageNotifications} from '@fluxer/constants/src/NotificationConstants';
import {describe, expect, it} from 'vitest';
import {resolveUnreadInboxVisibility, type UnreadInboxVisibilityInput} from './UnreadInboxVisibility';
function input(overrides: Partial<UnreadInboxVisibilityInput> = {}): UnreadInboxVisibilityInput {
return {
unreadBadgesLevel: null,
isMuted: false,
hasUnread: true,
hasMentions: false,
...overrides,
};
}
describe('resolveUnreadInboxVisibility', () => {
it('shows an unmuted channel with plain unread messages', () => {
expect(resolveUnreadInboxVisibility(input())).toBe(true);
});
it('shows a channel in a large community, where notification level is forced to only-mentions', () => {
expect(resolveUnreadInboxVisibility(input({unreadBadgesLevel: null, hasMentions: false}))).toBe(true);
});
it('hides a channel with nothing unread and no mentions', () => {
expect(resolveUnreadInboxVisibility(input({hasUnread: false, hasMentions: false}))).toBe(false);
});
it('hides plain unread in a muted channel', () => {
expect(resolveUnreadInboxVisibility(input({isMuted: true}))).toBe(false);
});
it('shows a muted channel when it has a mention', () => {
expect(resolveUnreadInboxVisibility(input({isMuted: true, hasMentions: true}))).toBe(true);
});
it('hides a channel whose explicit unread badges level is nothing, even with a mention', () => {
expect(
resolveUnreadInboxVisibility(input({unreadBadgesLevel: MessageNotifications.NO_MESSAGES, hasMentions: true})),
).toBe(false);
});
it('hides plain unread when the explicit unread badges level is only-mentions', () => {
expect(resolveUnreadInboxVisibility(input({unreadBadgesLevel: MessageNotifications.ONLY_MENTIONS}))).toBe(false);
});
it('shows a mention when the explicit unread badges level is only-mentions', () => {
expect(
resolveUnreadInboxVisibility(input({unreadBadgesLevel: MessageNotifications.ONLY_MENTIONS, hasMentions: true})),
).toBe(true);
});
it('shows plain unread when the explicit unread badges level is all messages', () => {
expect(resolveUnreadInboxVisibility(input({unreadBadgesLevel: MessageNotifications.ALL_MESSAGES}))).toBe(true);
});
it('takes no notification-level input at all, so a forced community level cannot gate it', () => {
const keys = Object.keys(input()).sort();
expect(keys).toEqual(['hasMentions', 'hasUnread', 'isMuted', 'unreadBadgesLevel']);
});
});
@@ -0,0 +1,26 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {MessageNotifications} from '@fluxer/constants/src/NotificationConstants';
export interface UnreadInboxVisibilityInput {
unreadBadgesLevel: number | null;
isMuted: boolean;
hasUnread: boolean;
hasMentions: boolean;
}
export function resolveUnreadInboxVisibility(input: UnreadInboxVisibilityInput): boolean {
if (!input.hasUnread && !input.hasMentions) {
return false;
}
if (input.unreadBadgesLevel === MessageNotifications.NO_MESSAGES) {
return false;
}
if (input.hasMentions) {
return true;
}
if (input.isMuted) {
return false;
}
return input.unreadBadgesLevel !== MessageNotifications.ONLY_MENTIONS;
}
@@ -4,6 +4,7 @@ import Channels from '@app/features/channel/state/Channels';
import Guilds from '@app/features/guild/state/Guilds';
import {Logger} from '@app/features/platform/utils/AppLogger';
import AdvancedSettings from '@app/features/user/state/AdvancedSettings';
import {resolveUnreadInboxVisibility} from '@app/features/user/state/UnreadInboxVisibility';
import {FAVORITES_GUILD_ID, ME} from '@fluxer/constants/src/AppConstants';
import {MessageNotifications} from '@fluxer/constants/src/NotificationConstants';
import type {ChannelId, GuildId} from '@fluxer/schema/src/branded/WireIds';
@@ -519,27 +520,17 @@ class UserGuildSettings {
return this.resolvedUnreadBadgesLevel(channel);
}
private shouldShowUnreadInboxStateAtLevel(level: number, readState: UnreadInboxReadState): boolean {
if (level === MessageNotifications.NO_MESSAGES) return false;
if (level === MessageNotifications.ONLY_MENTIONS) return readState.hasMentions;
return readState.hasUnread || readState.hasMentions;
}
shouldShowChannelInUnreadInbox(
channel: {id: string; guildId?: string; parentId?: string; type: number},
readState: UnreadInboxReadState,
): boolean {
const guildId = channel.guildId ?? null;
const level = this.resolvedUnreadBadgesLevel(channel);
if (isExplicitNotificationLevel(level)) {
return this.shouldShowUnreadInboxStateAtLevel(level, readState);
}
if (guildId == null) {
if (this.isGuildOrChannelMuted(null, channel.id)) return false;
} else if (this.isGuildOrCategoryOrChannelMuted(guildId, channel.id)) {
return false;
}
return this.shouldShowUnreadInboxStateAtLevel(this.resolvedMessageNotifications(channel), readState);
return resolveUnreadInboxVisibility({
unreadBadgesLevel: this.resolvedUnreadBadgesLevel(channel),
isMuted: this.isGuildOrCategoryOrChannelMuted(guildId, channel.id),
hasUnread: readState.hasUnread,
hasMentions: readState.hasMentions,
});
}
resolveUnreadSetting(channel: {id: string; guildId?: string; parentId?: string; type: number}): string {