diff --git a/desktop/src/features/sidebar/ui/CommunityRail.tsx b/desktop/src/features/sidebar/ui/CommunityRail.tsx
index b15e0bab71..aa44b5757d 100644
--- a/desktop/src/features/sidebar/ui/CommunityRail.tsx
+++ b/desktop/src/features/sidebar/ui/CommunityRail.tsx
@@ -368,71 +368,77 @@ export function CommunityRail({
};
return (
-
+ {communities.map((community) => (
+ onOpenSettings?.("community-members")}
+ onMarkAllRead={handleMarkAllRead}
+ onSetEditingCommunity={setEditingCommunity}
+ onSwitchCommunity={onSwitchCommunity}
+ />
+ ))}
+
+
+ {draggingCommunity ? (
+
+ ) : null}
+
+
+
+
+
+
+ Add community
+
+ 1}
+ onOpenChange={(open) => {
+ if (!open) setEditingCommunity(null);
+ }}
+ onRemove={onRemoveCommunity}
+ onSave={onUpdateCommunity}
+ open={editingCommunity !== null}
+ community={editingCommunity}
+ showIconEditor={editingCommunity?.id === activeCommunityId}
+ />
+
+
);
}
diff --git a/desktop/tests/e2e/community-rail.spec.ts b/desktop/tests/e2e/community-rail.spec.ts
index 68c12f69df..bbe2a1f367 100644
--- a/desktop/tests/e2e/community-rail.spec.ts
+++ b/desktop/tests/e2e/community-rail.spec.ts
@@ -648,6 +648,7 @@ test.describe("community rail", () => {
// Spoof macOS so the rail applies its traffic-light top inset.
await page.addInitScript(() => {
Object.defineProperty(navigator, "platform", { get: () => "MacIntel" });
+ window.localStorage.setItem("buzz-theme", "dracula");
});
await installMockBridge(page, undefined, { skipCommunitySeed: true });
await seedCommunities(page, [COMMUNITY_A, COMMUNITY_B], COMMUNITY_A.id);
@@ -661,6 +662,12 @@ test.describe("community rail", () => {
await expect(firstButton).toBeVisible();
const buttonBox = await firstButton.boundingBox();
const railBox = await page.getByTestId("community-rail").boundingBox();
+ const railSurfaceBox = await page
+ .getByTestId("community-rail-surface")
+ .boundingBox();
+ const appSurfaceBox = await page
+ .locator(".buzz-huddle-app-surface")
+ .boundingBox();
const searchBox = await page.getByTestId("open-search").boundingBox();
const contentBox = await page
.locator("[data-buzz-content-surface]")
@@ -670,10 +677,58 @@ test.describe("community rail", () => {
expect(railBox).not.toBeNull();
expect(searchBox).not.toBeNull();
expect(contentBox).not.toBeNull();
+ expect(railSurfaceBox).not.toBeNull();
+ expect(appSurfaceBox).not.toBeNull();
expect(buttonBox?.y ?? 0).toBeGreaterThanOrEqual(32);
expect(Math.abs((railBox?.y ?? 0) - (contentBox?.y ?? 0))).toBeLessThan(
0.5,
);
+ expect(
+ Math.abs((railSurfaceBox?.y ?? 0) - (appSurfaceBox?.y ?? 0)),
+ ).toBeLessThan(0.5);
+ expect(
+ Math.abs(
+ (railSurfaceBox?.y ?? 0) +
+ (railSurfaceBox?.height ?? 0) -
+ ((appSurfaceBox?.y ?? 0) + (appSurfaceBox?.height ?? 0)),
+ ),
+ ).toBeLessThan(0.5);
+
+ const gapPaint = await page.evaluate(() => {
+ const surface = document.querySelector(
+ '[data-testid="community-rail-surface"]',
+ );
+ const rail = document.querySelector(
+ '[data-testid="community-rail"]',
+ );
+ if (!surface || !rail) throw new Error("community rail is missing");
+
+ const surfaceBox = surface.getBoundingClientRect();
+ const railBox = rail.getBoundingClientRect();
+ const x = surfaceBox.left + surfaceBox.width / 2;
+ const bottomGapElement = document.elementFromPoint(
+ x,
+ railBox.bottom + (surfaceBox.bottom - railBox.bottom) / 2,
+ );
+ const topGapElement = document.elementFromPoint(
+ x,
+ surfaceBox.top + (railBox.top - surfaceBox.top) / 2,
+ );
+
+ return {
+ backgroundColor: getComputedStyle(surface).backgroundColor,
+ bottomOwned:
+ bottomGapElement?.closest(
+ '[data-testid="community-rail-surface"]',
+ ) === surface,
+ topOwned:
+ topGapElement?.closest('[data-testid="community-rail-surface"]') ===
+ surface,
+ };
+ });
+ expect(gapPaint.backgroundColor).not.toBe("rgba(0, 0, 0, 0)");
+ expect(gapPaint.topOwned).toBe(true);
+ expect(gapPaint.bottomOwned).toBe(true);
const leftInset = (buttonBox?.x ?? 0) - (railBox?.x ?? 0);
const rightInset =