mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-22 20:46:38 +08:00
feat(core): show ai-island and navigate to chat page if not available in sidebar (#13085)
close AI-318, AI-317 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## 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. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
@@ -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<string | ((path: string) => 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 (
|
||||
<IslandContainer className={clsx(toolStyle, { hide })}>
|
||||
@@ -29,11 +55,7 @@ export const AIIsland = () => {
|
||||
<button
|
||||
className={aiIslandBtn}
|
||||
data-testid="ai-island"
|
||||
onClick={() => {
|
||||
if (hide) return;
|
||||
workbench.openSidebar();
|
||||
activeView.activeSidebarTab('chat');
|
||||
}}
|
||||
onClick={onOpenChat}
|
||||
>
|
||||
<AIIcon />
|
||||
</button>
|
||||
|
||||
Reference in New Issue
Block a user