From 1e6c332eae390654d29ad7ccac82472e3d59ee2d Mon Sep 17 00:00:00 2001 From: Hampus Date: Fri, 4 Sep 2026 21:04:34 +0200 Subject: [PATCH] fix(app): show empty categories when hiding muted channels (#2460) --- .../components/layout/ChannelListContent.tsx | 7 ++-- .../utils/ChannelListVisibility.test.ts | 35 ++++++++++++++++++- .../layout/utils/ChannelListVisibility.ts | 12 +++++++ 3 files changed, 51 insertions(+), 3 deletions(-) diff --git a/fluxer_app/src/features/app/components/layout/ChannelListContent.tsx b/fluxer_app/src/features/app/components/layout/ChannelListContent.tsx index 52864c2d5..e092fe2eb 100644 --- a/fluxer_app/src/features/app/components/layout/ChannelListContent.tsx +++ b/fluxer_app/src/features/app/components/layout/ChannelListContent.tsx @@ -16,6 +16,7 @@ import {NullSpaceDropIndicator} from '@app/features/app/components/layout/NullSp import {ScrollIndicatorOverlay} from '@app/features/app/components/layout/ScrollIndicatorOverlay'; import {type DragItem, DragItemType, type DropResult} from '@app/features/app/components/layout/types/DndTypes'; import { + shouldShowCategoryWhenHidingMutedChannels, shouldShowChannelInCollapsedCategory, shouldShowChannelWhenHidingMutedChannels, } from '@app/features/app/components/layout/utils/ChannelListVisibility'; @@ -471,8 +472,10 @@ export const ChannelListContent = observer(({guild, scrollY}: {guild: Guild; scr if ( hideMutedChannels && group.category && - filteredTextChannels.length === 0 && - filteredVoiceChannels.length === 0 + !shouldShowCategoryWhenHidingMutedChannels({ + hasChannels: group.textChannels.length > 0 || group.voiceChannels.length > 0, + hasVisibleChannels: filteredTextChannels.length > 0 || filteredVoiceChannels.length > 0, + }) ) { continue; } diff --git a/fluxer_app/src/features/app/components/layout/utils/ChannelListVisibility.test.ts b/fluxer_app/src/features/app/components/layout/utils/ChannelListVisibility.test.ts index 1c8637121..a25f13b34 100644 --- a/fluxer_app/src/features/app/components/layout/utils/ChannelListVisibility.test.ts +++ b/fluxer_app/src/features/app/components/layout/utils/ChannelListVisibility.test.ts @@ -1,7 +1,11 @@ // SPDX-License-Identifier: AGPL-3.0-or-later import {describe, expect, it} from 'vitest'; -import {shouldShowChannelInCollapsedCategory, shouldShowChannelWhenHidingMutedChannels} from './ChannelListVisibility'; +import { + shouldShowCategoryWhenHidingMutedChannels, + shouldShowChannelInCollapsedCategory, + shouldShowChannelWhenHidingMutedChannels, +} from './ChannelListVisibility'; describe('shouldShowChannelWhenHidingMutedChannels', () => { it('keeps muted channels with visible unread state so mentions are findable', () => { @@ -57,6 +61,35 @@ describe('shouldShowChannelWhenHidingMutedChannels', () => { }); }); +describe('shouldShowCategoryWhenHidingMutedChannels', () => { + it('keeps a category that has no channels at all', () => { + expect( + shouldShowCategoryWhenHidingMutedChannels({ + hasChannels: false, + hasVisibleChannels: false, + }), + ).toBe(true); + }); + + it('hides a category whose channels were all filtered out as muted', () => { + expect( + shouldShowCategoryWhenHidingMutedChannels({ + hasChannels: true, + hasVisibleChannels: false, + }), + ).toBe(false); + }); + + it('keeps a category that still has visible channels', () => { + expect( + shouldShowCategoryWhenHidingMutedChannels({ + hasChannels: true, + hasVisibleChannels: true, + }), + ).toBe(true); + }); +}); + describe('shouldShowChannelInCollapsedCategory', () => { it('keeps visible unread channels reachable in collapsed categories', () => { expect( diff --git a/fluxer_app/src/features/app/components/layout/utils/ChannelListVisibility.ts b/fluxer_app/src/features/app/components/layout/utils/ChannelListVisibility.ts index 76afd7b45..10da18706 100644 --- a/fluxer_app/src/features/app/components/layout/utils/ChannelListVisibility.ts +++ b/fluxer_app/src/features/app/components/layout/utils/ChannelListVisibility.ts @@ -16,6 +16,18 @@ export function shouldShowChannelWhenHidingMutedChannels({ return isSelected || isConnected || !isMuted || hasVisibleUnread; } +export interface HiddenMutedCategoryVisibilityInput { + hasChannels: boolean; + hasVisibleChannels: boolean; +} + +export function shouldShowCategoryWhenHidingMutedChannels({ + hasChannels, + hasVisibleChannels, +}: HiddenMutedCategoryVisibilityInput): boolean { + return !hasChannels || hasVisibleChannels; +} + export interface CollapsedCategoryChannelVisibilityInput { isCategoryMuted: boolean; isSelected: boolean;