mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-18 09:20:15 +01:00
🎨 style: UI Style Enhancements and Refactor for Improved Consistency and Layout (#4471)
* 🎨 style: adjust padding and class names in UI components * 🎨 style: update ExportModal export button, update Export button hover style, refactor ChatForm style and fixed isRTL styles, update AttachFile position * 🎨 style: remove redundant border classes in SettingsTabs components for cleaner UI * 🎨 style: refactor Account component, extract DisplayUsernameMessages, and remove redundant border classes for cleaner layout * 🎨 style: conditionally render Dropdown in ForkSettings component for improved UI responsiveness * 🎨 style: replace DropdownNoState with Dropdown in voice selection components for consistency * 🎨 style: update Settings component layout for better responsivenes on large screens * 🎨 style: remove redundant margin-top classes for cleaner layout in various components
This commit is contained in:
parent
ecf5699513
commit
4d4a6b53f1
30 changed files with 118 additions and 145 deletions
|
|
@ -3,6 +3,7 @@ import { useRecoilState } from 'recoil';
|
||||||
import type { Option } from '~/common';
|
import type { Option } from '~/common';
|
||||||
import DropdownNoState from '~/components/ui/DropdownNoState';
|
import DropdownNoState from '~/components/ui/DropdownNoState';
|
||||||
import { useLocalize, useTTSBrowser, useTTSEdge, useTTSExternal } from '~/hooks';
|
import { useLocalize, useTTSBrowser, useTTSEdge, useTTSExternal } from '~/hooks';
|
||||||
|
import { Dropdown } from '~/components/ui';
|
||||||
import { logger } from '~/utils';
|
import { logger } from '~/utils';
|
||||||
import store from '~/store';
|
import store from '~/store';
|
||||||
|
|
||||||
|
|
@ -22,13 +23,12 @@ export function EdgeVoiceDropdown() {
|
||||||
return (
|
return (
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<div>{localize('com_nav_voice_select')}</div>
|
<div>{localize('com_nav_voice_select')}</div>
|
||||||
<DropdownNoState
|
<Dropdown
|
||||||
key={`edge-voice-dropdown-${voices.length}`}
|
key={`edge-voice-dropdown-${voices.length}`}
|
||||||
value={voice}
|
value={voice ?? ''}
|
||||||
options={voices}
|
options={voices}
|
||||||
onChange={handleVoiceChange}
|
onChange={handleVoiceChange}
|
||||||
sizeClasses="min-w-[200px] !max-w-[400px] [--anchor-max-width:400px]"
|
sizeClasses="min-w-[200px] !max-w-[400px] [--anchor-max-width:400px]"
|
||||||
anchor="bottom start"
|
|
||||||
testId="EdgeVoiceDropdown"
|
testId="EdgeVoiceDropdown"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -51,13 +51,12 @@ export function BrowserVoiceDropdown() {
|
||||||
return (
|
return (
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<div>{localize('com_nav_voice_select')}</div>
|
<div>{localize('com_nav_voice_select')}</div>
|
||||||
<DropdownNoState
|
<Dropdown
|
||||||
key={`browser-voice-dropdown-${voices.length}`}
|
key={`browser-voice-dropdown-${voices.length}`}
|
||||||
value={voice}
|
value={voice ?? ''}
|
||||||
options={voices}
|
options={voices}
|
||||||
onChange={handleVoiceChange}
|
onChange={handleVoiceChange}
|
||||||
sizeClasses="min-w-[200px] !max-w-[400px] [--anchor-max-width:400px]"
|
sizeClasses="min-w-[200px] !max-w-[400px] [--anchor-max-width:400px]"
|
||||||
anchor="bottom start"
|
|
||||||
testId="BrowserVoiceDropdown"
|
testId="BrowserVoiceDropdown"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -80,13 +79,12 @@ export function ExternalVoiceDropdown() {
|
||||||
return (
|
return (
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<div>{localize('com_nav_voice_select')}</div>
|
<div>{localize('com_nav_voice_select')}</div>
|
||||||
<DropdownNoState
|
<Dropdown
|
||||||
key={`external-voice-dropdown-${voices.length}`}
|
key={`external-voice-dropdown-${voices.length}`}
|
||||||
value={voice}
|
value={voice ?? ''}
|
||||||
options={voices}
|
options={voices}
|
||||||
onChange={handleVoiceChange}
|
onChange={handleVoiceChange}
|
||||||
sizeClasses="min-w-[200px] !max-w-[400px] [--anchor-max-width:400px]"
|
sizeClasses="min-w-[200px] !max-w-[400px] [--anchor-max-width:400px]"
|
||||||
anchor="bottom start"
|
|
||||||
testId="ExternalVoiceDropdown"
|
testId="ExternalVoiceDropdown"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,7 @@ export default function ExportAndShareMenu({
|
||||||
<Ariakit.MenuButton
|
<Ariakit.MenuButton
|
||||||
id="export-menu-button"
|
id="export-menu-button"
|
||||||
aria-label="Export options"
|
aria-label="Export options"
|
||||||
className="mr-4 inline-flex h-10 w-10 items-center justify-center rounded-md border border-border-light bg-transparent p-0 text-sm font-medium transition-all duration-300 ease-in-out focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50"
|
className="inline-flex size-10 items-center justify-center rounded-lg border border-border-light bg-transparent text-text-primary transition-all ease-in-out hover:bg-surface-tertiary disabled:pointer-events-none disabled:opacity-50 radix-state-open:bg-surface-tertiary"
|
||||||
>
|
>
|
||||||
<Upload className="icon-md dark:text-gray-300" aria-hidden="true" focusable="false" />
|
<Upload className="icon-md dark:text-gray-300" aria-hidden="true" focusable="false" />
|
||||||
</Ariakit.MenuButton>
|
</Ariakit.MenuButton>
|
||||||
|
|
|
||||||
|
|
@ -131,6 +131,14 @@ const ChatForm = ({ index = 0 }) => {
|
||||||
const endpointSupportsFiles: boolean = supportsFiles[endpointType ?? endpoint ?? ''] ?? false;
|
const endpointSupportsFiles: boolean = supportsFiles[endpointType ?? endpoint ?? ''] ?? false;
|
||||||
const isUploadDisabled: boolean = endpointFileConfig?.disabled ?? false;
|
const isUploadDisabled: boolean = endpointFileConfig?.disabled ?? false;
|
||||||
|
|
||||||
|
const baseClasses =
|
||||||
|
'md:py-3.5 m-0 w-full resize-none bg-surface-tertiary py-[13px] placeholder-black/50 dark:placeholder-white/50 [&:has(textarea:focus)]:shadow-[0_2px_6px_rgba(0,0,0,.05)] max-h-[65vh] md:max-h-[75vh]';
|
||||||
|
|
||||||
|
const uploadActive = endpointSupportsFiles && !isUploadDisabled;
|
||||||
|
const speechClass = isRTL
|
||||||
|
? `pr-${uploadActive ? '12' : '4'} pl-12`
|
||||||
|
: `pl-${uploadActive ? '12' : '4'} pr-12`;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form
|
<form
|
||||||
onSubmit={methods.handleSubmit((data) => submitMessage(data))}
|
onSubmit={methods.handleSubmit((data) => submitMessage(data))}
|
||||||
|
|
@ -177,15 +185,7 @@ const ChatForm = ({ index = 0 }) => {
|
||||||
data-testid="text-input"
|
data-testid="text-input"
|
||||||
style={{ height: 44, overflowY: 'auto' }}
|
style={{ height: 44, overflowY: 'auto' }}
|
||||||
rows={1}
|
rows={1}
|
||||||
className={cn(
|
className={cn(baseClasses, speechClass, removeFocusRings)}
|
||||||
endpointSupportsFiles && !isUploadDisabled
|
|
||||||
? 'pl-10 md:pl-[55px]'
|
|
||||||
: 'pl-3 md:pl-4',
|
|
||||||
'md:py-3.5- m-0 w-full resize-none bg-surface-tertiary py-[13px] placeholder-black/50 dark:placeholder-white/50 [&:has(textarea:focus)]:shadow-[0_2px_6px_rgba(0,0,0,.05)]',
|
|
||||||
SpeechToText && !isRTL ? 'pr-20 md:pr-[85px]' : 'pr-10 md:pr-12',
|
|
||||||
'max-h-[65vh] md:max-h-[75vh]',
|
|
||||||
removeFocusRings,
|
|
||||||
)}
|
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</FileFormWrapper>
|
</FileFormWrapper>
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ const AttachFile = ({
|
||||||
disabled={isUploadDisabled}
|
disabled={isUploadDisabled}
|
||||||
className={cn(
|
className={cn(
|
||||||
'absolute flex size-[35px] items-center justify-center rounded-full p-1 transition-colors hover:bg-surface-hover',
|
'absolute flex size-[35px] items-center justify-center rounded-full p-1 transition-colors hover:bg-surface-hover',
|
||||||
isRTL ? 'bottom-2 right-2' : 'bottom-2 left-2',
|
isRTL ? 'bottom-2 right-2' : 'bottom-2 left-1 md:left-2',
|
||||||
)}
|
)}
|
||||||
description={localize('com_sidepanel_attach_files')}
|
description={localize('com_sidepanel_attach_files')}
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ export default function StopButton({ stop, setShowStopButton }) {
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className={cn(
|
className={cn(
|
||||||
'rounded-full bg-text-primary p-1.5 text-text-primary outline-offset-4 transition-all duration-200 disabled:cursor-not-allowed disabled:text-text-secondary disabled:opacity-10',
|
'rounded-full bg-text-primary p-2 text-text-primary outline-offset-4 transition-all duration-200 disabled:cursor-not-allowed disabled:text-text-secondary disabled:opacity-10',
|
||||||
)}
|
)}
|
||||||
aria-label={localize('com_nav_stop_generating')}
|
aria-label={localize('com_nav_stop_generating')}
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ export function DeleteConversationDialog({
|
||||||
<OGDialogTemplate
|
<OGDialogTemplate
|
||||||
showCloseButton={false}
|
showCloseButton={false}
|
||||||
title={localize('com_ui_delete_conversation')}
|
title={localize('com_ui_delete_conversation')}
|
||||||
className="z-[1000] max-w-[450px]"
|
className="max-w-[450px]"
|
||||||
main={
|
main={
|
||||||
<>
|
<>
|
||||||
<div className="flex w-full flex-col items-center gap-2">
|
<div className="flex w-full flex-col items-center gap-2">
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ import type { TConversation } from 'librechat-data-provider';
|
||||||
import { OGDialog, Button, Input, Label, Checkbox, Dropdown } from '~/components/ui';
|
import { OGDialog, Button, Input, Label, Checkbox, Dropdown } from '~/components/ui';
|
||||||
import OGDialogTemplate from '~/components/ui/OGDialogTemplate';
|
import OGDialogTemplate from '~/components/ui/OGDialogTemplate';
|
||||||
import { useLocalize, useExportConversation } from '~/hooks';
|
import { useLocalize, useExportConversation } from '~/hooks';
|
||||||
import { cn, defaultTextProps } from '~/utils';
|
|
||||||
|
|
||||||
export default function ExportModal({
|
export default function ExportModal({
|
||||||
open,
|
open,
|
||||||
|
|
@ -78,10 +77,6 @@ export default function ExportModal({
|
||||||
value={filename}
|
value={filename}
|
||||||
onChange={(e) => setFileName(filenamify(e.target.value || ''))}
|
onChange={(e) => setFileName(filenamify(e.target.value || ''))}
|
||||||
placeholder={localize('com_nav_export_filename_placeholder')}
|
placeholder={localize('com_nav_export_filename_placeholder')}
|
||||||
className={cn(
|
|
||||||
defaultTextProps,
|
|
||||||
'flex h-10 max-h-10 w-full resize-none px-3 py-2',
|
|
||||||
)}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-span-1 flex w-full flex-col items-start justify-start gap-2">
|
<div className="col-span-1 flex w-full flex-col items-start justify-start gap-2">
|
||||||
|
|
@ -164,7 +159,7 @@ export default function ExportModal({
|
||||||
}
|
}
|
||||||
buttons={
|
buttons={
|
||||||
<>
|
<>
|
||||||
<Button onClick={exportConversation} variant="success">
|
<Button onClick={exportConversation} variant="submit">
|
||||||
{localize('com_endpoint_export')}
|
{localize('com_endpoint_export')}
|
||||||
</Button>
|
</Button>
|
||||||
</>
|
</>
|
||||||
|
|
|
||||||
|
|
@ -120,7 +120,9 @@ export default function Settings({ open, onOpenChange }: TDialogProps) {
|
||||||
aria-label="Settings"
|
aria-label="Settings"
|
||||||
className={cn(
|
className={cn(
|
||||||
'min-w-auto max-w-auto relative -ml-[8px] flex flex-shrink-0 flex-col flex-nowrap overflow-auto sm:max-w-none',
|
'min-w-auto max-w-auto relative -ml-[8px] flex flex-shrink-0 flex-col flex-nowrap overflow-auto sm:max-w-none',
|
||||||
isSmallScreen ? 'flex-row rounded-xl bg-surface-secondary' : '',
|
isSmallScreen
|
||||||
|
? 'flex-row rounded-xl bg-surface-secondary'
|
||||||
|
: 'sticky top-0 h-full',
|
||||||
)}
|
)}
|
||||||
onKeyDown={handleKeyDown}
|
onKeyDown={handleKeyDown}
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -1,43 +1,19 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { useRecoilState } from 'recoil';
|
import DisplayUsernameMessages from './DisplayUsernameMessages';
|
||||||
import HoverCardSettings from '../HoverCardSettings';
|
|
||||||
import DeleteAccount from './DeleteAccount';
|
import DeleteAccount from './DeleteAccount';
|
||||||
import { Switch } from '~/components/ui';
|
|
||||||
import { useLocalize } from '~/hooks';
|
|
||||||
import Avatar from './Avatar';
|
import Avatar from './Avatar';
|
||||||
import store from '~/store';
|
|
||||||
|
|
||||||
function Account({ onCheckedChange }: { onCheckedChange?: (value: boolean) => void }) {
|
|
||||||
const [UsernameDisplay, setUsernameDisplay] = useRecoilState<boolean>(store.UsernameDisplay);
|
|
||||||
const localize = useLocalize();
|
|
||||||
|
|
||||||
const handleCheckedChange = (value: boolean) => {
|
|
||||||
setUsernameDisplay(value);
|
|
||||||
if (onCheckedChange) {
|
|
||||||
onCheckedChange(value);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
function Account() {
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col gap-3 p-1 text-sm text-text-primary">
|
<div className="flex flex-col gap-3 p-1 text-sm text-text-primary">
|
||||||
<div className="border-b border-border-medium pb-3 last-of-type:border-b-0">
|
<div className="pb-3">
|
||||||
<Avatar />
|
<Avatar />
|
||||||
</div>
|
</div>
|
||||||
<div className="border-b border-border-medium pb-3 last-of-type:border-b-0">
|
<div className="pb-3">
|
||||||
<DeleteAccount />
|
<DeleteAccount />
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center justify-between">
|
<div className="pb-3">
|
||||||
<div className="flex items-center space-x-2">
|
<DisplayUsernameMessages />
|
||||||
<div>{localize('com_nav_user_name_display')}</div>
|
|
||||||
<HoverCardSettings side="bottom" text="com_nav_info_user_name_display" />
|
|
||||||
</div>
|
|
||||||
<Switch
|
|
||||||
id="UsernameDisplay"
|
|
||||||
checked={UsernameDisplay}
|
|
||||||
onCheckedChange={handleCheckedChange}
|
|
||||||
className="ml-4 mt-2"
|
|
||||||
data-testid="UsernameDisplay"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { useRecoilState } from 'recoil';
|
||||||
|
import HoverCardSettings from '../HoverCardSettings';
|
||||||
|
import { Switch, Label } from '~/components/ui';
|
||||||
|
import { useLocalize } from '~/hooks';
|
||||||
|
import store from '~/store';
|
||||||
|
|
||||||
|
export default function DisplayUsernameMessages() {
|
||||||
|
const localize = useLocalize();
|
||||||
|
const [UsernameDisplay, setUsernameDisplay] = useRecoilState(store.UsernameDisplay);
|
||||||
|
|
||||||
|
const handleCheckedChange = (checked: boolean) => {
|
||||||
|
setUsernameDisplay(checked);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<div className="flex items-center space-x-2">
|
||||||
|
<Label className="font-light">{localize('com_nav_user_name_display')}</Label>
|
||||||
|
<HoverCardSettings side="bottom" text="com_nav_info_user_name_display" />
|
||||||
|
</div>
|
||||||
|
<Switch
|
||||||
|
id="UsernameDisplay"
|
||||||
|
checked={UsernameDisplay}
|
||||||
|
onCheckedChange={handleCheckedChange}
|
||||||
|
className="ml-4"
|
||||||
|
data-testid="UsernameDisplay"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -4,7 +4,7 @@ import CodeArtifacts from './CodeArtifacts';
|
||||||
function Beta() {
|
function Beta() {
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col gap-3 p-1 text-sm text-text-primary">
|
<div className="flex flex-col gap-3 p-1 text-sm text-text-primary">
|
||||||
<div className="border-b border-border-light pb-3 last-of-type:border-b-0">
|
<div className="pb-3">
|
||||||
<CodeArtifacts />
|
<CodeArtifacts />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -86,7 +86,7 @@ function SwitchItem({
|
||||||
id={id}
|
id={id}
|
||||||
checked={checked}
|
checked={checked}
|
||||||
onCheckedChange={onCheckedChange}
|
onCheckedChange={onCheckedChange}
|
||||||
className="ml-4 mt-2"
|
className="ml-4"
|
||||||
data-testid={id}
|
data-testid={id}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -11,26 +11,26 @@ import SaveDraft from './SaveDraft';
|
||||||
function Chat() {
|
function Chat() {
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col gap-3 p-1 text-sm text-text-primary">
|
<div className="flex flex-col gap-3 p-1 text-sm text-text-primary">
|
||||||
<div className="border-b border-border-light pb-3 last-of-type:border-b-0">
|
<div className="pb-3">
|
||||||
<FontSizeSelector />
|
<FontSizeSelector />
|
||||||
</div>
|
</div>
|
||||||
<div className="border-b border-border-light pb-3 last-of-type:border-b-0">
|
<div className="pb-3">
|
||||||
<ChatDirection />
|
<ChatDirection />
|
||||||
</div>
|
</div>
|
||||||
<div className="border-b border-border-light pb-3 last-of-type:border-b-0">
|
<div className="pb-3">
|
||||||
<SendMessageKeyEnter />
|
<SendMessageKeyEnter />
|
||||||
</div>
|
</div>
|
||||||
<div className="border-b border-border-light pb-3 last-of-type:border-b-0">
|
<div className="pb-3">
|
||||||
<ShowCodeSwitch />
|
<ShowCodeSwitch />
|
||||||
</div>
|
</div>
|
||||||
<div className="border-b border-border-light pb-3 last-of-type:border-b-0">
|
<div className="pb-3">
|
||||||
<SaveDraft />
|
<SaveDraft />
|
||||||
</div>
|
</div>
|
||||||
<ForkSettings />
|
<ForkSettings />
|
||||||
<div className="border-b border-border-light pb-3 last-of-type:border-b-0">
|
<div className="pb-3">
|
||||||
<ModularChat />
|
<ModularChat />
|
||||||
</div>
|
</div>
|
||||||
<div className="border-b border-border-light pb-3 last-of-type:border-b-0">
|
<div className="pb-3">
|
||||||
<LaTeXParsing />
|
<LaTeXParsing />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ export default function SendMessageKeyEnter({
|
||||||
id="enterToSend"
|
id="enterToSend"
|
||||||
checked={enterToSend}
|
checked={enterToSend}
|
||||||
onCheckedChange={handleCheckedChange}
|
onCheckedChange={handleCheckedChange}
|
||||||
className="ml-4 mt-2"
|
className="ml-4"
|
||||||
data-testid="enterToSend"
|
data-testid="enterToSend"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,20 @@ export const ForkSettings = () => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="border-b border-border-light pb-3 last-of-type:border-b-0">
|
<div className="pb-3">
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<div> {localize('com_ui_fork_default')} </div>
|
||||||
|
<Switch
|
||||||
|
id="rememberDefaultFork"
|
||||||
|
checked={remember}
|
||||||
|
onCheckedChange={setRemember}
|
||||||
|
className="ml-4"
|
||||||
|
data-testid="rememberDefaultFork"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{remember && (
|
||||||
|
<div className="pb-3">
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<div className="flex items-center space-x-2">
|
<div className="flex items-center space-x-2">
|
||||||
<div>{localize('com_ui_fork_change_default')}</div>
|
<div>{localize('com_ui_fork_change_default')}</div>
|
||||||
|
|
@ -34,19 +47,8 @@ export const ForkSettings = () => {
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="border-b border-border-light pb-3 last-of-type:border-b-0">
|
)}
|
||||||
<div className="flex items-center justify-between">
|
<div className="pb-3">
|
||||||
<div> {localize('com_ui_fork_default')} </div>
|
|
||||||
<Switch
|
|
||||||
id="rememberDefaultFork"
|
|
||||||
checked={remember}
|
|
||||||
onCheckedChange={setRemember}
|
|
||||||
className="ml-4 mt-2"
|
|
||||||
data-testid="rememberDefaultFork"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="border-b border-border-light pb-3 last-of-type:border-b-0">
|
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<div className="flex items-center space-x-2">
|
<div className="flex items-center space-x-2">
|
||||||
<div>{localize('com_ui_fork_split_target_setting')}</div>
|
<div>{localize('com_ui_fork_split_target_setting')}</div>
|
||||||
|
|
@ -56,7 +58,7 @@ export const ForkSettings = () => {
|
||||||
id="splitAtTarget"
|
id="splitAtTarget"
|
||||||
checked={splitAtTarget}
|
checked={splitAtTarget}
|
||||||
onCheckedChange={setSplitAtTarget}
|
onCheckedChange={setSplitAtTarget}
|
||||||
className="ml-4 mt-2"
|
className="ml-4"
|
||||||
data-testid="splitAtTarget"
|
data-testid="splitAtTarget"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ export default function LaTeXParsingSwitch({
|
||||||
id="LaTeXParsing"
|
id="LaTeXParsing"
|
||||||
checked={LaTeXParsing}
|
checked={LaTeXParsing}
|
||||||
onCheckedChange={handleCheckedChange}
|
onCheckedChange={handleCheckedChange}
|
||||||
className="ml-4 mt-2"
|
className="ml-4"
|
||||||
data-testid="LaTeXParsing"
|
data-testid="LaTeXParsing"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ export default function ModularChatSwitch({
|
||||||
id="modularChat"
|
id="modularChat"
|
||||||
checked={modularChat}
|
checked={modularChat}
|
||||||
onCheckedChange={handleCheckedChange}
|
onCheckedChange={handleCheckedChange}
|
||||||
className="ml-4 mt-2"
|
className="ml-4"
|
||||||
data-testid="modularChat"
|
data-testid="modularChat"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ export default function SaveDraft({
|
||||||
id="saveDrafts"
|
id="saveDrafts"
|
||||||
checked={saveDrafts}
|
checked={saveDrafts}
|
||||||
onCheckedChange={handleCheckedChange}
|
onCheckedChange={handleCheckedChange}
|
||||||
className="ml-4 mt-2"
|
className="ml-4"
|
||||||
data-testid="saveDrafts"
|
data-testid="saveDrafts"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ export default function ShowCodeSwitch({
|
||||||
id="showCode"
|
id="showCode"
|
||||||
checked={showCode}
|
checked={showCode}
|
||||||
onCheckedChange={handleCheckedChange}
|
onCheckedChange={handleCheckedChange}
|
||||||
className="ml-4 mt-2"
|
className="ml-4"
|
||||||
data-testid="showCode"
|
data-testid="showCode"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ export default function AtCommandSwitch() {
|
||||||
id="atCommand"
|
id="atCommand"
|
||||||
checked={atCommand}
|
checked={atCommand}
|
||||||
onCheckedChange={handleCheckedChange}
|
onCheckedChange={handleCheckedChange}
|
||||||
className="ml-4 mt-2"
|
className="ml-4"
|
||||||
data-testid="atCommand"
|
data-testid="atCommand"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -28,16 +28,16 @@ function Commands() {
|
||||||
<HoverCardSettings side="bottom" text="com_nav_chat_commands_info" />
|
<HoverCardSettings side="bottom" text="com_nav_chat_commands_info" />
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col gap-3 text-sm text-text-primary">
|
<div className="flex flex-col gap-3 text-sm text-text-primary">
|
||||||
<div className="border-b border-border-light pb-3 last-of-type:border-b-0">
|
<div className="pb-3">
|
||||||
<AtCommandSwitch />
|
<AtCommandSwitch />
|
||||||
</div>
|
</div>
|
||||||
{hasAccessToMultiConvo === true && (
|
{hasAccessToMultiConvo === true && (
|
||||||
<div className="border-b border-border-light pb-3 last-of-type:border-b-0">
|
<div className="pb-3">
|
||||||
<PlusCommandSwitch />
|
<PlusCommandSwitch />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{hasAccessToPrompts === true && (
|
{hasAccessToPrompts === true && (
|
||||||
<div className="border-b border-border-light pb-3 last-of-type:border-b-0">
|
<div className="pb-3">
|
||||||
<SlashCommandSwitch />
|
<SlashCommandSwitch />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,8 @@ export default function PlusCommandSwitch() {
|
||||||
id="plusCommand"
|
id="plusCommand"
|
||||||
checked={plusCommand}
|
checked={plusCommand}
|
||||||
onCheckedChange={handleCheckedChange}
|
onCheckedChange={handleCheckedChange}
|
||||||
className="ml-4 mt-2"
|
f
|
||||||
|
className="ml-4"
|
||||||
data-testid="plusCommand"
|
data-testid="plusCommand"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ export default function SlashCommandSwitch() {
|
||||||
id="slashCommand"
|
id="slashCommand"
|
||||||
checked={slashCommand}
|
checked={slashCommand}
|
||||||
onCheckedChange={handleCheckedChange}
|
onCheckedChange={handleCheckedChange}
|
||||||
className="ml-4 mt-2"
|
f
|
||||||
data-testid="slashCommand"
|
data-testid="slashCommand"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -13,19 +13,19 @@ function Data() {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col gap-3 p-1 text-sm text-text-primary">
|
<div className="flex flex-col gap-3 p-1 text-sm text-text-primary">
|
||||||
<div className="border-b border-border-medium pb-3 last-of-type:border-b-0">
|
<div className="pb-3">
|
||||||
<ImportConversations />
|
<ImportConversations />
|
||||||
</div>
|
</div>
|
||||||
<div className="border-b border-border-medium pb-3 last-of-type:border-b-0">
|
<div className="pb-3">
|
||||||
<SharedLinks />
|
<SharedLinks />
|
||||||
</div>
|
</div>
|
||||||
<div className="border-b border-border-medium pb-3 last-of-type:border-b-0">
|
<div className="pb-3">
|
||||||
<RevokeAllKeys />
|
<RevokeAllKeys />
|
||||||
</div>
|
</div>
|
||||||
<div className="border-b border-border-medium pb-3 last-of-type:border-b-0">
|
<div className="pb-3">
|
||||||
<DeleteCache />
|
<DeleteCache />
|
||||||
</div>
|
</div>
|
||||||
<div className="border-b border-border-medium pb-3 last-of-type:border-b-0">
|
<div className="pb-3">
|
||||||
<ClearChats />
|
<ClearChats />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ export default function AutoScrollSwitch({
|
||||||
checked={autoScroll}
|
checked={autoScroll}
|
||||||
aria-label="Auto-Scroll to latest message on chat open"
|
aria-label="Auto-Scroll to latest message on chat open"
|
||||||
onCheckedChange={handleCheckedChange}
|
onCheckedChange={handleCheckedChange}
|
||||||
className="ml-4 mt-2 ring-ring-primary"
|
className="ml-4"
|
||||||
data-testid="autoScroll"
|
data-testid="autoScroll"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,12 @@
|
||||||
import { useRecoilState } from 'recoil';
|
import { useRecoilState } from 'recoil';
|
||||||
import Cookies from 'js-cookie';
|
import Cookies from 'js-cookie';
|
||||||
import React, { useContext, useCallback } from 'react';
|
import React, { useContext, useCallback } from 'react';
|
||||||
import type { TDangerButtonProps } from '~/common';
|
|
||||||
import UserMsgMarkdownSwitch from './UserMsgMarkdownSwitch';
|
import UserMsgMarkdownSwitch from './UserMsgMarkdownSwitch';
|
||||||
import HideSidePanelSwitch from './HideSidePanelSwitch';
|
import HideSidePanelSwitch from './HideSidePanelSwitch';
|
||||||
import { ThemeContext, useLocalize } from '~/hooks';
|
import { ThemeContext, useLocalize } from '~/hooks';
|
||||||
import AutoScrollSwitch from './AutoScrollSwitch';
|
import AutoScrollSwitch from './AutoScrollSwitch';
|
||||||
import ArchivedChats from './ArchivedChats';
|
import ArchivedChats from './ArchivedChats';
|
||||||
import { Dropdown } from '~/components/ui';
|
import { Dropdown } from '~/components/ui';
|
||||||
import DangerButton from '../DangerButton';
|
|
||||||
import store from '~/store';
|
import store from '~/store';
|
||||||
|
|
||||||
export const ThemeSelector = ({
|
export const ThemeSelector = ({
|
||||||
|
|
@ -41,34 +39,6 @@ export const ThemeSelector = ({
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
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"
|
|
||||||
infoDescriptionCode="com_nav_info_clear_all_chats"
|
|
||||||
onClick={onClick}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const LangSelector = ({
|
export const LangSelector = ({
|
||||||
langcode,
|
langcode,
|
||||||
onChange,
|
onChange,
|
||||||
|
|
@ -78,7 +48,6 @@ export const LangSelector = ({
|
||||||
}) => {
|
}) => {
|
||||||
const localize = useLocalize();
|
const localize = useLocalize();
|
||||||
|
|
||||||
// Create an array of options for the Dropdown
|
|
||||||
const languageOptions = [
|
const languageOptions = [
|
||||||
{ value: 'auto', label: localize('com_nav_lang_auto') },
|
{ value: 'auto', label: localize('com_nav_lang_auto') },
|
||||||
{ value: 'en-US', label: localize('com_nav_lang_english') },
|
{ value: 'en-US', label: localize('com_nav_lang_english') },
|
||||||
|
|
@ -147,22 +116,22 @@ function General() {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col gap-3 p-1 text-sm text-text-primary">
|
<div className="flex flex-col gap-3 p-1 text-sm text-text-primary">
|
||||||
<div className="border-b border-border-light pb-3 last-of-type:border-b-0">
|
<div className="pb-3">
|
||||||
<ThemeSelector theme={theme} onChange={changeTheme} />
|
<ThemeSelector theme={theme} onChange={changeTheme} />
|
||||||
</div>
|
</div>
|
||||||
<div className="border-b border-border-light pb-3 last-of-type:border-b-0">
|
<div className="pb-3">
|
||||||
<LangSelector langcode={langcode} onChange={changeLang} />
|
<LangSelector langcode={langcode} onChange={changeLang} />
|
||||||
</div>
|
</div>
|
||||||
<div className="border-b border-border-light pb-3 last-of-type:border-b-0">
|
<div className="pb-3">
|
||||||
<UserMsgMarkdownSwitch />
|
<UserMsgMarkdownSwitch />
|
||||||
</div>
|
</div>
|
||||||
<div className="border-b border-border-light pb-3 last-of-type:border-b-0">
|
<div className="pb-3">
|
||||||
<AutoScrollSwitch />
|
<AutoScrollSwitch />
|
||||||
</div>
|
</div>
|
||||||
<div className="border-b border-border-light pb-3 last-of-type:border-b-0">
|
<div className="pb-3">
|
||||||
<HideSidePanelSwitch />
|
<HideSidePanelSwitch />
|
||||||
</div>
|
</div>
|
||||||
<div className="border-b border-border-light pb-3 last-of-type:border-b-0">
|
<div className="pb-3">
|
||||||
<ArchivedChats />
|
<ArchivedChats />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ export default function HideSidePanelSwitch({
|
||||||
checked={hideSidePanel}
|
checked={hideSidePanel}
|
||||||
aria-label="Hide right-most side panel"
|
aria-label="Hide right-most side panel"
|
||||||
onCheckedChange={handleCheckedChange}
|
onCheckedChange={handleCheckedChange}
|
||||||
className="ml-4 mt-2"
|
className="ml-4"
|
||||||
data-testid="hideSidePanel"
|
data-testid="hideSidePanel"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ export default function UserMsgMarkdownSwitch({
|
||||||
id="enableUserMsgMarkdown"
|
id="enableUserMsgMarkdown"
|
||||||
checked={enableUserMsgMarkdown}
|
checked={enableUserMsgMarkdown}
|
||||||
onCheckedChange={handleCheckedChange}
|
onCheckedChange={handleCheckedChange}
|
||||||
className="ml-4 mt-2 ring-ring-primary"
|
className="ml-4"
|
||||||
data-testid="enableUserMsgMarkdown"
|
data-testid="enableUserMsgMarkdown"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
export { default as General } from './General/General';
|
export { default as General } from './General/General';
|
||||||
export { default as Chat } from './Chat/Chat';
|
export { default as Chat } from './Chat/Chat';
|
||||||
export { ClearChatsButton } from './General/General';
|
|
||||||
export { default as Data } from './Data/Data';
|
export { default as Data } from './Data/Data';
|
||||||
export { default as Beta } from './Beta/Beta';
|
export { default as Beta } from './Beta/Beta';
|
||||||
export { default as Commands } from './Commands/Commands';
|
export { default as Commands } from './Commands/Commands';
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,7 @@ const OGDialogTemplate = forwardRef((props: DialogTemplateProps, ref: Ref<HTMLDi
|
||||||
onClick={selectHandler}
|
onClick={selectHandler}
|
||||||
className={`${
|
className={`${
|
||||||
selectClasses ?? defaultSelect
|
selectClasses ?? defaultSelect
|
||||||
} flex h-10 w-full items-center justify-center rounded-lg border-none px-4 py-2 text-sm`}
|
} flex h-10 items-center justify-center rounded-lg border-none px-4 py-2 text-sm`}
|
||||||
>
|
>
|
||||||
{selectText}
|
{selectText}
|
||||||
</OGDialogClose>
|
</OGDialogClose>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue