perf(renderer): lazy render unread comment tooltip
This commit is contained in:
parent
c7af5cd891
commit
93b53dbeb2
2 changed files with 38 additions and 9 deletions
|
|
@ -117,4 +117,24 @@ describe('UnreadCommentsBadge', () => {
|
||||||
await flushReact();
|
await flushReact();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('does not mount tooltip content while closed', async () => {
|
||||||
|
vi.stubGlobal('IS_REACT_ACT_ENVIRONMENT', true);
|
||||||
|
const host = document.createElement('div');
|
||||||
|
document.body.appendChild(host);
|
||||||
|
const root = createRoot(host);
|
||||||
|
|
||||||
|
await act(async () => {
|
||||||
|
root.render(React.createElement(UnreadCommentsBadge, { unreadCount: 2, totalCount: 3 }));
|
||||||
|
await flushReact();
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(host.textContent).not.toContain('unread comments');
|
||||||
|
expect(host.textContent).not.toContain('total');
|
||||||
|
|
||||||
|
await act(async () => {
|
||||||
|
root.unmount();
|
||||||
|
await flushReact();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
import { type JSX, memo, useCallback, useState } from 'react';
|
||||||
|
|
||||||
import { Tooltip, TooltipContent, TooltipTrigger } from '@renderer/components/ui/tooltip';
|
import { Tooltip, TooltipContent, TooltipTrigger } from '@renderer/components/ui/tooltip';
|
||||||
import { MessageSquare } from 'lucide-react';
|
import { MessageSquare } from 'lucide-react';
|
||||||
|
|
||||||
|
|
@ -7,17 +9,22 @@ interface UnreadCommentsBadgeProps {
|
||||||
pulseKey?: number;
|
pulseKey?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const UnreadCommentsBadge = ({
|
export const UnreadCommentsBadge = memo(function UnreadCommentsBadge({
|
||||||
unreadCount,
|
unreadCount,
|
||||||
totalCount,
|
totalCount,
|
||||||
pulseKey,
|
pulseKey,
|
||||||
}: UnreadCommentsBadgeProps): React.JSX.Element | null => {
|
}: UnreadCommentsBadgeProps): JSX.Element | null {
|
||||||
|
const [open, setOpen] = useState(false);
|
||||||
|
const handleOpenChange = useCallback((nextOpen: boolean) => {
|
||||||
|
setOpen(nextOpen);
|
||||||
|
}, []);
|
||||||
|
|
||||||
if (totalCount === 0) return null;
|
if (totalCount === 0) return null;
|
||||||
|
|
||||||
const shouldPulse = (pulseKey ?? 0) > 0;
|
const shouldPulse = (pulseKey ?? 0) > 0;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Tooltip>
|
<Tooltip open={open} onOpenChange={handleOpenChange}>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<span className="relative inline-flex size-6 shrink-0 items-center justify-center text-[var(--color-text-muted)] transition-colors hover:text-[var(--color-text)]">
|
<span className="relative inline-flex size-6 shrink-0 items-center justify-center text-[var(--color-text-muted)] transition-colors hover:text-[var(--color-text)]">
|
||||||
<span
|
<span
|
||||||
|
|
@ -38,11 +45,13 @@ export const UnreadCommentsBadge = ({
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
<TooltipContent side="top">
|
{open ? (
|
||||||
{unreadCount > 0
|
<TooltipContent side="top">
|
||||||
? `${unreadCount} unread comments, ${totalCount} total`
|
{unreadCount > 0
|
||||||
: `${totalCount} comments`}
|
? `${unreadCount} unread comments, ${totalCount} total`
|
||||||
</TooltipContent>
|
: `${totalCount} comments`}
|
||||||
|
</TooltipContent>
|
||||||
|
) : null}
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
);
|
);
|
||||||
};
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue