This commit is contained in:
heheer 2025-12-23 11:13:32 +08:00
parent 884b38e9e1
commit d8d17031ae
No known key found for this signature in database
GPG Key ID: 37DCB43201661540
18 changed files with 194 additions and 216 deletions

View File

@ -18,7 +18,7 @@ import MyIcon from '@fastgpt/web/components/common/Icon';
import { useTranslation } from 'react-i18next';
import { useForm } from 'react-hook-form';
import { useContextSelector } from 'use-context-selector';
import { ChatSettingContext } from '@/web/core/chat/context/chatSettingContext';
import { ChatPageContext } from '@/web/core/chat/context/chatPageContext';
import { useMemo } from 'react';
import Avatar from '@fastgpt/web/components/common/Avatar';
import { ChatSettingTabOptionEnum, ChatSidebarPaneEnum } from '@/pageComponents/chat/constants';
@ -41,11 +41,11 @@ const ChatFavouriteApp = () => {
const onOpenSlider = useContextSelector(ChatContext, (v) => v.onOpenSlider);
const handlePaneChange = useContextSelector(ChatSettingContext, (v) => v.handlePaneChange);
const wideLogoUrl = useContextSelector(ChatSettingContext, (v) => v.chatSettings?.wideLogoUrl);
const homeTabTitle = useContextSelector(ChatSettingContext, (v) => v.chatSettings?.homeTabTitle);
const handlePaneChange = useContextSelector(ChatPageContext, (v) => v.handlePaneChange);
const wideLogoUrl = useContextSelector(ChatPageContext, (v) => v.chatSettings?.wideLogoUrl);
const homeTabTitle = useContextSelector(ChatPageContext, (v) => v.chatSettings?.homeTabTitle);
const tags = useContextSelector(ChatSettingContext, (v) => v.chatSettings?.favouriteTags || []);
const tags = useContextSelector(ChatPageContext, (v) => v.chatSettings?.favouriteTags || []);
const tagCache = useMemo(() => {
return tags.reduce(
(acc, tag) => {

View File

@ -23,7 +23,7 @@ import SelectOneResource from '@/components/common/folder/SelectOneResource';
import { ChatItemContext } from '@/web/core/chat/context/chatItemContext';
import VariablePopover from '@/components/core/chat/ChatContainer/components/VariablePopover';
import { useCopyData } from '@fastgpt/web/hooks/useCopyData';
import { ChatSettingContext } from '@/web/core/chat/context/chatSettingContext';
import { ChatPageContext } from '@/web/core/chat/context/chatPageContext';
import {
ChatSidebarPaneEnum,
DEFAULT_LOGO_BANNER_COLLAPSED_URL
@ -33,12 +33,10 @@ import { usePathname } from 'next/navigation';
import type { ChatSettingType } from '@fastgpt/global/core/chat/setting/type';
import { ChatTypeEnum } from '@/components/core/chat/ChatContainer/ChatBox/constants';
import type { GetRecentlyUsedAppsResponseType } from '@fastgpt/service/core/app/record/type';
const ChatHeader = ({
history,
showHistory,
apps,
totalRecordsCount,
pane,
@ -50,18 +48,15 @@ const ChatHeader = ({
history: ChatItemType[];
showHistory?: boolean;
apps?: GetRecentlyUsedAppsResponseType;
totalRecordsCount: number;
reserveSpace?: boolean;
}) => {
const { t } = useTranslation();
const { isPc } = useSystem();
const pathname = usePathname();
const { source } = useChatStore();
const chatData = useContextSelector(ChatItemContext, (v) => v.chatBoxData);
const isVariableVisible = useContextSelector(ChatItemContext, (v) => v.isVariableVisible);
const isPlugin = chatData.app.type === AppTypeEnum.workflowTool;
const isShare = source === 'share';
const chatType = isShare ? ChatTypeEnum.share : ChatTypeEnum.chat;
@ -87,7 +82,6 @@ const ChatHeader = ({
</>
) : (
<MobileHeader
apps={apps}
appId={chatData.appId}
name={
pane === ChatSidebarPaneEnum.HOME && !isShare
@ -113,15 +107,7 @@ const ChatHeader = ({
);
};
const MobileDrawer = ({
onCloseDrawer,
appId,
apps
}: {
onCloseDrawer: () => void;
appId: string;
apps?: GetRecentlyUsedAppsResponseType;
}) => {
const MobileDrawer = ({ onCloseDrawer, appId }: { onCloseDrawer: () => void; appId: string }) => {
enum TabEnum {
recently = 'recently',
app = 'app'
@ -129,6 +115,7 @@ const MobileDrawer = ({
const { t } = useTranslation();
const { setChatId } = useChatStore();
const myApps = useContextSelector(ChatPageContext, (v) => v.myApps);
const [currentTab, setCurrentTab] = useState<TabEnum>(TabEnum.recently);
@ -143,7 +130,7 @@ const MobileDrawer = ({
);
}, []);
const handlePaneChange = useContextSelector(ChatSettingContext, (v) => v.handlePaneChange);
const handlePaneChange = useContextSelector(ChatPageContext, (v) => v.handlePaneChange);
const onclickApp = (id: string) => {
handlePaneChange(ChatSidebarPaneEnum.RECENTLY_USED_APPS, id);
@ -201,8 +188,8 @@ const MobileDrawer = ({
{/* history */}
{currentTab === TabEnum.recently && (
<Box px={3} overflow={'auto'} h={'100%'}>
{Array.isArray(apps) &&
apps.map((item) => (
{Array.isArray(myApps) &&
myApps.map((item) => (
<Flex justify={'center'} key={item._id}>
<Flex
py={2.5}
@ -247,13 +234,11 @@ const MobileHeader = ({
showHistory,
name,
avatar,
appId,
apps
appId
}: {
showHistory?: boolean;
avatar: string;
name: string;
apps?: GetRecentlyUsedAppsResponseType;
appId: string;
}) => {
const router = useRouter();
@ -290,9 +275,7 @@ const MobileHeader = ({
</Flex>
</Flex>
{isOpenDrawer && !isShareChat && (
<MobileDrawer apps={apps} appId={appId} onCloseDrawer={onCloseDrawer} />
)}
{isOpenDrawer && !isShareChat && <MobileDrawer appId={appId} onCloseDrawer={onCloseDrawer} />}
</>
);
};

View File

@ -1,5 +1,5 @@
import LogChart from '@/pageComponents/app/detail/Logs/LogChart';
import { ChatSettingContext } from '@/web/core/chat/context/chatSettingContext';
import { ChatPageContext } from '@/web/core/chat/context/chatPageContext';
import { Flex } from '@chakra-ui/react';
import { ChatSourceEnum } from '@fastgpt/global/core/chat/constants';
import type { DateRangeType } from '@fastgpt/web/components/common/DateRangePicker';
@ -13,7 +13,7 @@ type Props = {
};
const LogDetails = ({ Header }: Props) => {
const appId = useContextSelector(ChatSettingContext, (v) => v.chatSettings?.appId || '');
const appId = useContextSelector(ChatPageContext, (v) => v.chatSettings?.appId || '');
const [dateRange, setDateRange] = useState<DateRangeType>({
from: new Date(addDays(new Date(), -6).setHours(0, 0, 0, 0)),

View File

@ -1,4 +1,4 @@
import { ChatSettingContext } from '@/web/core/chat/context/chatSettingContext';
import { ChatPageContext } from '@/web/core/chat/context/chatPageContext';
import { AddIcon } from '@chakra-ui/icons';
import {
Box,
@ -377,10 +377,10 @@ type Props = {
const TagManageModal = ({ onClose, onRefresh }: Props) => {
const { t } = useTranslation();
const refreshChatSetting = useContextSelector(ChatSettingContext, (v) => v.refreshChatSetting);
const refreshChatSetting = useContextSelector(ChatPageContext, (v) => v.refreshChatSetting);
// get tags from db
const tags = useContextSelector(ChatSettingContext, (v) => v.chatSettings?.favouriteTags || []);
const tags = useContextSelector(ChatPageContext, (v) => v.chatSettings?.favouriteTags || []);
// local editable tags list
const [localTags, setLocalTags] = useState<ChatFavouriteTagType[]>(tags);

View File

@ -1,20 +1,12 @@
import { ChatSettingContext } from '@/web/core/chat/context/chatSettingContext';
import { ChatPageContext } from '@/web/core/chat/context/chatPageContext';
import {
Button,
ButtonGroup,
Flex,
HStack,
IconButton,
Input,
InputGroup,
InputLeftElement,
Table,
TableContainer,
Tbody,
Td,
Th,
Thead,
Tr,
useDisclosure
} from '@chakra-ui/react';
import MySelect from '@fastgpt/web/components/common/MySelect';
@ -68,7 +60,7 @@ const FavouriteAppSetting = ({ Header }: Props) => {
const searchAppTagValue = watchSearchValue('tag');
// apps' tags options
const tagOptions = useContextSelector(ChatSettingContext, (v) => {
const tagOptions = useContextSelector(ChatPageContext, (v) => {
const tags = v.chatSettings?.favouriteTags || [];
return [
{ label: t('chat:setting.favourite.category_all'), value: '' },
@ -76,7 +68,7 @@ const FavouriteAppSetting = ({ Header }: Props) => {
];
});
// app's tags cache map
const tagMap = useContextSelector(ChatSettingContext, (v) =>
const tagMap = useContextSelector(ChatPageContext, (v) =>
(v.chatSettings?.favouriteTags || []).reduce<Record<string, ChatFavouriteTagType>>(
(acc, tag) => {
acc[tag.id] = { ...tag };

View File

@ -23,7 +23,7 @@ import Avatar from '@fastgpt/web/components/common/Avatar';
import type { NodeInputKeyEnum } from '@fastgpt/global/core/workflow/constants';
import { useMount } from 'ahooks';
import { useContextSelector } from 'use-context-selector';
import { ChatSettingContext } from '@/web/core/chat/context/chatSettingContext';
import { ChatPageContext } from '@/web/core/chat/context/chatPageContext';
import {
DEFAULT_LOGO_BANNER_COLLAPSED_URL,
DEFAULT_LOGO_BANNER_URL
@ -46,8 +46,8 @@ const HomepageSetting = ({ Header, onDiagramShow }: Props) => {
const { t } = useTranslation();
const { feConfigs } = useSystemStore();
const chatSettings = useContextSelector(ChatSettingContext, (v) => v.chatSettings);
const refreshChatSetting = useContextSelector(ChatSettingContext, (v) => v.refreshChatSetting);
const chatSettings = useContextSelector(ChatPageContext, (v) => v.chatSettings);
const refreshChatSetting = useContextSelector(ChatPageContext, (v) => v.refreshChatSetting);
const chatSettings2Form = useCallback(
(data?: ChatSettingType) => {

View File

@ -1,5 +1,5 @@
import LogTable from '@/pageComponents/app/detail/Logs/LogTable';
import { ChatSettingContext } from '@/web/core/chat/context/chatSettingContext';
import { ChatPageContext } from '@/web/core/chat/context/chatPageContext';
import { Flex } from '@chakra-ui/react';
import { ChatSourceEnum } from '@fastgpt/global/core/chat/constants';
import type { DateRangeType } from '@fastgpt/web/components/common/DateRangePicker';
@ -16,7 +16,7 @@ type Props = {
const chatSourceValues = Object.values(ChatSourceEnum);
const LogDetails = ({ Header }: Props) => {
const appId = useContextSelector(ChatSettingContext, (v) => v.chatSettings?.appId || '');
const appId = useContextSelector(ChatPageContext, (v) => v.chatSettings?.appId || '');
const [dateRange, setDateRange] = useState<DateRangeType>({
from: new Date(addDays(new Date(), -6).setHours(0, 0, 0, 0)),

View File

@ -9,7 +9,7 @@ import { useContextSelector } from 'use-context-selector';
import MyIcon from '@fastgpt/web/components/common/Icon';
import { ChatContext } from '@/web/core/chat/context/chatContext';
import NextHead from '@/components/common/NextHead';
import { ChatSettingContext } from '@/web/core/chat/context/chatSettingContext';
import { ChatPageContext } from '@/web/core/chat/context/chatPageContext';
import ChatSliderMobileDrawer from '@/pageComponents/chat/slider/ChatSliderMobileDrawer';
import { useTranslation } from 'react-i18next';
import { useMount } from 'ahooks';
@ -43,8 +43,8 @@ const ChatSetting = () => {
);
const onOpenSlider = useContextSelector(ChatContext, (v) => v.onOpenSlider);
const chatSettings = useContextSelector(ChatSettingContext, (v) => v.chatSettings);
const handlePaneChange = useContextSelector(ChatSettingContext, (v) => v.handlePaneChange);
const chatSettings = useContextSelector(ChatPageContext, (v) => v.chatSettings);
const handlePaneChange = useContextSelector(ChatPageContext, (v) => v.handlePaneChange);
const handleTabChange = useCallback(
(tab: ChatSettingTabOptionEnum) => {

View File

@ -15,7 +15,7 @@ import AppTypeTag from '@/pageComponents/chat/ChatTeamApp/TypeTag';
import { formatTimeToChatTime } from '@fastgpt/global/common/string/time';
import { useSystem } from '@fastgpt/web/hooks/useSystem';
import UserBox from '@fastgpt/web/components/common/UserBox';
import { ChatSettingContext } from '@/web/core/chat/context/chatSettingContext';
import { ChatPageContext } from '@/web/core/chat/context/chatPageContext';
import { ChatSidebarPaneEnum } from '@/pageComponents/chat/constants';
const List = ({ appType }: { appType: AppTypeEnum | 'all' }) => {
@ -33,7 +33,7 @@ const List = ({ appType }: { appType: AppTypeEnum | 'all' }) => {
].includes(app.type)
)
);
const handlePaneChange = useContextSelector(ChatSettingContext, (v) => v.handlePaneChange);
const handlePaneChange = useContextSelector(ChatPageContext, (v) => v.handlePaneChange);
return (
<>

View File

@ -13,7 +13,7 @@ import SearchInput from '@fastgpt/web/components/common/Input/SearchInput';
import MyIcon from '@fastgpt/web/components/common/Icon';
import { ChatContext } from '@/web/core/chat/context/chatContext';
import NextHead from '@/components/common/NextHead';
import { ChatSettingContext } from '@/web/core/chat/context/chatSettingContext';
import { ChatPageContext } from '@/web/core/chat/context/chatPageContext';
import ChatSliderMobileDrawer from '@/pageComponents/chat/slider/ChatSliderMobileDrawer';
import { useSystemStore } from '@/web/common/system/useSystemStore';
import { getWebReqUrl } from '@fastgpt/web/common/system/utils';
@ -29,7 +29,7 @@ const MyApps = () => {
(v) => v
);
const chatSettings = useContextSelector(ChatSettingContext, (v) => v.chatSettings);
const chatSettings = useContextSelector(ChatPageContext, (v) => v.chatSettings);
const onOpenSlider = useContextSelector(ChatContext, (v) => v.onOpenSlider);

View File

@ -7,7 +7,6 @@ import SideBar from '@/components/SideBar';
import { ChatContext } from '@/web/core/chat/context/chatContext';
import { useContextSelector } from 'use-context-selector';
import { ChatItemContext } from '@/web/core/chat/context/chatItemContext';
import { type AppListItemType } from '@fastgpt/global/core/app/type';
import { ChatTypeEnum } from '@/components/core/chat/ChatContainer/ChatBox/constants';
import { useCallback } from 'react';
import type { StartChatFnProps } from '@/components/core/chat/ChatContainer/type';
@ -20,23 +19,17 @@ import { useRequest2 } from '@fastgpt/web/hooks/useRequest';
import { getInitChatInfo } from '@/web/core/chat/api';
import { useUserStore } from '@/web/support/user/useUserStore';
import NextHead from '@/components/common/NextHead';
import { ChatSettingContext } from '@/web/core/chat/context/chatSettingContext';
import { ChatPageContext } from '@/web/core/chat/context/chatPageContext';
import { ChatSidebarPaneEnum } from '../constants';
import ChatHistorySidebar from '@/pageComponents/chat/slider/ChatSliderSidebar';
import ChatSliderMobileDrawer from '@/pageComponents/chat/slider/ChatSliderMobileDrawer';
import dynamic from 'next/dynamic';
import { getNanoid } from '@fastgpt/global/common/string/tools';
import { ChatErrEnum } from '@fastgpt/global/common/error/code/chat';
import type { GetRecentlyUsedAppsResponseType } from '@fastgpt/service/core/app/record/type';
const CustomPluginRunBox = dynamic(() => import('@/pageComponents/chat/CustomPluginRunBox'));
type Props = {
myApps: GetRecentlyUsedAppsResponseType;
refreshRecentlyUsed?: () => void;
};
const AppChatWindow = ({ myApps, refreshRecentlyUsed }: Props) => {
const AppChatWindow = () => {
const { userInfo } = useUserStore();
const { chatId, appId, outLinkAuthData } = useChatStore();
@ -57,9 +50,10 @@ const AppChatWindow = ({ myApps, refreshRecentlyUsed }: Props) => {
const chatRecords = useContextSelector(ChatRecordContext, (v) => v.chatRecords);
const totalRecordsCount = useContextSelector(ChatRecordContext, (v) => v.totalRecordsCount);
const pane = useContextSelector(ChatSettingContext, (v) => v.pane);
const chatSettings = useContextSelector(ChatSettingContext, (v) => v.chatSettings);
const handlePaneChange = useContextSelector(ChatSettingContext, (v) => v.handlePaneChange);
const pane = useContextSelector(ChatPageContext, (v) => v.pane);
const chatSettings = useContextSelector(ChatPageContext, (v) => v.chatSettings);
const handlePaneChange = useContextSelector(ChatPageContext, (v) => v.handlePaneChange);
const refreshRecentlyUsed = useContextSelector(ChatPageContext, (v) => v.refreshRecentlyUsed);
const { loading } = useRequest2(
async () => {
@ -124,7 +118,7 @@ const AppChatWindow = ({ myApps, refreshRecentlyUsed }: Props) => {
title: newTitle
}));
refreshRecentlyUsed?.();
refreshRecentlyUsed();
return { responseText, isNewChat: forbidLoadChat.current };
},
@ -170,7 +164,6 @@ const AppChatWindow = ({ myApps, refreshRecentlyUsed }: Props) => {
pane={pane}
chatSettings={chatSettings}
showHistory
apps={myApps}
history={chatRecords}
totalRecordsCount={totalRecordsCount}
/>

View File

@ -36,7 +36,7 @@ import { getDefaultAppForm } from '@fastgpt/global/core/app/utils';
import { getToolPreviewNode } from '@/web/core/app/api/tool';
import type { FlowNodeTemplateType } from '@fastgpt/global/core/workflow/type/node';
import { getWebLLMModel } from '@/web/common/system/utils';
import { ChatSettingContext } from '@/web/core/chat/context/chatSettingContext';
import { ChatPageContext } from '@/web/core/chat/context/chatPageContext';
import type { AppFileSelectConfigType, AppWhisperConfigType } from '@fastgpt/global/core/app/type';
import ChatHeader from '@/pageComponents/chat/ChatHeader';
import { ChatRecordContext } from '@/web/core/chat/context/chatRecordContext';
@ -44,12 +44,6 @@ import { ChatSidebarPaneEnum } from '../constants';
import ChatHistorySidebar from '@/pageComponents/chat/slider/ChatSliderSidebar';
import ChatSliderMobileDrawer from '@/pageComponents/chat/slider/ChatSliderMobileDrawer';
import { getWebReqUrl } from '@fastgpt/web/common/system/utils';
import type { GetRecentlyUsedAppsResponseType } from '@fastgpt/service/core/app/record/type';
type Props = {
myApps: GetRecentlyUsedAppsResponseType;
refreshRecentlyUsed?: () => void;
};
const defaultFileSelectConfig: AppFileSelectConfigType = {
maxFiles: 20,
@ -66,7 +60,7 @@ const defaultWhisperConfig: AppWhisperConfigType = {
autoTTSResponse: false
};
const HomeChatWindow = ({ myApps, refreshRecentlyUsed }: Props) => {
const HomeChatWindow = () => {
const { t } = useTranslation();
const { isPc } = useSystem();
@ -84,10 +78,11 @@ const HomeChatWindow = ({ myApps, refreshRecentlyUsed }: Props) => {
const resetVariables = useContextSelector(ChatItemContext, (v) => v.resetVariables);
const isShowCite = useContextSelector(ChatItemContext, (v) => v.isShowCite);
const pane = useContextSelector(ChatSettingContext, (v) => v.pane);
const chatSettings = useContextSelector(ChatSettingContext, (v) => v.chatSettings);
const handlePaneChange = useContextSelector(ChatSettingContext, (v) => v.handlePaneChange);
const homeAppId = useContextSelector(ChatSettingContext, (v) => v.chatSettings?.appId || '');
const pane = useContextSelector(ChatPageContext, (v) => v.pane);
const chatSettings = useContextSelector(ChatPageContext, (v) => v.chatSettings);
const handlePaneChange = useContextSelector(ChatPageContext, (v) => v.handlePaneChange);
const homeAppId = useContextSelector(ChatPageContext, (v) => v.chatSettings?.appId || '');
const refreshRecentlyUsed = useContextSelector(ChatPageContext, (v) => v.refreshRecentlyUsed);
const chatRecords = useContextSelector(ChatRecordContext, (v) => v.chatRecords);
const totalRecordsCount = useContextSelector(ChatRecordContext, (v) => v.totalRecordsCount);
@ -230,7 +225,7 @@ const HomeChatWindow = ({ myApps, refreshRecentlyUsed }: Props) => {
title: newTitle
}));
refreshRecentlyUsed?.();
refreshRecentlyUsed();
return { responseText, isNewChat: forbidLoadChat.current };
}
@ -281,7 +276,7 @@ const HomeChatWindow = ({ myApps, refreshRecentlyUsed }: Props) => {
title: newTitle
}));
refreshRecentlyUsed?.();
refreshRecentlyUsed();
return { responseText, isNewChat: forbidLoadChat.current };
}
@ -451,7 +446,6 @@ const HomeChatWindow = ({ myApps, refreshRecentlyUsed }: Props) => {
pane={pane}
chatSettings={chatSettings}
showHistory
apps={myApps}
history={chatRecords}
totalRecordsCount={totalRecordsCount}
/>

View File

@ -1,5 +1,5 @@
import React from 'react';
import { ChatSettingContext } from '@/web/core/chat/context/chatSettingContext';
import { ChatPageContext } from '@/web/core/chat/context/chatPageContext';
import { ChatSidebarPaneEnum } from '@/pageComponents/chat/constants';
import { useContextSelector } from 'use-context-selector';
import { ChatContext } from '@/web/core/chat/context/chatContext';
@ -15,8 +15,8 @@ const ChatSliderFooter = () => {
const { feConfigs } = useSystemStore();
const onCloseSlider = useContextSelector(ChatContext, (v) => v.onCloseSlider);
const handlePaneChange = useContextSelector(ChatSettingContext, (v) => v.handlePaneChange);
const pane = useContextSelector(ChatSettingContext, (v) => v.pane);
const handlePaneChange = useContextSelector(ChatPageContext, (v) => v.handlePaneChange);
const pane = useContextSelector(ChatPageContext, (v) => v.pane);
const isAdmin = !!userInfo?.team.permission.hasManagePer;
const isSettingPane = pane === ChatSidebarPaneEnum.SETTING;

View File

@ -1,6 +1,6 @@
import { GridItem, Grid } from '@chakra-ui/react';
import React from 'react';
import { ChatSettingContext } from '@/web/core/chat/context/chatSettingContext';
import { ChatPageContext } from '@/web/core/chat/context/chatPageContext';
import { ChatSidebarPaneEnum } from '@/pageComponents/chat/constants';
import { useContextSelector } from 'use-context-selector';
import { ChatContext } from '@/web/core/chat/context/chatContext';
@ -24,9 +24,9 @@ const ChatSliderHeader = ({ title, banner }: Props) => {
const { isPc } = useSystem();
const { setChatId } = useChatStore();
const pane = useContextSelector(ChatSettingContext, (v) => v.pane);
const handlePaneChange = useContextSelector(ChatSettingContext, (v) => v.handlePaneChange);
const enableHome = useContextSelector(ChatSettingContext, (v) => v.chatSettings?.enableHome);
const pane = useContextSelector(ChatPageContext, (v) => v.pane);
const handlePaneChange = useContextSelector(ChatPageContext, (v) => v.handlePaneChange);
const enableHome = useContextSelector(ChatPageContext, (v) => v.chatSettings?.enableHome);
const appName = useContextSelector(ChatItemContext, (v) => v.chatBoxData?.app.name);
const appAvatar = useContextSelector(ChatItemContext, (v) => v.chatBoxData?.app.avatar);

View File

@ -17,13 +17,12 @@ import {
} from '@/pageComponents/chat/constants';
import { useSystemStore } from '@/web/common/system/useSystemStore';
import { useContextSelector } from 'use-context-selector';
import { ChatSettingContext } from '@/web/core/chat/context/chatSettingContext';
import { ChatPageContext } from '@/web/core/chat/context/chatPageContext';
import { usePathname } from 'next/navigation';
import type { GetRecentlyUsedAppsResponseType } from '@fastgpt/service/core/app/record/type';
type Props = {
activeAppId: string;
apps: GetRecentlyUsedAppsResponseType;
};
const MotionBox = motion(Box);
@ -149,13 +148,13 @@ const AnimatedText: React.FC<AnimatedTextProps> = ({ show, children, className,
);
const LogoSection = () => {
const isCollapsed = useContextSelector(ChatSettingContext, (v) => v.collapse === 1);
const logos = useContextSelector(ChatSettingContext, (v) => v.logos);
const isCollapsed = useContextSelector(ChatPageContext, (v) => v.collapse === 1);
const logos = useContextSelector(ChatPageContext, (v) => v.logos);
const isHomeActive = useContextSelector(
ChatSettingContext,
ChatPageContext,
(v) => v.pane === ChatSidebarPaneEnum.HOME
);
const onTriggerCollapse = useContextSelector(ChatSettingContext, (v) => v.onTriggerCollapse);
const onTriggerCollapse = useContextSelector(ChatPageContext, (v) => v.onTriggerCollapse);
const wideLogoSrc = logos.wideLogoUrl;
const squareLogoSrc = logos.squareLogoUrl;
@ -257,24 +256,24 @@ const NavigationSection = () => {
const { feConfigs } = useSystemStore();
const isEnableHome = useContextSelector(
ChatSettingContext,
ChatPageContext,
(v) => v.chatSettings?.enableHome ?? true
);
const isCollapsed = useContextSelector(ChatSettingContext, (v) => v.collapse === 1);
const onTriggerCollapse = useContextSelector(ChatSettingContext, (v) => v.onTriggerCollapse);
const isCollapsed = useContextSelector(ChatPageContext, (v) => v.collapse === 1);
const onTriggerCollapse = useContextSelector(ChatPageContext, (v) => v.onTriggerCollapse);
const isHomeActive = useContextSelector(
ChatSettingContext,
ChatPageContext,
(v) => v.pane === ChatSidebarPaneEnum.HOME
);
const isTeamAppsActive = useContextSelector(
ChatSettingContext,
ChatPageContext,
(v) => v.pane === ChatSidebarPaneEnum.TEAM_APPS
);
const isFavouriteAppsActive = useContextSelector(
ChatSettingContext,
ChatPageContext,
(v) => v.pane === ChatSidebarPaneEnum.FAVORITE_APPS
);
const handlePaneChange = useContextSelector(ChatSettingContext, (v) => v.handlePaneChange);
const handlePaneChange = useContextSelector(ChatPageContext, (v) => v.handlePaneChange);
return (
<Flex mt={4} flexDirection={'column'} gap={1} px={4}>
@ -366,12 +365,12 @@ const BottomSection = () => {
const isAdmin = !!userInfo?.team.permission.hasManagePer;
const isShare = pathname === '/chat/share';
const isCollapsed = useContextSelector(ChatSettingContext, (v) => v.collapse === 1);
const isCollapsed = useContextSelector(ChatPageContext, (v) => v.collapse === 1);
const isSettingActive = useContextSelector(
ChatSettingContext,
ChatPageContext,
(v) => v.pane === ChatSidebarPaneEnum.SETTING
);
const onSettingClick = useContextSelector(ChatSettingContext, (v) => v.handlePaneChange);
const onSettingClick = useContextSelector(ChatPageContext, (v) => v.handlePaneChange);
return (
<MotionBox mt={'auto'} px={3} py={4} layout={false}>
@ -486,13 +485,14 @@ const BottomSection = () => {
);
};
const ChatSlider = ({ apps, activeAppId }: Props) => {
const ChatSlider = ({ activeAppId }: Props) => {
const { t } = useTranslation();
const isCollapsed = useContextSelector(ChatSettingContext, (v) => v.collapse === 1);
const pane = useContextSelector(ChatSettingContext, (v) => v.pane);
const isCollapsed = useContextSelector(ChatPageContext, (v) => v.collapse === 1);
const pane = useContextSelector(ChatPageContext, (v) => v.pane);
const myApps = useContextSelector(ChatPageContext, (v) => v.myApps);
const handlePaneChange = useContextSelector(ChatSettingContext, (v) => v.handlePaneChange);
const handlePaneChange = useContextSelector(ChatPageContext, (v) => v.handlePaneChange);
return (
<MotionFlex
@ -532,7 +532,7 @@ const ChatSlider = ({ apps, activeAppId }: Props) => {
</HStack>
<MyBox flex={'1 0 0'} h={0} overflow={'overlay'} px={4} position={'relative'}>
{apps.map((item) => (
{myApps.map((item) => (
<Flex
key={item._id}
py={2}

View File

@ -1,49 +0,0 @@
import { getRecentlyUsedApps } from '@/web/core/app/api';
import { useChatStore } from '@/web/core/chat/context/useChatStore';
import { useUserStore } from '@/web/support/user/useUserStore';
import { useRequest2 } from '@fastgpt/web/hooks/useRequest';
import { useMount } from 'ahooks';
import { useState, useEffect } from 'react';
export const useChat = (appId: string) => {
const { setSource, setAppId } = useChatStore();
const { userInfo, initUserInfo } = useUserStore();
const [isInitedUser, setIsInitedUser] = useState(false);
// get app list
const { data: myApps = [], refresh } = useRequest2(() => getRecentlyUsedApps(), {
manual: false,
errorToast: '',
refreshDeps: [userInfo],
pollingInterval: 30000
});
// initialize user info
useMount(async () => {
// ensure store has current appId before setting source (avoids fallback to lastChatAppId)
if (appId) setAppId(appId);
try {
await initUserInfo();
} catch (error) {
console.log('User not logged in:', error);
} finally {
setSource('online');
setIsInitedUser(true);
}
});
// sync appId to store as soon as route/appId changes
useEffect(() => {
if (appId) {
setAppId(appId);
}
}, [appId, setAppId, userInfo]);
return {
isInitedUser,
userInfo,
myApps,
refreshRecentlyUsed: refresh
};
};

View File

@ -8,7 +8,6 @@ import { serviceSideProps } from '@/web/common/i18n/utils';
import { ChatSidebarPaneEnum } from '@/pageComponents/chat/constants';
import { GetChatTypeEnum } from '@/global/core/chat/constants';
import ChatContextProvider from '@/web/core/chat/context/chatContext';
import { type AppListItemType } from '@fastgpt/global/core/app/type';
import { useContextSelector } from 'use-context-selector';
import { useSystem } from '@fastgpt/web/hooks/useSystem';
import { ChatSourceEnum } from '@fastgpt/global/core/chat/constants';
@ -18,13 +17,9 @@ import ChatQuoteList from '@/pageComponents/chat/ChatQuoteList';
import LoginModal from '@/pageComponents/login/LoginModal';
import { useSystemStore } from '@/web/common/system/useSystemStore';
import ChatSetting from '@/pageComponents/chat/ChatSetting';
import { useChat } from '@/pageComponents/chat/useChat';
import AppChatWindow from '@/pageComponents/chat/ChatWindow/AppChatWindow';
import HomeChatWindow from '@/pageComponents/chat/ChatWindow/HomeChatWindow';
import {
ChatSettingContext,
ChatSettingContextProvider
} from '@/web/core/chat/context/chatSettingContext';
import { ChatPageContext, ChatPageContextProvider } from '@/web/core/chat/context/chatPageContext';
import ChatTeamApp from '@/pageComponents/chat/ChatTeamApp';
import ChatFavouriteApp from '@/pageComponents/chat/ChatFavouriteApp';
import { useUserStore } from '@/web/support/user/useUserStore';
@ -32,15 +27,8 @@ import type { LoginSuccessResponse } from '@/global/support/api/userRes';
import { MongoOutLink } from '@fastgpt/service/support/outLink/schema';
import { addLog } from '@fastgpt/service/common/system/log';
import { PublishChannelEnum } from '@fastgpt/global/support/outLink/constant';
import type { GetRecentlyUsedAppsResponseType } from '@fastgpt/service/core/app/record/type';
const Chat = ({
myApps,
refreshRecentlyUsed
}: {
myApps: GetRecentlyUsedAppsResponseType;
refreshRecentlyUsed: () => void;
}) => {
const Chat = () => {
const { isPc } = useSystem();
const { appId } = useChatStore();
@ -48,8 +36,8 @@ const Chat = ({
const datasetCiteData = useContextSelector(ChatItemContext, (v) => v.datasetCiteData);
const setCiteModalData = useContextSelector(ChatItemContext, (v) => v.setCiteModalData);
const collapse = useContextSelector(ChatSettingContext, (v) => v.collapse);
const pane = useContextSelector(ChatSettingContext, (v) => v.pane);
const collapse = useContextSelector(ChatPageContext, (v) => v.collapse);
const pane = useContextSelector(ChatPageContext, (v) => v.pane);
return (
<Flex h={'100%'}>
@ -62,16 +50,14 @@ const Chat = ({
overflow={'hidden'}
transition={'width 0.1s ease-in-out'}
>
<ChatSlider apps={myApps} activeAppId={appId} />
<ChatSlider activeAppId={appId} />
</Box>
)}
{(!datasetCiteData || isPc) && (
<PageContainer flex="1 0 0" w={0} position="relative">
{/* home chat window */}
{pane === ChatSidebarPaneEnum.HOME && (
<HomeChatWindow myApps={myApps} refreshRecentlyUsed={refreshRecentlyUsed} />
)}
{pane === ChatSidebarPaneEnum.HOME && <HomeChatWindow />}
{/* favourite apps */}
{pane === ChatSidebarPaneEnum.FAVORITE_APPS && <ChatFavouriteApp />}
@ -80,9 +66,7 @@ const Chat = ({
{pane === ChatSidebarPaneEnum.TEAM_APPS && <ChatTeamApp />}
{/* recently used apps chat window */}
{pane === ChatSidebarPaneEnum.RECENTLY_USED_APPS && (
<AppChatWindow myApps={myApps} refreshRecentlyUsed={refreshRecentlyUsed} />
)}
{pane === ChatSidebarPaneEnum.RECENTLY_USED_APPS && <AppChatWindow />}
{/* setting */}
{pane === ChatSidebarPaneEnum.SETTING && <ChatSetting />}
@ -102,19 +86,23 @@ const Chat = ({
);
};
const Render = (props: {
type ChatPageProps = {
appId: string;
isStandalone?: string;
showRunningStatus: boolean;
showCite: boolean;
showFullText: boolean;
canDownloadSource: boolean;
}) => {
};
const ChatContent = (props: ChatPageProps) => {
const { appId, isStandalone } = props;
const { chatId } = useChatStore();
const { setUserInfo } = useUserStore();
const { feConfigs } = useSystemStore();
const { isInitedUser, userInfo, myApps, refreshRecentlyUsed } = useChat(appId);
const isInitedUser = useContextSelector(ChatPageContext, (v) => v.isInitedUser);
const userInfo = useContextSelector(ChatPageContext, (v) => v.userInfo);
const chatHistoryProviderParams = useMemo(
() => ({ appId, source: ChatSourceEnum.online }),
@ -155,21 +143,27 @@ const Render = (props: {
// show main chat interface
return (
<ChatSettingContextProvider>
<ChatContextProvider params={chatHistoryProviderParams}>
<ChatItemContextProvider
showRouteToDatasetDetail={isStandalone !== '1'}
showRunningStatus={props.showRunningStatus}
canDownloadSource={props.canDownloadSource}
isShowCite={props.showCite}
isShowFullText={props.showFullText}
>
<ChatRecordContextProvider params={chatRecordProviderParams}>
<Chat myApps={myApps} refreshRecentlyUsed={refreshRecentlyUsed} />
</ChatRecordContextProvider>
</ChatItemContextProvider>
</ChatContextProvider>
</ChatSettingContextProvider>
<ChatContextProvider params={chatHistoryProviderParams}>
<ChatItemContextProvider
showRouteToDatasetDetail={isStandalone !== '1'}
showRunningStatus={props.showRunningStatus}
canDownloadSource={props.canDownloadSource}
isShowCite={props.showCite}
isShowFullText={props.showFullText}
>
<ChatRecordContextProvider params={chatRecordProviderParams}>
<Chat />
</ChatRecordContextProvider>
</ChatItemContextProvider>
</ChatContextProvider>
);
};
const Render = (props: ChatPageProps) => {
return (
<ChatPageContextProvider appId={props.appId}>
<ChatContent {...props} />
</ChatPageContextProvider>
);
};

View File

@ -13,8 +13,14 @@ import { useRouter } from 'next/router';
import { useCallback, useEffect, useMemo, useState } from 'react';
import { createContext } from 'use-context-selector';
import { useMemoEnhance } from '@fastgpt/web/hooks/useMemoEnhance';
import { getRecentlyUsedApps } from '@/web/core/app/api';
import { useUserStore } from '@/web/support/user/useUserStore';
import { useMount } from 'ahooks';
import type { GetRecentlyUsedAppsResponseType } from '@fastgpt/service/core/app/record/type';
import type { UserType } from '@fastgpt/global/support/user/type';
export type ChatSettingContextValue = {
export type ChatPageContextValue = {
// Pane & collapse
pane: ChatSidebarPaneEnum;
handlePaneChange: (
pane: ChatSidebarPaneEnum,
@ -23,12 +29,18 @@ export type ChatSettingContextValue = {
) => void;
collapse: CollapseStatusType;
onTriggerCollapse: () => void;
// Chat settings
chatSettings: ChatSettingType | undefined;
refreshChatSetting: () => Promise<ChatSettingType | undefined>;
logos: { wideLogoUrl?: string; squareLogoUrl?: string };
// User & apps
isInitedUser: boolean;
userInfo: UserType | null;
myApps: GetRecentlyUsedAppsResponseType;
refreshRecentlyUsed: () => void;
};
export const ChatSettingContext = createContext<ChatSettingContextValue>({
export const ChatPageContext = createContext<ChatPageContextValue>({
pane: ChatSidebarPaneEnum.HOME,
handlePaneChange: () => {},
collapse: defaultCollapseStatus,
@ -37,19 +49,62 @@ export const ChatSettingContext = createContext<ChatSettingContextValue>({
logos: { wideLogoUrl: '', squareLogoUrl: '' },
refreshChatSetting: function (): Promise<ChatSettingType | undefined> {
throw new Error('Function not implemented.');
}
},
isInitedUser: false,
userInfo: null,
myApps: [],
refreshRecentlyUsed: () => {}
});
export const ChatSettingContextProvider = ({ children }: { children: React.ReactNode }) => {
export const ChatPageContextProvider = ({
appId: routeAppId,
children
}: {
appId: string;
children: React.ReactNode;
}) => {
const router = useRouter();
const { feConfigs } = useSystemStore();
const { appId, setLastPane, setLastChatAppId, lastPane } = useChatStore();
const { setSource, setAppId, setLastPane, setLastChatAppId, lastPane } = useChatStore();
const { userInfo, initUserInfo } = useUserStore();
const { pane = lastPane || ChatSidebarPaneEnum.HOME } = router.query as {
pane: ChatSidebarPaneEnum;
};
const [collapse, setCollapse] = useState<CollapseStatusType>(defaultCollapseStatus);
const [isInitedUser, setIsInitedUser] = useState(false);
// Get recently used apps
const { data: myApps = [], refresh: refreshRecentlyUsed } = useRequest2(
() => getRecentlyUsedApps(),
{
manual: false,
errorToast: '',
refreshDeps: [userInfo],
pollingInterval: 30000
}
);
// Initialize user info
useMount(async () => {
if (routeAppId) setAppId(routeAppId);
try {
await initUserInfo();
} catch (error) {
console.log('User not logged in:', error);
} finally {
setSource('online');
setIsInitedUser(true);
}
});
// Sync appId to store as route/appId changes
useEffect(() => {
if (routeAppId) {
setAppId(routeAppId);
}
}, [routeAppId, setAppId, userInfo]);
const { data: chatSettings, runAsync: refreshChatSetting } = useRequest2(
async () => {
@ -69,8 +124,8 @@ export const ChatSettingContextProvider = ({ children }: { children: React.React
if (
pane === ChatSidebarPaneEnum.HOME &&
appId !== data.appId &&
data.quickAppList.every((q) => q._id !== appId)
routeAppId !== data.appId &&
data.quickAppList.every((q) => q._id !== routeAppId)
) {
handlePaneChange(ChatSidebarPaneEnum.HOME, data.appId);
}
@ -126,7 +181,7 @@ export const ChatSettingContextProvider = ({ children }: { children: React.React
setCollapse(collapse === 0 ? 1 : 0);
}, [collapse]);
const value: ChatSettingContextValue = useMemoEnhance(
const value: ChatPageContextValue = useMemoEnhance(
() => ({
pane,
handlePaneChange,
@ -134,10 +189,26 @@ export const ChatSettingContextProvider = ({ children }: { children: React.React
onTriggerCollapse,
chatSettings,
refreshChatSetting,
logos
logos,
isInitedUser,
userInfo,
myApps,
refreshRecentlyUsed
}),
[pane, handlePaneChange, collapse, chatSettings, refreshChatSetting, onTriggerCollapse, logos]
[
pane,
handlePaneChange,
collapse,
onTriggerCollapse,
chatSettings,
refreshChatSetting,
logos,
isInitedUser,
userInfo,
myApps,
refreshRecentlyUsed
]
);
return <ChatSettingContext.Provider value={value}>{children}</ChatSettingContext.Provider>;
return <ChatPageContext.Provider value={value}>{children}</ChatPageContext.Provider>;
};