70 lines
2.1 KiB
TypeScript
70 lines
2.1 KiB
TypeScript
/**
|
|
* OngoingIndicator - Pulsing green dot for sessions/groups in progress.
|
|
* Shared across SessionItem (sidebar) and LastOutputDisplay (chat).
|
|
*/
|
|
|
|
import React from 'react';
|
|
|
|
import { useAppTranslation } from '@features/localization/renderer';
|
|
import { Loader2 } from 'lucide-react';
|
|
|
|
interface OngoingIndicatorProps {
|
|
/** Size variant */
|
|
size?: 'sm' | 'md';
|
|
/** Whether to show text label */
|
|
showLabel?: boolean;
|
|
/** Custom label text */
|
|
label?: string;
|
|
/** Accessible title/tooltip text */
|
|
title?: string;
|
|
}
|
|
|
|
/**
|
|
* Pulsing green dot indicator for ongoing sessions.
|
|
* Use size="sm" for compact displays (sidebar), size="md" for larger displays (chat).
|
|
*/
|
|
export const OngoingIndicator = ({
|
|
size = 'sm',
|
|
showLabel = false,
|
|
label = 'Session in progress...',
|
|
title = label,
|
|
}: Readonly<OngoingIndicatorProps>): React.JSX.Element => {
|
|
const dotSize = size === 'sm' ? 'h-2 w-2' : 'h-2.5 w-2.5';
|
|
|
|
return (
|
|
<span className="inline-flex items-center gap-2" title={title}>
|
|
<span className={`relative flex ${dotSize} shrink-0`}>
|
|
<span className="absolute inline-flex size-full animate-ping rounded-full bg-green-400 opacity-75" />
|
|
<span className={`relative inline-flex rounded-full ${dotSize} bg-green-500`} />
|
|
</span>
|
|
{showLabel && (
|
|
<span className="text-sm" style={{ color: 'var(--info-text)' }}>
|
|
{label}
|
|
</span>
|
|
)}
|
|
</span>
|
|
);
|
|
};
|
|
|
|
/**
|
|
* OngoingBanner - Full-width banner variant for the LastOutputDisplay.
|
|
* Shows animated spinner and text.
|
|
*/
|
|
export const OngoingBanner = (): React.JSX.Element => {
|
|
const { t } = useAppTranslation('common');
|
|
|
|
return (
|
|
<div
|
|
className="flex w-full items-center justify-center gap-2 rounded-lg px-4 py-3"
|
|
style={{
|
|
backgroundColor: 'var(--info-bg)',
|
|
border: '1px solid var(--info-border)',
|
|
}}
|
|
>
|
|
<Loader2 className="size-4 shrink-0 animate-spin" style={{ color: 'var(--info-text)' }} />
|
|
<span className="text-sm font-medium" style={{ color: 'var(--info-text)' }}>
|
|
{t('sessions.inProgress')}
|
|
</span>
|
|
</div>
|
|
);
|
|
};
|