mirror of
https://github.com/block/buzz.git
synced 2026-10-29 05:21:31 +00:00
Sort direct messages alphabetically (#1180)
Signed-off-by: Wes <wesbillman@users.noreply.github.com> Co-authored-by: Pinky <44b8e82baa6e0e254e0208d68f335c283c94e7b78dd1fa10d5a49d3f13dd0435@sprout-oss.stage.blox.sqprod.co>
This commit is contained in:
72
desktop/src/features/sidebar/lib/dmSidebarSort.test.mjs
Normal file
72
desktop/src/features/sidebar/lib/dmSidebarSort.test.mjs
Normal file
@@ -0,0 +1,72 @@
|
||||
import assert from "node:assert/strict";
|
||||
import test from "node:test";
|
||||
|
||||
import { sortDmChannelsByLabel } from "./dmSidebarSort.ts";
|
||||
|
||||
function makeDm(id, name) {
|
||||
return {
|
||||
archivedAt: null,
|
||||
channelType: "dm",
|
||||
description: "",
|
||||
id,
|
||||
isMember: true,
|
||||
lastMessageAt: null,
|
||||
memberCount: 2,
|
||||
memberPubkeys: [],
|
||||
name,
|
||||
participantPubkeys: [],
|
||||
participants: [],
|
||||
purpose: null,
|
||||
topic: null,
|
||||
ttlDeadline: null,
|
||||
ttlSeconds: null,
|
||||
visibility: "private",
|
||||
};
|
||||
}
|
||||
|
||||
test("sorts direct messages by resolved display label", () => {
|
||||
const sorted = sortDmChannelsByLabel(
|
||||
[
|
||||
makeDm("c", "Group DM (3)"),
|
||||
makeDm("a", "Group DM (3)"),
|
||||
makeDm("b", "Group DM (3)"),
|
||||
],
|
||||
{
|
||||
a: "Fizz",
|
||||
b: "Brain",
|
||||
c: "Wes",
|
||||
},
|
||||
);
|
||||
|
||||
assert.deepEqual(
|
||||
sorted.map((channel) => channel.id),
|
||||
["b", "a", "c"],
|
||||
);
|
||||
});
|
||||
|
||||
test("falls back to channel name until labels resolve", () => {
|
||||
const sorted = sortDmChannelsByLabel(
|
||||
[makeDm("b", "Zed"), makeDm("a", "Amy")],
|
||||
{},
|
||||
);
|
||||
|
||||
assert.deepEqual(
|
||||
sorted.map((channel) => channel.id),
|
||||
["a", "b"],
|
||||
);
|
||||
});
|
||||
|
||||
test("uses channel id as a deterministic tie breaker", () => {
|
||||
const sorted = sortDmChannelsByLabel(
|
||||
[makeDm("b", "Group DM (3)"), makeDm("a", "Group DM (3)")],
|
||||
{
|
||||
a: "Wes",
|
||||
b: "Wes",
|
||||
},
|
||||
);
|
||||
|
||||
assert.deepEqual(
|
||||
sorted.map((channel) => channel.id),
|
||||
["a", "b"],
|
||||
);
|
||||
});
|
||||
14
desktop/src/features/sidebar/lib/dmSidebarSort.ts
Normal file
14
desktop/src/features/sidebar/lib/dmSidebarSort.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import type { Channel } from "@/shared/api/types";
|
||||
|
||||
export function sortDmChannelsByLabel(
|
||||
channels: Channel[],
|
||||
channelLabels: Record<string, string>,
|
||||
) {
|
||||
return [...channels].sort((left, right) => {
|
||||
const leftLabel = channelLabels[left.id] ?? left.name;
|
||||
const rightLabel = channelLabels[right.id] ?? right.name;
|
||||
return (
|
||||
leftLabel.localeCompare(rightLabel) || left.id.localeCompare(right.id)
|
||||
);
|
||||
});
|
||||
}
|
||||
@@ -21,6 +21,7 @@ import {
|
||||
type ChannelSection,
|
||||
} from "@/features/sidebar/lib/useChannelSections";
|
||||
import { useDmSidebarMetadata } from "@/features/sidebar/useDmSidebarMetadata";
|
||||
import { sortDmChannelsByLabel } from "@/features/sidebar/lib/dmSidebarSort";
|
||||
import { useSidebarScrollLock } from "@/features/sidebar/lib/useSidebarScrollLock";
|
||||
import { useUnreadOverflow } from "@/features/sidebar/lib/useUnreadOverflow";
|
||||
import {
|
||||
@@ -458,6 +459,10 @@ export function AppSidebar({
|
||||
fallbackDisplayName,
|
||||
profileDisplayName: profile?.displayName,
|
||||
});
|
||||
const sortedDirectMessages = React.useMemo(
|
||||
() => sortDmChannelsByLabel(directMessages, dmChannelLabels),
|
||||
[directMessages, dmChannelLabels],
|
||||
);
|
||||
const sidebarLoadingShape = useSidebarLoadingShape({
|
||||
activeWorkspaceId: activeWorkspace?.id,
|
||||
currentPubkey,
|
||||
@@ -787,7 +792,7 @@ export function AppSidebar({
|
||||
dmParticipantsByChannelId={dmParticipantsByChannelId}
|
||||
isCollapsed={collapsedGroups.directMessages}
|
||||
isActiveChannel={selectedView === "channel"}
|
||||
items={directMessages}
|
||||
items={sortedDirectMessages}
|
||||
channelLabels={dmChannelLabels}
|
||||
onHideDm={onHideDm}
|
||||
onMarkChannelRead={onMarkChannelRead}
|
||||
|
||||
Reference in New Issue
Block a user