mirror of
https://github.com/block/buzz.git
synced 2026-10-29 21:41:33 +00:00
fix(desktop): keep sidebar surfaces inset beside relay rail
Apply the multi-community overlap only to the pinned header so footer action cards and draggable channel rows retain their normal sidebar inset. Add a smoke regression for the update card, channel row, and drag overlay. Signed-off-by: Codex <noreply@openai.com> Signed-off-by: Matt Toohey <contact@matttoohey.com>
This commit is contained in:
@@ -85,6 +85,7 @@ export default defineConfig({
|
||||
"**/relay-connectivity.spec.ts",
|
||||
"**/unread-pill.spec.ts",
|
||||
"**/sidebar-more-unread-overlap.spec.ts",
|
||||
"**/sidebar-community-rail-insets.spec.ts",
|
||||
"**/sidebar-snapshot.spec.ts",
|
||||
"**/home-collapsed-top-chrome.spec.ts",
|
||||
"**/top-chrome-zoom-clearance.spec.ts",
|
||||
|
||||
@@ -503,13 +503,12 @@ export function AppSidebar({
|
||||
variant="sidebar"
|
||||
>
|
||||
<div
|
||||
className={`relative flex min-h-0 flex-1 flex-col overflow-hidden ${
|
||||
communities.length > 1 ? "md:-ml-[11px] md:w-[calc(100%+11px)]" : ""
|
||||
}`}
|
||||
className="relative flex min-h-0 flex-1 flex-col overflow-hidden"
|
||||
data-sidebar-background
|
||||
data-testid="app-sidebar-scroll-anchor"
|
||||
>
|
||||
<AppSidebarPinnedHeader
|
||||
className={communities.length > 1 ? "md:-ml-2" : undefined}
|
||||
channelLabels={dmChannelLabels}
|
||||
currentPubkey={currentPubkey}
|
||||
currentChannelId={
|
||||
|
||||
@@ -4,6 +4,7 @@ import { TopbarSearch } from "@/features/search/ui/TopbarSearch";
|
||||
import { SidebarProjectsSection } from "@/features/sidebar/ui/SidebarProjectsSection";
|
||||
import { FeatureGate } from "@/shared/features";
|
||||
import type { Channel, SearchHit } from "@/shared/api/types";
|
||||
import { cn } from "@/shared/lib/cn";
|
||||
import {
|
||||
SidebarHeader,
|
||||
SidebarMenu,
|
||||
@@ -24,6 +25,7 @@ type SidebarSelectedView =
|
||||
|
||||
type AppSidebarPinnedHeaderProps = {
|
||||
channelLabels: Record<string, string>;
|
||||
className?: string;
|
||||
currentChannelId?: string | null;
|
||||
currentPubkey?: string;
|
||||
onBrowseChannels?: () => void;
|
||||
@@ -51,6 +53,7 @@ type AppSidebarPrimaryMenuProps = {
|
||||
|
||||
export function AppSidebarPinnedHeader({
|
||||
channelLabels,
|
||||
className,
|
||||
currentChannelId,
|
||||
currentPubkey,
|
||||
onBrowseChannels,
|
||||
@@ -66,7 +69,7 @@ export function AppSidebarPinnedHeader({
|
||||
}: AppSidebarPinnedHeaderProps) {
|
||||
return (
|
||||
<div
|
||||
className="mx-[3px] shrink-0 px-2 pb-2 pt-3"
|
||||
className={cn("mx-[3px] shrink-0 px-2 pb-2 pt-3", className)}
|
||||
data-testid="sidebar-pinned-header"
|
||||
>
|
||||
<TopbarSearch
|
||||
|
||||
110
desktop/tests/e2e/sidebar-community-rail-insets.spec.ts
Normal file
110
desktop/tests/e2e/sidebar-community-rail-insets.spec.ts
Normal file
@@ -0,0 +1,110 @@
|
||||
import { expect, test, type Locator, type Page } from "@playwright/test";
|
||||
|
||||
import { installMockBridge } from "../helpers/bridge";
|
||||
|
||||
const COMMUNITIES = [
|
||||
{
|
||||
id: "ws-a",
|
||||
name: "Alpha",
|
||||
relayUrl: "ws://localhost:3000",
|
||||
addedAt: "2026-01-01T00:00:00.000Z",
|
||||
},
|
||||
{
|
||||
id: "ws-b",
|
||||
name: "Bravo",
|
||||
relayUrl: "ws://localhost:3001",
|
||||
addedAt: "2026-01-02T00:00:00.000Z",
|
||||
},
|
||||
];
|
||||
|
||||
async function seedCommunities(page: Page) {
|
||||
await page.addInitScript((communities) => {
|
||||
window.localStorage.setItem(
|
||||
"buzz-communities",
|
||||
JSON.stringify(communities),
|
||||
);
|
||||
window.localStorage.setItem("buzz-active-community-id", "ws-a");
|
||||
}, COMMUNITIES);
|
||||
}
|
||||
|
||||
async function showUpdateCard(page: Page) {
|
||||
await page.evaluate(() => {
|
||||
const testWindow = window as Window & {
|
||||
__BUZZ_E2E__?: { mock?: { updateAvailable?: boolean } };
|
||||
};
|
||||
testWindow.__BUZZ_E2E__ = {
|
||||
...(testWindow.__BUZZ_E2E__ ?? {}),
|
||||
mock: {
|
||||
...(testWindow.__BUZZ_E2E__?.mock ?? {}),
|
||||
updateAvailable: true,
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
await page.getByTestId("sidebar-profile-card").click();
|
||||
await page.getByTestId("profile-popover-settings").click();
|
||||
await page.getByTestId("settings-nav-updates").click();
|
||||
await page.getByRole("button", { name: "Check for Updates" }).click();
|
||||
await expect(page.getByTestId("settings-panel-updates")).toContainText(
|
||||
"Update downloaded. Click to apply.",
|
||||
);
|
||||
await page.getByTestId("settings-back-to-app").click();
|
||||
}
|
||||
|
||||
async function settleElementAnimations(locator: Locator) {
|
||||
await locator.evaluate((element) =>
|
||||
Promise.allSettled(
|
||||
element.getAnimations().map((animation) => animation.finished),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
test("keeps sidebar cards and drag surfaces inset beside the community rail", async ({
|
||||
page,
|
||||
}) => {
|
||||
await installMockBridge(page, undefined, { skipCommunitySeed: true });
|
||||
await seedCommunities(page);
|
||||
await page.goto("/");
|
||||
await expect(page.getByTestId("community-rail")).toBeVisible();
|
||||
|
||||
await showUpdateCard(page);
|
||||
|
||||
const sidebar = page.getByTestId("app-sidebar");
|
||||
const updateCard = page.getByTestId("sidebar-update-card");
|
||||
await expect(updateCard).toBeVisible();
|
||||
await settleElementAnimations(updateCard);
|
||||
const [sidebarBox, updateCardBox] = await Promise.all([
|
||||
sidebar.boundingBox(),
|
||||
updateCard.boundingBox(),
|
||||
]);
|
||||
expect(sidebarBox).not.toBeNull();
|
||||
expect(updateCardBox).not.toBeNull();
|
||||
expect((updateCardBox?.x ?? 0) - (sidebarBox?.x ?? 0)).toBeCloseTo(8, 0);
|
||||
|
||||
const channelRow = page.getByTestId("channel-general");
|
||||
await expect(channelRow).toBeVisible();
|
||||
const channelRowBox = await channelRow.boundingBox();
|
||||
expect(channelRowBox).not.toBeNull();
|
||||
expect((channelRowBox?.x ?? 0) - (sidebarBox?.x ?? 0)).toBeCloseTo(11, 0);
|
||||
if (!channelRowBox) return;
|
||||
|
||||
await page.mouse.move(
|
||||
channelRowBox.x + channelRowBox.width / 2,
|
||||
channelRowBox.y + channelRowBox.height / 2,
|
||||
);
|
||||
await page.mouse.down();
|
||||
await page.mouse.move(
|
||||
channelRowBox.x + channelRowBox.width / 2,
|
||||
channelRowBox.y + channelRowBox.height / 2 + 8,
|
||||
{ steps: 5 },
|
||||
);
|
||||
|
||||
const dragOverlay = page.getByTestId("sidebar-channel-drag-overlay");
|
||||
await expect(dragOverlay).toBeVisible();
|
||||
const dragOverlayBox = await dragOverlay.boundingBox();
|
||||
expect(dragOverlayBox).not.toBeNull();
|
||||
expect(
|
||||
(dragOverlayBox?.x ?? 0) - (sidebarBox?.x ?? 0),
|
||||
).toBeGreaterThanOrEqual(10);
|
||||
await page.mouse.up();
|
||||
});
|
||||
Reference in New Issue
Block a user