From e04d407b2fb8d565190950fe8e0678c344ce021c Mon Sep 17 00:00:00 2001 From: Cats Juice Date: Tue, 8 Jul 2025 21:17:28 +0800 Subject: [PATCH] feat(core): show ai-island and navigate to chat page if not available in sidebar (#13085) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit close AI-318, AI-317 ## Summary by CodeRabbit * **New Features** * Updated the AI chat button label to "AFFiNE Intelligence" and changed its icon for improved clarity. * Enhanced the AI chat button's placement in the sidebar for better accessibility. * Improved the AI chat button’s visibility and interaction logic based on current view and sidebar state. * **Style** * Adjusted button styles to disable interaction when hidden, enhancing user experience. --- .../src/components/root-app-sidebar/index.tsx | 8 ++-- .../desktop/components/ai-island/index.tsx | 38 +++++++++++++++---- .../workbench/view/route-container.css.ts | 2 + 3 files changed, 36 insertions(+), 12 deletions(-) diff --git a/packages/frontend/core/src/components/root-app-sidebar/index.tsx b/packages/frontend/core/src/components/root-app-sidebar/index.tsx index 46b3a1e673..c97a178537 100644 --- a/packages/frontend/core/src/components/root-app-sidebar/index.tsx +++ b/packages/frontend/core/src/components/root-app-sidebar/index.tsx @@ -18,7 +18,7 @@ import { useI18n } from '@affine/i18n'; import { track } from '@affine/track'; import type { Store } from '@blocksuite/affine/store'; import { - AiIcon, + AiOutlineIcon, AllDocsIcon, ImportIcon, JournalIcon, @@ -97,8 +97,8 @@ const AIChatButton = () => { ); return ( - } active={aiChatActive} to={'/chat'}> - Intelligent + } active={aiChatActive} to={'/chat'}> + AFFiNE Intelligence ); }; @@ -198,10 +198,10 @@ export const RootAppSidebar = memo((): ReactElement => { /> - {sessionStatus === 'authenticated' && } + } diff --git a/packages/frontend/core/src/desktop/components/ai-island/index.tsx b/packages/frontend/core/src/desktop/components/ai-island/index.tsx index a40c106583..61e56847c2 100644 --- a/packages/frontend/core/src/desktop/components/ai-island/index.tsx +++ b/packages/frontend/core/src/desktop/components/ai-island/index.tsx @@ -1,12 +1,17 @@ import { WorkbenchService } from '@affine/core/modules/workbench'; import { useLiveData, useService } from '@toeverything/infra'; import clsx from 'clsx'; -import { useEffect, useState } from 'react'; +import { useCallback, useEffect, useState } from 'react'; import { IslandContainer } from './container'; import { AIIcon } from './icons'; import { aiIslandBtn, aiIslandWrapper, toolStyle } from './styles.css'; +const hideChat: Array boolean)> = [ + '/chat', + path => path.includes('attachments'), +]; + export const AIIsland = () => { // to make sure ai island is hidden first and animate in const [hide, setHide] = useState(true); @@ -16,12 +21,33 @@ export const AIIsland = () => { const haveChatTab = useLiveData( activeView.sidebarTabs$.map(tabs => tabs.some(t => t.id === 'chat')) ); + const activeLocation = useLiveData(activeView.location$); const activeTab = useLiveData(activeView.activeSidebarTab$); const sidebarOpen = useLiveData(workbench.sidebarOpen$); useEffect(() => { - setHide((sidebarOpen && activeTab?.id === 'chat') || !haveChatTab); - }, [activeTab, haveChatTab, sidebarOpen]); + let hide = true; + if (haveChatTab) { + hide = !!sidebarOpen && activeTab?.id === 'chat'; + } else { + const path = activeLocation.pathname; + hide = hideChat.some(item => + typeof item === 'string' ? path === item : item(path) + ); + } + setHide(hide); + }, [activeLocation.pathname, activeTab, haveChatTab, sidebarOpen]); + + const onOpenChat = useCallback(() => { + if (hide) return; + if (haveChatTab) { + workbench.openSidebar(); + activeView.activeSidebarTab('chat'); + } else { + workbench.open('/chat'); + workbench.closeSidebar(); + } + }, [activeView, haveChatTab, hide, workbench]); return ( @@ -29,11 +55,7 @@ export const AIIsland = () => { diff --git a/packages/frontend/core/src/modules/workbench/view/route-container.css.ts b/packages/frontend/core/src/modules/workbench/view/route-container.css.ts index 7a5b44db0b..09cb5f8f92 100644 --- a/packages/frontend/core/src/modules/workbench/view/route-container.css.ts +++ b/packages/frontend/core/src/modules/workbench/view/route-container.css.ts @@ -57,6 +57,8 @@ export const rightSidebarButton = style({ opacity: 0, maxWidth: 0, marginLeft: 0, + // prevent click event from being triggered + pointerEvents: 'none', }, }, });