mirror of
https://github.com/fluxerapp/fluxer
synced 2026-10-19 05:55:34 +09:00
fix(app): separate unread state from unread counts
This commit is contained in:
1 parent
d3976e33f8
commit
cb4c847d41
16 files changed
+175
-23
No files matched your search
@@ -230,6 +230,7 @@ export const ChannelItem = observer(
|
||||
const isVoiceDragActive = draggingChannel?.channelType === ChannelTypes.GUILD_VOICE;
|
||||
const shouldDimForVoiceDrag = Boolean(isVoiceDragActive && channelIsText && channel.parentId !== null);
|
||||
const unreadCount = ReadStates.getUnreadCount(channel.id);
|
||||
const hasUnread = ReadStates.hasUnread(channel.id);
|
||||
const connectedVoiceGuildId = channelIsVoice ? MediaEngine.guildId : null;
|
||||
const connectedVoiceChannelId = channelIsVoice ? MediaEngine.channelId : null;
|
||||
const canManageChannels = Permission.can(Permissions.MANAGE_CHANNELS, channel);
|
||||
@@ -265,6 +266,7 @@ export const ChannelItem = observer(
|
||||
type: channel.type,
|
||||
});
|
||||
const unreadState = getChannelUnreadState({
|
||||
hasUnread,
|
||||
unreadCount,
|
||||
mentionCount,
|
||||
isMuted: isChannelDirectlyMuted,
|
||||
|
||||
@@ -335,6 +335,7 @@ export const ChannelListContent = observer(({guild, scrollY}: {guild: Guild; scr
|
||||
);
|
||||
const hasVisibleUnreadInChannel = (channelId: string): boolean => {
|
||||
const unreadCount = ReadStates.getUnreadCount(channelId);
|
||||
const hasUnread = ReadStates.hasUnread(channelId);
|
||||
const mentionCount = ReadStates.getMentionCount(channelId);
|
||||
const isMuted =
|
||||
UserGuildSettings.isParentCategoryMuted(guild.id, channelId) ||
|
||||
@@ -349,6 +350,7 @@ export const ChannelListContent = observer(({guild, scrollY}: {guild: Guild; scr
|
||||
})
|
||||
: null;
|
||||
const unreadState = getChannelUnreadState({
|
||||
hasUnread,
|
||||
unreadCount,
|
||||
mentionCount,
|
||||
isMuted,
|
||||
|
||||
@@ -197,6 +197,7 @@ const FavoriteChannelResolvedItem = observer(
|
||||
);
|
||||
const refs = useMergeRefs([dragConnectorRef, dropConnectorRef, elementRef]);
|
||||
const unreadCount = ReadStates.getUnreadCount(channel.id);
|
||||
const hasUnread = ReadStates.hasUnread(channel.id);
|
||||
const mentionCount = ReadStates.getMentionCount(channel.id);
|
||||
const isGroupDM = channel.isGroupDM();
|
||||
const isDM = channel.isDM();
|
||||
@@ -220,6 +221,7 @@ const FavoriteChannelResolvedItem = observer(
|
||||
})
|
||||
: null;
|
||||
const unreadState = getChannelUnreadState({
|
||||
hasUnread,
|
||||
unreadCount,
|
||||
mentionCount,
|
||||
isMuted,
|
||||
|
||||
@@ -663,6 +663,7 @@ function resolveGuildTargetBounds({
|
||||
function getDMScrollIndicatorSeverity(channelId: string): ScrollIndicatorSeverity | null {
|
||||
const mentionCount = ReadStates.getPrivateChannelMentionCount(channelId);
|
||||
const unreadState = getChannelUnreadState({
|
||||
hasUnread: ReadStates.hasUnreadPrivateChannel(channelId),
|
||||
unreadCount: ReadStates.getPrivateChannelUnreadCount(channelId),
|
||||
mentionCount,
|
||||
isMuted: UserGuildSettings.isChannelDirectlyMuted(null, channelId),
|
||||
|
||||
@@ -70,6 +70,7 @@ const ACTIVE_CALL_DESCRIPTOR = msg({
|
||||
|
||||
export function resolveDMListItemUnreadState(channelId: string): ChannelUnreadState {
|
||||
return getChannelUnreadState({
|
||||
hasUnread: ReadStates.hasUnread(channelId),
|
||||
unreadCount: ReadStates.getUnreadCount(channelId),
|
||||
mentionCount: ReadStates.getMentionCount(channelId),
|
||||
isMuted: UserGuildSettings.isChannelDirectlyMuted(null, channelId),
|
||||
|
||||
@@ -7,6 +7,7 @@ import {getChannelUnreadState} from './ChannelUnreadState';
|
||||
describe('getChannelUnreadState', () => {
|
||||
it('shows a normal unread indicator for all-messages unread badges', () => {
|
||||
const state = getChannelUnreadState({
|
||||
hasUnread: true,
|
||||
unreadCount: 3,
|
||||
mentionCount: 0,
|
||||
isMuted: false,
|
||||
@@ -19,6 +20,7 @@ describe('getChannelUnreadState', () => {
|
||||
});
|
||||
it('shows a muted unread indicator for only-mentions unread badges without highlighting the channel', () => {
|
||||
const state = getChannelUnreadState({
|
||||
hasUnread: true,
|
||||
unreadCount: 3,
|
||||
mentionCount: 0,
|
||||
isMuted: false,
|
||||
@@ -31,6 +33,7 @@ describe('getChannelUnreadState', () => {
|
||||
});
|
||||
it('hides unread and mention surfaces when unread badges are disabled', () => {
|
||||
const state = getChannelUnreadState({
|
||||
hasUnread: true,
|
||||
unreadCount: 3,
|
||||
mentionCount: 1,
|
||||
isMuted: false,
|
||||
@@ -43,6 +46,7 @@ describe('getChannelUnreadState', () => {
|
||||
});
|
||||
it('keeps legacy muted-channel fading for channels without an unread-badges level', () => {
|
||||
const hiddenState = getChannelUnreadState({
|
||||
hasUnread: true,
|
||||
unreadCount: 3,
|
||||
mentionCount: 0,
|
||||
isMuted: true,
|
||||
@@ -50,6 +54,7 @@ describe('getChannelUnreadState', () => {
|
||||
unreadBadgesLevel: null,
|
||||
});
|
||||
const fadedState = getChannelUnreadState({
|
||||
hasUnread: true,
|
||||
unreadCount: 3,
|
||||
mentionCount: 0,
|
||||
isMuted: true,
|
||||
@@ -60,4 +65,27 @@ describe('getChannelUnreadState', () => {
|
||||
expect(fadedState.shouldShowUnreadIndicator).toBe(true);
|
||||
expect(fadedState.isUnreadIndicatorMuted).toBe(true);
|
||||
});
|
||||
it('shows the indicator from the unread flag rather than the message count', () => {
|
||||
const state = getChannelUnreadState({
|
||||
hasUnread: true,
|
||||
unreadCount: 0,
|
||||
mentionCount: 0,
|
||||
isMuted: false,
|
||||
showFadedUnreadOnMutedChannels: false,
|
||||
unreadBadgesLevel: null,
|
||||
});
|
||||
expect(state.shouldShowUnreadIndicator).toBe(true);
|
||||
});
|
||||
it('hides the indicator for a read channel even if a stale count survives', () => {
|
||||
const state = getChannelUnreadState({
|
||||
hasUnread: false,
|
||||
unreadCount: 7,
|
||||
mentionCount: 0,
|
||||
isMuted: false,
|
||||
showFadedUnreadOnMutedChannels: false,
|
||||
unreadBadgesLevel: null,
|
||||
});
|
||||
expect(state.shouldShowUnreadIndicator).toBe(false);
|
||||
expect(state.hasVisibleUnread).toBe(false);
|
||||
});
|
||||
});
|
||||
@@ -3,6 +3,7 @@
|
||||
import {resolveChannelUnreadState} from './ChannelUnreadStateMachine';
|
||||
|
||||
export interface ChannelUnreadStateInput {
|
||||
hasUnread: boolean;
|
||||
unreadCount: number;
|
||||
mentionCount: number;
|
||||
isMuted: boolean;
|
||||
@@ -20,6 +21,7 @@ export interface ChannelUnreadState {
|
||||
}
|
||||
|
||||
export function getChannelUnreadState({
|
||||
hasUnread,
|
||||
unreadCount,
|
||||
mentionCount,
|
||||
isMuted,
|
||||
@@ -27,6 +29,7 @@ export function getChannelUnreadState({
|
||||
unreadBadgesLevel,
|
||||
}: ChannelUnreadStateInput): ChannelUnreadState {
|
||||
return resolveChannelUnreadState({
|
||||
hasUnread,
|
||||
unreadCount,
|
||||
mentionCount,
|
||||
isMuted,
|
||||
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
|
||||
function input(overrides: Partial<ChannelUnreadStateInput> = {}): ChannelUnreadStateInput {
|
||||
return {
|
||||
hasUnread: false,
|
||||
unreadCount: 0,
|
||||
mentionCount: 0,
|
||||
isMuted: false,
|
||||
@@ -38,6 +39,7 @@ describe('channelUnreadStateMachine', () => {
|
||||
const snapshot = createChannelUnreadSnapshot(
|
||||
input({
|
||||
unreadBadgesLevel: MessageNotifications.NO_MESSAGES,
|
||||
hasUnread: true,
|
||||
unreadCount: 1,
|
||||
mentionCount: 1,
|
||||
}),
|
||||
@@ -55,6 +57,7 @@ describe('channelUnreadStateMachine', () => {
|
||||
it('transitions without preserving stale policy output', () => {
|
||||
const legacySnapshot = createChannelUnreadSnapshot(
|
||||
input({
|
||||
hasUnread: true,
|
||||
unreadCount: 2,
|
||||
isMuted: true,
|
||||
showFadedUnreadOnMutedChannels: false,
|
||||
@@ -66,6 +69,7 @@ describe('channelUnreadStateMachine', () => {
|
||||
type: 'channelUnread.updated',
|
||||
input: input({
|
||||
unreadBadgesLevel: MessageNotifications.ALL_MESSAGES,
|
||||
hasUnread: true,
|
||||
unreadCount: 2,
|
||||
isMuted: true,
|
||||
}),
|
||||
|
||||
@@ -86,7 +86,7 @@ export function transitionChannelUnreadSnapshot(
|
||||
|
||||
export function selectChannelUnreadState(snapshot: ChannelUnreadSnapshot): ChannelUnreadState {
|
||||
const context = snapshot.context;
|
||||
const hasUnreadMessages = context.unreadCount > 0;
|
||||
const hasUnreadMessages = context.hasUnread;
|
||||
const rawHasMentions = context.mentionCount > 0;
|
||||
switch (getUnreadStateValue(snapshot)) {
|
||||
case 'disabled':
|
||||
|
||||
Reference in new issue
Block a user