fix(desktop): align sidebar unread pills (#1138)

This commit is contained in:
thomaspblock
2026-06-19 11:37:10 -04:00
committed by GitHub
parent c448f1c729
commit 5975421889
3 changed files with 64 additions and 68 deletions
+59 -66
View File
@@ -229,15 +229,6 @@ export function AppSidebar({
React.useState(false);
const showSidebarUpdateCard =
canShowSidebarUpdateCard && !isSidebarUpdateCardDismissed;
const sidebarFooterCardCount =
(sidebarRelayConnectionCard.showSidebarRelayConnectionCard ? 1 : 0) +
(showSidebarUpdateCard ? 1 : 0);
const unreadBelowBottomClass =
sidebarFooterCardCount >= 2
? "bottom-56"
: sidebarFooterCardCount >= 1
? "bottom-44"
: "bottom-24";
const [isNewDmOpenInternal, setIsNewDmOpenInternal] = React.useState(false);
const isNewDmOpen = isNewDmOpenProp ?? isNewDmOpenInternal;
const setIsNewDmOpen = onNewDmOpenChange ?? setIsNewDmOpenInternal;
@@ -776,64 +767,66 @@ export function AppSidebar({
) : null}
</SidebarContent>
{unreadBelowCount > 0 ? (
<MoreUnreadButton
bottomClassName={unreadBelowBottomClass}
count={unreadBelowCount}
onClick={scrollToNextBelow}
position="bottom"
testId="sidebar-more-unread-below"
/>
) : null}
<SidebarFooter className="z-30 shrink-0 bg-sidebar/55 backdrop-blur-xl supports-[backdrop-filter]:bg-sidebar/45 dark:bg-sidebar/45 dark:supports-[backdrop-filter]:bg-sidebar/35">
<AnimatePresence>
{sidebarRelayConnectionCard.showSidebarRelayConnectionCard ? (
<SidebarRelayConnectionCard
className="mb-2 group-data-[collapsible=icon]:hidden"
isConnected={
sidebarRelayConnectionCard.isRelayConnectionSuccess
}
isReconnectPending={
sidebarRelayConnectionCard.isRelayReconnectPending
}
onDismiss={
sidebarRelayConnectionCard.onDismissRelayConnectionCard
}
onReconnect={sidebarRelayConnectionCard.onReconnectRelay}
key="sidebar-relay-connection-card"
/>
) : null}
</AnimatePresence>
{showSidebarUpdateCard ? (
<div className="mb-2 group-data-[collapsible=icon]:hidden">
<SidebarUpdateCard
onDismiss={() => setIsSidebarUpdateCardDismissed(true)}
/>
</div>
<div className="relative z-30 shrink-0">
{unreadBelowCount > 0 ? (
<MoreUnreadButton
bottomClassName="bottom-full"
count={unreadBelowCount}
onClick={scrollToNextBelow}
position="bottom"
testId="sidebar-more-unread-below"
/>
) : null}
<SidebarMenu>
<SidebarMenuItem>
<SidebarProfileCard
activeWorkspace={activeWorkspace}
isPresencePending={isPresencePending}
onOpenAddWorkspace={onOpenAddWorkspace}
onOpenSettings={onSelectSettings}
onRemoveWorkspace={onRemoveWorkspace}
onSetPresenceStatus={onSetPresenceStatus}
onSetUserStatus={onSetUserStatus}
onClearUserStatus={onClearUserStatus}
onSwitchWorkspace={onSwitchWorkspace}
onUpdateWorkspace={onUpdateWorkspace}
profile={profile}
resolvedDisplayName={resolvedDisplayName}
selfPresenceStatus={selfPresenceStatus}
selfUserStatus={selfUserStatus}
workspaces={workspaces}
/>
</SidebarMenuItem>
</SidebarMenu>
</SidebarFooter>
<SidebarFooter className="bg-sidebar/55 backdrop-blur-xl supports-[backdrop-filter]:bg-sidebar/45 dark:bg-sidebar/45 dark:supports-[backdrop-filter]:bg-sidebar/35">
<AnimatePresence>
{sidebarRelayConnectionCard.showSidebarRelayConnectionCard ? (
<SidebarRelayConnectionCard
className="mb-2 group-data-[collapsible=icon]:hidden"
isConnected={
sidebarRelayConnectionCard.isRelayConnectionSuccess
}
isReconnectPending={
sidebarRelayConnectionCard.isRelayReconnectPending
}
onDismiss={
sidebarRelayConnectionCard.onDismissRelayConnectionCard
}
onReconnect={sidebarRelayConnectionCard.onReconnectRelay}
key="sidebar-relay-connection-card"
/>
) : null}
</AnimatePresence>
{showSidebarUpdateCard ? (
<div className="mb-2 group-data-[collapsible=icon]:hidden">
<SidebarUpdateCard
onDismiss={() => setIsSidebarUpdateCardDismissed(true)}
/>
</div>
) : null}
<SidebarMenu>
<SidebarMenuItem>
<SidebarProfileCard
activeWorkspace={activeWorkspace}
isPresencePending={isPresencePending}
onOpenAddWorkspace={onOpenAddWorkspace}
onOpenSettings={onSelectSettings}
onRemoveWorkspace={onRemoveWorkspace}
onSetPresenceStatus={onSetPresenceStatus}
onSetUserStatus={onSetUserStatus}
onClearUserStatus={onClearUserStatus}
onSwitchWorkspace={onSwitchWorkspace}
onUpdateWorkspace={onUpdateWorkspace}
profile={profile}
resolvedDisplayName={resolvedDisplayName}
selfPresenceStatus={selfPresenceStatus}
selfUserStatus={selfUserStatus}
workspaces={workspaces}
/>
</SidebarMenuItem>
</SidebarMenu>
</SidebarFooter>
</div>
</div>
<CreateChannelDialog
@@ -14,9 +14,12 @@ export function MoreUnreadButton({
position: "top" | "bottom";
testId: string;
}) {
const positionClassName =
position === "top" ? topChromeInset.top : bottomClassName;
return (
<div
className={`pointer-events-none absolute inset-x-0 z-10 flex justify-center py-1 ${position === "top" ? topChromeInset.top : bottomClassName}`}
className={`pointer-events-none absolute inset-x-0 z-10 flex justify-center py-1 ${positionClassName}`}
>
<UnreadPill
direction={position === "top" ? "up" : "down"}
+1 -1
View File
@@ -3,7 +3,7 @@ import { ArrowDown, ArrowUp } from "lucide-react";
import { Button } from "@/shared/ui/button";
const UNREAD_PILL_CLASS =
"pointer-events-auto h-7 min-h-7 gap-1.5 rounded-full border-primary/40 bg-primary/10 px-2.5 text-2xs font-medium text-primary shadow-xs backdrop-blur-sm hover:bg-primary/20 [&_svg]:size-4";
"pointer-events-auto h-7 min-h-7 gap-1.5 rounded-full border-border/70 bg-background/95 px-2 py-1 text-2xs font-medium tracking-[0.02em] text-muted-foreground/70 shadow-xs backdrop-blur-sm hover:bg-muted/70 hover:text-foreground [&_svg]:size-4";
export function unreadCountLabel(count: number) {
return `${count} new message${count === 1 ? "" : "s"}`;