Skip to content

Commit

Permalink
✨ feat: agent profile
Browse files Browse the repository at this point in the history
  • Loading branch information
arvinxx committed Jul 16, 2023
1 parent d37bb47 commit e9560a8
Show file tree
Hide file tree
Showing 13 changed files with 252 additions and 70 deletions.
19 changes: 18 additions & 1 deletion public/locales/zh_CN/common.json
Original file line number Diff line number Diff line change
@@ -1,16 +1,33 @@
{
"advanceSettings": "高级设置",
"agentAvatar": "头像",
"agentDescription": "描述",
"agentDescriptionPlaceholder": "请输入描述",
"agentName": "名称",
"agentNamePlaceholder": "请输入名称",
"agentProfile": "助手信息",
"agentPrompt": "提示词",
"agentPromptPlaceholder": "请输入 AI 提示词",
"agentTag": "标签",
"agentTagPlaceholder": "请输入标签",
"archive": "归档",
"autoGenerate": "自动补全",
"cancel": "取消",
"close": "关闭",
"confirmRemoveSessionItemAlert": "即将删除该助手,删除后该将无法找回,请确认你的操作",
"defaultAgent": "默认助手",
"edit": "编辑",
"editAgentProfile": "编辑助手信息",

"modelTemperature": "发散度",
"newAgent": "新建助手",
"noDescription": "暂无描述",
"ok": "确定",
"profile": "身份卡",
"reset": "重置",
"searchAgentPlaceholder": "搜索助手和对话...",
"sessionSetting": "会话设置",
"setting": "设置",
"share": "分享"
"share": "分享",
"updateAgent": "更新助理信息"
}
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { ActionIcon, DraggablePanel, DraggablePanelContainer } from '@lobehub/ui
import { createStyles } from 'antd-style';
import { LucideEdit, LucideX } from 'lucide-react';
import { useTranslation } from 'next-i18next';
import Router from 'next/router';
import { Flexbox } from 'react-layout-kit';
import { shallow } from 'zustand/shallow';

