import React, { useState } from 'react'; import { useRecoilState } from 'recoil'; import type { TConversation, TMessage } from 'librechat-data-provider'; import { Clipboard, CheckMark, EditIcon, RegenerateIcon, ContinueIcon, VolumeIcon, VolumeMuteIcon, Spinner, } from '~/components/svg'; import { useGenerationsByLatest, useLocalize, useTextToSpeech } from '~/hooks'; import { Fork } from '~/components/Conversations'; import { cn } from '~/utils'; import store from '~/store'; type THoverButtons = { isEditing: boolean; enterEdit: (cancel?: boolean) => void; copyToClipboard: (setIsCopied: React.Dispatch>) => void; conversation: TConversation | null; isSubmitting: boolean; message: TMessage; regenerate: () => void; handleContinue: (e: React.MouseEvent) => void; latestMessage: TMessage | null; isLast: boolean; index: number; }; export default function HoverButtons({ index, isEditing, enterEdit, copyToClipboard, conversation, isSubmitting, message, regenerate, handleContinue, latestMessage, isLast, }: THoverButtons) { const localize = useLocalize(); const { endpoint: _endpoint, endpointType } = conversation ?? {}; const endpoint = endpointType ?? _endpoint; const [isCopied, setIsCopied] = useState(false); const [TextToSpeech] = useRecoilState(store.TextToSpeech); const { handleMouseDown, handleMouseUp, toggleSpeech, isSpeaking, isLoading } = useTextToSpeech( message?.content ?? message?.text ?? '', isLast, index, ); const { hideEditButton, regenerateEnabled, continueSupported, forkingSupported, isEditableEndpoint, } = useGenerationsByLatest({ isEditing, isSubmitting, message, endpoint: endpoint ?? '', latestMessage, }); if (!conversation) { return null; } const { isCreatedByUser } = message; const onEdit = () => { if (isEditing) { return enterEdit(true); } enterEdit(); }; const renderIcon = (size: string) => { if (isLoading) { return ; } if (isSpeaking) { return ; } return ; }; return (
{TextToSpeech && ( )} {isEditableEndpoint && ( )} {regenerateEnabled ? ( ) : null} {continueSupported ? ( ) : null}
); }