From 3d7361f8a283d2082cb3655a19e61b82a33c3038 Mon Sep 17 00:00:00 2001 From: Pavlenex <36959754+pavlenex@users.noreply.github.com> Date: Sat, 18 Jul 2026 12:13:20 +0500 Subject: [PATCH] fix(desktop): restore channel browsing and add recent sorting Signed-off-by: Pavlenex <36959754+pavlenex@users.noreply.github.com> --- .../channels/ui/ChannelBrowserDialog.tsx | 58 +++++++++++-------- .../features/search/ui/SearchResultItem.tsx | 6 +- .../src/features/search/ui/TopbarSearch.tsx | 21 ++++++- .../src/features/sidebar/ui/AppSidebar.tsx | 3 +- .../sidebar/ui/AppSidebarPinnedHeader.tsx | 3 + desktop/tests/e2e/channel-browser.spec.ts | 30 ++++++++++ 6 files changed, 92 insertions(+), 29 deletions(-) diff --git a/desktop/src/features/channels/ui/ChannelBrowserDialog.tsx b/desktop/src/features/channels/ui/ChannelBrowserDialog.tsx index 8f1d162af1..b1371f8bd7 100644 --- a/desktop/src/features/channels/ui/ChannelBrowserDialog.tsx +++ b/desktop/src/features/channels/ui/ChannelBrowserDialog.tsx @@ -10,6 +10,10 @@ import { import type { Channel } from "@/shared/api/types"; import { scoreChannelMatch } from "@/features/channels/lib/channelSearchScore"; +import { + type ChannelSortMode, + sortChannelsForSidebar, +} from "@/features/sidebar/lib/channelSortPreference"; import { ListSortDescending } from "@/shared/ui/icons"; import { Dialog, @@ -45,10 +49,11 @@ import { } from "@/features/sidebar/ui/CreateChannelFormFields"; type BrowserTab = "all" | "joined" | "archived"; -type ChannelSort = "alphabetical" | "members"; +type ChannelSort = ChannelSortMode | "members"; const CHANNEL_SORT_OPTIONS: { label: string; value: ChannelSort }[] = [ - { label: "Alphabetical", value: "alphabetical" }, + { label: "Alphabetical", value: "alpha" }, + { label: "Recent", value: "recent" }, { label: "Most members", value: "members" }, ]; @@ -102,7 +107,7 @@ export function ChannelBrowserDialog({ }: ChannelBrowserDialogProps) { const [query, setQuery] = React.useState(""); const [activeTab, setActiveTab] = React.useState("all"); - const [sort, setSort] = React.useState("alphabetical"); + const [sort, setSort] = React.useState("alpha"); const [selectedIndex, setSelectedIndex] = React.useState(null); const [joiningChannelId, setJoiningChannelId] = React.useState( null, @@ -132,7 +137,7 @@ export function ChannelBrowserDialog({ const isForumMode = channelTypeFilter === "forum"; const canCreate = Boolean(onCreateChannel); const createKind = isForumMode ? "forum" : "stream"; - const browseTitle = isForumMode ? "Add a forum" : "Add a channel"; + const browseTitle = isForumMode ? "Add a forum" : "Browse channels"; const searchPlaceholder = canCreate ? isForumMode ? "Search or create a forum" @@ -206,23 +211,30 @@ export function ChannelBrowserDialog({ const isSearching = deferredQuery.length > 0; const orderedVisibleChannels = React.useMemo(() => { - return [...visibleChannels].sort((a, b) => { - // While searching, best match wins so the channel you meant floats to - // the top; ties fall back to the user's chosen sort below. - if (isSearching) { - const scoreA = matchScoreById.get(a.id) ?? Number.POSITIVE_INFINITY; - const scoreB = matchScoreById.get(b.id) ?? Number.POSITIVE_INFINITY; - if (scoreA !== scoreB) return scoreA - scoreB; - } - - if (sort === "members" && b.memberCount !== a.memberCount) { - return b.memberCount - a.memberCount; - } - - return a.name.localeCompare(b.name, undefined, { sensitivity: "base" }); - }); + const sorted = + sort === "members" + ? [...visibleChannels].sort( + (a, b) => + b.memberCount - a.memberCount || + a.name.localeCompare(b.name, undefined, { + sensitivity: "base", + }), + ) + : sortChannelsForSidebar(visibleChannels, sort); + + if (!isSearching) return sorted; + + return sorted.sort( + (a, b) => + (matchScoreById.get(a.id) ?? Number.POSITIVE_INFINITY) - + (matchScoreById.get(b.id) ?? Number.POSITIVE_INFINITY), + ); }, [isSearching, matchScoreById, sort, visibleChannels]); + const selectedSortLabel = + CHANNEL_SORT_OPTIONS.find((option) => option.value === sort)?.label ?? + "Alphabetical"; + const allTabLabel = isForumMode ? "All forums" : "All channels"; // Whether an exact name match already exists — if so we don't offer to @@ -320,7 +332,7 @@ export function ChannelBrowserDialog({ if (!open) { setQuery(""); setActiveTab("all"); - setSort("alphabetical"); + setSort("alpha"); setSelectedIndex(null); setJoiningChannelId(null); setMode("browse"); @@ -500,11 +512,7 @@ export function ChannelBrowserDialog({