mirror of
https://github.com/lobehub/lobe-chat.git
synced 2026-06-14 03:30:19 +00:00
✨ feat: add open new topic when open a topic
This commit is contained in:
@@ -53,7 +53,8 @@
|
||||
"confirmRemoveAll": "All topics will be deleted and cannot be recovered. Please proceed with caution.",
|
||||
"confirmRemoveUnstarred": "All unstarred topics will be deleted and cannot be recovered. Please proceed with caution.",
|
||||
"removeAll": "Remove All Topics",
|
||||
"removeUnstarred": "Remove Unstarred Topics"
|
||||
"removeUnstarred": "Remove Unstarred Topics",
|
||||
"openNewTopic": "Open a new topic"
|
||||
},
|
||||
"translate": {
|
||||
"clear": "Clear Translation"
|
||||
|
||||
@@ -53,7 +53,8 @@
|
||||
"confirmRemoveAll": "すべてのトピックを削除します。削除後は元に戻すことはできませんので、注意して操作してください。",
|
||||
"confirmRemoveUnstarred": "スターをつけていないトピックを削除します。削除後は元に戻すことはできませんので、注意して操作してください。",
|
||||
"removeAll": "すべてのトピックを削除",
|
||||
"removeUnstarred": "スターをつけていないトピックを削除"
|
||||
"removeUnstarred": "スターをつけていないトピックを削除",
|
||||
"openNewTopic": "新しいトピックを開く"
|
||||
},
|
||||
"translate": {
|
||||
"clear": "翻訳をクリア"
|
||||
|
||||
@@ -53,7 +53,8 @@
|
||||
"confirmRemoveAll": "모든 주제를 삭제하려고 합니다. 삭제 후에는 복구할 수 없으므로 신중하게 작업하십시오.",
|
||||
"confirmRemoveUnstarred": "스타를 지정하지 않은 주제를 삭제하려고 합니다. 삭제 후에는 복구할 수 없으므로 신중하게 작업하십시오.",
|
||||
"removeAll": "모든 주제 삭제",
|
||||
"removeUnstarred": "스타를 지정하지 않은 주제 삭제"
|
||||
"removeUnstarred": "스타를 지정하지 않은 주제 삭제",
|
||||
"openNewTopic": "새로운 주제 열기"
|
||||
},
|
||||
"translate": {
|
||||
"clear": "번역 지우기"
|
||||
|
||||
@@ -53,7 +53,8 @@
|
||||
"confirmRemoveAll": "Вы собираетесь удалить все темы. После удаления их будет невозможно восстановить. Пожалуйста, будьте осторожны.",
|
||||
"confirmRemoveUnstarred": "Вы собираетесь удалить неотмеченные темы. После удаления их будет невозможно восстановить. Пожалуйста, будьте осторожны.",
|
||||
"removeAll": "Удалить все темы",
|
||||
"removeUnstarred": "Удалить неотмеченные темы"
|
||||
"removeUnstarred": "Удалить неотмеченные темы",
|
||||
"openNewTopic": "Открыть новую тему"
|
||||
},
|
||||
"translate": {
|
||||
"clear": "Очистить перевод"
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
"confirmRemoveTopic": "即将删除该话题,删除后将不可恢复,请谨慎操作。",
|
||||
"confirmRemoveUnstarred": "即将删除未收藏话题,删除后将不可恢复,请谨慎操作。",
|
||||
"defaultTitle": "默认话题",
|
||||
"openNewTopic": "开启新话题",
|
||||
"removeAll": "删除全部话题",
|
||||
"removeUnstarred": "删除未收藏话题",
|
||||
"saveCurrentMessages": "将当前会话保存为话题",
|
||||
|
||||
@@ -53,7 +53,8 @@
|
||||
"confirmRemoveAll": "即將刪除全部話題,刪除後將無法恢復,請謹慎操作。",
|
||||
"confirmRemoveUnstarred": "即將刪除未收藏話題,刪除後將無法恢復,請謹慎操作。",
|
||||
"removeAll": "刪除全部話題",
|
||||
"removeUnstarred": "刪除未收藏話題"
|
||||
"removeUnstarred": "刪除未收藏話題",
|
||||
"openNewTopic": "開啟新話題"
|
||||
},
|
||||
"translate": {
|
||||
"clear": "刪除翻譯"
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@ import { memo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Flexbox } from 'react-layout-kit';
|
||||
|
||||
import SaveTopic from './SaveTopic';
|
||||
import SaveTopic from '../../../features/ChatInputContent/Topic';
|
||||
|
||||
const Footer = memo(() => {
|
||||
const theme = useTheme();
|
||||
+3
-2
@@ -4,7 +4,8 @@ import { memo, useState } from 'react';
|
||||
import { CHAT_TEXTAREA_HEIGHT, HEADER_HEIGHT } from '@/const/layoutTokens';
|
||||
import { useGlobalStore } from '@/store/global';
|
||||
|
||||
import ChatInputContent from '../../features/ChatInputContent';
|
||||
import ChatInputContent from '../../../features/ChatInputContent';
|
||||
import Footer from './Footer';
|
||||
|
||||
const ChatInputDesktopLayout = memo(() => {
|
||||
const [expand, setExpand] = useState<boolean>(false);
|
||||
@@ -29,7 +30,7 @@ const ChatInputDesktopLayout = memo(() => {
|
||||
size={{ height: inputHeight, width: '100%' }}
|
||||
style={{ zIndex: 10 }}
|
||||
>
|
||||
<ChatInputContent expand={expand} onExpandChange={setExpand} />
|
||||
<ChatInputContent expand={expand} footer={<Footer />} onExpandChange={setExpand} />
|
||||
</DraggablePanel>
|
||||
);
|
||||
});
|
||||
@@ -10,7 +10,7 @@ import HotKeys from '@/components/HotKeys';
|
||||
import { CLEAN_MESSAGE_KEY, PREFIX_KEY } from '@/const/hotkeys';
|
||||
import { useSessionStore } from '@/store/session';
|
||||
|
||||
import SaveTopic from '../Footer/SaveTopic';
|
||||
import SaveTopic from '../Topic';
|
||||
|
||||
const ActionsRight = memo(() => {
|
||||
const { t } = useTranslation('setting');
|
||||
|
||||
+13
-11
@@ -1,7 +1,7 @@
|
||||
import { ActionIcon, Icon, Tooltip } from '@lobehub/ui';
|
||||
import { Button } from 'antd';
|
||||
import { useResponsive } from 'antd-style';
|
||||
import { LucideGalleryVerticalEnd } from 'lucide-react';
|
||||
import { LucideGalleryVerticalEnd, LucideMessageSquarePlus } from 'lucide-react';
|
||||
import { memo } from 'react';
|
||||
import { useHotkeys } from 'react-hotkeys-hook';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@@ -12,23 +12,25 @@ import { useSessionStore } from '@/store/session';
|
||||
|
||||
const SaveTopic = memo(() => {
|
||||
const { t } = useTranslation('chat');
|
||||
const [hasTopic, saveToTopic] = useSessionStore((s) => [!!s.activeTopicId, s.saveToTopic]);
|
||||
const [hasTopic, openNewTopicOrSaveTopic] = useSessionStore((s) => [
|
||||
!!s.activeTopicId,
|
||||
s.openNewTopicOrSaveTopic,
|
||||
]);
|
||||
const { mobile } = useResponsive();
|
||||
|
||||
const hotkeys = [PREFIX_KEY, SAVE_TOPIC_KEY].join('+');
|
||||
const icon = hasTopic ? LucideMessageSquarePlus : LucideGalleryVerticalEnd;
|
||||
const Render = mobile ? ActionIcon : Button;
|
||||
const iconRender: any = mobile ? icon : <Icon icon={icon} />;
|
||||
const desc = t(hasTopic ? 'topic.openNewTopic' : 'topic.saveCurrentMessages');
|
||||
|
||||
useHotkeys(hotkeys, saveToTopic, {
|
||||
const hotkeys = [PREFIX_KEY, SAVE_TOPIC_KEY].join('+');
|
||||
useHotkeys(hotkeys, openNewTopicOrSaveTopic, {
|
||||
preventDefault: true,
|
||||
});
|
||||
|
||||
if (hasTopic) return undefined;
|
||||
|
||||
const Render = mobile ? ActionIcon : Button;
|
||||
const icon: any = mobile ? LucideGalleryVerticalEnd : <Icon icon={LucideGalleryVerticalEnd} />;
|
||||
|
||||
return (
|
||||
<Tooltip title={<HotKeys desc={t('topic.saveCurrentMessages')} keys={hotkeys} />}>
|
||||
<Render aria-label={t('topic.saveCurrentMessages')} icon={icon} onClick={saveToTopic} />
|
||||
<Tooltip title={<HotKeys desc={desc} keys={hotkeys} />}>
|
||||
<Render aria-label={desc} icon={iconRender} onClick={openNewTopicOrSaveTopic} />
|
||||
</Tooltip>
|
||||
);
|
||||
});
|
||||
@@ -1,7 +1,7 @@
|
||||
import { ChatInputArea } from '@lobehub/ui';
|
||||
import { useResponsive } from 'antd-style';
|
||||
import dynamic from 'next/dynamic';
|
||||
import { Suspense, memo, useState } from 'react';
|
||||
import { ReactNode, Suspense, memo, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { CHAT_TEXTAREA_HEIGHT } from '@/const/layoutTokens';
|
||||
@@ -10,18 +10,18 @@ import { agentSelectors } from '@/store/session/selectors';
|
||||
|
||||
import ActionLeft from './ActionBar/ActionLeft';
|
||||
import ActionsRight from './ActionBar/ActionRight';
|
||||
import Footer from './Footer';
|
||||
|
||||
const Token = dynamic(() => import('./ActionBar/Token'), { ssr: false });
|
||||
|
||||
interface ChatContentProps {
|
||||
expand?: boolean;
|
||||
footer?: ReactNode;
|
||||
mobile?: boolean;
|
||||
onExpandChange?: (expand: boolean) => void;
|
||||
}
|
||||
|
||||
const ChatInputContent = memo<ChatContentProps>(
|
||||
({ expand, onExpandChange, mobile: defaultMobile }) => {
|
||||
({ expand, onExpandChange, mobile: defaultMobile, footer }) => {
|
||||
const { t } = useTranslation('common');
|
||||
|
||||
const [message, setMessage] = useState('');
|
||||
@@ -50,7 +50,7 @@ const ChatInputContent = memo<ChatContentProps>(
|
||||
}
|
||||
actionsRight={<ActionsRight />}
|
||||
expand={expand}
|
||||
footer={<Footer />}
|
||||
footer={footer}
|
||||
loading={isLoading}
|
||||
minHeight={mobile ? 0 : CHAT_TEXTAREA_HEIGHT}
|
||||
onExpandChange={onExpandChange}
|
||||
|
||||
@@ -50,6 +50,7 @@ export default {
|
||||
confirmRemoveTopic: '即将删除该话题,删除后将不可恢复,请谨慎操作。',
|
||||
confirmRemoveUnstarred: '即将删除未收藏话题,删除后将不可恢复,请谨慎操作。',
|
||||
defaultTitle: '默认话题',
|
||||
openNewTopic: '开启新话题',
|
||||
removeAll: '删除全部话题',
|
||||
removeUnstarred: '删除未收藏话题',
|
||||
saveCurrentMessages: '将当前会话保存为话题',
|
||||
|
||||
@@ -18,6 +18,7 @@ export interface ChatTopicAction {
|
||||
* @param payload - 要分发的主题
|
||||
*/
|
||||
dispatchTopic: (payload: ChatTopicDispatch) => void;
|
||||
openNewTopicOrSaveTopic: () => void;
|
||||
/**
|
||||
* 移出所有话题
|
||||
*/
|
||||
@@ -62,6 +63,15 @@ export const chatTopic: StateCreator<
|
||||
|
||||
get().dispatchSession({ id: activeId, topics, type: 'updateSessionTopic' });
|
||||
},
|
||||
openNewTopicOrSaveTopic: () => {
|
||||
const { toggleTopic, saveToTopic, activeTopicId } = get();
|
||||
const hasTopic = !!activeTopicId;
|
||||
|
||||
if (hasTopic) toggleTopic();
|
||||
else {
|
||||
saveToTopic();
|
||||
}
|
||||
},
|
||||
removeAllTopic: () => {
|
||||
const { removeTopic, toggleTopic } = get();
|
||||
const topics = topicSelectors.currentTopics(get());
|
||||
@@ -79,10 +89,7 @@ export const chatTopic: StateCreator<
|
||||
// 移除关联的 message
|
||||
const messages = topicSelectors.getTopicMessages(id)(get());
|
||||
for (const m of messages) {
|
||||
dispatchMessage({
|
||||
id: m.id,
|
||||
type: 'deleteMessage',
|
||||
});
|
||||
dispatchMessage({ id: m.id, type: 'deleteMessage' });
|
||||
}
|
||||
|
||||
// 最后移除 topic
|
||||
@@ -107,9 +114,12 @@ export const chatTopic: StateCreator<
|
||||
if (!session) return;
|
||||
|
||||
const { dispatchTopic, dispatchMessage, updateTopicLoading } = get();
|
||||
// 获取当前的 messages
|
||||
// get current messages
|
||||
const messages = chatSelectors.currentChats(get());
|
||||
|
||||
// if there is no message, stop saving
|
||||
if (messages.length === 0) return;
|
||||
|
||||
const topicId = nanoid();
|
||||
|
||||
const defaultTitle = '默认话题';
|
||||
@@ -154,6 +164,7 @@ export const chatTopic: StateCreator<
|
||||
toggleTopic: (id) => {
|
||||
set({ activeTopicId: id }, false, t('toggleTopic'));
|
||||
},
|
||||
|
||||
updateTopicLoading: (id) => {
|
||||
set({ topicLoadingId: id }, false, t('updateTopicLoading'));
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user