Chat Split: land. Controls in Page Menu. Fixes #208

This commit is contained in:
Enrico Ros
2024-02-03 15:31:59 -08:00
parent 190010b3e3
commit c089ea7499
5 changed files with 36 additions and 51 deletions
+12 -13
View File
@@ -22,7 +22,6 @@ import { themeBgAppChatComposer } from '~/common/app.theme';
import { useFolderStore } from '~/common/state/store-folders';
import { useIsMobile } from '~/common/components/useMatchMedia';
import { useOptimaLayout, usePluggableOptimaLayout } from '~/common/layout/optima/useOptimaLayout';
import { useUXLabsStore } from '~/common/state/store-ux-labs';
import type { ComposerOutputMultiPart } from './components/composer/composer.types';
import { ChatDrawerMemo } from './components/applayout/ChatDrawer';
@@ -311,24 +310,23 @@ export function AppChat() {
const handleConversationBranch = React.useCallback((conversationId: DConversationId, messageId: string | null): DConversationId | null => {
showNextTitle.current = true;
const branchedConversationId = branchConversation(conversationId, messageId);
if (isSplitPane)
openSplitConversationId(branchedConversationId);
else
setFocusedConversationId(branchedConversationId);
addSnackbar({
key: 'branch-conversation',
message: 'Branch started.',
type: 'success',
overrides: {
autoHideDuration: 3000,
autoHideDuration: 2000,
startDecorator: <ForkRightIcon />,
},
});
const branchInAltPanel = useUXLabsStore.getState().labsSplitBranching;
if (branchInAltPanel)
openSplitConversationId(branchedConversationId);
else
setFocusedConversationId(branchedConversationId);
return branchedConversationId;
}, [branchConversation, openSplitConversationId, setFocusedConversationId]);
}, [branchConversation, isSplitPane, openSplitConversationId, setFocusedConversationId]);
const handleConversationFlatten = (conversationId: DConversationId) => setFlattenConversationId(conversationId);
const handleConversationFlatten = React.useCallback((conversationId: DConversationId) => setFlattenConversationId(conversationId), []);
const handleConfirmedClearConversation = React.useCallback(() => {
if (clearConversationId) {
@@ -386,10 +384,8 @@ export function AppChat() {
const centerItems = React.useMemo(() =>
<ChatDropdowns
conversationId={focusedConversationId}
isSplitPanes={isSplitPane}
onToggleSplitPanes={toggleSplitPane}
/>,
[focusedConversationId, isSplitPane, toggleSplitPane],
[focusedConversationId],
);
const drawerContent = React.useMemo(() =>
@@ -410,16 +406,19 @@ export function AppChat() {
const menuItems = React.useMemo(() =>
<ChatMenuItems
isMobile={isMobile}
conversationId={focusedConversationId}
hasConversations={!areChatsEmpty}
isConversationEmpty={isFocusedChatEmpty}
isMessageSelectionMode={isMessageSelectionMode}
isSplitPane={isSplitPane}
setIsMessageSelectionMode={setIsMessageSelectionMode}
onConversationBranch={handleConversationBranch}
onConversationClear={handleConversationClear}
onConversationFlatten={handleConversationFlatten}
onToggleSplitPanes={toggleSplitPane}
/>,
[areChatsEmpty, focusedConversationId, handleConversationBranch, handleConversationClear, isFocusedChatEmpty, isMessageSelectionMode],
[areChatsEmpty, focusedConversationId, handleConversationBranch, handleConversationClear, handleConversationFlatten, isFocusedChatEmpty, isMessageSelectionMode, isMobile, isSplitPane, toggleSplitPane],
);
usePluggableOptimaLayout(drawerContent, centerItems, menuItems, 'AppChat');
@@ -1,12 +1,6 @@
import * as React from 'react';
import { IconButton } from '@mui/joy';
import VerticalSplitIcon from '@mui/icons-material/VerticalSplit';
import VerticalSplitOutlinedIcon from '@mui/icons-material/VerticalSplitOutlined';
import type { DConversationId } from '~/common/state/store-chats';
import { GoodTooltip } from '~/common/components/GoodTooltip';
import { useUXLabsStore } from '~/common/state/store-ux-labs';
import { useChatLLMDropdown } from './useLLMDropdown';
import { usePersonaIdDropdown } from './usePersonaDropdown';
@@ -15,8 +9,6 @@ import { useFolderDropdown } from './folder/useFolderDropdown';
export function ChatDropdowns(props: {
conversationId: DConversationId | null
isSplitPanes: boolean
onToggleSplitPanes: () => void
}) {
// state
@@ -24,9 +16,6 @@ export function ChatDropdowns(props: {
const { personaDropdown } = usePersonaIdDropdown(props.conversationId);
const { folderDropdown } = useFolderDropdown(props.conversationId);
// external state
const labsSplitBranching = useUXLabsStore(state => state.labsSplitBranching);
return <>
{/* Persona selector */}
@@ -38,18 +27,5 @@ export function ChatDropdowns(props: {
{/* Folder selector */}
{folderDropdown}
{/* Split Panes button */}
{labsSplitBranching && (
<GoodTooltip title={props.isSplitPanes ? 'Close Split Panes' : 'Split Conversation Vertically'}>
<IconButton
variant={props.isSplitPanes ? 'outlined' : undefined}
onClick={props.onToggleSplitPanes}
// sx={{ mx: 'auto' }}
>
{props.isSplitPanes ? <VerticalSplitIcon /> : <VerticalSplitOutlinedIcon />}
</IconButton>
</GoodTooltip>
)}
</>;
}
@@ -6,9 +6,14 @@ import CheckBoxOutlinedIcon from '@mui/icons-material/CheckBoxOutlined';
import ClearIcon from '@mui/icons-material/Clear';
import CompressIcon from '@mui/icons-material/Compress';
import ForkRightIcon from '@mui/icons-material/ForkRight';
import HorizontalSplitIcon from '@mui/icons-material/HorizontalSplit';
import HorizontalSplitOutlinedIcon from '@mui/icons-material/HorizontalSplitOutlined';
import SettingsSuggestIcon from '@mui/icons-material/SettingsSuggest';
import VerticalSplitIcon from '@mui/icons-material/VerticalSplit';
import VerticalSplitOutlinedIcon from '@mui/icons-material/VerticalSplitOutlined';
import type { DConversationId } from '~/common/state/store-chats';
import { GoodTooltip } from '~/common/components/GoodTooltip';
import { KeyStroke } from '~/common/components/KeyStroke';
import { useOptimaDrawers } from '~/common/layout/optima/useOptimaDrawers';
@@ -16,14 +21,17 @@ import { useChatShowSystemMessages } from '../../store-app-chat';
export function ChatMenuItems(props: {
isMobile: boolean,
conversationId: DConversationId | null,
hasConversations: boolean,
isConversationEmpty: boolean,
isMessageSelectionMode: boolean,
isSplitPane: boolean
setIsMessageSelectionMode: (isMessageSelectionMode: boolean) => void,
onConversationBranch: (conversationId: DConversationId, messageId: string | null) => void,
onConversationClear: (conversationId: DConversationId) => void,
onConversationFlatten: (conversationId: DConversationId) => void,
onToggleSplitPanes: () => void,
}) {
// external state
@@ -64,6 +72,20 @@ export function ChatMenuItems(props: {
return <>
{/* Split/Unsplit panes */}
<GoodTooltip title={props.isSplitPane ? 'Close Split Panes' : 'Split Conversation Vertically'}>
<MenuItem onClick={props.onToggleSplitPanes}>
<ListItemDecorator>{
props.isMobile
? (props.isSplitPane ? <HorizontalSplitIcon /> : <HorizontalSplitOutlinedIcon />)
: (props.isSplitPane ? <VerticalSplitIcon /> : <VerticalSplitOutlinedIcon />)
}</ListItemDecorator>
{props.isSplitPane ? 'Unsplit' : props.isMobile ? 'Split Down' : 'Split Right'}
</MenuItem>
</GoodTooltip>
<ListDivider />
{/*<ListItem>*/}
{/* <Typography level='body-sm'>*/}
{/* Conversation*/}
+2 -8
View File
@@ -3,7 +3,6 @@ import * as React from 'react';
import { FormControl, Typography } from '@mui/joy';
import AddAPhotoIcon from '@mui/icons-material/AddAPhoto';
import ScreenshotMonitorIcon from '@mui/icons-material/ScreenshotMonitor';
import VerticalSplitIcon from '@mui/icons-material/VerticalSplit';
import { FormLabelStart } from '~/common/components/forms/FormLabelStart';
import { FormSwitchControl } from '~/common/components/forms/FormSwitchControl';
@@ -19,7 +18,6 @@ export function UxLabsSettings() {
const {
labsAttachScreenCapture, setLabsAttachScreenCapture,
labsCameraDesktop, setLabsCameraDesktop,
labsSplitBranching, setLabsSplitBranching,
} = useUXLabsStore();
return <>
@@ -34,15 +32,11 @@ export function UxLabsSettings() {
checked={labsCameraDesktop} onChange={setLabsCameraDesktop}
/>}
<FormSwitchControl
title={<><VerticalSplitIcon color={labsSplitBranching ? 'primary' : undefined} sx={{ mr: 0.25 }} /> Split Branching</>} description={/*'v1.6 · ' +*/ (labsSplitBranching ? 'Enabled' : 'Disabled')}
checked={labsSplitBranching} onChange={setLabsSplitBranching}
/>
<FormControl orientation='horizontal' sx={{ justifyContent: 'space-between', alignItems: 'center' }}>
<FormLabelStart title='Graduated' description='Ex-labs' />
<Typography level='body-xs'>
<Link href='https://github.com/enricoros/big-AGI/issues/359' target='_blank'>Draw App</Link>
<Link href='https://github.com/enricoros/big-AGI/issues/208' target='_blank'>Split Chats</Link>
{' · '}<Link href='https://github.com/enricoros/big-AGI/issues/359' target='_blank'>Draw App</Link>
{' · '}<Link href='https://github.com/enricoros/big-AGI/issues/354' target='_blank'>Call AGI</Link>
{' · '}<Link href='https://github.com/enricoros/big-AGI/issues/282' target='_blank'>Persona Creator</Link>
{' · '}<Link href='https://github.com/enricoros/big-agi/issues/192' target='_blank'>Auto Diagrams</Link>
-6
View File
@@ -18,9 +18,6 @@ interface UXLabsStore {
labsCameraDesktop: boolean;
setLabsCameraDesktop: (labsCameraDesktop: boolean) => void;
labsSplitBranching: boolean;
setLabsSplitBranching: (labsSplitBranching: boolean) => void;
}
export const useUXLabsStore = create<UXLabsStore>()(
@@ -33,9 +30,6 @@ export const useUXLabsStore = create<UXLabsStore>()(
labsCameraDesktop: false,
setLabsCameraDesktop: (labsCameraDesktop: boolean) => set({ labsCameraDesktop }),
labsSplitBranching: false,
setLabsSplitBranching: (labsSplitBranching: boolean) => set({ labsSplitBranching }),
}),
{
name: 'app-ux-labs',