N.Achyuth Reddy
Upload 683 files
9705b6c
raw
history blame
6.01 kB
import { useRecoilState } from 'recoil';
import * as Tabs from '@radix-ui/react-tabs';
import React, { useState, useContext, useEffect, useCallback, useRef } from 'react';
import { useClearConversationsMutation } from 'librechat-data-provider';
import {
ThemeContext,
useLocalize,
useOnClickOutside,
useConversation,
useConversations,
} from '~/hooks';
import type { TDangerButtonProps } from '~/common';
import DangerButton from './DangerButton';
import store from '~/store';
import useLocalStorage from '~/hooks/useLocalStorage';
export const ThemeSelector = ({
theme,
onChange,
}: {
theme: string;
onChange: (value: string) => void;
}) => {
const localize = useLocalize();
return (
<div className="flex items-center justify-between">
<div>{localize('com_nav_theme')}</div>
<select
className="w-24 rounded border border-black/10 bg-transparent text-sm dark:border-white/20 dark:bg-gray-900"
onChange={(e) => onChange(e.target.value)}
value={theme}
>
<option value="system">{localize('com_nav_theme_system')}</option>
<option value="dark">{localize('com_nav_theme_dark')}</option>
<option value="light">{localize('com_nav_theme_light')}</option>
</select>
</div>
);
};
export const ClearChatsButton = ({
confirmClear,
className = '',
showText = true,
mutation,
onClick,
}: Pick<
TDangerButtonProps,
'confirmClear' | 'mutation' | 'className' | 'showText' | 'onClick'
>) => {
return (
<DangerButton
id="clearConvosBtn"
mutation={mutation}
confirmClear={confirmClear}
className={className}
showText={showText}
infoTextCode="com_nav_clear_all_chats"
actionTextCode="com_ui_clear"
confirmActionTextCode="com_nav_confirm_clear"
dataTestIdInitial="clear-convos-initial"
dataTestIdConfirm="clear-convos-confirm"
onClick={onClick}
/>
);
};
export const LangSelector = ({
langcode,
onChange,
}: {
langcode: string;
onChange: (value: string) => void;
}) => {
const localize = useLocalize();
return (
<div className="flex items-center justify-between">
<div>{localize('com_nav_language')}</div>
<select
className="w-24 rounded border border-black/10 bg-transparent text-sm dark:border-white/20 dark:bg-gray-900"
onChange={(e) => onChange(e.target.value)}
value={langcode}
>
<option value="auto">{localize('com_nav_lang_auto')}</option>
<option value="en-US">{localize('com_nav_lang_english')}</option>
<option value="zh-CN">{localize('com_nav_lang_chinese')}</option>
<option value="zh-TC">{localize('com_nav_lang_traditionalchinese')}</option>
<option value="de-DE">{localize('com_nav_lang_german')}</option>
<option value="es-ES">{localize('com_nav_lang_spanish')}</option>
<option value="fr-FR">{localize('com_nav_lang_french')}</option>
<option value="it-IT">{localize('com_nav_lang_italian')}</option>
<option value="pl-PL">{localize('com_nav_lang_polish')}</option>
<option value="pt-BR">{localize('com_nav_lang_brazilian_portuguese')}</option>
<option value="ru-RU">{localize('com_nav_lang_russian')}</option>
<option value="ja-JP">{localize('com_nav_lang_japanese')}</option>
<option value="sv-SE">{localize('com_nav_lang_swedish')}</option>
<option value="ko-KR">{localize('com_nav_lang_korean')}</option>
</select>
</div>
);
};
function General() {
const { theme, setTheme } = useContext(ThemeContext);
const clearConvosMutation = useClearConversationsMutation();
const [confirmClear, setConfirmClear] = useState(false);
const [langcode, setLangcode] = useRecoilState(store.lang);
const [selectedLang, setSelectedLang] = useLocalStorage('selectedLang', langcode);
const { newConversation } = useConversation();
const { refreshConversations } = useConversations();
const contentRef = useRef(null);
useOnClickOutside(contentRef, () => confirmClear && setConfirmClear(false), []);
useEffect(() => {
if (clearConvosMutation.isSuccess) {
newConversation();
refreshConversations();
}
}, [clearConvosMutation.isSuccess, newConversation, refreshConversations]);
const clearConvos = useCallback(() => {
if (confirmClear) {
console.log('Clearing conversations...');
clearConvosMutation.mutate({});
setConfirmClear(false);
} else {
setConfirmClear(true);
}
}, [confirmClear, clearConvosMutation]);
const changeTheme = useCallback(
(value: string) => {
setTheme(value);
},
[setTheme],
);
const changeLang = useCallback(
(value: string) => {
setSelectedLang(value);
if (value === 'auto') {
const userLang = navigator.language || navigator.languages[0];
setLangcode(userLang);
localStorage.setItem('lang', userLang);
} else {
setLangcode(value);
localStorage.setItem('lang', value);
}
},
[setLangcode, setSelectedLang],
);
return (
<Tabs.Content
value="general"
role="tabpanel"
className="w-full md:min-h-[300px]"
ref={contentRef}
>
<div className="flex flex-col gap-3 text-sm text-gray-600 dark:text-gray-300">
<div className="border-b pb-3 last-of-type:border-b-0 dark:border-gray-700">
<ThemeSelector theme={theme} onChange={changeTheme} />
</div>
<div className="border-b pb-3 last-of-type:border-b-0 dark:border-gray-700">
<LangSelector langcode={selectedLang} onChange={changeLang} />
</div>
<div className="border-b pb-3 last-of-type:border-b-0 dark:border-gray-700">
<ClearChatsButton
confirmClear={confirmClear}
onClick={clearConvos}
showText={true}
mutation={clearConvosMutation}
/>
</div>
</div>
</Tabs.Content>
);
}
export default React.memo(General);