fix(desktop): navigate to channel from inbox thread header (#1847)

Signed-off-by: Matt Toohey <contact@matttoohey.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Matt Toohey
2026-07-14 09:26:57 -07:00
committed by GitHub
co-authored by Claude Fable 5
parent b1d323c4e7
commit ff11f26bcd
3 changed files with 87 additions and 14 deletions
+2 -1
View File
@@ -788,10 +788,11 @@ export function HomeView({
setIsDeletingMessage(false);
});
}}
onOpenChannel={(channelId) => {
onManageChannel={(channelId) => {
handleCloseProfilePanel();
setManagedChannelId(channelId);
}}
onOpenContext={onOpenContext}
onSendReply={async ({
content,
mediaTags,
@@ -77,7 +77,12 @@ type InboxDetailPaneProps = {
latchedDefaultParentId?: string | null;
onBack?: () => void;
onDelete: () => void;
onOpenChannel: (channelId: string) => void;
onManageChannel: (channelId: string) => void;
onOpenContext: (
channelId: string,
messageId: string,
threadRootId?: string | null,
) => void;
onSendReply: (input: {
content: string;
mediaTags?: string[][];
@@ -111,7 +116,8 @@ export function InboxDetailPane({
latchedDefaultParentId = null,
onBack,
onDelete,
onOpenChannel,
onManageChannel,
onOpenContext,
onSendReply,
onToggleReaction,
}: InboxDetailPaneProps) {
@@ -318,6 +324,7 @@ export function InboxDetailPane({
const contextLabel = channelContextName ?? formatInboxTypeLabel(item);
const hasChannelContext = Boolean(channelContextName);
const contextChannelId = item.item.channelId;
const contextThreadRootId = getThreadReference(item.item.tags).rootId;
const handleSelectReplyTarget = (message: InboxDisplayMessage) => {
setReplyTargetId((currentReplyTargetId) =>
@@ -358,7 +365,13 @@ export function InboxDetailPane({
{canOpenChannel && contextChannelId ? (
<button
className="flex min-w-0 items-center gap-[4px] text-left text-sm font-semibold leading-5 tracking-tight text-foreground hover:underline focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
onClick={() => onOpenChannel(contextChannelId)}
onClick={() =>
onOpenContext(
contextChannelId,
item.id,
contextThreadRootId,
)
}
title={item.fullTimestampLabel}
type="button"
>
@@ -394,7 +407,7 @@ export function InboxDetailPane({
currentPubkey={currentPubkey}
onManageChannel={() => {
if (contextChannelId) {
onOpenChannel(contextChannelId);
onManageChannel(contextChannelId);
}
}}
onToggleMembers={() =>
+68 -9
View File
@@ -2389,9 +2389,11 @@ test("manage channel keeps canvas near the top of the sheet", async ({
expect(canvasBox?.y).toBeLessThan(nameBox?.y);
});
test("home inbox channel label opens management without leaving home", async ({
page,
}) => {
async function seedHomeInboxMention(
page: import("@playwright/test").Page,
itemId: string,
tags?: string[][],
) {
await page.goto("/");
await expect(page.getByTestId("home-inbox-list")).toBeVisible();
await page.waitForFunction(
@@ -2401,7 +2403,14 @@ test("home inbox channel label opens management without leaving home", async ({
);
await page.evaluate(
({ channelId, createdAt, currentPubkey, senderPubkey }) => {
({
channelId,
createdAt,
currentPubkey,
itemId: id,
senderPubkey,
tags: seededTags,
}) => {
const pushFeedItem = (window as MockFeedWindow)
.__BUZZ_E2E_PUSH_MOCK_FEED_ITEM__;
if (!pushFeedItem) {
@@ -2409,14 +2418,14 @@ test("home inbox channel label opens management without leaving home", async ({
}
pushFeedItem({
id: "mock-feed-home-channel-panel",
id,
kind: 9,
pubkey: senderPubkey,
content: "Please review the home panel routing.",
created_at: createdAt,
channel_id: channelId,
channel_name: "general",
tags: [
tags: seededTags ?? [
["e", channelId],
["p", currentPubkey],
],
@@ -2427,18 +2436,68 @@ test("home inbox channel label opens management without leaving home", async ({
channelId: GENERAL_CHANNEL_ID,
createdAt: Math.floor(Date.now() / 1000),
currentPubkey: TEST_IDENTITIES.tyler.pubkey,
itemId,
senderPubkey: TEST_IDENTITIES.alice.pubkey,
tags,
},
);
await page
.getByTestId("home-inbox-item-mock-feed-home-channel-panel")
.click();
await page.getByTestId(`home-inbox-item-${itemId}`).click();
}
test("home inbox channel label navigates to the channel message", async ({
page,
}) => {
await seedHomeInboxMention(page, "mock-feed-home-channel-navigate");
await page
.getByTestId("home-inbox-detail")
.getByRole("button", { exact: true, name: "general" })
.click();
await expect(page).toHaveURL(
new RegExp(`#/channels/${GENERAL_CHANNEL_ID}\\?`),
);
await expect(page).toHaveURL(/messageId=mock-feed-home-channel-navigate/);
await expect(page).not.toHaveURL(/threadRootId=/);
await expect(page.getByTestId("message-timeline")).toBeVisible();
await expect(page.getByTestId("home-inbox-list")).toHaveCount(0);
});
test("home inbox thread reply mention carries threadRootId to the channel", async ({
page,
}) => {
const rootEventId = "mock-feed-home-thread-root";
await seedHomeInboxMention(page, "mock-feed-home-thread-navigate", [
["e", rootEventId, "", "root"],
["e", "mock-feed-home-thread-parent", "", "reply"],
["p", TEST_IDENTITIES.tyler.pubkey],
]);
await page
.getByTestId("home-inbox-detail")
.getByRole("button", { exact: true, name: "general" })
.click();
await expect(page).toHaveURL(
new RegExp(`#/channels/${GENERAL_CHANNEL_ID}\\?`),
);
await expect(page).toHaveURL(/messageId=mock-feed-home-thread-navigate/);
await expect(page).toHaveURL(new RegExp(`threadRootId=${rootEventId}`));
await expect(page.getByTestId("message-timeline")).toBeVisible();
await expect(page.getByTestId("home-inbox-list")).toHaveCount(0);
});
test("home inbox manage affordance opens management without leaving home", async ({
page,
}) => {
await seedHomeInboxMention(page, "mock-feed-home-channel-panel");
await page
.getByTestId("home-inbox-detail")
.getByTestId("channel-management-trigger")
.click();
await expect(page.getByTestId("channel-management-sheet")).toBeVisible();
await expect(page.getByTestId("channel-management-name-row")).toContainText(
"general",