Skip to content

Commit

Permalink
🚧 wip: 子话题模式
Browse files Browse the repository at this point in the history
  • Loading branch information
arvinxx committed Nov 6, 2024
1 parent be0d4d9 commit cb1bdfa
Show file tree
Hide file tree
Showing 17 changed files with 115 additions and 12 deletions.
15 changes: 11 additions & 4 deletions src/app/(main)/chat/(workspace)/_layout/Desktop/Portal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,21 @@ const useStyles = createStyles(({ css, token, isDarkMode }) => ({
height: 100%;
background: ${isDarkMode ? rgba(token.colorBgElevated, 0.8) : token.colorBgElevated};
`,

thread: css`
background: ${token.colorBgLayout};
`,
}));

const PortalPanel = memo(({ children }: PropsWithChildren) => {
const { styles } = useStyles();
const { styles, cx } = useStyles();
const { md = true } = useResponsive();

const [showInspector, showToolUI, showArtifactUI] = useChatStore((s) => [
const [showInspector, showToolUI, showArtifactUI, showThread] = useChatStore((s) => [
chatPortalSelectors.showPortal(s),
chatPortalSelectors.showPluginUI(s),
chatPortalSelectors.showArtifactUI(s),
chatPortalSelectors.showThread(s),
]);

return (
Expand All @@ -54,7 +59,9 @@ const PortalPanel = memo(({ children }: PropsWithChildren) => {
expand
hanlderStyle={{ display: 'none' }}
maxWidth={CHAT_PORTAL_MAX_WIDTH}
minWidth={showArtifactUI || showToolUI ? CHAT_PORTAL_TOOL_UI_WIDTH : CHAT_PORTAL_WIDTH}
minWidth={
showArtifactUI || showToolUI || showThread ? CHAT_PORTAL_TOOL_UI_WIDTH : CHAT_PORTAL_WIDTH
}
mode={md ? 'fixed' : 'float'}
placement={'right'}
showHandlerWhenUnexpand={false}
Expand All @@ -68,7 +75,7 @@ const PortalPanel = memo(({ children }: PropsWithChildren) => {
minWidth: CHAT_PORTAL_WIDTH,
}}
>
<Flexbox className={styles.panel}>{children}</Flexbox>
<Flexbox className={cx(styles.panel, showThread && styles.thread)}>{children}</Flexbox>
</DraggablePanelContainer>
</DraggablePanel>
)
Expand Down
5 changes: 3 additions & 2 deletions src/features/Conversation/Actions/Assistant.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ import { ErrorActionsBar } from './Error';
import { useCustomActions } from './customAction';

export const AssistantActionsBar: RenderAction = memo(({ id, onActionClick, error, tools }) => {
const { regenerate, edit, delAndRegenerate, copy, divider, del } = useChatListActionsBar();
const { regenerate, edit, delAndRegenerate, copy, divider, del, branching } =
useChatListActionsBar();
const { translate, tts } = useCustomActions();
const hasTools = !!tools;

Expand All @@ -28,7 +29,7 @@ export const AssistantActionsBar: RenderAction = memo(({ id, onActionClick, erro
delAndRegenerate,
del,
]}
items={[hasTools ? delAndRegenerate : edit, copy]}
items={[hasTools ? delAndRegenerate : edit, copy, branching]}
onActionClick={onActionClick}
type="ghost"
/>
Expand Down
4 changes: 2 additions & 2 deletions src/features/Conversation/Actions/User.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ import { RenderAction } from '../types';
import { useCustomActions } from './customAction';

export const UserActionsBar: RenderAction = memo(({ onActionClick }) => {
const { regenerate, edit, copy, divider, del } = useChatListActionsBar();
const { regenerate, edit, copy, divider, del, branching } = useChatListActionsBar();
const { translate, tts } = useCustomActions();

return (
<ActionIconGroup
dropdownMenu={[edit, copy, divider, tts, translate, divider, regenerate, del]}
items={[regenerate, edit]}
items={[regenerate, edit, branching]}
onActionClick={onActionClick}
type="ghost"
/>
Expand Down
6 changes: 6 additions & 0 deletions src/features/Conversation/Actions/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,15 @@ export const useActionsClick = (): OnActionsClick => {
ttsMessage,
delAndRegenerateMessage,
copyMessage,
openThreadCreator,
] = useChatStore((s) => [
s.deleteMessage,
s.regenerateMessage,
s.translateMessage,
s.ttsMessage,
s.delAndRegenerateMessage,
s.copyMessage,
s.openThreadCreator,
]);
const { message } = App.useApp();

Expand All @@ -44,6 +46,10 @@ export const useActionsClick = (): OnActionsClick => {
message.success(t('copySuccess', { defaultValue: 'Copy Success' }));
break;
}
case 'branching': {
openThreadCreator(id);
break;
}

case 'del': {
deleteMessage(id);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import SkeletonList from '../SkeletonList';

interface VirtualizedListProps {
mobile?: boolean;
threadMode?: boolean;
}
const VirtualizedList = memo<VirtualizedListProps>(({ mobile }) => {
const virtuosoRef = useRef<VirtuosoHandle>(null);
Expand Down
8 changes: 7 additions & 1 deletion src/features/Conversation/hooks/useChatListActionsBar.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { ActionIconGroupItems } from '@lobehub/ui/es/ActionIconGroup';
import { Copy, Edit, ListRestart, RotateCcw, Trash } from 'lucide-react';
import { Copy, Edit, ListRestart, RotateCcw, Split, Trash } from 'lucide-react';
import { useMemo } from 'react';
import { useTranslation } from 'react-i18next';

interface ChatListActionsBar {
branching: ActionIconGroupItems;
copy: ActionIconGroupItems;
del: ActionIconGroupItems;
delAndRegenerate: ActionIconGroupItems;
Expand All @@ -17,6 +18,11 @@ export const useChatListActionsBar = (): ChatListActionsBar => {

return useMemo(
() => ({
branching: {
icon: Split,
key: 'branching',
label: t('branching', { defaultValue: 'Create Sub Topic' }),
},
copy: {
icon: Copy,
key: 'copy',
Expand Down
5 changes: 3 additions & 2 deletions src/features/Conversation/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ const ChatList = lazy(() => import('./components/VirtualizedList'));

interface ConversationProps {
mobile?: boolean;
threadMode?: boolean;
}

const Conversation = ({ mobile }: ConversationProps) => {
const Conversation = ({ mobile, threadMode }: ConversationProps) => {
return (
<Flexbox
flex={1}
Expand All @@ -21,7 +22,7 @@ const Conversation = ({ mobile }: ConversationProps) => {
width={'100%'}
>
<Suspense fallback={<SkeletonList mobile={mobile} />}>
<ChatList mobile={mobile} />
<ChatList mobile={mobile} threadMode={threadMode} />
</Suspense>
</Flexbox>
);
Expand Down
30 changes: 30 additions & 0 deletions src/features/Portal/Thread/Body/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { Avatar, Icon } from '@lobehub/ui';
import { Input } from 'antd';
import { GitBranch } from 'lucide-react';
import { Flexbox } from 'react-layout-kit';

import DesktopChatInput from '@/app/(main)/chat/(workspace)/@conversation/features/ChatInput/Desktop';
import Conversation from '@/features/Conversation';

const ThreadBody = () => {
return (
<Flexbox height={'100%'} justify={'space-between'} paddingInline={12}>
<div />
<Flexbox flex={1} gap={12}>
<Avatar
avatar={<Icon icon={GitBranch} size={'large'} />}
background={'#3f4148'}
size={56}
/>
子话题名称(Optional)
<Input placeholder={'abc'} variant={'filled'} />
<Flexbox height={'100%'}>
<Conversation threadMode />
<DesktopChatInput />
</Flexbox>
</Flexbox>
</Flexbox>
);
};

export default ThreadBody;
Empty file.
23 changes: 23 additions & 0 deletions src/features/Portal/Thread/Header.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { Icon } from '@lobehub/ui';
import { Typography } from 'antd';
import { GitBranch } from 'lucide-react';
import { Flexbox } from 'react-layout-kit';

import { useChatStore } from '@/store/chat';
import { chatPortalSelectors } from '@/store/chat/selectors';
import { oneLineEllipsis } from '@/styles';

const Header = () => {
// const [previewFileId] = useChatStore((s) => [chatPortalSelectors.previewFileId(s)]);

return (
<Flexbox align={'center'} gap={8} horizontal style={{ marginInlineStart: 8 }}>
<Icon icon={GitBranch} size={{ fontSize: 20 }} />
<Typography.Text className={oneLineEllipsis} style={{ fontSize: 16, fontWeight: 'bold' }}>
新子话题
</Typography.Text>
</Flexbox>
);
};

export default Header;
10 changes: 10 additions & 0 deletions src/features/Portal/Thread/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { PortalImpl } from '../type';
import Body from './Body';
import Header from './Header';
import { useEnable } from './useEnable';

export const Thread: PortalImpl = {
Body,
Header,
useEnable,
};
6 changes: 6 additions & 0 deletions src/features/Portal/Thread/useEnable.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { useChatStore } from '@/store/chat';
import { chatPortalSelectors } from '@/store/chat/selectors';

export const useEnable = () => {
return useChatStore(chatPortalSelectors.showThread);
};
3 changes: 2 additions & 1 deletion src/features/Portal/router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ import { FilePreview } from './FilePreview';
import { HomeBody, HomeHeader } from './Home';
import { MessageDetail } from './MessageDetail';
import { Plugins } from './Plugins';
import { Thread } from './Thread';
import { PortalImpl } from './type';

const items: PortalImpl[] = [MessageDetail, Artifacts, Plugins, FilePreview];
const items: PortalImpl[] = [Thread, MessageDetail, Artifacts, Plugins, FilePreview];

export const PortalHeader = memo(() => {
const enabledList: boolean[] = [];
Expand Down
1 change: 1 addition & 0 deletions src/locales/default/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export default {
back: '返回',
batchDelete: '批量删除',
blog: '产品博客',
branching: '创建子话题',
cancel: '取消',
changelog: '更新日志',
close: '关闭',
Expand Down
6 changes: 6 additions & 0 deletions src/store/chat/slices/portal/action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export interface ChatPortalAction {
openArtifact: (artifact: PortalArtifact) => void;
openFilePreview: (portal: PortalFile) => void;
openMessageDetail: (messageId: string) => void;
openThreadCreator: (messageId: string) => void;
openToolUI: (messageId: string, identifier: string) => void;
togglePortal: (open?: boolean) => void;
}
Expand Down Expand Up @@ -51,6 +52,11 @@ export const chatPortalSlice: StateCreator<

set({ portalMessageDetail: messageId }, false, 'openMessageDetail');
},
openThreadCreator: (messageId) => {
get().togglePortal(true);

set({ portalThreadStartMessageId: messageId }, false, 'openMessageDetail');
},
openToolUI: (id, identifier) => {
get().togglePortal(true);

Expand Down
1 change: 1 addition & 0 deletions src/store/chat/slices/portal/initialState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export interface ChatPortalState {
portalArtifactDisplayMode?: 'code' | 'preview';
portalFile?: PortalFile;
portalMessageDetail?: string;
portalThreadStartMessageId?: string;
portalToolMessage?: { id: string; identifier: string };
showPortal: boolean;
}
Expand Down
3 changes: 3 additions & 0 deletions src/store/chat/slices/portal/selectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const isPluginUIOpen = (id: string) => (s: ChatStoreState) =>
const toolUIIdentifier = (s: ChatStoreState) => s.portalToolMessage?.identifier;

const showFilePreview = (s: ChatStoreState) => !!s.portalFile;
const showThread = (s: ChatStoreState) => !!s.portalThreadStartMessageId;
const previewFileId = (s: ChatStoreState) => s.portalFile?.fileId;
const chunkText = (s: ChatStoreState) => s.portalFile?.chunkText;

Expand Down Expand Up @@ -55,6 +56,8 @@ export const chatPortalSelectors = {
messageDetailId,
showMessageDetail,

showThread,

showPluginUI,
showPortal,

Expand Down

0 comments on commit cb1bdfa

Please sign in to comment.