fix(desktop): experiment with overlaid inbox context header

Move the Home inbox context header into the conversation pane so the thread content sits directly under a blurred top overlay.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Thomas Petersen
2026-05-15 10:18:14 -04:00
parent 1e2ccec60e
commit c2363ff7f3
2 changed files with 63 additions and 63 deletions

View File

@@ -325,9 +325,9 @@ export function HomeView({
selectedItem.item.pubkey.trim().toLowerCase();
return (
<div className="flex-1 overflow-hidden">
<div className="flex min-h-0 flex-1 flex-col overflow-hidden">
<div
className="grid h-full min-h-0 w-full lg:grid-cols-[320px_minmax(0,1fr)]"
className="grid min-h-0 flex-1 w-full lg:grid-cols-[320px_minmax(0,1fr)]"
data-testid="home-inbox"
>
<InboxListPane
@@ -424,11 +424,6 @@ export function HomeView({
setIsSendingReply(false);
}
}}
onToggleDone={() => {
if (selectedItem) {
handleToggleDone(selectedItem.id);
}
}}
onToggleReaction={
canReply
? async (message, emoji, remove) => {
@@ -442,6 +437,11 @@ export function HomeView({
}
: undefined
}
onToggleDone={() => {
if (selectedItem) {
handleToggleDone(selectedItem.id);
}
}}
/>
</div>
</div>

View File

@@ -1,4 +1,5 @@
import {
ArrowUpRight,
CheckCheck,
Mail,
MailOpen,
@@ -17,13 +18,13 @@ import { MessageActionBar } from "@/features/messages/ui/MessageActionBar";
import { MessageComposer } from "@/features/messages/ui/MessageComposer";
import { cn } from "@/shared/lib/cn";
import { Button } from "@/shared/ui/button";
import { Markdown } from "@/shared/ui/markdown";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from "@/shared/ui/dropdown-menu";
import { Markdown } from "@/shared/ui/markdown";
import {
Tooltip,
TooltipContent,
@@ -53,12 +54,12 @@ type InboxDetailPaneProps = {
mentionPubkeys: string[];
parentEventId: string;
}) => Promise<void>;
onToggleDone: () => void;
onToggleReaction?: (
message: TimelineMessage,
emoji: string,
remove: boolean,
) => Promise<void>;
onToggleDone: () => void;
};
type InboxDisplayMessage = InboxContextMessage & {
@@ -94,8 +95,8 @@ export function InboxDetailPane({
onDelete,
onOpenContext,
onSendReply,
onToggleDone,
onToggleReaction,
onToggleDone,
}: InboxDetailPaneProps) {
const detailPaneRef = React.useRef<HTMLElement | null>(null);
const [replyTargetId, setReplyTargetId] = React.useState<string | null>(null);
@@ -202,60 +203,59 @@ export function InboxDetailPane({
data-testid="home-inbox-detail"
ref={detailPaneRef}
>
<div className="px-6 pb-1 pt-14">
<div className="flex flex-wrap items-center justify-between gap-3">
<div className="min-w-0">
<div className="flex min-w-0 flex-wrap items-center gap-2">
{canOpenChannel && contextChannelId && onOpenContext ? (
<button
className="truncate text-left text-sm font-semibold text-foreground hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
onClick={() => onOpenContext(contextChannelId, item.id)}
type="button"
>
{contextLabel}
</button>
) : (
<p className="truncate text-sm font-semibold text-foreground">
{contextLabel}
</p>
)}
</div>
<div className="mt-1 flex min-w-0 flex-wrap items-center gap-2 text-xs text-muted-foreground">
<span>{item.fullTimestampLabel}</span>
</div>
</div>
<div className="flex shrink-0 items-center gap-4">
<TooltipProvider delayDuration={200}>
<div className="flex items-center gap-4">
<div className="flex items-center gap-0.5">
<HeaderIconAction
label={isDone ? "Mark unread" : "Mark done"}
onClick={onToggleDone}
icon={
isDone ? (
<MailOpen className="h-4 w-4" />
) : (
<CheckCheck className="h-4 w-4" />
)
}
/>
</div>
{canDelete ? (
<HeaderMoreMenu
isDeletingMessage={isDeletingMessage}
onDelete={onDelete}
/>
) : null}
</div>
</TooltipProvider>
</div>
</div>
</div>
<div className="relative min-h-0 flex-1 overflow-hidden">
<div className="absolute inset-0 overflow-y-auto overscroll-contain pb-32 pt-1">
<div className="absolute inset-x-0 top-0 z-40 flex min-h-[44px] items-center justify-between gap-3 bg-background/70 px-6 py-[6px] backdrop-blur-xl supports-[backdrop-filter]:bg-background/55">
<div className="min-w-0">
{canOpenChannel && contextChannelId && onOpenContext ? (
<button
className="truncate text-left text-sm font-semibold leading-5 tracking-tight text-foreground hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
onClick={() => onOpenContext(contextChannelId, item.id)}
title={item.fullTimestampLabel}
type="button"
>
{contextLabel}
</button>
) : (
<h2
className="truncate text-sm font-semibold leading-5 tracking-tight text-foreground"
title={item.fullTimestampLabel}
>
{contextLabel}
</h2>
)}
</div>
<TooltipProvider delayDuration={200}>
<div className="flex shrink-0 items-center gap-1">
{canOpenChannel && contextChannelId && onOpenContext ? (
<HeaderIconAction
label="Open context"
onClick={() => onOpenContext(contextChannelId, item.id)}
icon={<ArrowUpRight className="h-4 w-4" />}
/>
) : null}
<HeaderIconAction
label={isDone ? "Mark unread" : "Mark done"}
onClick={onToggleDone}
icon={
isDone ? (
<MailOpen className="h-4 w-4" />
) : (
<CheckCheck className="h-4 w-4" />
)
}
/>
{canDelete ? (
<HeaderMoreMenu
isDeletingMessage={isDeletingMessage}
onDelete={onDelete}
/>
) : null}
</div>
</TooltipProvider>
</div>
<div className="absolute inset-0 overflow-y-auto overscroll-contain pb-32 pt-14">
<div>
{isThreadContextLoading ? (
<div className="px-6 pb-3 text-[11px] text-muted-foreground">