Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/main'
Browse files Browse the repository at this point in the history
  • Loading branch information
bentwnghk committed Mar 2, 2024
2 parents 5f7bc05 + 01c7ad4 commit 749ef2f
Show file tree
Hide file tree
Showing 26 changed files with 1,700 additions and 1,152 deletions.
4 changes: 2 additions & 2 deletions README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@

### `3` [模型视觉识别 (Model Visual)][docs-feat-vision]

LobeChat 已经支持 OpenAI 最新的 [`gpt-4-vision`](https://platform.openai.com/docs/guides/vision) 支持视觉识别的模型,这是一个具备视觉识别能力的多模态智能
LobeChat 已经支持 OpenAI 最新的 [`gpt-4-vision`](https://platform.openai.com/docs/guides/vision) 支持视觉识别的模型,这是一个具备视觉识别能力的多模态应用
用户可以轻松上传图片或者拖拽图片到对话框中,助手将能够识别图片内容,并在此基础上进行智能对话,构建更智能、更多元化的聊天场景。

这一特性打开了新的互动方式,使得交流不再局限于文字,而是可以涵盖丰富的视觉元素。无论是日常使用中的图片分享,还是在特定行业内的图像解读,助手都能提供出色的对话体验。
Expand Down Expand Up @@ -300,7 +300,7 @@ LobeChat 的插件生态系统是其核心功能的重要扩展,它极大地
### `10` [自定义主题][docs-feat-theme]

作为设计工程师出身 LobeChat 在界面设计上十分考虑用户的个性化体验,因此引入了灵活多变的主题模式,其中包括日间的亮色模式和夜间的深色模式。
除了主题模式的切换,提供了一系列的颜色定制选项,允许用户根据自己的喜好来调整应用的主题色彩。无论是想要沉稳的深蓝,还是希望活泼的桃粉,或者是专业的灰白,用户都能够在 LobeChat 中找到匹配自己风格的颜色选择。
除了主题模式的切换,还提供了一系列的颜色定制选项,允许用户根据自己的喜好来调整应用的主题色彩。无论是想要沉稳的深蓝,还是希望活泼的桃粉,或者是专业的灰白,用户都能够在 LobeChat 中找到匹配自己风格的颜色选择。

> \[!TIP]
>
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"tts",
"stt"
],
"homepage": "https://mr5drive.com/",
"homepage": "https://ai3.mister5.net/",
"bugs": {
"url": "https://github.com/bentwnghk/lobe-chat/issues/new/choose"
},
Expand Down
102 changes: 0 additions & 102 deletions src/app/chat/(desktop)/features/ChatHeader.tsx

This file was deleted.

34 changes: 34 additions & 0 deletions src/app/chat/(desktop)/features/ChatHeader/HeaderAction.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { ActionIcon } from '@lobehub/ui';
import { PanelRightClose, PanelRightOpen } from 'lucide-react';
import { memo } from 'react';
import { useTranslation } from 'react-i18next';

import { DESKTOP_HEADER_ICON_SIZE } from '@/const/layoutTokens';
import { useGlobalStore } from '@/store/global';

import SettingButton from '../../../features/ChatHeader/SettingButton';
import ShareButton from '../../../features/ChatHeader/ShareButton';

const HeaderAction = memo(() => {
const { t } = useTranslation('chat');

const [showAgentSettings, toggleConfig] = useGlobalStore((s) => [
s.preference.showChatSideBar,
s.toggleChatSideBar,
]);

return (
<>
<ShareButton />
<ActionIcon
icon={showAgentSettings ? PanelRightClose : PanelRightOpen}
onClick={() => toggleConfig()}
size={DESKTOP_HEADER_ICON_SIZE}
title={t('roleAndArchive')}
/>
<SettingButton />
</>
);
});

export default HeaderAction;
58 changes: 58 additions & 0 deletions src/app/chat/(desktop)/features/ChatHeader/Main.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { Avatar, ChatHeaderTitle } from '@lobehub/ui';
import { Skeleton } from 'antd';
import { useRouter } from 'next/navigation';
import { memo } from 'react';
import { useTranslation } from 'react-i18next';
import { Flexbox } from 'react-layout-kit';

import { useSessionStore } from '@/store/session';
import { agentSelectors, sessionSelectors } from '@/store/session/selectors';
import { pathString } from '@/utils/url';

import Tags from './Tags';

const Main = memo(() => {
const { t } = useTranslation('chat');

const router = useRouter();

const [init, isInbox, title, description, avatar, backgroundColor] = useSessionStore((s) => [
sessionSelectors.isSomeSessionActive(s),
sessionSelectors.isInboxSession(s),
agentSelectors.currentAgentTitle(s),
agentSelectors.currentAgentDescription(s),
agentSelectors.currentAgentAvatar(s),
agentSelectors.currentAgentBackgroundColor(s),
]);

const displayTitle = isInbox ? t('inbox.title') : title;
const displayDesc = isInbox ? t('inbox.desc') : description;

return !init ? (
<Flexbox horizontal>
<Skeleton
active
avatar={{ shape: 'circle', size: 'default' }}
paragraph={false}
title={{ style: { margin: 0, marginTop: 8 }, width: 200 }}
/>
</Flexbox>
) : (
<Flexbox align={'flex-start'} gap={12} horizontal>
<Avatar
avatar={avatar}
background={backgroundColor}
onClick={() =>
isInbox
? router.push('/settings/agent')
: router.push(pathString('/chat/settings', { search: location.search }))
}
size={40}
title={title}
/>
<ChatHeaderTitle desc={displayDesc} tag={<Tags />} title={displayTitle} />
</Flexbox>
);
});

export default Main;
30 changes: 30 additions & 0 deletions src/app/chat/(desktop)/features/ChatHeader/Tags.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { memo } from 'react';

import ModelTag from '@/components/ModelTag';
import ModelSwitchPanel from '@/features/ModelSwitchPanel';
import { useGlobalStore } from '@/store/global';
import { modelProviderSelectors } from '@/store/global/selectors';
import { useSessionStore } from '@/store/session';
import { agentSelectors } from '@/store/session/selectors';

import PluginTag from '../../../features/PluginTag';

const TitleTags = memo(() => {
const [model, plugins] = useSessionStore((s) => [
agentSelectors.currentAgentModel(s),
agentSelectors.currentAgentPlugins(s),
]);

const showPlugin = useGlobalStore(modelProviderSelectors.modelEnabledFunctionCall(model));

return (
<>
<ModelSwitchPanel>
<ModelTag model={model} />
</ModelSwitchPanel>
{showPlugin && plugins?.length > 0 && <PluginTag plugins={plugins} />}
</>
);
});

export default TitleTags;
9 changes: 9 additions & 0 deletions src/app/chat/(desktop)/features/ChatHeader/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { ChatHeader } from '@lobehub/ui';
import { memo } from 'react';

import HeaderAction from './HeaderAction';
import Main from './Main';

const Header = memo(() => <ChatHeader left={<Main />} right={<HeaderAction />} />);

export default Header;
2 changes: 1 addition & 1 deletion src/app/chat/features/ChatHeader/ShareButton/Preview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import ChatList from '@/features/Conversation/components/ChatList';
import { useSessionStore } from '@/store/session';
import { agentSelectors, sessionSelectors } from '@/store/session/selectors';

import PluginTag from '../../ChatHeader/PluginTag';
import PluginTag from '../../PluginTag';
import { useStyles } from './style';
import { FieldType } from './type';

Expand Down
File renamed without changes.
75 changes: 4 additions & 71 deletions src/features/ChatInput/ActionBar/ModelSwitch.tsx
Original file line number Diff line number Diff line change
@@ -1,84 +1,17 @@
import { ActionIcon } from '@bentwnghk/ui';
import { Dropdown } from 'antd';
import { createStyles } from 'antd-style';
import isEqual from 'fast-deep-equal';
import { BrainCog } from 'lucide-react';
import { memo, useMemo } from 'react';
import { memo } from 'react';
import { useTranslation } from 'react-i18next';

import { ModelItemRender, ProviderItemRender } from '@/components/ModelSelect';
import { useGlobalStore } from '@/store/global';
import { modelProviderSelectors } from '@/store/global/selectors';
import { useSessionStore } from '@/store/session';
import { agentSelectors } from '@/store/session/selectors';
import { ModelProviderCard } from '@/types/llm';

const useStyles = createStyles(({ css, prefixCls }) => ({
menu: css`
.${prefixCls}-dropdown-menu-item {
display: flex;
gap: 8px;
}
.${prefixCls}-dropdown-menu {
&-item-group-title {
padding-inline: 8px;
}
&-item-group-list {
margin: 0 !important;
}
}
`,
}));
import ModelSwitchPanel from '@/features/ModelSwitchPanel';

const ModelSwitch = memo(() => {
const { t } = useTranslation('chat');
const { styles } = useStyles();
const model = useSessionStore(agentSelectors.currentAgentModel);
const updateAgentConfig = useSessionStore((s) => s.updateAgentConfig);

const select = useGlobalStore(modelProviderSelectors.modelSelectList, isEqual);
const enabledList = select.filter((s) => s.enabled);

const items = useMemo(() => {
const getModelItems = (provider: ModelProviderCard) =>
provider.chatModels
.filter((c) => !c.hidden)
.map((model) => ({
key: model.id,
label: <ModelItemRender {...model} />,
onClick: () => {
updateAgentConfig({ model: model.id, provider: provider.id });
},
}));

if (enabledList.length === 1) {
const provider = enabledList[0];
return getModelItems(provider);
}

return enabledList.map((provider) => ({
children: getModelItems(provider),
key: provider.id,
label: <ProviderItemRender provider={provider.id} />,
type: 'group',
}));
}, [enabledList]);
return (
<Dropdown
menu={{
activeKey: model,
className: styles.menu,
items,
style: {
maxHeight: 500,
overflowY: 'scroll',
},
}}
trigger={['click']}
>
<ModelSwitchPanel>
<ActionIcon icon={BrainCog} placement={'bottom'} title={t('ModelSwitch.title')} />
</Dropdown>
</ModelSwitchPanel>
);
});

Expand Down
Loading

0 comments on commit 749ef2f

Please sign in to comment.