feat(sidebar): add grid loader indicator for active sessions (#158)
Replace the subtle pulse animation with a visible 3x3 grid loader that appears before the session name when a session is actively processing. This provides clearer visual feedback of session activity. - Add new GridLoader component (pure CSS, no dependencies) - Show loader in sidebar when session phase is 'busy' or 'cooldown'
This commit is contained in:
@@ -27,6 +27,7 @@ import {
|
||||
|
||||
import { ScrollableOverlay } from '@/components/ui/ScrollableOverlay';
|
||||
import { Tooltip, TooltipTrigger, TooltipContent } from '@/components/ui/tooltip';
|
||||
import { GridLoader } from '@/components/ui/grid-loader';
|
||||
import {
|
||||
RiAddLine,
|
||||
RiArrowDownSLine,
|
||||
@@ -1117,12 +1118,10 @@ export const SessionSidebar: React.FC<SessionSidebarProps> = ({
|
||||
>
|
||||
{}
|
||||
<div className="flex items-center gap-2 min-w-0 flex-1">
|
||||
<span
|
||||
className={cn(
|
||||
'truncate typography-ui-label font-normal text-foreground',
|
||||
isStreaming && 'animate-pulse [animation-duration:1.8s]'
|
||||
)}
|
||||
>
|
||||
{isStreaming ? (
|
||||
<GridLoader size="xs" className="text-primary flex-shrink-0" />
|
||||
) : null}
|
||||
<span className="truncate typography-ui-label font-normal text-foreground">
|
||||
{sessionTitle}
|
||||
</span>
|
||||
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
import * as React from 'react';
|
||||
import { cn } from '@/lib/utils';
|
||||
|
||||
interface GridLoaderProps {
|
||||
className?: string;
|
||||
size?: 'xs' | 'sm' | 'md' | 'lg';
|
||||
}
|
||||
|
||||
const sizeConfig = {
|
||||
xs: { container: 'gap-[1px]', dot: 'h-[3px] w-[3px]' },
|
||||
sm: { container: 'gap-0.5', dot: 'h-1 w-1' },
|
||||
md: { container: 'gap-1', dot: 'h-1.5 w-1.5' },
|
||||
lg: { container: 'gap-1.5', dot: 'h-2 w-2' },
|
||||
};
|
||||
|
||||
const GridLoader: React.FC<GridLoaderProps> = ({ className, size = 'md' }) => {
|
||||
const config = sizeConfig[size];
|
||||
|
||||
return (
|
||||
<div
|
||||
className={cn('grid grid-cols-3', config.container, className)}
|
||||
aria-label="Loading"
|
||||
>
|
||||
{Array.from({ length: 9 }, (_, i) => (
|
||||
<div
|
||||
key={i}
|
||||
className={cn('rounded-full bg-current animate-grid-pulse', config.dot)}
|
||||
style={{ animationDelay: `${((i % 3) + Math.floor(i / 3)) * 150}ms` }}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export { GridLoader };
|
||||
@@ -1546,3 +1546,18 @@ html:not(.dark) .chat-scroll {
|
||||
.fonts-loaded .terminal-viewport-container {
|
||||
font-family: "JetBrainsMono Nerd Font", "FiraCode Nerd Font", "Fira Code", "JetBrains Mono", "SFMono-Regular", Menlo, Consolas, "Liberation Mono", "Courier New", monospace;
|
||||
}
|
||||
|
||||
@keyframes grid-pulse {
|
||||
0%, 100% {
|
||||
opacity: 0.2;
|
||||
transform: scale(0.8);
|
||||
}
|
||||
50% {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
.animate-grid-pulse {
|
||||
animation: grid-pulse 1.2s ease-in-out infinite;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user