mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-18 01:10:14 +01:00
* fix: remove duplicate keys in German language translations * wip: multi-convo role permissions * ci: Update loadDefaultInterface tests due to MULTI_CONVO * ci: update Role.spec.js with tests for MULTI_CONVO permission type * fix: Update ContentParts component to handle undefined content array * feat: render Multi-Convo based on UI permissions
124 lines
3.4 KiB
TypeScript
124 lines
3.4 KiB
TypeScript
import { useCallback, useMemo } from 'react';
|
|
import { useSetRecoilState, useRecoilValue } from 'recoil';
|
|
import { PermissionTypes, Permissions } from 'librechat-data-provider';
|
|
import type { SetterOrUpdater } from 'recoil';
|
|
import useHasAccess from '~/hooks/Roles/useHasAccess';
|
|
import store from '~/store';
|
|
|
|
/** Event Keys that shouldn't trigger a command */
|
|
const invalidKeys = {
|
|
Escape: true,
|
|
Backspace: true,
|
|
Enter: true,
|
|
};
|
|
|
|
/**
|
|
* Utility function to determine if a command should trigger.
|
|
*/
|
|
const shouldTriggerCommand = (
|
|
textAreaRef: React.RefObject<HTMLTextAreaElement>,
|
|
commandChar: string,
|
|
) => {
|
|
const text = textAreaRef.current?.value;
|
|
if (typeof text !== 'string' || text.length === 0 || text[0] !== commandChar) {
|
|
return false;
|
|
}
|
|
|
|
const startPos = textAreaRef.current?.selectionStart;
|
|
if (typeof startPos !== 'number') {
|
|
return false;
|
|
}
|
|
|
|
return startPos === 1;
|
|
};
|
|
|
|
/**
|
|
* Custom hook for handling key up events with command triggers.
|
|
*/
|
|
const useHandleKeyUp = ({
|
|
index,
|
|
textAreaRef,
|
|
setShowPlusPopover,
|
|
setShowMentionPopover,
|
|
}: {
|
|
index: number;
|
|
textAreaRef: React.RefObject<HTMLTextAreaElement>;
|
|
setShowPlusPopover: SetterOrUpdater<boolean>;
|
|
setShowMentionPopover: SetterOrUpdater<boolean>;
|
|
}) => {
|
|
const hasPromptsAccess = useHasAccess({
|
|
permissionType: PermissionTypes.PROMPTS,
|
|
permission: Permissions.USE,
|
|
});
|
|
const hasMultiConvoAccess = useHasAccess({
|
|
permissionType: PermissionTypes.MULTI_CONVO,
|
|
permission: Permissions.USE,
|
|
});
|
|
const setShowPromptsPopover = useSetRecoilState(store.showPromptsPopoverFamily(index));
|
|
|
|
// Get the current state of command toggles
|
|
const atCommandEnabled = useRecoilValue(store.atCommand);
|
|
const plusCommandEnabled = useRecoilValue(store.plusCommand);
|
|
const slashCommandEnabled = useRecoilValue(store.slashCommand);
|
|
|
|
const handleAtCommand = useCallback(() => {
|
|
if (atCommandEnabled && shouldTriggerCommand(textAreaRef, '@')) {
|
|
setShowMentionPopover(true);
|
|
}
|
|
}, [textAreaRef, setShowMentionPopover, atCommandEnabled]);
|
|
|
|
const handlePlusCommand = useCallback(() => {
|
|
if (!hasMultiConvoAccess || !plusCommandEnabled) {
|
|
return;
|
|
}
|
|
if (shouldTriggerCommand(textAreaRef, '+')) {
|
|
setShowPlusPopover(true);
|
|
}
|
|
}, [textAreaRef, setShowPlusPopover, plusCommandEnabled, hasMultiConvoAccess]);
|
|
|
|
const handlePromptsCommand = useCallback(() => {
|
|
if (!hasPromptsAccess || !slashCommandEnabled) {
|
|
return;
|
|
}
|
|
if (shouldTriggerCommand(textAreaRef, '/')) {
|
|
setShowPromptsPopover(true);
|
|
}
|
|
}, [textAreaRef, hasPromptsAccess, setShowPromptsPopover, slashCommandEnabled]);
|
|
|
|
const commandHandlers = useMemo(
|
|
() => ({
|
|
'@': handleAtCommand,
|
|
'+': handlePlusCommand,
|
|
'/': handlePromptsCommand,
|
|
}),
|
|
[handleAtCommand, handlePlusCommand, handlePromptsCommand],
|
|
);
|
|
|
|
/**
|
|
* Main key up handler.
|
|
*/
|
|
const handleKeyUp = useCallback(
|
|
(event: React.KeyboardEvent<HTMLTextAreaElement>) => {
|
|
const text = textAreaRef.current?.value;
|
|
if (typeof text !== 'string' || text.length === 0) {
|
|
return;
|
|
}
|
|
|
|
if (invalidKeys[event.key as keyof typeof invalidKeys]) {
|
|
return;
|
|
}
|
|
|
|
const firstChar = text[0];
|
|
const handler = commandHandlers[firstChar as keyof typeof commandHandlers];
|
|
|
|
if (typeof handler === 'function') {
|
|
handler();
|
|
}
|
|
},
|
|
[textAreaRef, commandHandlers],
|
|
);
|
|
|
|
return handleKeyUp;
|
|
};
|
|
|
|
export default useHandleKeyUp;
|