diff --git a/desktop/src/features/messages/ui/MessageTimeline.tsx b/desktop/src/features/messages/ui/MessageTimeline.tsx index 73e96dfa7..6e549bc8c 100644 --- a/desktop/src/features/messages/ui/MessageTimeline.tsx +++ b/desktop/src/features/messages/ui/MessageTimeline.tsx @@ -1,5 +1,5 @@ import * as React from "react"; -import { ArrowDown, ArrowUp, Hash } from "lucide-react"; +import { Hash } from "lucide-react"; import { selectTimelineBodySurface, @@ -11,9 +11,9 @@ import type { UserProfileLookup } from "@/features/profile/lib/identity"; import type { ChannelType } from "@/shared/api/types"; import { cn } from "@/shared/lib/cn"; import { channelChrome } from "@/shared/layout/chromeLayout"; -import { Button } from "@/shared/ui/button"; import { Spinner } from "@/shared/ui/spinner"; import { TooltipProvider } from "@/shared/ui/tooltip"; +import { UnreadPill, unreadCountLabel } from "@/shared/ui/UnreadPill"; import { UserAvatar } from "@/shared/ui/UserAvatar"; import { TimelineSkeleton, useTimelineSkeletonRows } from "./TimelineSkeleton"; import { TimelineMessageList } from "./TimelineMessageList"; @@ -313,17 +313,12 @@ const MessageTimelineBase = React.forwardRef< channelChrome.top, )} > - + testId="message-unread-pill" + /> ) : null}
- + testId="message-scroll-to-latest" + />
) : null} diff --git a/desktop/src/features/sidebar/ui/AppSidebar.tsx b/desktop/src/features/sidebar/ui/AppSidebar.tsx index 9262d27e3..358937cff 100644 --- a/desktop/src/features/sidebar/ui/AppSidebar.tsx +++ b/desktop/src/features/sidebar/ui/AppSidebar.tsx @@ -1,8 +1,6 @@ // biome-ignore format: keep compact to stay within file size limit import { Activity, - ArrowDown, - ArrowUp, Bot, FolderGit2, Home, @@ -556,7 +554,6 @@ export function AppSidebar({ {unreadAboveCount > 0 ? ( } onClick={scrollToNextAbove} position="top" testId="sidebar-more-unread-above" @@ -768,7 +765,6 @@ export function AppSidebar({ } onClick={scrollToNextBelow} position="bottom" testId="sidebar-more-unread-below" diff --git a/desktop/src/features/sidebar/ui/MoreUnreadButton.tsx b/desktop/src/features/sidebar/ui/MoreUnreadButton.tsx index e0b2d027b..403883482 100644 --- a/desktop/src/features/sidebar/ui/MoreUnreadButton.tsx +++ b/desktop/src/features/sidebar/ui/MoreUnreadButton.tsx @@ -1,21 +1,14 @@ -import type * as React from "react"; - -import { Button } from "@/shared/ui/button"; - -const MORE_UNREAD_BUTTON_CLASS = - "h-7 min-h-7 gap-1.5 rounded-full border-0 bg-primary px-2.5 text-2xs font-medium text-primary-foreground shadow-md hover:bg-primary/90 [&_svg]:size-4"; +import { UnreadPill, unreadCountLabel } from "@/shared/ui/UnreadPill"; export function MoreUnreadButton({ bottomClassName = "bottom-0", count, - icon, onClick, position, testId, }: { bottomClassName?: string; count: number; - icon: React.ReactNode; onClick: () => void; position: "top" | "bottom"; testId: string; @@ -24,17 +17,12 @@ export function MoreUnreadButton({
- + testId={testId} + />
); } diff --git a/desktop/src/shared/ui/UnreadPill.tsx b/desktop/src/shared/ui/UnreadPill.tsx new file mode 100644 index 000000000..50f481c0b --- /dev/null +++ b/desktop/src/shared/ui/UnreadPill.tsx @@ -0,0 +1,37 @@ +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"; + +export function unreadCountLabel(count: number) { + return `${count} new message${count === 1 ? "" : "s"}`; +} + +export function UnreadPill({ + direction, + label, + onClick, + testId, +}: { + direction: "up" | "down"; + label: string; + onClick: () => void; + testId: string; +}) { + const Arrow = direction === "up" ? ArrowUp : ArrowDown; + return ( + + ); +}