Expand All @@ -23,8 +24,8 @@ const useStyles = createStyles(({ css, token }) => ({
const Config = () => {
const { t } = useTranslation('common');
const { styles } = useStyles();
const [showAgentSettings, toggleConfig] = useChatStore(
(s) => [s.showAgentSettings, s.toggleConfig],
const [showAgentSettings, toggleConfig, id] = useChatStore(
(s) => [s.showAgentSettings, s.toggleConfig, s.activeId],
shallow,
);

Expand Down Expand Up @@ -53,6 +54,9 @@ const Config = () => {
<Flexbox gap={4} horizontal>
<ActionIcon
icon={LucideEdit}
onClick={() => {
Router.push(`/chat/${id}/edit`);
}}
size={{ blockSize: 32, fontSize: 20 }}
title={t('edit')}
/>
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
11 changes: 2 additions & 9 deletions src/pages/chat/Header.tsx → src/pages/chat/[id]/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,18 +58,11 @@ const Header = memo(() => {
</Flexbox>
</Flexbox>
<Flexbox gap={8} horizontal>
<ActionIcon
icon={Share2Icon}
onClick={() => {
// genShareUrl();
}}
size={{ fontSize: 24 }}
title={t('share')}
/>
<ActionIcon icon={Share2Icon} size={{ fontSize: 24 }} title={t('share')} />
<ActionIcon icon={ArchiveIcon} size={{ fontSize: 24 }} title={t('archive')} />
<ActionIcon
icon={MoreVerticalIcon}
onClick={toggleConfig}
onClick={() => toggleConfig()}
size={{ fontSize: 24 }}
title={t('sessionSetting')}
/>
Expand Down
27 changes: 27 additions & 0 deletions src/pages/chat/[id]/edit/Form.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { createStyles } from 'antd-style';
import { ReactNode, memo } from 'react';
import { Flexbox } from 'react-layout-kit';

const useStyles = createStyles(({ css, token }) => ({
header: css``,
title: css`
color: ${token.colorTextSecondary};
`,
}));

interface FormItemProps {
children: ReactNode;
label: string;
}
const FormItem = memo<FormItemProps>(({ label, children }) => {
const { styles } = useStyles();

return (
<Flexbox className={styles.header} gap={12}>
<Flexbox className={styles.title}>{label}</Flexbox>
<Flexbox>{children}</Flexbox>
</Flexbox>
);
});

export default FormItem;
130 changes: 130 additions & 0 deletions src/pages/chat/[id]/edit/index.page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
import { ActionIcon, Avatar, Input, TextArea } from '@lobehub/ui';
import { Button, Slider } from 'antd';
import { createStyles } from 'antd-style';
import { LucideChevronLeft } from 'lucide-react';
import { useTranslation } from 'next-i18next';
import { serverSideTranslations } from 'next-i18next/serverSideTranslations';
import Router from 'next/router';
import { memo } from 'react';
import { Flexbox } from 'react-layout-kit';

import ChatLayout from '../../layout';
import FormItem from './Form';

const useStyles = createStyles(({ css, token }) => ({
footer: css`
position: sticky;
bottom: 0;
border-top: 1px solid ${token.colorBorder};
`,
form: css`
overflow-y: auto;
`,
header: css`
background: ${token.colorBgContainer};
border-bottom: 1px solid ${token.colorSplit};
`,
profile: css`
font-size: 20px;
color: ${token.colorTextTertiary};
`,
title: css`
font-size: 16px;
font-weight: 500;
`,
}));

const EditPage = memo(() => {
const { t } = useTranslation('common');

const { styles, theme } = useStyles();

const basic = [
{ label: t('agentName'), placeholder: t('agentNamePlaceholder') },
{ label: t('agentDescription'), placeholder: t('agentDescriptionPlaceholder') },
{ label: t('agentTag'), placeholder: t('agentTagPlaceholder') },
];
return (
<ChatLayout>
<Flexbox height={'100vh'} style={{ position: 'relative' }} width={'100%'}>
{/*header*/}
<Flexbox
align={'center'}
className={styles.header}
gap={8}
horizontal
paddingBlock={8}
paddingInline={16}
>
<ActionIcon
icon={LucideChevronLeft}
onClick={() => {
Router.back();
}}
title={'返回'}
/>
<Flexbox className={styles.title}>{t('editAgentProfile')}</Flexbox>
</Flexbox>

{/*form*/}
<Flexbox className={styles.form} flex={1} gap={10} padding={24}>
<FormItem label={t('agentPrompt')}>
<TextArea
placeholder={t('agentPromptPlaceholder')}
// style={{ minHeight: 64 }}
type={'block'}
/>
</FormItem>

<Flexbox
align={'center'}
distribution={'space-between'}
horizontal
paddingBlock={12}
style={{
borderBottom: `1px solid ${theme.colorBorder}`,
}}
>
<Flexbox className={styles.profile}> {t('profile')}</Flexbox>
<Button size={'large'}>{t('autoGenerate')}</Button>
</Flexbox>
<Flexbox gap={80} horizontal style={{ marginTop: 16 }}>
<Flexbox flex={1} gap={24}>
{basic.map((item) => (
<FormItem key={item.label} label={item.label}>
<Input placeholder={item.placeholder} type={'block'} />
</FormItem>
))}

<Flexbox className={styles.profile}> {t('advanceSettings')}</Flexbox>

<FormItem label={t('modelTemperature')}>
<Slider />
</FormItem>
</Flexbox>
<FormItem label={t('agentAvatar')}>
<Avatar size={200} />
</FormItem>
</Flexbox>
</Flexbox>

{/*bottom*/}
<Flexbox
className={styles.footer}
direction={'horizontal-reverse'}
gap={8}
padding={'16px 24px'}
>
<Button type={'primary'}>{t('updateAgent')}</Button>
<Button>{t('reset')}</Button>
</Flexbox>
</Flexbox>
</ChatLayout>
);
});

export default EditPage;

export const getServerSideProps = async (context: any) => ({
props: await serverSideTranslations(context.locale),
});
70 changes: 22 additions & 48 deletions src/pages/chat/[id]/index.page.tsx
Original file line number Diff line number Diff line change
@@ -1,70 +1,44 @@
import isEqual from 'fast-deep-equal';
import { serverSideTranslations } from 'next-i18next/serverSideTranslations';
import Head from 'next/head';
import { useRouter } from 'next/router';
import { memo, useEffect } from 'react';
import { memo } from 'react';
import { Flexbox } from 'react-layout-kit';

import { sessionSelectors, useChatStore } from '@/store/session';
import { useSettings } from '@/store/settings';

import Config from '../Config';
import Conversation from '../Conversation';
import Header from '../Header';
import { Sessions } from '../SessionList';
import Sidebar from '../Sidebar';
import Layout from '../layout';
import Config from './Config';
import Conversation from './Conversation';
import Header from './Header';

const ChatLayout = memo(() => {
const Chat = memo(() => {
const [title] = useChatStore((s) => {
const context = sessionSelectors.currentSession(s);
return [context?.meta.title];
}, isEqual);

useEffect(() => {
useSettings.persist.rehydrate();
useSettings.setState({ sidebarKey: 'chat' });
}, []);

const router = useRouter();
const { id } = router.query;

useEffect(() => {
if (typeof id === 'string') {
useChatStore.setState({ activeId: id });
}
}, [id]);

return (
<>
<Layout>
<Head>
<title>{title ? `${title} - LobeChat` : 'LobeChat'}</title>
</Head>
<Flexbox horizontal width={'100%'}>
<Sidebar />
<Sessions />
<Flexbox flex={1}>
<Header />
<Flexbox
id={'lobe-conversion-container'}
style={{ height: 'calc(100vh - 64px)', position: 'relative' }}
>
<Conversation />
<Config />
</Flexbox>

<Flexbox flex={1}>
<Header />
<Flexbox
id={'lobe-conversion-container'}
style={{ height: 'calc(100vh - 64px)', position: 'relative' }}
>
<Conversation />
<Config />
</Flexbox>
</Flexbox>
</>
</Layout>
);
});
export default Chat;

export async function getServerSideProps(context: any) {
const { locale } = context;
return {
props: {
// pass the translation props to the page component
...(await serverSideTranslations(locale)),
},
};
}

export default ChatLayout;
// pass the translation props to the page component
export const getServerSideProps = async (context: any) => ({
props: await serverSideTranslations(context.locale),
});
47 changes: 47 additions & 0 deletions src/pages/chat/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import isEqual from 'fast-deep-equal';
import Head from 'next/head';
import { useRouter } from 'next/router';
import { PropsWithChildren, memo, useEffect } from 'react';
import { Flexbox } from 'react-layout-kit';

import { sessionSelectors, useChatStore } from '@/store/session';
import { useSettings } from '@/store/settings';

import { Sessions } from './SessionList';
import Sidebar from './Sidebar';

const ChatLayout = memo<PropsWithChildren>(({ children }) => {
const [title] = useChatStore((s) => {
const context = sessionSelectors.currentSession(s);
return [context?.meta.title];
}, isEqual);

useEffect(() => {
useSettings.persist.rehydrate();
useSettings.setState({ sidebarKey: 'chat' });
}, []);

const router = useRouter();
const { id } = router.query;

useEffect(() => {
if (typeof id === 'string') {
useChatStore.setState({ activeId: id });
}
}, [id]);

return (
<>
<Head>
<title>{title ? `${title} - LobeChat` : 'LobeChat'}</title>
</Head>
<Flexbox horizontal width={'100%'}>
<Sidebar />
<Sessions />
{children}
</Flexbox>
</>
);
});

export default ChatLayout;
Loading

0 comments on commit e9560a8

Please sign in to comment.