Merge remote-tracking branch 'origin/main'

main
liushujing 4 months ago
commit 88454da6f1

@ -19,6 +19,7 @@
"try": "试一下"
},
"back": "返回发现",
"collectSuccess": "收藏成功",
"category": {
"assistant": {
"all": "全部",

@ -19,6 +19,7 @@
"try": "試一下"
},
"back": "返回發現",
"collectSuccess": "收藏成功",
"category": {
"assistant": {
"academic": "學術",

@ -1,29 +1,13 @@
import { ActionIcon } from '@lobehub/ui';
import {Image, Tooltip} from 'antd';
import { LucideX } from 'lucide-react';
import {Image} from 'antd';
import { memo } from 'react';
import { useTranslation } from 'react-i18next';
import { Flexbox } from 'react-layout-kit';
import UserAvatar from '@/features/User/UserAvatar';
import UserPanel from '@/features/User/UserPanel';
import { useUserStore } from '@/store/user';
import { preferenceSelectors } from '@/store/user/selectors';
// import UserAvatar from '@/features/User/UserAvatar';
// import UserPanel from '@/features/User/UserPanel';
const Avatar = memo(() => {
const { t } = useTranslation('common');
const hideSettingsMoveGuide = useUserStore(preferenceSelectors.hideSettingsMoveGuide);
const updateGuideState = useUserStore((s) => s.updateGuideState);
const content = (
<UserPanel>
<UserAvatar clickable />
</UserPanel>
);
return (
<>
<Image alt={""} preview={false} src="/images/logo.png" />
</>
)
});

@ -1,25 +1,29 @@
import { ActionIcon } from '@lobehub/ui';
import { Compass, FolderClosed, MessageSquare } from 'lucide-react';
// import { ActionIcon } from '@lobehub/ui';
// import { Compass, FolderClosed, MessageSquare } from 'lucide-react';
import Link from 'next/link';
import {memo, useEffect, useState} from 'react';
import {memo, useState} from 'react';
import { useTranslation } from 'react-i18next';
import { useGlobalStore } from '@/store/global';
import { SidebarTabKey } from '@/store/global/initialState';
import { featureFlagsSelectors, useServerConfigStore } from '@/store/serverConfig';
import { useSessionStore } from '@/store/session';
import { useUserStore } from '@/store/user';
import { createStyles } from 'antd-style';
import {Button, Image} from "antd";
import { Image } from "antd";
const useStyles = createStyles(({ css, token }) => ({
const useStyles = createStyles(({ css }) => ({
iconImg: css`
width: 48px;
height: 48px;
`,
iconText: css`
text-align: center;
color: #fff;
`,
iconImg: css`
width: 48px;
height: 48px;
iconSelectText: css`
color: #0044FF;
`,
linkUrl: css`
width: 100%;
@ -28,28 +32,26 @@ const useStyles = createStyles(({ css, token }) => ({
linkclic: css`
background-color: #fff;
`,
iconSelectText: css`
color: #0044FF;
`,
}));
export interface TopActionProps {
tab?: SidebarTabKey;
}
const TopActions = memo<TopActionProps>(({ tab }) => {
const getUserId = (s) => s.user?.id
const TopActions = memo<TopActionProps>(() => {
const { t } = useTranslation('common');
const switchBackToChat = useGlobalStore((s) => s.switchBackToChat);
const { showMarket, enableKnowledgeBase } = useServerConfigStore(featureFlagsSelectors);
const { styles, cx } = useStyles()
const [value, setValue] = useState("chat")
const userId = getUserId(useUserStore.getState())
console.log(userId,'3837373266262266')
return (
<div style={{ width: '100%', textAlign: 'center'}}>
<div style={{ textAlign: 'center', width: '100%'}}>
<Link
aria-label={t('tab.chat')}
className={value === '/chat' ? cx(styles.linkUrl, styles.linkclic) : cx(styles.linkUrl)}
href={'/chat'}
className={value == '/chat' ? cx(styles.linkUrl, styles.linkclic) : cx(styles.linkUrl)}
onClick={(e) => {
e.preventDefault();
setValue("/chat")
@ -58,48 +60,48 @@ const TopActions = memo<TopActionProps>(({ tab }) => {
}}
>
<Image alt={"chat"} className={cx(styles.iconImg)} preview={false} src="/images/hh.png" />
<div className={value == '/chat' ? cx(styles.iconText, styles.iconSelectText) : cx(styles.iconText) }></div>
<div className={value === '/chat' ? cx(styles.iconText, styles.iconSelectText) : cx(styles.iconText) }></div>
</Link>
{enableKnowledgeBase && (
<Link className={value == '/discover/assistants' ? cx(styles.linkUrl, styles.linkclic) : cx(styles.linkUrl)} aria-label={t('tab.files')} href={`/discover/assistants?userid=${localStorage.getItem('userId')}`} onClick={() => {setValue("/discover/assistants"); window.localStorage.setItem("nowChat", "")}}>
<Link aria-label={t('tab.files')} className={value === '/discover/assistants' ? cx(styles.linkUrl, styles.linkclic) : cx(styles.linkUrl)} href={`/discover/assistants?userid=${userId}`} onClick={() => {setValue("/discover/assistants"); window.localStorage.setItem("nowChat", "")}}>
<Image alt={"files"} className={cx(styles.iconImg)} preview={false} src="/images/zs.png" />
<div className={value == '/discover/assistants' ? cx(styles.iconText, styles.iconSelectText) : cx(styles.iconText) }></div>
<div className={value === '/discover/assistants' ? cx(styles.iconText, styles.iconSelectText) : cx(styles.iconText) }></div>
</Link>
)}
{showMarket && (
<Link className={value == '/files' ? cx(styles.linkUrl, styles.linkclic) : cx(styles.linkUrl)} aria-label={t('tab.discover')} href={'/files'} onClick={() => {setValue("/files"); window.localStorage.setItem("nowChat", "")}}>
<Link aria-label={t('tab.discover')} className={value === '/files' ? cx(styles.linkUrl, styles.linkclic) : cx(styles.linkUrl)} href={'/files'} onClick={() => {setValue("/files"); window.localStorage.setItem("nowChat", "")}}>
<Image alt={"discover"} className={cx(styles.iconImg)} preview={false} src="/images/gj.png" />
<div className={value == '/files' ? cx(styles.iconText, styles.iconSelectText) : cx(styles.iconText) }></div>
<div className={value === '/files' ? cx(styles.iconText, styles.iconSelectText) : cx(styles.iconText) }></div>
</Link>
)}
{showMarket && (
<Link className={value == '/model' ? cx(styles.linkUrl, styles.linkclic) : cx(styles.linkUrl)} aria-label={t('tab.Model')} href={'/model'} onClick={() => {setValue("/model"); window.localStorage.setItem("nowChat", "")}}>
<Link aria-label={t('tab.Model')} className={value === '/model' ? cx(styles.linkUrl, styles.linkclic) : cx(styles.linkUrl)} href={`/discover/models?userid=${userId}`} onClick={() => {setValue("/model"); window.localStorage.setItem("nowChat", "")}}>
<Image alt={"model"} className={cx(styles.iconImg)} preview={false} src="/images/mx.png" />
<div className={value == '/model' ? cx(styles.iconText, styles.iconSelectText) : cx(styles.iconText) }></div>
<div className={value === '/model' ? cx(styles.iconText, styles.iconSelectText) : cx(styles.iconText) }></div>
</Link>
)}
{showMarket && (
<Link className={value == '/robot' ? cx(styles.linkUrl, styles.linkclic) : cx(styles.linkUrl)} aria-label={t('tab.robot')} href={'/robot'} onClick={() => {setValue("/robot"); window.localStorage.setItem("nowChat", "")}}>
<Link aria-label={t('tab.robot')} className={value === '/robot' ? cx(styles.linkUrl, styles.linkclic) : cx(styles.linkUrl)} href={'/robot'} onClick={() => {setValue("/robot"); window.localStorage.setItem("nowChat", "")}}>
<Image alt={"robot"} className={cx(styles.iconImg)} preview={false} src="/images/szr.png" />
<div className={value == '/robot' ? cx(styles.iconText, styles.iconSelectText) : cx(styles.iconText) }></div>
<div className={value === '/robot' ? cx(styles.iconText, styles.iconSelectText) : cx(styles.iconText) }></div>
</Link>
)}
{showMarket && (
<Link className={value == '/plugins' ? cx(styles.linkUrl, styles.linkclic) : cx(styles.linkUrl)} aria-label={t('tab.Plugins')} href={'/discover/plugins'} onClick={() => {setValue("/plugins"); window.localStorage.setItem("nowChat", "")}}>
<Link aria-label={t('tab.Plugins')} className={value === '/plugins' ? cx(styles.linkUrl, styles.linkclic) : cx(styles.linkUrl)} href={`/discover/plugins?userid=${userId}`} onClick={() => {setValue("/plugins"); window.localStorage.setItem("nowChat", "")}}>
<Image alt={"plugins"} className={cx(styles.iconImg)} preview={false} src="/images/cj.png" />
<div className={value == '/plugins' ? cx(styles.iconText, styles.iconSelectText) : cx(styles.iconText) }></div>
<div className={value === '/plugins' ? cx(styles.iconText, styles.iconSelectText) : cx(styles.iconText) }></div>
</Link>
)}
{showMarket && (
<Link className={value == '/power' ? cx(styles.linkUrl, styles.linkclic) : cx(styles.linkUrl)} aria-label={t('tab.Power')} href={'/power'} onClick={() => {setValue("/power"); window.localStorage.setItem("nowChat", "")}}>
<Link aria-label={t('tab.Power')} className={value === '/power' ? cx(styles.linkUrl, styles.linkclic) : cx(styles.linkUrl)} href={'/power'} onClick={() => {setValue("/power"); window.localStorage.setItem("nowChat", "")}}>
<Image alt={"power"} className={cx(styles.iconImg)} preview={false} src="/images/sl.png" />
<div className={value == '/power' ? cx(styles.iconText, styles.iconSelectText) : cx(styles.iconText) }></div>
<div className={value === '/power' ? cx(styles.iconText, styles.iconSelectText) : cx(styles.iconText) }></div>
</Link>
)}
{showMarket && (
<Link className={value == '/knowledge' ? cx(styles.linkUrl, styles.linkclic) : cx(styles.linkUrl)} aria-label={t('tab.knowledge')} href={'/knowledge'} onClick={() => {setValue("/knowledge")}}>
<Link aria-label={t('tab.knowledge')} className={value === '/knowledge' ? cx(styles.linkUrl, styles.linkclic) : cx(styles.linkUrl)} href={'/knowledge'} onClick={() => {setValue("/knowledge")}}>
<Image className={cx(styles.iconImg)} preview={false} src="/images/zsk.png" />
<div className={value == '/knowledge' ? cx(styles.iconText, styles.iconSelectText) : cx(styles.iconText) }></div>
<div className={value === '/knowledge' ? cx(styles.iconText, styles.iconSelectText) : cx(styles.iconText) }></div>
</Link>
)}
</div>

@ -6,7 +6,6 @@ import { memo } from 'react';
import { useActiveTabKey } from '@/hooks/useActiveTabKey';
import Avatar from './Avatar';
import BottomActions from './BottomActions';
import TopActions from './TopActions';
const Nav = memo(() => {
@ -14,8 +13,8 @@ const Nav = memo(() => {
return (
<SideNav
avatar={<Avatar />}
// bottomActions={<BottomActions />}
style={{ height: '100%', zIndex: 100, width: '100px', backgroundColor: '#2E62FF' }}
bottomActions={<></>}
style={{ backgroundColor: '#2E62FF', height: '100%', width: '100px', zIndex: 100 }}
topActions={<TopActions tab={sidebarKey} />}
/>
);

@ -9,9 +9,7 @@ import { usePlatform } from '@/hooks/usePlatform';
import { featureFlagsSelectors, useServerConfigStore } from '@/store/serverConfig';
import { UserOutlined, SearchOutlined } from '@ant-design/icons';
import { LayoutProps } from './type';
import { Divider, Input, Avatar } from "antd";
const { Search } = Input;
import { Divider, Avatar } from "antd";
const title = {
"/chat": '会话',
"/discover/assistants": "助手",
@ -25,6 +23,7 @@ const title = {
const useStyles = createStyles(({ css, token }) => ({
topCenten: css`
width: 100%;
line-height: 60px;
background: #FFFFFF;
box-sizing: border-box;
/* 分割线颜色 */
@ -38,7 +37,7 @@ const useStyles = createStyles(({ css, token }) => ({
display: inline-block
`,
dividerCen: css`
width: 2px;
width: 1px;
height: 26px;
background-color: #d8d8d8;
margin: 8px 16px;
@ -48,8 +47,8 @@ const useStyles = createStyles(({ css, token }) => ({
display: inline-block;
`,
nameSpn: css`
margin-right: 80px;
margin-left: 8px;
margin-right: 16px;
margin-left: 18px;
display: inline-block;
`,
serchIcon: css`
@ -71,9 +70,9 @@ const Layout = memo<LayoutProps>(({ children, nav }) => {
const { isPWA } = usePlatform();
const theme = useTheme();
const { styles, cx } = useStyles()
console.log(window?.location?.pathname,'3837373666router--------------------------------------------')
const { showCloudPromotion } = useServerConfigStore(featureFlagsSelectors);
const pathName = window?.location?.pathname
return (
<>
{showCloudPromotion && <CloudBanner />}
@ -87,7 +86,20 @@ const Layout = memo<LayoutProps>(({ children, nav }) => {
width={'100%'}
>
{nav}
<div style={{ width: '100%' }}>
<div className={cx(styles.topCenten)}>
<div className={cx(styles.ledDiv)}>
<span className={cx(styles.leftTitle)} style={{ marginLeft: '16px' }}>AI</span>
<Divider className={cx(styles.dividerCen)} type="vertical" />
<span className={cx(styles.leftTitle)}>{title[pathName]}</span>
</div>
<div className={cx(styles.ledDiv)} style={{ height: '42px', lineHeight: "42px", textAlign: 'right' }}>
<Avatar style={{ backgroundColor: '#90ACFF' }} icon={<UserOutlined />} />
<span className={cx(styles.nameSpn)}> </span>
</div>
</div>
{children}
</div>
</Flexbox>
</>
);

@ -15,9 +15,9 @@ const ChatConversation = () => {
<ChatInput />
<div style={{ fontSize: '13px', color: '#909090', backgroundColor: "rgba(200, 205, 220, 0.2)"}}>
<div style={{ backgroundColor: "rgba(200, 205, 220, 0.2)", color: '#909090', fontSize: '13px'}}>
<span style={{ display: 'inline-block', }}>:</span>
<span style={{ display: 'inline-block', margin: "0px 13px", fontSize: "20px" }}>&crarr;</span>
<span style={{ display: 'inline-block', fontSize: "20px", margin: "0px 13px" }}>&crarr;</span>
<span> </span>
<span style={{ display: 'inline-block', fontSize: "20px", marginLeft: '30px', marginRight: '11px' }}>&crarr;</span>
<span> + Ctrl </span>

@ -1,23 +1,23 @@
import { Icon } from '@lobehub/ui';
import { Button, Skeleton, Space } from 'antd';
// import { Icon } from '@lobehub/ui';
import { Button, Space } from 'antd';
import { createStyles } from 'antd-style';
import { ChevronUp, CornerDownLeft, LucideCommand, Eraser } from 'lucide-react';
// import { ChevronUp, CornerDownLeft, LucideCommand } from 'lucide-react';
import { rgba } from 'polished';
import { memo, useEffect, useState } from 'react';
import { memo } from 'react';
import { useTranslation } from 'react-i18next';
import { Center, Flexbox } from 'react-layout-kit';
import { Flexbox } from 'react-layout-kit';
import StopLoadingIcon from '@/components/StopLoading';
import SaveTopic from '@/features/ChatInput/Topic';
// import SaveTopic from '@/features/ChatInput/Topic';
import { useSendMessage } from '@/features/ChatInput/useSend';
import { useChatStore } from '@/store/chat';
import { chatSelectors } from '@/store/chat/selectors';
import { useUserStore } from '@/store/user';
import { preferenceSelectors } from '@/store/user/selectors';
import { isMacOS } from '@/utils/platform';
// import { useUserStore } from '@/store/user';
// import { preferenceSelectors } from '@/store/user/selectors';
// import { isMacOS } from '@/utils/platform';
import LocalFiles from '../FilePreview';
import SendMore from './SendMore';
// import LocalFiles from '../FilePreview';
// import SendMore from './SendMore';
import {HighlightOutlined, SendOutlined} from "@ant-design/icons";
const useStyles = createStyles(({ css, prefixCls, token }) => {
@ -27,10 +27,6 @@ const useStyles = createStyles(({ css, prefixCls, token }) => {
width: 28px;
}
`,
btnDiv: css`
height: 50%;
width: 100px;
`,
btn: css`
width: 96px;
height: 80%;
@ -39,6 +35,10 @@ const useStyles = createStyles(({ css, prefixCls, token }) => {
color: #2E62FF !important;
font-size: 16px;
`,
btnDiv: css`
height: 50%;
width: 100px;
`,
btnSend: css`
width: 96px;
height: 80%;
@ -77,47 +77,47 @@ interface FooterProps {
setExpand?: (expand: boolean) => void;
}
const Footer = memo<FooterProps>(({ setExpand, expand, clearClick }) => {
const Footer = memo<FooterProps>(({ clearClick, setExpand }) => {
const { t } = useTranslation('chat');
const { theme, styles } = useStyles();
const { styles } = useStyles();
const [isAIGenerating, stopGenerateMessage] = useChatStore((s) => [
chatSelectors.isAIGenerating(s),
s.stopGenerateMessage,
]);
const [useCmdEnterToSend] = useUserStore((s) => [preferenceSelectors.useCmdEnterToSend(s)]);
// const [useCmdEnterToSend] = useUserStore((s) => [preferenceSelectors.useCmdEnterToSend(s)]);
const { send: sendMessage, canSend } = useSendMessage();
const [isMac, setIsMac] = useState<boolean>();
useEffect(() => {
setIsMac(isMacOS());
}, [setIsMac]);
const cmdEnter = (
<Flexbox gap={2} horizontal>
{typeof isMac === 'boolean' ? (
<Icon icon={isMac ? LucideCommand : ChevronUp} />
) : (
<Skeleton.Node active style={{ height: '100%', width: 12 }}>
{' '}
</Skeleton.Node>
)}
<Icon icon={CornerDownLeft} />
</Flexbox>
);
const enter = (
<Center>
<Icon icon={CornerDownLeft} />
</Center>
);
const sendShortcut = useCmdEnterToSend ? cmdEnter : enter;
const wrapperShortcut = useCmdEnterToSend ? enter : cmdEnter;
// const [isMac, setIsMac] = useState<boolean>();
// useEffect(() => {
// setIsMac(isMacOS());
// }, [setIsMac]);
// const cmdEnter = (
// <Flexbox gap={2} horizontal>
// {typeof isMac === 'boolean' ? (
// <Icon icon={isMac ? LucideCommand : ChevronUp} />
// ) : (
// <Skeleton.Node active style={{ height: '100%', width: 12 }}>
// {' '}
// </Skeleton.Node>
// )}
// <Icon icon={CornerDownLeft} />
// </Flexbox>
// );
// const enter = (
// <Center>
// <Icon icon={CornerDownLeft} />
// </Center>
// );
// const sendShortcut = useCmdEnterToSend ? cmdEnter : enter;
// const wrapperShortcut = useCmdEnterToSend ? enter : cmdEnter;
const handleClickClear = () => {
clearClick()
@ -127,12 +127,12 @@ const Footer = memo<FooterProps>(({ setExpand, expand, clearClick }) => {
<Flexbox
align={'end'}
className={styles.overrideAntdIcon}
style={{ display: 'inline-block', height: '100%', width: "140px" }}
distribution={'space-between'}
flex={'none'}
gap={8}
horizontal
padding={'0 24px'}
style={{ display: 'inline-block', height: '100%', width: "140px" }}
>
{/*<Flexbox align={'center'} gap={8} horizontal style={{ overflow: 'hidden' }}>*/}
{/* {expand && <LocalFiles />}*/}

@ -8,7 +8,6 @@ import {
CHAT_TEXTAREA_HEIGHT,
CHAT_TEXTAREA_MAX_HEIGHT,
HEADER_HEIGHT,
CHAT_TEXTAREA_MIN_HEIGHT,
} from '@/const/layoutTokens';
import { useGlobalStore } from '@/store/global';
import { systemStatusSelectors } from '@/store/global/selectors';
@ -59,9 +58,9 @@ const DesktopChatInput = memo(() => {
style={{ minHeight: CHAT_TEXTAREA_HEIGHT, position: 'relative' }}
>
<Head expand={expand} setExpand={setExpand} />
<div style={{ height: '100%', display: 'flex' }}>
<div style={{ display: 'flex', height: '100%'}}>
<TextArea setExpand={setExpand} />
<Footer expand={expand} setExpand={setExpand} clearClick={() => clearClick()} />
<Footer clearClick={() => clearClick()} expand={expand} setExpand={setExpand} />
</div>
</Flexbox>
</DraggablePanel>

@ -86,7 +86,6 @@ const TopicListContent = memo(() => {
)}
<Virtuoso
// components={{ ScrollSeekPlaceholder: Placeholder }}
style={{ height: "150px" }}
computeItemKey={(_, item) => item.id}
data={topics}
fixedItemHeight={44}
@ -94,6 +93,7 @@ const TopicListContent = memo(() => {
itemContent={itemContent}
overscan={44 * 10}
ref={virtuosoRef}
style={{ height: "150px" }}
// scrollSeekConfiguration={{
// enter: (velocity) => Math.abs(velocity) > 350,
// exit: (velocity) => Math.abs(velocity) < 10,

@ -1,35 +1,35 @@
'use client';
import { ActionIcon } from '@lobehub/ui';
import { PanelRightClose, PanelRightOpen } from 'lucide-react';
// import { ActionIcon } from '@lobehub/ui';
// import { PanelRightClose, PanelRightOpen } from 'lucide-react';
import { memo } from 'react';
import { useTranslation } from 'react-i18next';
// import { useTranslation } from 'react-i18next';
import { DESKTOP_HEADER_ICON_SIZE } from '@/const/layoutTokens';
import { useGlobalStore } from '@/store/global';
import { systemStatusSelectors } from '@/store/global/selectors';
import { featureFlagsSelectors, useServerConfigStore } from '@/store/serverConfig';
// import { DESKTOP_HEADER_ICON_SIZE } from '@/const/layoutTokens';
// import { useGlobalStore } from '@/store/global';
// import { systemStatusSelectors } from '@/store/global/selectors';
// import { featureFlagsSelectors, useServerConfigStore } from '@/store/serverConfig';
import SettingButton from '../../../features/SettingButton';
import ShareButton from '../../../features/ShareButton';
// import SettingButton from '../../../features/SettingButton';
// import ShareButton from '../../../features/ShareButton';
import {Button} from "antd";
import { useOpenChatSettings } from '@/hooks/useInterceptingRoutes';
const HeaderAction = memo(() => {
const { t } = useTranslation('chat');
// const { t } = useTranslation('chat');
const [showAgentSettings, toggleConfig] = useGlobalStore((s) => [
systemStatusSelectors.showChatSideBar(s),
s.toggleChatSideBar,
]);
// const [showAgentSettings, toggleConfig] = useGlobalStore((s) => [
// systemStatusSelectors.showChatSideBar(s),
// s.toggleChatSideBar,
// ]);
const { isAgentEditable } = useServerConfigStore(featureFlagsSelectors);
// const { isAgentEditable } = useServerConfigStore(featureFlagsSelectors);
const openChatSettings = useOpenChatSettings();
return (
<>
<Button onClick={() => openChatSettings()} style={{ borderColor: '#2E62FF', color: "#2E62FF" }} shape="round"></Button>
<Button onClick={() => openChatSettings()} shape="round" style={{ borderColor: '#2E62FF', color: "#2E62FF" }}></Button>
{/*<ShareButton />*/}
{/*<ActionIcon*/}
{/* icon={showAgentSettings ? PanelRightClose : PanelRightOpen}*/}

@ -1,28 +1,28 @@
'use client';
import { ActionIcon, Avatar, ChatHeaderTitle } from '@lobehub/ui';
import { Avatar } from '@lobehub/ui';
import { Skeleton } from 'antd';
import { PanelLeftClose, PanelLeftOpen } from 'lucide-react';
// import { PanelLeftClose, PanelLeftOpen } from 'lucide-react';
import { Suspense, memo } from 'react';
import { useTranslation } from 'react-i18next';
import { Flexbox } from 'react-layout-kit';
import { DESKTOP_HEADER_ICON_SIZE } from '@/const/layoutTokens';
// import { DESKTOP_HEADER_ICON_SIZE } from '@/const/layoutTokens';
import { useOpenChatSettings } from '@/hooks/useInterceptingRoutes';
import { useGlobalStore } from '@/store/global';
import { systemStatusSelectors } from '@/store/global/selectors';
// import { useGlobalStore } from '@/store/global';
// import { systemStatusSelectors } from '@/store/global/selectors';
import { useSessionStore } from '@/store/session';
import { sessionMetaSelectors, sessionSelectors } from '@/store/session/selectors';
import { useInitAgentConfig } from '../../useInitAgentConfig';
import Tags from './Tags';
// import Tags from './Tags';
const Main = memo(() => {
const { t } = useTranslation('chat');
useInitAgentConfig();
const [init, isInbox, title, description, avatar, backgroundColor] = useSessionStore((s) => [
const [init, isInbox, title, avatar, backgroundColor] = useSessionStore((s) => [
sessionSelectors.isSomeSessionActive(s),
sessionSelectors.isInboxSession(s),
sessionMetaSelectors.currentAgentTitle(s),
@ -34,9 +34,9 @@ const Main = memo(() => {
const openChatSettings = useOpenChatSettings();
const displayTitle = isInbox ? t('inbox.title') : title;
const displayDesc = isInbox ? t('inbox.desc') : description;
const showSessionPanel = useGlobalStore(systemStatusSelectors.showSessionPanel);
const updateSystemStatus = useGlobalStore((s) => s.updateSystemStatus);
// const displayDesc = isInbox ? t('inbox.desc') : description;
// const showSessionPanel = useGlobalStore(systemStatusSelectors.showSessionPanel);
// const updateSystemStatus = useGlobalStore((s) => s.updateSystemStatus);
return !init ? (
<Flexbox horizontal>
@ -73,7 +73,7 @@ const Main = memo(() => {
<div>
<div style={{ fontSize: "15px" }}>{displayTitle}</div>
{/*<ChatHeaderTitle desc={displayDesc} title={displayTitle} />*/}
<div style={{ fontSize: '12px', color: "#A7A0A0" }}>{displayTitle}</div>
<div style={{ color: "#A7A0A0", fontSize: '12px' }}>{displayTitle}</div>
</div>
</Flexbox>
);

@ -17,7 +17,6 @@ const TitleTags = memo(() => {
agentSelectors.currentAgentModel(s),
agentSelectors.hasKnowledge(s),
]);
console.log(model, 20202020)
const plugins = useAgentStore(agentSelectors.currentAgentPlugins, isEqual);
const enabledKnowledge = useAgentStore(agentSelectors.currentEnabledKnowledge, isEqual);

@ -3,16 +3,16 @@
import { DraggablePanel, DraggablePanelContainer } from '@lobehub/ui';
import { createStyles, useResponsive } from 'antd-style';
import isEqual from 'fast-deep-equal';
import { PropsWithChildren, memo, useEffect, useState } from 'react';
import { memo, useEffect, useState } from 'react';
import SafeSpacing from '@/components/SafeSpacing';
// import SafeSpacing from '@/components/SafeSpacing';
import { CHAT_SIDEBAR_WIDTH } from '@/const/layoutTokens';
import { useChatStore } from '@/store/chat';
import { chatPortalSelectors } from '@/store/chat/slices/portal/selectors';
import { useGlobalStore } from '@/store/global';
import { systemStatusSelectors } from '@/store/global/selectors';
import {Form, Image} from "antd";
import {EditFilled, EditTwoTone} from "@ant-design/icons";
import {EditFilled} from "@ant-design/icons";
import TopicListContent from "@/app/(main)/chat/(workspace)/@topic/features/TopicListContent";
import Header from "@/app/(main)/chat/(workspace)/@topic/features/Header";
@ -31,11 +31,6 @@ const useStyles = createStyles(({ css, token }) => ({
header: css`
border-block-end: 1px solid ${token.colorBorder};
`,
topTitle: css`
font-size: 18px;
display: inline-block;
width: calc(100% - 24px)
`,
topEdit: css`
display: inline-block;
text-align: center;
@ -44,9 +39,14 @@ const useStyles = createStyles(({ css, token }) => ({
background-color: #AFC1FF;
color: #fff;
`,
topTitle: css`
font-size: 18px;
display: inline-block;
width: calc(100% - 24px)
`,
}));
const TopicPanel = memo(({ children }: PropsWithChildren) => {
const TopicPanel = memo(() => {
const { styles } = useStyles();
const [form] = Form.useForm()
const { md = true, lg = true } = useResponsive();
@ -87,8 +87,8 @@ const TopicPanel = memo(({ children }: PropsWithChildren) => {
style={{
flex: 'none',
height: '100%',
maxHeight: '100vh',
border: "1px solid #ddd",
maxHeight: '100vh',
minWidth: CHAT_SIDEBAR_WIDTH,
}}
>
@ -97,14 +97,14 @@ const TopicPanel = memo(({ children }: PropsWithChildren) => {
<div className={styles.topEdit}><EditFilled /></div>
</div>
<div><Image alt="头像" preview={false} src="/images/zsImage.png" /></div>
<Form layout="horizontal" colon={false} form={form} labelCol={{ span: 6 }} wrapperCol={{ span: 18 }}>
<Form.Item name="name" label="名称">
<Form colon={false} form={form} labelCol={{ span: 6 }} layout="horizontal" wrapperCol={{ span: 18 }}>
<Form.Item label="名称" name="name">
<span style={{ width: "18px" }}>Linda</span>
</Form.Item>
<Form.Item name="jj" label="简介">
<Form.Item label="简介" name="jj">
<span style={{ color: "#999999", fontSize: '13px' }}></span>
</Form.Item>
<Form.Item name="rw" label="任务">
<Form.Item label="任务" name="rw">
<span style={{ color: "#999999", fontSize: '13px' }}></span>
</Form.Item>
</Form>

@ -2,12 +2,11 @@
import { memo } from 'react';
import { Flexbox, FlexboxProps } from 'react-layout-kit';
import urlJoin from 'url-join';
import { OFFICIAL_URL } from '@/const/url';
// import { OFFICIAL_URL } from '@/const/url';
import { DiscoverAssistantItem } from '@/types/discover';
import ShareButton from '../../../features/ShareButton';
// import ShareButton from '../../../features/ShareButton';
import AddAgent from './AddAgent';
interface AssistantActionProps extends FlexboxProps {
@ -15,19 +14,10 @@ interface AssistantActionProps extends FlexboxProps {
identifier: string;
}
const AssistantAction = memo<AssistantActionProps>(({ identifier, data }) => {
const AssistantAction = memo<AssistantActionProps>(({ data }) => {
return (
<Flexbox align={'center'} gap={8} horizontal>
<Flexbox align={'center'} gap={8} horizontal style={{marginLeft: 100}}>
<AddAgent data={data} />
<ShareButton
meta={{
avatar: data.meta.avatar,
desc: data.meta.description,
hashtags: data.meta.tags,
title: data.meta.title,
url: urlJoin(OFFICIAL_URL, '/discover/assistant', identifier),
}}
/>
</Flexbox>
);
});

@ -1,9 +1,9 @@
'use client';
import { ActionIcon, Icon } from '@lobehub/ui';
import { App, Dropdown, Button } from 'antd';
import { ActionIcon } from '@lobehub/ui';
import { App, Button } from 'antd';
import { createStyles } from 'antd-style';
import { ChevronDownIcon, PlusIcon } from 'lucide-react';
import { PlusIcon } from 'lucide-react';
import { useRouter } from 'next/navigation';
import { memo, useState } from 'react';
import { useTranslation } from 'react-i18next';
@ -40,13 +40,13 @@ const AddAgent = memo<{ data: DiscoverAssistantItem; mobile?: boolean }>(({ data
router.push(SESSION_CHAT_URL(session, mobile));
};
const handleAddAgent = async () => {
if (!data) return;
setIsLoading(true);
createSession({ config: data.config, meta: data.meta }, false);
message.success(t('assistants.addAgentSuccess'));
setIsLoading(false);
};
// const handleAddAgent = async () => {
// if (!data) return;
// setIsLoading(true);
// createSession({ config: data.config, meta: data.meta }, false);
// message.success(t('assistants.addAgentSuccess'));
// setIsLoading(false);
// };
if (mobile)
return (
@ -60,9 +60,7 @@ const AddAgent = memo<{ data: DiscoverAssistantItem; mobile?: boolean }>(({ data
);
return (
<>
<Button className={styles.button} loading={isLoading} onClick={handleAddAgentAndConverse}></Button>
</>
);
});

@ -1,21 +1,20 @@
'use client';
import { Avatar, Icon, Tag } from '@lobehub/ui';
import { Avatar, Tag } from '@lobehub/ui';
import { Button } from 'antd';
import { createStyles } from 'antd-style';
import { startCase } from 'lodash-es';
import { ChevronRight } from 'lucide-react';
// import { ChevronRight } from 'lucide-react';
import Link from 'next/link';
import qs from 'query-string';
// import qs from 'query-string';
import { memo } from 'react';
import { useTranslation } from 'react-i18next';
// import { useTranslation } from 'react-i18next';
import { Flexbox } from 'react-layout-kit';
import urlJoin from 'url-join';
// import urlJoin from 'url-join';
import { useRouter } from 'next/navigation';
import { DiscoverAssistantItem } from '@/types/discover';
import { useUserStore } from '@/store/user';
import GitHubAvatar from '../../../../components/GitHubAvatar';
import Back from '../../../features/Back';
import Actions from './Actions';
export const useStyles = createStyles(({ css, token }) => ({
tag: css`
@ -41,15 +40,10 @@ export const useStyles = createStyles(({ css, token }) => ({
border-color: rgba(187, 204, 253, 0.24);
padding: 20px 50px;
`,
topBtn: css`
border-radius: 20px;
color: #2E62FF;
border: 1px solid #2E62FF;
`,
conTitle: css`
width: 125px;
height: 50px;
line-height: 50px;
height: 40px;
line-height: 40px;
text-align: center;
color: #fff;
font-size: 20px;
@ -57,11 +51,18 @@ export const useStyles = createStyles(({ css, token }) => ({
opacity: 1;
background: linear-gradient(270deg, #2D65FF 0%, rgba(0, 166, 255, 0.52) 99%);
`,
topBtn: css`
border-radius: 20px;
color: #2E62FF;
border: 1px solid #2E62FF;
`,
description: css`
padding: 0 45px;
margin-top: 10px;
`,
tag: css`
padding: 0px 45px;
margin-bottom: 10px;
`,
}));
@ -70,17 +71,18 @@ interface HeaderProps {
identifier: string;
mobile?: boolean;
}
const getUserId = (s) => s.user?.id
const Header = memo<HeaderProps>(({ identifier, data, mobile }) => {
const { styles, theme } = useStyles();
const router = useRouter()
const { t } = useTranslation('discover');
// const { t } = useTranslation('discover');
const userId = getUserId(useUserStore.getState())
const handleBack = () => {
router.push('/discover/assistants?userid=' + localStorage.getItem('userId'))
router.push('/discover/assistants?userid=' + userId)
}
return (
<Flexbox gap={12} width={'100%'}>
<Flexbox align={'center'} gap={8} horizontal justify={'space-between'} width={'100%'} className={styles.top}>
<Flexbox align={'center'} className={styles.top} gap={8} horizontal justify={'space-between'} width={'100%'}>
<Flexbox align={'center'} gap={16} horizontal justify={'flex-start'}>
<Avatar
alt={identifier}
@ -118,17 +120,9 @@ const Header = memo<HeaderProps>(({ identifier, data, mobile }) => {
{data.meta.tags && (
<Flexbox gap={4} horizontal wrap={'wrap'}>
{data.meta.tags.map((tag) => (
<Link
href={qs.stringifyUrl({
query: { q: tag, type: 'assistants' },
url: '/discover/search',
})}
key={tag}
>
<Tag key={tag} style={{ margin: 0 }}>
{startCase(tag).trim()}
</Tag>
</Link>
))}
</Flexbox>
)}

@ -3,14 +3,14 @@
import { Markdown } from '@lobehub/ui';
import { Skeleton } from 'antd';
import { useTheme } from 'antd-style';
import { BotMessageSquare } from 'lucide-react';
// import { BotMessageSquare } from 'lucide-react';
import { memo } from 'react';
import { useTranslation } from 'react-i18next';
// import { useTranslation } from 'react-i18next';
import { Flexbox, FlexboxProps } from 'react-layout-kit';
import { DiscoverAssistantItem } from '@/types/discover';
import HighlightBlock from '../../../features/HighlightBlock';
// import HighlightBlock from '../../../features/HighlightBlock';
interface ConversationExampleProps extends FlexboxProps {
data: DiscoverAssistantItem;
@ -19,11 +19,10 @@ interface ConversationExampleProps extends FlexboxProps {
}
const ConversationExample = memo<ConversationExampleProps>(({ data }) => {
const { t } = useTranslation('discover');
// const { t } = useTranslation('discover');
const theme = useTheme();
console.log(data.config.systemRole,111111111)
return (
<>
<Flexbox paddingInline={16} style={{padding: '0 45'}}>
{data.config.systemRole ? (
<Markdown fontSize={theme.fontSize}>{data.config.systemRole}</Markdown>
@ -31,7 +30,6 @@ const ConversationExample = memo<ConversationExampleProps>(({ data }) => {
<Skeleton paragraph={{ rows: 4 }} title={false} />
)}
</Flexbox>
</>
);
});

@ -11,9 +11,9 @@ import { DiscoverPlugintem } from '@/types/discover';
import { isMobileDevice } from '@/utils/responsive';
import DetailLayout from '../../features/DetailLayout';
import Actions from './features/Actions';
// import Actions from './features/Actions';
import Header from './features/Header';
import InfoSidebar from './features/InfoSidebar';
// import InfoSidebar from './features/InfoSidebar';
import Temp from './features/Temp';
// import ConversationExample from './features/ConversationExample';
@ -67,10 +67,10 @@ const Page = async ({ params, searchParams }: Props) => {
console.log(data,'37373733737')
const { meta, createdAt, author, config } = data;
let pluginData: DiscoverPlugintem[] = [];
if (config?.plugins && config.plugins?.length > 0) {
pluginData = await discoverService.getPluginByIds(locale, config.plugins);
}
// let pluginData: DiscoverPlugintem[] = [];
// if (config?.plugins && config.plugins?.length > 0) {
// pluginData = await discoverService.getPluginByIds(locale, config.plugins);
// }
const ld = ldModule.generate({
article: {

@ -6,7 +6,7 @@ import { Flexbox } from 'react-layout-kit';
import Footer from '@/features/Setting/Footer';
import SidebarContainer from './SidebarContainer';
// import SidebarContainer from './SidebarContainer';
interface DetailLayoutProps {
actions?: ReactNode;
@ -36,24 +36,15 @@ const DetailLayout = memo<DetailLayoutProps>(
);
return (
<>
<div style={{ backgroundColor: '#fff'}}>
{header}
<Flexbox gap={32} horizontal width={'100%'}>
<Flexbox flex={1} gap={48} style={{ overflow: 'hidden', position: 'relative' }}>
<Flexbox flex={1} gap={48} style={{ overflow: 'hidden', position: 'relative',padding: '0 30px' }}>
{children}
<Footer />
</Flexbox>
<SidebarContainer>
<Flexbox gap={16} width={'100%'}>
{actions}
{statistics}
</Flexbox>
{sidebar}
</SidebarContainer>
</Flexbox>
</div>
</>
);
},
);

@ -61,7 +61,7 @@ const HighlightBlock = memo<HighlightBlockProps>(({ avatar, title, icon, childre
const { styles } = useStyles();
const mobile = useServerConfigStore((s) => s.isMobile);
return (
<Flexbox className={styles.container} flex={'none'} width={'100%'} {...rest}>
<Flexbox className={styles.container} flex={'none'} width={'100%'} {...rest} style={{marginTop: 20}}>
<Flexbox
align={'center'}
className={styles.header}

@ -9,7 +9,8 @@ import { useTranslation } from 'react-i18next';
import { Flexbox } from 'react-layout-kit';
import { DiscoverModelItem } from '@/types/discover';
import { useRouter } from 'next/navigation';
import { useUserStore } from '@/store/user';
import ModelFeatureTags from '../../../../features/ModelFeatureTags';
import Back from '../../../features/Back';
@ -29,6 +30,38 @@ export const useStyles = createStyles(({ css, token }) => ({
font-weight: bold;
line-height: 1.2;
`,
top: css`
padding: 20px 0px;
box-sizing: border-box;
border-width: 0px 0px 2px 0px;
border-style: solid;
border-color: rgba(187, 204, 253, 0.24);
padding: 20px 50px;
`,
topBtn: css`
border-radius: 20px;
color: #2E62FF;
border: 1px solid #2E62FF;
`,
conTitle: css`
width: 125px;
height: 40px;
line-height: 40px;
text-align: center;
color: #fff;
font-size: 20px;
border-radius: 0px 129px 129px 0px;
opacity: 1;
background: linear-gradient(270deg, #2D65FF 0%, rgba(0, 166, 255, 0.52) 99%);
`,
description: css`
padding: 0 45px;
margin-top: 10px;
`,
tag: css`
padding: 0px 45px;
margin-bottom: 10px;
`,
}));
interface HeaderProps {
@ -39,12 +72,16 @@ interface HeaderProps {
const Header = memo<HeaderProps>(({ identifier, data, mobile }) => {
const { styles, theme } = useStyles();
const router = useRouter()
const { t } = useTranslation(['discover', 'models']);
const getUserId = (s: UserStore) => s.user?.id
const userId = getUserId(useUserStore.getState())
const handleBack = () => {
router.push('/discover/models?userid=' + userId)
}
return (
<Flexbox gap={12} width={'100%'}>
{!mobile && <Back href={'/discover/models'} />}
<Flexbox align={'center'} gap={8} horizontal justify={'space-between'} width={'100%'}>
<Flexbox align={'center'} gap={8} horizontal justify={'space-between'} width={'100%'} className={styles.top}>
<Flexbox align={'center'} gap={16} horizontal justify={'flex-start'}>
<ModelIcon model={identifier} size={48} type={'avatar'} />
<Flexbox gap={2}>
@ -64,20 +101,20 @@ const Header = memo<HeaderProps>(({ identifier, data, mobile }) => {
</Flexbox>
{!mobile && (
<Flexbox align={'center'} gap={4} horizontal justify={'flex-end'}>
<Link href={'/discover/models'}>
<Button className={styles.tag} shape={'round'} size={'small'}>
{t('tab.models')}
</Button>
</Link>
<Button className={styles.topBtn} onClick={() => handleBack()}></Button>
</Flexbox>
)}
</Flexbox>
{data.meta.description && <div>{t(`${identifier}.description`, { ns: 'models' })}</div>}
<div className={styles.conTitle}></div>
{data.meta.description && <div className={styles.description}>{t(`${identifier}.description`, { ns: 'models' })}</div>}
<div className={styles.tag}>
<ModelFeatureTags
functionCall={data.meta.functionCall}
tokens={data.meta.tokens}
vision={data.meta.vision}
/>
</div>
<div className={styles.conTitle}></div>
</Flexbox>
);
});

@ -95,10 +95,10 @@ const Page = async ({ params, searchParams }: Props) => {
<>
<StructuredData ld={ld} />
<DetailLayout
actions={<Actions data={data} identifier={identifier} providerData={providerData} />}
// actions={<Actions data={data} identifier={identifier} providerData={providerData} />}
header={<Header data={data} identifier={identifier} mobile={mobile} />}
mobile={mobile}
sidebar={<InfoSidebar data={data} identifier={identifier} mobile={mobile} />}
// sidebar={<InfoSidebar data={data} identifier={identifier} mobile={mobile} />}
/* ↓ cloud slot ↓ */
/* ↑ cloud slot ↑ */

@ -11,11 +11,11 @@ import { memo } from 'react';
import { useTranslation } from 'react-i18next';
import { Flexbox } from 'react-layout-kit';
import urlJoin from 'url-join';
import { useUserStore } from '@/store/user';
import { useRouter } from 'next/navigation';
import { DiscoverPlugintem } from '@/types/discover';
import Back from '../../../features/Back';
export const useStyles = createStyles(({ css, token }) => ({
tag: css`
color: ${token.colorTextSecondary};
@ -32,6 +32,38 @@ export const useStyles = createStyles(({ css, token }) => ({
font-weight: bold;
line-height: 1.2;
`,
top: css`
padding: 20px 0px;
box-sizing: border-box;
border-width: 0px 0px 2px 0px;
border-style: solid;
border-color: rgba(187, 204, 253, 0.24);
padding: 20px 50px;
`,
topBtn: css`
border-radius: 20px;
color: #2E62FF;
border: 1px solid #2E62FF;
`,
conTitle: css`
width: 125px;
height: 40px;
line-height: 40px;
text-align: center;
color: #fff;
font-size: 20px;
border-radius: 0px 129px 129px 0px;
opacity: 1;
background: linear-gradient(270deg, #2D65FF 0%, rgba(0, 166, 255, 0.52) 99%);
`,
description: css`
padding: 0 45px;
margin-top: 10px;
`,
tag: css`
padding: 0px 45px;
margin-bottom: 10px;
`,
}));
interface HeaderProps {
@ -42,12 +74,16 @@ interface HeaderProps {
const Header = memo<HeaderProps>(({ identifier, data, mobile }) => {
const { styles, theme } = useStyles();
const router = useRouter()
const { t } = useTranslation('discover');
const getUserId = (s: UserStore) => s.user?.id
const userId = getUserId(useUserStore.getState())
const handleBack = () => {
router.push('/discover/plugins?userid=' + userId)
}
return (
<Flexbox gap={12} width={'100%'}>
{!mobile && <Back href={'/discover/plugins'} />}
<Flexbox align={'center'} gap={8} horizontal justify={'space-between'} width={'100%'}>
<Flexbox align={'center'} gap={8} horizontal justify={'space-between'} width={'100%'} className={styles.top}>
<Flexbox align={'center'} gap={16} horizontal justify={'flex-start'}>
<Avatar
alt={identifier}
@ -71,42 +107,24 @@ const Header = memo<HeaderProps>(({ identifier, data, mobile }) => {
</Flexbox>
{!mobile && (
<Flexbox align={'center'} gap={4} horizontal justify={'flex-end'}>
<Link href={'/discover/plugins'}>
<Button className={styles.tag} shape={'round'} size={'small'}>
{t('tab.plugins')}
</Button>
</Link>
{data.meta?.category && (
<>
<Icon color={theme.colorTextSecondary} icon={ChevronRight} />
<Link href={urlJoin('/discover/plugins', data.meta?.category || '')}>
<Button className={styles.tag} shape={'round'} size={'small'}>
{t(`category.plugin.${data.meta?.category}` as any)}
</Button>
</Link>
</>
)}
<Button className={styles.topBtn} onClick={() => handleBack()}></Button>
</Flexbox>
)}
</Flexbox>
<div>{data.meta.description}</div>
<div className={styles.conTitle}></div>
<div className={styles.description}>{data.meta.description}</div>
<div className={styles.tag}>
{data.meta.tags && (
<Flexbox gap={4} horizontal wrap={'wrap'}>
{data.meta.tags.map((tag) => (
<Link
href={qs.stringifyUrl({
query: { q: tag },
url: '/discover/search',
})}
key={tag}
>
<Tag key={tag} style={{ margin: 0 }}>
{startCase(tag).trim()}
</Tag>
</Link>
))}
</Flexbox>
)}
</div>
<div className={styles.conTitle}></div>
</Flexbox>
);
});

@ -84,10 +84,10 @@ const Page = async ({ params, searchParams }: Props) => {
<>
<StructuredData ld={ld} />
<DetailLayout
actions={<Actions data={data} identifier={identifier} />}
// actions={<Actions data={data} identifier={identifier} />}
header={<Header data={data} identifier={identifier} mobile={mobile} />}
mobile={mobile}
sidebar={<InfoSidebar data={data} identifier={identifier} mobile={mobile} />}
// sidebar={<InfoSidebar data={data} identifier={identifier} mobile={mobile} />}
/* ↓ cloud slot ↓ */
/* ↑ cloud slot ↑ */

@ -32,45 +32,7 @@ const Page = async ({ params, searchParams }: Props) => {
const mobile = isMobileDevice();
const discoverService = new DiscoverService();
console.log(params.slug,3333333)
let items;
if(params.slug == "collect") {
const res = await request({
url: "/flxai/api/robot/appaiassistant/getAllAiAssistant",
method: "get",
params: {
userid: searchParams.userid
}
})
items = res.data;
items = items.map((item,index)=> {
item.classify = 'collect';
return item
})
} else {
const res = await request({
url: "/flxai/api/robot/appaiassistant/getAllAiAssistant",
method: "get",
params: {
userid: searchParams.userid
}
})
const array2Object = {};
res?.data?.forEach(item => {
array2Object[item.identifier] = item;
});
items = await discoverService.getAssistantCategory(locale, params.slug);
items = items.map((item,index)=> {
const matchingItem = array2Object[item.identifier];
if (matchingItem) {
console.log('3838383838',matchingItem);
matchingItem.status = '1';
return matchingItem
} else {
item.status = '0';
return item
}
})
}
const items = await discoverService.getAssistantCategory(locale, params.slug);
console.log(8272772727,items)
const ld = ldModule.generate({
description: t('discover.assistants.description'),

@ -13,6 +13,8 @@ import CardBanner from '../../../components/CardBanner';
import GitHubAvatar from '../../../components/GitHubAvatar';
import { useCategoryItem } from '../../assistants/features/useCategory';
import { StarOutlined } from '@ant-design/icons';
import { useUserStore } from '@/store/user';
import { useTranslation } from 'react-i18next';
const Link = dynamic(() => import('next/link'), {
loading: () => <Skeleton.Button size={'small'} style={{ height: 22 }} />,
ssr: false,
@ -80,12 +82,15 @@ const AssistantCard = memo<AssistantCardProps>(
const { avatar, title, description, tags = [], category } = meta;
const { createAt,homepage,identifier,schemaVersion,status,classify } = {...rest}
const { cx, styles, theme } = useStyles();
const { t } = useTranslation('discover');
const { message } = App.useApp();
const categoryItem = useCategoryItem(category, 12);
const isCompact = variant === 'compact';
const getUserId = (s: UserStore) => s.user?.id
const userId = getUserId(useUserStore.getState())
// console.log(tags,avatar,author,9383737)
console.log(status,9999999999)
const [val, setVal] = useState(status)
console.log(userId,9999999999)
const [val, setVal] = useState('')
const handleCollect = (e) => {
console.log(e,8844848)
e.preventDefault()
@ -102,7 +107,7 @@ const AssistantCard = memo<AssistantCardProps>(
"title": title,
"category": category,
"schemaVersion": schemaVersion,
"userid": localStorage.getItem('userId'),
"userid": userId,
}
request({
url: "/flxai/api/robot/appaiassistant",
@ -111,7 +116,7 @@ const AssistantCard = memo<AssistantCardProps>(
}).then(response => {
console.log(response,222222222)
if (response.code == 0) {
message.success('收藏成功')
message.success(t('collectSuccess'));
setVal("1")
}
}).catch(error => {
@ -131,7 +136,7 @@ const AssistantCard = memo<AssistantCardProps>(
);
const renderElement = () => {
if (classify != 'collect') {
if(val == "1") {
if(status == "1" || val == "1") {
return <div className={styles.collectBtn} onClick={(e) => {e.stopPropagation()}}><StarOutlined style={{color: '#FFAD01'}}/></div>
} else {
return <div className={styles.collectBtn} style={{background: '#F1F1F1'}} onClick={(e) => handleCollect(e)}><StarOutlined style={{color: '#D6D6D6'}}/></div>

@ -7,7 +7,7 @@ import urlJoin from 'url-join';
import { useQueryRoute } from '@/hooks/useQueryRoute';
import { AssistantCategory } from '@/types/discover';
import { useUserStore } from '@/store/user';
import CategoryMenu from '../../../components/CategoryMenu';
import { useCategory } from './useCategory';
@ -21,7 +21,9 @@ const Category = memo(() => {
return 'all';
}, [pathname]);
const router = useQueryRoute();
const getUserId = (s: UserStore) => s.user?.id
const userId = getUserId(useUserStore.getState())
console.log(userId,'category333333')
return (
<CategoryMenu
items={items.map((item: any) => ({
@ -30,7 +32,7 @@ const Category = memo(() => {
<Link
href={urlJoin(
'/discover/assistants',
item.key === AssistantCategory.All ? '' : item.key + '?userid=' + localStorage.getItem('userId'),
item.key === AssistantCategory.All ? '' : item.key + '?userid=' + userId,
)}
>
{item.label}
@ -38,7 +40,7 @@ const Category = memo(() => {
),
}))}
onSelect={({ key }) => {
router.push(urlJoin('/discover/assistants', key === AssistantCategory.All ? '' : key + '?userid=' + localStorage.getItem('userId')));
router.push(urlJoin('/discover/assistants', key === AssistantCategory.All ? '' : key + '?userid=' + userId));
}}
selectedKeys={[selectedKey || 'all']}
/>

@ -3,7 +3,7 @@
import { Grid } from '@lobehub/ui';
import {Button, Empty, Image, Tag} from 'antd';
import Link from 'next/link';
import {memo, useMemo, useState} from 'react';
import {memo, useMemo, useEffect, useState} from 'react';
import { useTranslation } from 'react-i18next';
import urlJoin from 'url-join';
import { useRouter } from 'next/navigation';
@ -13,8 +13,8 @@ import SearchResultCount from '../../../components/SearchResultCount';
import Title from '../../../components/Title';
import VirtuosoGridList from '../../../components/VirtuosoGridList';
import Card from './Card';
import {createStyles} from "antd-style";
import request from '@/app/api/request';
import { useUserStore } from '@/store/user';
export interface ListProps {
category?: string;
items?: DiscoverAssistantItem[];
@ -22,133 +22,69 @@ export interface ListProps {
searchKeywords?: string;
}
const useStyles = createStyles(({css, token}) => ({
top: css`
padding: 20px 0px;
box-sizing: border-box;
border-width: 0px 0px 2px 0px;
border-style: solid;
border-color: rgba(187, 204, 253, 0.24);
padding: 20px 50px;
`,
topFirAc: css`
width: 86px;
height: 86px;
display: inline-block;
border-radius: 86px;
border: 4px solid #6D94FF;
`,
topSecAc: css`
width: 60px;
height: 60px;
border-radius: 60px;
margin: 9px;
text-align: center;
line-height: 50px;
font-size: 26px;
border: 4px solid #6D94FF;
`,
topBtn: css`
border-radius: 20px;
color: #2E62FF;
border: 1px solid #2E62FF;
`,
topRight: css`
width: 50%;
text-align: right;
display: inline-block
`,
topLeft: css`
width: 50%;
display: inline-block
`,
title: css`
display: inline-block;
vertical-align: middle;
margin-top: -10px;
margin-left: 25px
`,
des: css`
margin-top: 5px;
font-size: 12px;
color: #999
`,
desImg: css`
margin: 0px 5px;
width: 20px
`,
time: css`
display: inline-block;
margin-left: 5px
`,
conTitle: css`
margin: 12px 0;
width: 125px;
height: 50px;
line-height: 50px;
text-align: center;
color: #fff;
font-size: 20px;
border-radius: 0px 129px 129px 0px;
opacity: 1;
background: linear-gradient(270deg, #2D65FF 0%, rgba(0, 166, 255, 0.52) 99%);
`,
description: css`
padding: 20px 50px;
`,
tag: css`
padding: 0px 50px;
margin-bottom: 20px;
`,
set: css`
padding: 0px 30px 20px;
`,
setBtn: css`
background: #EDF2FF;
width: 80px;
border-radius: 40px;
color: #0044FF;
`,
setText: css`
padding: 0px 50px 20px;
`,
setOl: css`
display: inline-block;
width: 8px;
height: 8px;
background: #0044FF;
margin-right: 10px;
`,
rwDes: css`
padding: 0px 70px 20px;
`,
}))
const List = memo<ListProps>(({ category, mobile, searchKeywords, items = [] }) => {
const { t } = useTranslation('discover');
const { styles, cx } = useStyles()
const router = useRouter()
const { all, recent, last } = useMemo(() => {
const [stData, setStData] = useState(items)
const recentLength = mobile ? 4 : 8;
const getUserId = (s: UserStore) => s.user?.id
const userId = getUserId(useUserStore.getState())
console.log(userId,'zhushou---3837373266262266')
console.log('zhushou--------------',items)
const { all, recent, last } = useMemo(() => {
return {
all: items,
last: items.slice(recentLength),
recent: items.slice(0, recentLength),
all: stData,
last: stData.slice(recentLength),
recent: stData.slice(0, recentLength),
};
}, [stData, mobile]);
useEffect(() => {
const fetchData = async() => {
if(category == "collect") {
const res = await request({
url: "/flxai/api/robot/appaiassistant/getAllAiAssistant",
method: "get",
params: {
userid: userId
}
})
setStData(res?.data.map((item,index)=> {
item.classify = 'collect';
return item
}))
} else {
const res = await request({
url: "/flxai/api/robot/appaiassistant/getAllAiAssistant",
method: "get",
params: {
userid: userId
}
})
const array2Object = {};
res?.data?.forEach((item) => {
array2Object[item.identifier] = item;
});
console.log('chajian22222222222222222222222222222--------------')
setStData(stData.map((item,index)=> {
const matchingItem = array2Object[item.identifier];
if (matchingItem) {
matchingItem.status = '1';
return matchingItem
} else {
item.status = '0';
return item
}
}))
}
};
}, [items, mobile]);
fetchData();
}, []); // 空数组[]意味着仅在组件挂载时调用一次
console.log(category,recent,last,92929292)
const [val, setVal] = useState("")
const handleClickCard = (item) => {
console.log(item)
setVal(item)
router.push(urlJoin('/discover/assistant/', item.identifier))
}
const handleBack = () => {
setVal("")
}
if (searchKeywords) {
if (!items || items?.length === 0) return <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />;
return (

@ -5,7 +5,6 @@ import { metadataModule } from '@/server/metadata';
import { DiscoverService } from '@/server/services/discover';
import { translation } from '@/server/translation';
import { isMobileDevice } from '@/utils/responsive';
import request from '@/app/api/request';
import List from './features/List';
import urlJoin from 'url-join';
type Props = { searchParams: { hl?: Locales } };
@ -27,31 +26,7 @@ const Page = async ({ searchParams }: Props) => {
const mobile = isMobileDevice();
const discoverService = new DiscoverService();
console.log(searchParams,22222222222)
const res = await request({
url: "/flxai/api/robot/appaiassistant/getAllAiAssistant",
method: "get",
params: {
userid: searchParams.userid
}
})
console.log(res,4322222)
const array2Object = {};
res?.data?.forEach(item => {
array2Object[item.identifier] = item;
});
let items = await discoverService.getAssistantList(locale);
console.log(8272772727,'jiangxucong')
items = items.map((item,index)=> {
const matchingItem = array2Object[item.identifier];
if (matchingItem) {
console.log('5959595959',matchingItem);
matchingItem.status = '1';
return matchingItem
} else {
item.status = '0';
return item
}
})
const items = await discoverService.getAssistantList(locale);
const ld = ldModule.generate({
description: t('discover.assistants.description'),
title: t('discover.assistants.title'),

@ -9,14 +9,13 @@ import { DiscoverService } from '@/server/services/discover';
import { translation } from '@/server/translation';
import { AssistantCategory } from '@/types/discover';
import { isMobileDevice } from '@/utils/responsive';
import List from '../features/List';
type Props = { params: { slug: AssistantCategory }; searchParams: { hl?: Locales } };
export const generateMetadata = async ({ params, searchParams }: Props) => {
const { t, locale } = await translation('metadata', searchParams?.hl);
console.log('jiangxucong---model----------------------------')
const discoverService = new DiscoverService();
const list = await discoverService.getProviderList(locale);
const cate = list.find((cate) => cate.identifier === params.slug);
@ -37,12 +36,12 @@ const Page = async ({ params, searchParams }: Props) => {
const discoverService = new DiscoverService();
const list = await discoverService.getProviderList(locale);
const cate = list.find((cate) => cate.identifier === params.slug);
console.log(params.slug,3333333)
const items = await discoverService.getModelCategory(locale, params.slug);
const ld = ldModule.generate({
description: t('discover.models.description'),
title: [cate?.meta.title, t('discover.models.title')].join(' · '),
url: urlJoin('/discover/models', params.slug),
url: urlJoin('/discover/models', params.slug + '?userid=' + searchParams.userid),
webpage: {
enable: true,
search: '/discover/search',

@ -1,14 +1,14 @@
import { ModelIcon } from '@lobehub/icons';
import { Typography } from 'antd';
import { Typography, App } from 'antd';
import { createStyles } from 'antd-style';
import { memo } from 'react';
import { memo, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { Flexbox, FlexboxProps } from 'react-layout-kit';
import { useUserStore } from '@/store/user';
import { DiscoverModelItem } from '@/types/discover';
import { StarOutlined } from '@ant-design/icons';
import ModelFeatureTags from '../../../features/ModelFeatureTags';
import request from '@/app/api/request';
const { Paragraph, Title } = Typography;
const useStyles = createStyles(({ css, token, isDarkMode }) => ({
@ -65,17 +65,79 @@ const useStyles = createStyles(({ css, token, isDarkMode }) => ({
token: css`
font-family: ${token.fontFamilyCode};
`,
collectBtn: css`
font-size: 12px;
width: 20px;
height: 20px;
line-height: 20px;
border-radius: 50%;
background: #FFF3D9;
text-align: center;
`,
}));
export interface ModelCardProps extends DiscoverModelItem, FlexboxProps {
showCategory?: boolean;
}
const ModelCard = memo<ModelCardProps>(({ className, meta, identifier, ...rest }) => {
const { description, title, functionCall, vision, tokens } = meta;
const ModelCard = memo<ModelCardProps>(({ className, meta, socialData, identifier, ...rest }) => {
const { title, description, functionCall, vision, tokens, category, id, displayName, enabled } = meta;
const { conversations, likes, tokens: socialDataToken } = socialData;
// console.log(socialDataToken,"7373736262626----------------------------",meta)
const { createdAt, providers, suggestions, status, classify } = {...rest}
const { t } = useTranslation('models');
const { t:d } = useTranslation('discover');
const { cx, styles } = useStyles();
const { message } = App.useApp();
const getUserId = (s: UserStore) => s.user?.id
const userId = getUserId(useUserStore.getState())
const [val, setVal] = useState(status)
const handleCollect = (e) => {
console.log(e,8844848)
e.preventDefault()
e.stopPropagation()
const params = {
"identifier": identifier,
"metaId": id,
"displayname": displayName,
"description": description,
"title": title,
"conversations": conversations,
"enabled": enabled,
"metaTokens": tokens,
"createdAt": createdAt,
"tokens": socialDataToken,
"suggestions": suggestions.join(','),
"category": category,
"providers": providers.join(','),
"likes": likes,
"userid": userId,
}
request({
url: "/flxai/api/robot/appaimodel",
method: "post",
data: params
}).then(response => {
console.log(response,222222222)
if (response.code == 0) {
message.success(d('collectSuccess'));
setVal("1")
}
}).catch(error => {
console.error('Error fetching data: ', error);
})
}
const renderElement = () => {
if (classify != 'collect') {
if(val == "1") {
return <div className={styles.collectBtn} onClick={(e) => {e.stopPropagation()}}><StarOutlined style={{color: '#FFAD01'}}/></div>
} else {
return <div className={styles.collectBtn} style={{background: '#F1F1F1'}} onClick={(e) => handleCollect(e)}><StarOutlined style={{color: '#D6D6D6'}}/></div>
}
} else {
return;
}
};
return (
<Flexbox className={cx(styles.container, className)} gap={24} key={identifier} {...rest}>
<Flexbox
@ -106,8 +168,10 @@ const ModelCard = memo<ModelCardProps>(({ className, meta, identifier, ...rest }
{t(`${identifier}.description`)}
</Paragraph>
)}
<Flexbox gap={6} horizontal style={{ flexWrap: 'wrap',justifyContent: 'space-between' }}>
<ModelFeatureTags functionCall={functionCall} tokens={tokens} vision={vision} />
{renderElement()}
</Flexbox>
</Flexbox>
</Flexbox>
);

@ -4,13 +4,13 @@ import { ProviderIcon } from '@lobehub/icons';
import { Icon } from '@lobehub/ui';
import { MenuProps } from 'antd';
import { useTheme } from 'antd-style';
import { LayoutPanelTop } from 'lucide-react';
import { LayoutPanelTop,Star } from 'lucide-react';
import Link from 'next/link';
import { usePathname } from 'next/navigation';
import { memo, useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import urlJoin from 'url-join';
import { useUserStore } from '@/store/user';
import { useQueryRoute } from '@/hooks/useQueryRoute';
import { DiscoverProviderItem } from '@/types/discover';
@ -26,20 +26,26 @@ const Category = memo<{ data: DiscoverProviderItem[] }>(({ data }) => {
}, [pathname]);
const router = useQueryRoute();
const theme = useTheme();
const getUserId = (s: UserStore) => s.user?.id
const userId = getUserId(useUserStore.getState())
const { t } = useTranslation('discover');
const items: MenuProps['items'] = [
{
icon: <Icon color={theme.colorTextSecondary} icon={LayoutPanelTop} size={ICON_SIZE} />,
icon: <Icon color="#003BFF" icon={LayoutPanelTop} size={ICON_SIZE} />,
key: 'all',
label: t('category.plugin.all'),
},
{
icon: <Icon color="#FFAD01" icon={Star} size={ICON_SIZE} />,
key: 'collect',
label: t('category.plugin.collect'),
},
...data.map((item) => ({
icon: (
<ProviderIcon
provider={item.identifier}
size={18}
style={{ color: theme.colorTextSecondary }}
style={{ color: "#2A4DFF" }}
type={'mono'}
/>
),

@ -5,14 +5,15 @@ import Link from 'next/link';
import { memo } from 'react';
import { useTranslation } from 'react-i18next';
import urlJoin from 'url-join';
import { useRouter } from 'next/navigation';
import { DiscoverModelItem } from '@/types/discover';
import { Grid } from '@lobehub/ui';
import SearchResultCount from '../../../components/SearchResultCount';
import Title from '../../../components/Title';
import VirtuosoGridList from '../../../components/VirtuosoGridList';
import Card from './Card';
import request from '@/app/api/request';
import { useUserStore } from '@/store/user';
export interface ListProps {
category?: string;
items?: DiscoverModelItem[];
@ -20,9 +21,54 @@ export interface ListProps {
searchKeywords?: string;
}
const List = memo<ListProps>(({ category, searchKeywords, items = [] }) => {
const List = memo<ListProps>(async ({ category, searchKeywords, items = [] }) => {
const { t } = useTranslation('discover');
const router = useRouter()
const getUserId = (s: UserStore) => s.user?.id
const userId = getUserId(useUserStore.getState())
console.log(userId,'models---3837373266262266')
console.log('models---99999999',items)
if(category == "collect") {
const res = await request({
url: "/flxai/api/robot/appaimodel/getAllAiModel",
method: "get",
params: {
userid: userId
}
})
items = res.data;
items = items.map((item,index)=> {
item.classify = 'collect';
return item
})
} else {
const res = await request({
url: "/flxai/api/robot/appaimodel/getAllAiModel",
method: "get",
params: {
userid: userId
}
})
const array2Object = {};
res?.data?.forEach(item => {
array2Object[item.identifier] = item;
});
items = items.map((item,index)=> {
const matchingItem = array2Object[item.identifier];
if (matchingItem) {
console.log('3838383838',matchingItem);
matchingItem.status = '1';
return matchingItem
} else {
item.status = '0';
return item
}
})
}
const handleClickCard = (item) => {
console.log(item)
router.push(urlJoin('/discover/model/', item.identifier))
}
if (searchKeywords) {
if (!items || items?.length === 0) return <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />;
return (
@ -32,9 +78,9 @@ const List = memo<ListProps>(({ category, searchKeywords, items = [] }) => {
data={items}
initialItemCount={24}
itemContent={(_, item) => (
<Link href={urlJoin('/discover/model/', item.identifier)} key={item.identifier}>
<Card showCategory {...item} />
</Link>
// <Link href={urlJoin('/discover/model/', item.identifier)} key={item.identifier}>
<Card onClick={() => handleClickCard(item)} showCategory {...item} />
// </Link>
)}
style={{
minHeight: '75vh',
@ -45,21 +91,36 @@ const List = memo<ListProps>(({ category, searchKeywords, items = [] }) => {
}
return (
<>
{category == "collect"?(
<>
<Title tag={items.length}></Title>
<Grid maxItemWidth={280} rows={4}>
{items.map((item) => (
// <Link href={urlJoin('/discover/assistant/', item.identifier)} key={item.identifier}>
<Card onClick={() => handleClickCard(item)} showCategory={!category} {...item} />
// </Link>
))}
</Grid>
</>
):(
<>
<Title tag={items.length}>{t('models.list')}</Title>
<VirtuosoGridList
data={items}
initialItemCount={24}
itemContent={(_, item) => (
<Link href={urlJoin('/discover/model/', item.identifier)} key={item.identifier}>
<Card showCategory={!category} {...item} />
</Link>
// <Link href={urlJoin('/discover/model/', item.identifier)} key={item.identifier}>
<Card onClick={() => handleClickCard(item)} showCategory={!category} {...item} />
// </Link>
)}
style={{
minHeight: '75vh',
}}
/>
</>
)}
</>
);
});

@ -8,7 +8,7 @@ import { translation } from '@/server/translation';
import { isMobileDevice } from '@/utils/responsive';
import List from './features/List';
import urlJoin from 'url-join';
type Props = { searchParams: { hl?: Locales } };
export const generateMetadata = async ({ searchParams }: Props) => {
@ -26,14 +26,14 @@ export const generateMetadata = async ({ searchParams }: Props) => {
const Page = async ({ searchParams }: Props) => {
const { t, locale } = await translation('metadata', searchParams?.hl);
const mobile = isMobileDevice();
const discoverService = new DiscoverService();
const items = await discoverService.getModelList(locale);
console.log(8272772727,'jiangxucong')
const ld = ldModule.generate({
description: t('discover.models.description'),
title: t('discover.models.title'),
url: '/discover/models',
url: urlJoin('/discover/models?userid=',searchParams.userid),
webpage: {
enable: true,
search: '/discover/search',

@ -8,7 +8,6 @@ import { DiscoverService } from '@/server/services/discover';
import { translation } from '@/server/translation';
import { PluginCategory } from '@/types/discover';
import { isMobileDevice } from '@/utils/responsive';
import List from '../features/List';
type Props = { params: { slug: PluginCategory }; searchParams: { hl?: Locales } };
@ -30,14 +29,12 @@ const Page = async ({ params, searchParams }: Props) => {
const { t, locale } = await translation('metadata', searchParams?.hl);
const { t: td } = await translation('discover', searchParams?.hl);
const mobile = isMobileDevice();
const discoverService = new DiscoverService();
const items = await discoverService.getPluginCategory(locale, params.slug);
const ld = ldModule.generate({
description: t('discover.plugins.description'),
title: [td(`category.plugin.${params.slug}`), t('discover.plugins.title')].join(' · '),
url: urlJoin('/discover/plugins', params.slug),
url: urlJoin('/discover/plugins', params.slug + '?userid=' + searchParams.userid),
webpage: {
enable: true,
search: '/discover/search',

@ -1,18 +1,19 @@
import { Avatar, Tag } from '@lobehub/ui';
import { Skeleton, Typography } from 'antd';
import { Skeleton, Typography, App } from 'antd';
import { createStyles } from 'antd-style';
import { startCase } from 'lodash-es';
import dynamic from 'next/dynamic';
import qs from 'query-string';
import { memo } from 'react';
import { memo, useState } from 'react';
import { Center, Flexbox, FlexboxProps } from 'react-layout-kit';
import urlJoin from 'url-join';
import { useTranslation } from 'react-i18next';
import { DiscoverPlugintem } from '@/types/discover';
import { useUserStore } from '@/store/user';
import CardBanner from '../../../components/CardBanner';
import { useCategoryItem } from './useCategory';
import { StarOutlined } from '@ant-design/icons';
import request from '@/app/api/request';
const Link = dynamic(() => import('next/link'), {
loading: () => <Skeleton.Button size={'small'} style={{ height: 22 }} />,
ssr: false,
@ -61,6 +62,15 @@ const useStyles = createStyles(({ css, token, isDarkMode }) => ({
font-size: 18px !important;
font-weight: bold;
`,
collectBtn: css`
font-size: 12px;
width: 20px;
height: 20px;
line-height: 20px;
border-radius: 50%;
background: #FFF3D9;
text-align: center;
`,
}));
interface PluginCardProps
@ -73,10 +83,63 @@ interface PluginCardProps
const PluginCard = memo<PluginCardProps>(
({ className, showCategory, meta, createdAt, author, variant, ...rest }) => {
const { avatar, title, description, tags = [], category } = meta;
const { createAt, homepage, identifier, schemaVersion, status, classify, manifest,locale } = {...rest}
const categoryItem = useCategoryItem(category, 12);
const { cx, styles, theme } = useStyles();
const { t } = useTranslation('discover');
const { message } = App.useApp();
const isCompact = variant === 'compact';
const getUserId = (s: UserStore) => s.user?.id
const userId = getUserId(useUserStore.getState())
console.log(status,"9383737-------------------------------------")
console.log(manifest,locale,"plugins9999999999-------------------")
const [val, setVal] = useState('')
const handleCollect = (e) => {
console.log(e,8844848)
e.preventDefault()
e.stopPropagation()
const params = {
"author": author,
"createdAt": createdAt,
"homepage": homepage,
"identifier": identifier,
"avatar": avatar,
"description": description,
"tags": tags.join(','),
"title": title,
"category": category,
"schemaVersion": schemaVersion,
"manifest": manifest,
"locale": locale,
"userid": userId,
}
request({
url: "/flxai/api/robot/appaiplugin",
method: "post",
data: params
}).then(response => {
console.log(response,222222222)
if (response.code == 0) {
message.success(t('collectSuccess'));
setVal("1")
}
}).catch(error => {
console.error('Error fetching data: ', error);
})
}
const renderElement = () => {
console.log(classify,'66666----------------------')
if (classify != 'collect') {
console.log(status,"222222222--------------------------")
if(status == "1" || val == "1") {
return <div className={styles.collectBtn} onClick={(e) => {e.stopPropagation()}}><StarOutlined style={{color: '#FFAD01'}}/></div>
} else {
return <div className={styles.collectBtn} style={{background: '#F1F1F1'}} onClick={(e) => handleCollect(e)}><StarOutlined style={{color: '#D6D6D6'}}/></div>
}
} else {
return;
}
};
return (
<Flexbox className={cx(styles.container, className)} gap={24} {...rest}>
{!isCompact && <CardBanner avatar={avatar} />}
@ -121,13 +184,12 @@ const PluginCard = memo<PluginCardProps>(
<Paragraph className={styles.desc} ellipsis={{ rows: 2 }}>
{description}
</Paragraph>
<Flexbox gap={6} horizontal style={{ flexWrap: 'wrap' }}>
<Flexbox gap={6} horizontal style={{ flexWrap: 'wrap',justifyContent: 'space-between' }}>
<div onClick={(e) => {e.stopPropagation()}} style={{width: '85%'}}>
{showCategory && categoryItem ? (
<Link href={urlJoin('/discover/plugins', categoryItem.key)}>
<Tag icon={categoryItem.icon} style={{ margin: 0 }}>
<Tag icon={categoryItem.icon} style={{ margin: '0 5' }}>
{categoryItem.label}
</Tag>
</Link>
) : (
tags
.slice(0, 4)
@ -138,12 +200,12 @@ const PluginCard = memo<PluginCardProps>(
url: '/discover/search',
});
return (
<Link href={url} key={index}>
<Tag style={{ margin: 0 }}>{startCase(tag).trim()}</Tag>
</Link>
<Tag style={{ margin: '0 5' }}>{startCase(tag).trim()}</Tag>
);
})
)}
</div>
{renderElement()}
</Flexbox>
</Flexbox>
</Flexbox>

@ -7,7 +7,7 @@ import urlJoin from 'url-join';
import { useQueryRoute } from '@/hooks/useQueryRoute';
import { PluginCategory } from '@/types/discover';
import { useUserStore } from '@/store/user';
import CategoryMenu from '../../../components/CategoryMenu';
import { useCategory } from './useCategory';
@ -21,7 +21,8 @@ const Category = memo(() => {
return 'all';
}, [pathname]);
const router = useQueryRoute();
const getUserId = (s: UserStore) => s.user?.id
const userId = getUserId(useUserStore.getState())
return (
<CategoryMenu
items={items.map((item: any) => ({

@ -3,17 +3,18 @@
import { Grid } from '@lobehub/ui';
import { Empty } from 'antd';
import Link from 'next/link';
import { memo, useMemo } from 'react';
import { memo, useMemo, useEffect,useState } from 'react';
import { useTranslation } from 'react-i18next';
import urlJoin from 'url-join';
import { useRouter } from 'next/navigation';
import { DiscoverPlugintem } from '@/types/discover';
import SearchResultCount from '../../../components/SearchResultCount';
import Title from '../../../components/Title';
import VirtuosoGridList from '../../../components/VirtuosoGridList';
import Card from './Card';
import request from '@/app/api/request';
import { useUserStore } from '@/store/user';
export interface ListProps {
category?: string;
items: DiscoverPlugintem[];
@ -23,14 +24,68 @@ export interface ListProps {
const List = memo<ListProps>(({ category, mobile, searchKeywords, items = [] }) => {
const { t } = useTranslation('discover');
const router = useRouter()
const [stData, setStData] = useState(items)
const recentLength = mobile ? 4 : 8;
const getUserId = (s: UserStore) => s.user?.id
const userId = getUserId(useUserStore.getState())
console.log(userId,'chajian---3837373266262266')
console.log('chajian33333333--------------',items)
const { all, recent, last } = useMemo(() => {
return {
all: items,
last: items.slice(recentLength),
recent: items.slice(0, recentLength),
all: stData,
last: stData.slice(recentLength),
recent: stData.slice(0, recentLength),
};
}, [items, mobile]);
}, [stData, mobile]);
useEffect(() => {
const fetchData = async() => {
if(category == "collect") {
const res = await request({
url: "/flxai/api/robot/appaiplugin/getAllAiPlugin",
method: "get",
params: {
userid: userId
}
})
setStData(res?.data.map((item,index)=> {
item.classify = 'collect';
return item
}))
} else {
const res = await request({
url: "/flxai/api/robot/appaiplugin/getAllAiPlugin",
method: "get",
params: {
userid: userId
}
})
const array2Object = {};
res?.data?.forEach((item) => {
array2Object[item.identifier] = item;
});
console.log('chajian22222222222222222222222222222--------------')
setStData(stData.map((item,index)=> {
const matchingItem = array2Object[item.identifier];
if (matchingItem) {
matchingItem.status = '1';
return matchingItem
} else {
item.status = '0';
return item
}
}))
}
};
fetchData();
}, []); // 空数组[]意味着仅在组件挂载时调用一次
console.log('chajian999999999999999--------------',stData)
const handleClickCard = (item) => {
console.log(item)
router.push(urlJoin('/discover/plugin/', item.identifier))
}
if (searchKeywords) {
if (!items || items?.length === 0) return <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />;
@ -41,9 +96,7 @@ const List = memo<ListProps>(({ category, mobile, searchKeywords, items = [] })
data={all}
initialItemCount={24}
itemContent={(_, item) => (
<Link href={urlJoin('/discover/plugin/', item.identifier)} key={item.identifier}>
<Card showCategory variant={'compact'} {...item} />
</Link>
<Card onClick={() => handleClickCard(item)} showCategory variant={'compact'} {...item} />
)}
style={{
minHeight: '75vh',
@ -54,13 +107,24 @@ const List = memo<ListProps>(({ category, mobile, searchKeywords, items = [] })
}
return (
<>
{category == "collect"?(
<>
<Title tag={all.length}></Title>
<Grid maxItemWidth={280} rows={4}>
{all?.map((item) => (
// <Link href={urlJoin('/discover/assistant/', item.identifier)} key={item.identifier}>
<Card onClick={() => handleClickCard(item)} showCategory={!category} {...item} />
// </Link>
))}
</Grid>
</>
):(
<>
<Title>{t('plugins.recentSubmits')}</Title>
<Grid maxItemWidth={280} rows={4}>
{recent.map((item) => (
<Link href={urlJoin('/discover/plugin/', item.identifier)} key={item.identifier}>
<Card showCategory={!category} {...item} />
</Link>
{recent?.map((item) => (
<Card onClick={() => handleClickCard(item)} showCategory={!category} {...item} />
))}
</Grid>
{last && last?.length > 0 && (
@ -70,9 +134,7 @@ const List = memo<ListProps>(({ category, mobile, searchKeywords, items = [] })
data={last}
initialItemCount={12}
itemContent={(_, item) => (
<Link href={urlJoin('/discover/plugin/', item.identifier)} key={item.identifier}>
<Card showCategory={!category} variant={'compact'} {...item} />
</Link>
<Card onClick={() => handleClickCard(item)} showCategory={!category} variant={'compact'} {...item} />
)}
style={{
minHeight: '75vh',
@ -81,6 +143,8 @@ const List = memo<ListProps>(({ category, mobile, searchKeywords, items = [] })
</>
)}
</>
)}
</>
);
});

@ -37,42 +37,42 @@ export const useCategory = (fontsize?: number) => {
label: t('category.plugin.collect'),
},
{
icon: <Icon color={theme.colorTextSecondary} icon={ImagePlay} size={size} />,
icon: <Icon color="#FF4D4D" icon={ImagePlay} size={size} />,
key: PluginCategory.MediaGenerate,
label: t('category.plugin.media-generate'),
},
{
icon: <Icon color={theme.colorTextSecondary} icon={ScanSearch} size={size} />,
icon: <Icon color="#5BD941" icon={ScanSearch} size={size} />,
key: PluginCategory.WebSearch,
label: t('category.plugin.web-search'),
},
{
icon: <Icon color={theme.colorTextSecondary} icon={Receipt} size={size} />,
icon: <Icon color="#FF34AD" icon={Receipt} size={size} />,
key: PluginCategory.StocksFinance,
label: t('category.plugin.stocks-finance'),
},
{
icon: <Icon color={theme.colorTextSecondary} icon={PocketKnife} size={size} />,
icon: <Icon color="#FF9B06" icon={PocketKnife} size={size} />,
key: PluginCategory.Tools,
label: t('category.plugin.tools'),
},
{
icon: <Icon color={theme.colorTextSecondary} icon={Umbrella} size={size} />,
icon: <Icon color="#0095FF" icon={Umbrella} size={size} />,
key: PluginCategory.LifeStyle,
label: t('category.plugin.life-style'),
},
{
icon: <Icon color={theme.colorTextSecondary} icon={MicroscopeIcon} size={size} />,
icon: <Icon color="#00B0CB" icon={MicroscopeIcon} size={size} />,
key: PluginCategory.ScienceEducation,
label: t('category.plugin.science-education'),
},
{
icon: <Icon color={theme.colorTextSecondary} icon={TwitterIcon} size={size} />,
icon: <Icon color="#E138FF" icon={TwitterIcon} size={size} />,
key: PluginCategory.Social,
label: t('category.plugin.social'),
},
{
icon: <Icon color={theme.colorTextSecondary} icon={Gamepad2} size={size} />,
icon: <Icon color="#0CD66D" icon={Gamepad2} size={size} />,
key: PluginCategory.GamingEntertainment,
label: t('category.plugin.gaming-entertainment'),
},

@ -5,9 +5,8 @@ import { metadataModule } from '@/server/metadata';
import { DiscoverService } from '@/server/services/discover';
import { translation } from '@/server/translation';
import { isMobileDevice } from '@/utils/responsive';
import List from './features/List';
import urlJoin from 'url-join';
type Props = { searchParams: { hl?: Locales } };
export const generateMetadata = async ({ searchParams }: Props) => {
@ -25,14 +24,14 @@ export const generateMetadata = async ({ searchParams }: Props) => {
const Page = async ({ searchParams }: Props) => {
const { t, locale } = await translation('metadata', searchParams?.hl);
const mobile = isMobileDevice();
const discoverService = new DiscoverService();
console.log(searchParams.userid,'plugins555555555555-----------------')
const items = await discoverService.getPluginList(locale);
const ld = ldModule.generate({
description: t('discover.plugins.description'),
title: t('discover.plugins.title'),
url: '/discover/plugins',
url: urlJoin('/discover/plugins?userid=',searchParams.userid),
webpage: {
enable: true,
search: '/discover/search',

@ -9,7 +9,7 @@ const Layout = ({ children }: PropsWithChildren) => {
return (
<>
<NProgress />
<Flexbox height={'100%'} style={{ overflow: 'hidden', position: 'relative' }} width={'100%'}>
<Flexbox height={'100%'} style={{ overflow: 'hidden', position: 'relative',marginTop: '-64px' }} width={'100%'}>
<Header />
{children}
</Flexbox>

@ -13,7 +13,7 @@ import { useQueryRoute } from '@/hooks/useQueryRoute';
import { DiscoverTab } from '@/types/discover';
import { useNav } from './useNav';
import { useUserStore } from '@/store/user';
export const useStyles = createStyles(({ css, prefixCls, token }) => ({
active: css`
box-shadow: ${token.boxShadow};
@ -41,15 +41,16 @@ const StoreSearchBar = memo<StoreSearchBarProps>(({ mobile, onBlur, onFocus, ...
const router = useQueryRoute();
const activeType = activeKey === DiscoverTab.Home ? DiscoverTab.Assistants : activeKey;
const getUserId = (s: UserStore) => s.user?.id
const userId = getUserId(useUserStore.getState())
useEffect(() => {
if (!pathname.includes('/discover/search')) return;
// 使用 useQueryState 时,当 handleSearch 为空时无法回跳
if (!q) router.push(urlJoin('/discover', activeType), { query: { userid: localStorage.getItem('userId') }, replace: true });
if (!q) router.push(urlJoin('/discover', activeType), { query: { userid: userId }, replace: true });
}, [q, pathname, activeType]);
const handleSearch = (value: string) => {
router.push('/discover/search', { query: { q: value, type: activeType, userid: localStorage.getItem('userId') } });
router.push('/discover/search', { query: { q: value, type: activeType, userid: userId } });
};
return (

@ -19,6 +19,7 @@ export default {
try: '试一下',
},
back: '返回发现',
collectSuccess: '收藏成功',
category: {
assistant: {
'all': "全部",

@ -96,7 +96,7 @@ export const createCommonSlice: StateCreator<
data.avatar || data.userId
? merge(get().user, { avatar: data.avatar, id: data.userId })
: get().user;
console.log(user,'777777777777777777777777')
set(
{
defaultSettings,

Loading…
Cancel
Save