From 03ced7a894f13d50b67c50f87e58bfef66505e62 Mon Sep 17 00:00:00 2001 From: Danny Avila Date: Mon, 15 Dec 2025 17:02:16 -0500 Subject: [PATCH] =?UTF-8?q?Revert=20"=E2=8C=A8=EF=B8=8F=20feat:=20Add=20Sh?= =?UTF-8?q?ift-Key=20Shortcuts=20for=20Instant=20Conversation=20Actions=20?= =?UTF-8?q?(#10732)"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 41c0a96d39d0285f51e91461f67195feb0b1a4c1. --- client/src/components/Conversations/Convo.tsx | 8 +- .../ConvoOptions/ConvoOptions.tsx | 170 +++++------------- client/src/hooks/Generic/index.ts | 1 - client/src/hooks/Generic/useShiftKey.ts | 40 ----- 4 files changed, 43 insertions(+), 176 deletions(-) delete mode 100644 client/src/hooks/Generic/useShiftKey.ts diff --git a/client/src/components/Conversations/Convo.tsx b/client/src/components/Conversations/Convo.tsx index c10aad33e3..e85b341d5e 100644 --- a/client/src/components/Conversations/Convo.tsx +++ b/client/src/components/Conversations/Convo.tsx @@ -6,7 +6,7 @@ import { useToastContext, useMediaQuery } from '@librechat/client'; import type { TConversation } from 'librechat-data-provider'; import { useUpdateConversationMutation } from '~/data-provider'; import EndpointIcon from '~/components/Endpoints/EndpointIcon'; -import { useNavigateToConvo, useLocalize, useShiftKey } from '~/hooks'; +import { useNavigateToConvo, useLocalize } from '~/hooks'; import { useGetEndpointsQuery } from '~/data-provider'; import { NotificationSeverity } from '~/common'; import { ConvoOptions } from './ConvoOptions'; @@ -31,7 +31,6 @@ export default function Conversation({ conversation, retainView, toggleNav }: Co const updateConvoMutation = useUpdateConversationMutation(currentConvoId ?? ''); const activeConvos = useRecoilValue(store.allConversationsSelector); const isSmallScreen = useMediaQuery('(max-width: 768px)'); - const isShiftHeld = useShiftKey(); const { conversationId, title = '' } = conversation; const [titleInput, setTitleInput] = useState(title || ''); @@ -195,9 +194,8 @@ export default function Conversation({ conversation, retainView, toggleNav }: Co className={cn( 'mr-2 flex origin-left', isPopoverActive || isActiveConvo - ? 'pointer-events-auto scale-x-100 opacity-100' - : 'pointer-events-none max-w-0 scale-x-0 opacity-0 group-focus-within:pointer-events-auto group-focus-within:max-w-[60px] group-focus-within:scale-x-100 group-focus-within:opacity-100 group-hover:pointer-events-auto group-hover:max-w-[60px] group-hover:scale-x-100 group-hover:opacity-100', - (isPopoverActive || isActiveConvo) && (isShiftHeld ? 'max-w-[60px]' : 'max-w-[28px]'), + ? 'pointer-events-auto max-w-[28px] scale-x-100 opacity-100' + : 'pointer-events-none max-w-0 scale-x-0 opacity-0 group-focus-within:pointer-events-auto group-focus-within:max-w-[28px] group-focus-within:scale-x-100 group-focus-within:opacity-100 group-hover:pointer-events-auto group-hover:max-w-[28px] group-hover:scale-x-100 group-hover:opacity-100', )} // Removing aria-hidden to fix accessibility issue: ARIA hidden element must not be focusable or contain focusable elements // but not sure what its original purpose was, so leaving the property commented out until it can be cleared safe to delete. diff --git a/client/src/components/Conversations/ConvoOptions/ConvoOptions.tsx b/client/src/components/Conversations/ConvoOptions/ConvoOptions.tsx index b090027645..9a06049a28 100644 --- a/client/src/components/Conversations/ConvoOptions/ConvoOptions.tsx +++ b/client/src/components/Conversations/ConvoOptions/ConvoOptions.tsx @@ -1,19 +1,15 @@ import { useState, useId, useRef, memo, useCallback, useMemo } from 'react'; import * as Ariakit from '@ariakit/react'; import { useParams, useNavigate } from 'react-router-dom'; -import { QueryKeys } from 'librechat-data-provider'; -import { useQueryClient } from '@tanstack/react-query'; import { DropdownPopup, Spinner, useToastContext } from '@librechat/client'; import { Ellipsis, Share2, CopyPlus, Archive, Pen, Trash } from 'lucide-react'; import type { MouseEvent } from 'react'; -import type { TMessage } from 'librechat-data-provider'; import { useDuplicateConversationMutation, - useDeleteConversationMutation, useGetStartupConfig, useArchiveConvoMutation, } from '~/data-provider'; -import { useLocalize, useNavigateToConvo, useNewConvo, useShiftKey } from '~/hooks'; +import { useLocalize, useNavigateToConvo, useNewConvo } from '~/hooks'; import { NotificationSeverity } from '~/common'; import { useChatContext } from '~/Providers'; import DeleteButton from './DeleteButton'; @@ -38,8 +34,6 @@ function ConvoOptions({ isActiveConvo: boolean; }) { const localize = useLocalize(); - const queryClient = useQueryClient(); - const isShiftHeld = useShiftKey(); const { index } = useChatContext(); const { data: startupConfig } = useGetStartupConfig(); const { navigateToConvo } = useNavigateToConvo(index); @@ -58,28 +52,6 @@ function ConvoOptions({ const archiveConvoMutation = useArchiveConvoMutation(); - const deleteMutation = useDeleteConversationMutation({ - onSuccess: () => { - if (currentConvoId === conversationId || currentConvoId === 'new') { - newConversation(); - navigate('/c/new', { replace: true }); - } - retainView(); - showToast({ - message: localize('com_ui_convo_delete_success'), - severity: NotificationSeverity.SUCCESS, - showIcon: true, - }); - }, - onError: () => { - showToast({ - message: localize('com_ui_convo_delete_error'), - severity: NotificationSeverity.ERROR, - showIcon: true, - }); - }, - }); - const duplicateConversation = useDuplicateConversationMutation({ onSuccess: (data) => { navigateToConvo(data.conversation); @@ -105,7 +77,6 @@ function ConvoOptions({ const isDuplicateLoading = duplicateConversation.isLoading; const isArchiveLoading = archiveConvoMutation.isLoading; - const isDeleteLoading = deleteMutation.isLoading; const shareHandler = useCallback(() => { setShowShareDialog(true); @@ -115,70 +86,47 @@ function ConvoOptions({ setShowDeleteDialog(true); }, []); - const handleInstantDelete = useCallback( - (e: MouseEvent) => { - e.stopPropagation(); - const convoId = conversationId ?? ''; - if (!convoId) { - return; - } + const handleArchiveClick = useCallback(async () => { + const convoId = conversationId ?? ''; + if (!convoId) { + return; + } - const messages = queryClient.getQueryData([QueryKeys.messages, convoId]); - const thread_id = messages?.[messages.length - 1]?.thread_id; - const endpoint = messages?.[messages.length - 1]?.endpoint; - - deleteMutation.mutate({ conversationId: convoId, thread_id, endpoint, source: 'button' }); - }, - [conversationId, deleteMutation, queryClient], - ); - - const handleArchiveClick = useCallback( - async (e?: MouseEvent) => { - e?.stopPropagation(); - const convoId = conversationId ?? ''; - if (!convoId) { - return; - } - - archiveConvoMutation.mutate( - { conversationId: convoId, isArchived: true }, - { - onSuccess: () => { - setAnnouncement(localize('com_ui_convo_archived')); - setTimeout(() => { - setAnnouncement(''); - }, 10000); - - if (currentConvoId === convoId || currentConvoId === 'new') { - newConversation(); - navigate('/c/new', { replace: true }); - } - - retainView(); - setIsPopoverActive(false); - }, - onError: () => { - showToast({ - message: localize('com_ui_archive_error'), - severity: NotificationSeverity.ERROR, - showIcon: true, - }); - }, + archiveConvoMutation.mutate( + { conversationId: convoId, isArchived: true }, + { + onSuccess: () => { + setAnnouncement(localize('com_ui_convo_archived')); + setTimeout(() => { + setAnnouncement(''); + }, 10000); + if (currentConvoId === convoId || currentConvoId === 'new') { + newConversation(); + navigate('/c/new', { replace: true }); + } + retainView(); + setIsPopoverActive(false); }, - ); - }, - [ - conversationId, - currentConvoId, - archiveConvoMutation, - navigate, - newConversation, - retainView, - setIsPopoverActive, - showToast, - localize, - ], - ); + onError: () => { + showToast({ + message: localize('com_ui_archive_error'), + severity: NotificationSeverity.ERROR, + showIcon: true, + }); + }, + }, + ); + }, [ + conversationId, + currentConvoId, + archiveConvoMutation, + navigate, + newConversation, + retainView, + setIsPopoverActive, + showToast, + localize, + ]); const handleDuplicateClick = useCallback(() => { duplicateConversation.mutate({ @@ -250,44 +198,6 @@ function ConvoOptions({ ], ); - const buttonClassName = cn( - 'inline-flex h-7 w-7 items-center justify-center rounded-md border-none p-0 text-sm font-medium ring-ring-primary transition-all duration-200 ease-in-out focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:opacity-50', - isActiveConvo === true || isPopoverActive - ? 'opacity-100' - : 'opacity-0 focus:opacity-100 group-focus-within:opacity-100 group-hover:opacity-100 data-[open]:opacity-100', - ); - - if (isShiftHeld) { - return ( -
- - -
- ); - } - return ( <> diff --git a/client/src/hooks/Generic/index.ts b/client/src/hooks/Generic/index.ts index 9674014afa..9d9d64459f 100644 --- a/client/src/hooks/Generic/index.ts +++ b/client/src/hooks/Generic/index.ts @@ -1,2 +1 @@ export * from './useLazyEffect'; -export { default as useShiftKey } from './useShiftKey'; diff --git a/client/src/hooks/Generic/useShiftKey.ts b/client/src/hooks/Generic/useShiftKey.ts deleted file mode 100644 index 57fddee162..0000000000 --- a/client/src/hooks/Generic/useShiftKey.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { useState, useEffect } from 'react'; - -/** - * Hook to track whether the shift key is currently being held down - * @returns boolean indicating if shift key is pressed - */ -export default function useShiftKey(): boolean { - const [isShiftHeld, setIsShiftHeld] = useState(false); - - useEffect(() => { - const handleKeyDown = (e: KeyboardEvent) => { - if (e.key === 'Shift') { - setIsShiftHeld(true); - } - }; - - const handleKeyUp = (e: KeyboardEvent) => { - if (e.key === 'Shift') { - setIsShiftHeld(false); - } - }; - - // Reset shift state when window loses focus - const handleBlur = () => { - setIsShiftHeld(false); - }; - - window.addEventListener('keydown', handleKeyDown); - window.addEventListener('keyup', handleKeyUp); - window.addEventListener('blur', handleBlur); - - return () => { - window.removeEventListener('keydown', handleKeyDown); - window.removeEventListener('keyup', handleKeyUp); - window.removeEventListener('blur', handleBlur); - }; - }, []); - - return isShiftHeld; -}