控制画布 Agent 入口默认关闭
新增 VITE_ENABLE_IMAGE_EDITOR_AGENT_SIDEBAR 控制画布 Agent 入口显示。 默认 .env 关闭、本地 .env.local 开启,并补充示例和类型声明。 禁用时隐藏 dock 按钮和收起态 Agent 面板,开启时保留右侧任务列表互斥逻辑。 修正右侧 Agent 和任务列表切换不影响左侧资源栏。 补充画布 Agent 开关、面板独立性和 dock 隐藏测试。
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
# 微信小程序 web-view 登录配置。
|
||||
# 留空时不覆盖已有微信网页 OAuth 配置;正式联调时再填小程序 AppID / AppSecret。
|
||||
VITE_ENABLE_IMAGE_EDITOR_AGENT_SIDEBAR=false
|
||||
|
||||
WECHAT_MINI_PROGRAM_APP_ID=""
|
||||
WECHAT_MINI_PROGRAM_APP_SECRET=""
|
||||
WECHAT_JS_CODE_SESSION_ENDPOINT=""
|
||||
|
||||
@@ -199,6 +199,10 @@ VITE_LLM_DEBUG_LOG="false"
|
||||
# Set to "true" to expose local diagnostic panels, or "false" to hide them.
|
||||
VITE_DEBUG_MODE=""
|
||||
|
||||
# Optional: show the image editor right-side Agent entry.
|
||||
# Keep this off by default outside local development.
|
||||
VITE_ENABLE_IMAGE_EDITOR_AGENT_SIDEBAR="false"
|
||||
|
||||
# Optional: official VikingDB credentials for regenerating build-tag similarities
|
||||
# with the Python embedding script. The script auto-loads `.env.local` and uses
|
||||
# the fixed `bge-large-zh` embedding model.
|
||||
|
||||
@@ -42,6 +42,8 @@ LLM_DEBUG_LOG="true"
|
||||
# 注意:不要在客户端启用调试日志,避免敏感数据泄露
|
||||
# VITE_LLM_DEBUG_LOG="false"
|
||||
|
||||
VITE_ENABLE_IMAGE_EDITOR_AGENT_SIDEBAR=true
|
||||
|
||||
ALIYUN_OSS_BUCKET="xushi-dev"
|
||||
ALIYUN_OSS_REGION="oss-cn-beijing"
|
||||
ALIYUN_OSS_ENDPOINT="oss-cn-beijing.aliyuncs.com"
|
||||
|
||||
@@ -139,6 +139,7 @@ function createStageProps(): ImageCanvasStageViewProps {
|
||||
editorAgentAssets: [],
|
||||
taskListRefreshKey: 0,
|
||||
isTaskSidebarOpen: false,
|
||||
isAgentConversationEnabled: false,
|
||||
isAgentConversationOpen: false,
|
||||
generateDialog: null,
|
||||
cropExpandPanel: null,
|
||||
|
||||
@@ -12,6 +12,7 @@ import userEvent from '@testing-library/user-event';
|
||||
import JSZip from 'jszip';
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
|
||||
import type { EditorAgentConversationClient } from './useEditorAgentConversation';
|
||||
import {
|
||||
ApiClientError,
|
||||
AuthUiContext,
|
||||
@@ -25,11 +26,73 @@ import {
|
||||
setupImageCanvasEditorViewTestLifecycle,
|
||||
} from './ImageCanvasEditorView.test-utils';
|
||||
|
||||
const listEditorAgentConversationsMock = vi.hoisted(() => vi.fn());
|
||||
const createEditorAgentConversationMock = vi.hoisted(() => vi.fn());
|
||||
const getEditorAgentConversationMock = vi.hoisted(() => vi.fn());
|
||||
const deleteEditorAgentConversationMock = vi.hoisted(() => vi.fn());
|
||||
const streamEditorAgentMessageMock = vi.hoisted(() => vi.fn());
|
||||
type EditorAgentListConversations =
|
||||
EditorAgentConversationClient['listConversations'];
|
||||
type EditorAgentCreateConversation =
|
||||
EditorAgentConversationClient['createConversation'];
|
||||
type EditorAgentGetConversation =
|
||||
EditorAgentConversationClient['getConversation'];
|
||||
type EditorAgentDeleteConversation =
|
||||
EditorAgentConversationClient['deleteConversation'];
|
||||
type EditorAgentStreamMessage = EditorAgentConversationClient['streamMessage'];
|
||||
type EditorAgentConversationSummary = Awaited<
|
||||
ReturnType<EditorAgentListConversations>
|
||||
>[number];
|
||||
type EditorAgentConversationDetail = Awaited<
|
||||
ReturnType<EditorAgentGetConversation>
|
||||
>;
|
||||
const EDITOR_AGENT_SIDEBAR_ENV = 'VITE_ENABLE_IMAGE_EDITOR_AGENT_SIDEBAR';
|
||||
|
||||
const listEditorAgentConversationsMock = vi.hoisted(() =>
|
||||
vi.fn<
|
||||
Parameters<EditorAgentListConversations>,
|
||||
ReturnType<EditorAgentListConversations>
|
||||
>(async () => []),
|
||||
);
|
||||
const createEditorAgentConversationMock = vi.hoisted(() =>
|
||||
vi.fn<
|
||||
Parameters<EditorAgentCreateConversation>,
|
||||
ReturnType<EditorAgentCreateConversation>
|
||||
>(async () => ({
|
||||
conversationId: 'editor-agent-conv-created',
|
||||
projectId: 'editor-project-default',
|
||||
title: '画布 Agent',
|
||||
createdAt: '2026-07-03T00:00:00.000Z',
|
||||
updatedAt: '2026-07-03T00:00:00.000Z',
|
||||
messages: [],
|
||||
})),
|
||||
);
|
||||
const getEditorAgentConversationMock = vi.hoisted(() =>
|
||||
vi.fn<
|
||||
Parameters<EditorAgentGetConversation>,
|
||||
ReturnType<EditorAgentGetConversation>
|
||||
>(async () => ({
|
||||
conversationId: 'editor-agent-conv-test',
|
||||
projectId: 'editor-project-default',
|
||||
title: '画布 Agent',
|
||||
createdAt: '2026-07-03T00:00:00.000Z',
|
||||
updatedAt: '2026-07-03T00:00:00.000Z',
|
||||
messages: [],
|
||||
})),
|
||||
);
|
||||
const deleteEditorAgentConversationMock = vi.hoisted(() =>
|
||||
vi.fn<
|
||||
Parameters<EditorAgentDeleteConversation>,
|
||||
ReturnType<EditorAgentDeleteConversation>
|
||||
>(async () => ({
|
||||
conversationId: 'editor-agent-conv-test',
|
||||
projectId: 'editor-project-default',
|
||||
title: '画布 Agent',
|
||||
createdAt: '2026-07-03T00:00:00.000Z',
|
||||
updatedAt: '2026-07-03T00:00:00.000Z',
|
||||
})),
|
||||
);
|
||||
const streamEditorAgentMessageMock = vi.hoisted(() =>
|
||||
vi.fn<
|
||||
Parameters<EditorAgentStreamMessage>,
|
||||
ReturnType<EditorAgentStreamMessage>
|
||||
>(async () => undefined),
|
||||
);
|
||||
const generateEditorImageMock = vi.hoisted(() => vi.fn());
|
||||
const generateEditorIconSpritesheetMock = vi.hoisted(() => vi.fn());
|
||||
const generateEditorCharacterAnimationMock = vi.hoisted(() => vi.fn());
|
||||
@@ -85,7 +148,9 @@ vi.mock('../../services/image-editor/editorAgentClient', () => ({
|
||||
streamEditorAgentMessage: streamEditorAgentMessageMock,
|
||||
}));
|
||||
|
||||
function createEditorAgentConversationSummary(overrides = {}) {
|
||||
function createEditorAgentConversationSummary(
|
||||
overrides: Partial<EditorAgentConversationSummary> = {},
|
||||
): EditorAgentConversationSummary {
|
||||
return {
|
||||
conversationId: 'editor-agent-conv-test',
|
||||
projectId: 'editor-project-default',
|
||||
@@ -96,7 +161,9 @@ function createEditorAgentConversationSummary(overrides = {}) {
|
||||
};
|
||||
}
|
||||
|
||||
function createEditorAgentDetailWithGeneration(resourceId: string) {
|
||||
function createEditorAgentDetailWithGeneration(
|
||||
resourceId: string,
|
||||
): EditorAgentConversationDetail {
|
||||
const summary = createEditorAgentConversationSummary();
|
||||
return {
|
||||
...summary,
|
||||
@@ -146,6 +213,18 @@ function openMinimap() {
|
||||
return screen.getByRole('button', { name: '画布小地图' });
|
||||
}
|
||||
|
||||
async function ensureAgentConversationOpen() {
|
||||
const agentButton = screen.getByRole('button', { name: '画布 Agent' });
|
||||
if (agentButton.getAttribute('aria-pressed') !== 'true') {
|
||||
fireEvent.click(agentButton);
|
||||
}
|
||||
return screen.findByLabelText('发送给画布 Agent');
|
||||
}
|
||||
|
||||
function enableEditorAgentSidebarForTest() {
|
||||
vi.stubEnv(EDITOR_AGENT_SIDEBAR_ENV, 'true');
|
||||
}
|
||||
|
||||
describe('ImageCanvasEditorView', () => {
|
||||
setupImageCanvasEditorViewTestLifecycle({
|
||||
generateEditorImageMock,
|
||||
@@ -167,6 +246,7 @@ describe('ImageCanvasEditorView', () => {
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
vi.stubEnv(EDITOR_AGENT_SIDEBAR_ENV, 'false');
|
||||
listEditorAgentConversationsMock.mockResolvedValue([]);
|
||||
createEditorAgentConversationMock.mockResolvedValue({
|
||||
...createEditorAgentConversationSummary({
|
||||
@@ -197,9 +277,11 @@ describe('ImageCanvasEditorView', () => {
|
||||
deleteEditorAgentConversationMock.mockReset();
|
||||
streamEditorAgentMessageMock.mockReset();
|
||||
getPlatformProfileDashboardMock.mockReset();
|
||||
vi.unstubAllEnvs();
|
||||
});
|
||||
|
||||
it('loads the project from projectid query before falling back to recent project', async () => {
|
||||
listEditorAgentConversationsMock.mockResolvedValue([]);
|
||||
loadEditorProjectMock.mockResolvedValueOnce({
|
||||
projectId: 'editor-project-query',
|
||||
title: '查询项目',
|
||||
@@ -481,6 +563,7 @@ describe('ImageCanvasEditorView', () => {
|
||||
});
|
||||
|
||||
it('does not inject built-in mock assets when the persisted library is empty', async () => {
|
||||
listEditorAgentConversationsMock.mockResolvedValue([]);
|
||||
loadOrCreateRecentEditorProjectMock.mockResolvedValueOnce({
|
||||
projectId: 'editor-project-empty',
|
||||
title: '空画布',
|
||||
@@ -939,10 +1022,10 @@ describe('ImageCanvasEditorView', () => {
|
||||
});
|
||||
|
||||
it('moves focus from the Agent input back to the canvas layer before handling shortcuts', async () => {
|
||||
enableEditorAgentSidebarForTest();
|
||||
render(<ImageCanvasEditorView />);
|
||||
|
||||
fireEvent.click(screen.getByRole('button', { name: '画布 Agent' }));
|
||||
const agentInput = await screen.findByLabelText('发送给画布 Agent');
|
||||
const agentInput = await ensureAgentConversationOpen();
|
||||
agentInput.focus();
|
||||
expect(document.activeElement).toBe(agentInput);
|
||||
|
||||
@@ -1341,6 +1424,74 @@ describe('ImageCanvasEditorView', () => {
|
||||
expect(screen.getByRole('button', { name: '添加拼图素材' })).toBeTruthy();
|
||||
});
|
||||
|
||||
it('hides the right Agent conversation entry by default', () => {
|
||||
render(<ImageCanvasEditorView />);
|
||||
|
||||
expect(screen.queryByRole('button', { name: '画布 Agent' })).toBeNull();
|
||||
expect(
|
||||
screen.queryByRole('button', { name: '打开画布 Agent' }),
|
||||
).toBeNull();
|
||||
expect(screen.queryByLabelText('发送给画布 Agent')).toBeNull();
|
||||
expect(listEditorAgentConversationsMock).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('opens the right Agent conversation panel by default when enabled', async () => {
|
||||
enableEditorAgentSidebarForTest();
|
||||
render(<ImageCanvasEditorView />);
|
||||
|
||||
expect(await screen.findByLabelText('发送给画布 Agent')).toBeTruthy();
|
||||
expect(
|
||||
screen.queryByRole('complementary', { name: '画布任务列表' }),
|
||||
).toBeNull();
|
||||
|
||||
fireEvent.click(screen.getByRole('button', { name: '画布 Agent' }));
|
||||
|
||||
expect(screen.queryByLabelText('发送给画布 Agent')).toBeNull();
|
||||
});
|
||||
|
||||
it('keeps the left resource sidebar independent from right-side task and Agent panels', async () => {
|
||||
enableEditorAgentSidebarForTest();
|
||||
render(<ImageCanvasEditorView />);
|
||||
|
||||
const assetSidebar = openAssetSidebar();
|
||||
expect(within(assetSidebar).getByText('素材')).toBeTruthy();
|
||||
|
||||
fireEvent.click(screen.getByRole('button', { name: '任务列表' }));
|
||||
expect(
|
||||
screen.getByRole('complementary', { name: '画布任务列表' }),
|
||||
).toBeTruthy();
|
||||
expect(
|
||||
screen.getByRole('complementary', { name: '图片资源栏' }),
|
||||
).toBeTruthy();
|
||||
|
||||
fireEvent.click(screen.getByRole('button', { name: '打开图层' }));
|
||||
const layerSidebar = screen.getByRole('complementary', {
|
||||
name: '图片资源栏',
|
||||
});
|
||||
expect(within(layerSidebar).getByText('图层')).toBeTruthy();
|
||||
expect(
|
||||
screen.getByRole('complementary', { name: '画布任务列表' }),
|
||||
).toBeTruthy();
|
||||
|
||||
fireEvent.click(screen.getByRole('button', { name: '画布 Agent' }));
|
||||
expect(
|
||||
screen.getByRole('complementary', { name: '图片资源栏' }),
|
||||
).toBeTruthy();
|
||||
expect(
|
||||
screen.queryByRole('complementary', { name: '画布任务列表' }),
|
||||
).toBeNull();
|
||||
expect(await screen.findByLabelText('发送给画布 Agent')).toBeTruthy();
|
||||
|
||||
fireEvent.click(screen.getByRole('button', { name: '任务列表' }));
|
||||
expect(
|
||||
screen.getByRole('complementary', { name: '图片资源栏' }),
|
||||
).toBeTruthy();
|
||||
expect(
|
||||
screen.getByRole('complementary', { name: '画布任务列表' }),
|
||||
).toBeTruthy();
|
||||
expect(screen.queryByLabelText('发送给画布 Agent')).toBeNull();
|
||||
});
|
||||
|
||||
it('adds assets from the sidebar and supports zoom buttons', () => {
|
||||
render(<ImageCanvasEditorView />);
|
||||
|
||||
@@ -1557,6 +1708,7 @@ describe('ImageCanvasEditorView', () => {
|
||||
});
|
||||
|
||||
it('renders Agent generation thumbnails as passive previews', async () => {
|
||||
enableEditorAgentSidebarForTest();
|
||||
const detail = createEditorAgentDetailWithGeneration('resource-puzzle');
|
||||
listEditorAgentConversationsMock.mockResolvedValueOnce([
|
||||
createEditorAgentConversationSummary(),
|
||||
@@ -1565,7 +1717,7 @@ describe('ImageCanvasEditorView', () => {
|
||||
|
||||
render(<ImageCanvasEditorView />);
|
||||
|
||||
fireEvent.click(screen.getByRole('button', { name: '画布 Agent' }));
|
||||
await ensureAgentConversationOpen();
|
||||
const messageLog = await screen.findByRole('log', {
|
||||
name: '画布 Agent 消息流',
|
||||
});
|
||||
@@ -1578,6 +1730,7 @@ describe('ImageCanvasEditorView', () => {
|
||||
});
|
||||
|
||||
it('refreshes canvas and asset library when Agent generation finishes', async () => {
|
||||
enableEditorAgentSidebarForTest();
|
||||
let showGeneratedAsset = false;
|
||||
loadEditorAssetLibraryMock.mockImplementation(async () => ({
|
||||
folders: [
|
||||
@@ -1692,7 +1845,7 @@ describe('ImageCanvasEditorView', () => {
|
||||
|
||||
render(<ImageCanvasEditorView />);
|
||||
|
||||
fireEvent.click(screen.getByRole('button', { name: '画布 Agent' }));
|
||||
await ensureAgentConversationOpen();
|
||||
await waitFor(() => {
|
||||
expect(getEditorAgentConversationMock).toHaveBeenCalledWith(
|
||||
'editor-agent-conv-test',
|
||||
|
||||
@@ -117,6 +117,12 @@ type ImageCanvasEditorViewProps = {
|
||||
onProjectAccessLost?: () => void;
|
||||
};
|
||||
|
||||
function resolveEditorAgentSidebarEnabled(
|
||||
rawValue = import.meta.env.VITE_ENABLE_IMAGE_EDITOR_AGENT_SIDEBAR,
|
||||
): boolean {
|
||||
return rawValue === 'true' || rawValue === '1';
|
||||
}
|
||||
|
||||
function isCanvasStartupTool(value: string | null): value is CanvasStartupTool {
|
||||
return CANVAS_STARTUP_TOOLS.includes(value as CanvasStartupTool);
|
||||
}
|
||||
@@ -1161,44 +1167,49 @@ export function ImageCanvasEditorView({
|
||||
applyProjectSnapshot: applyGeneratedProjectSnapshot,
|
||||
onWalletBalanceMayHaveChanged: refreshEditorWalletBalance,
|
||||
});
|
||||
const [isAgentConversationOpen, setIsAgentConversationOpen] = useState(false);
|
||||
const isAgentConversationEnabled = resolveEditorAgentSidebarEnabled();
|
||||
const [isAgentConversationOpen, setIsAgentConversationOpen] = useState(
|
||||
() => isAgentConversationEnabled,
|
||||
);
|
||||
const effectiveIsAgentConversationOpen =
|
||||
isAgentConversationEnabled && isAgentConversationOpen;
|
||||
const toggleAgentConversation = useCallback(() => {
|
||||
if (!isAgentConversationEnabled) {
|
||||
return;
|
||||
}
|
||||
const nextOpen = !isAgentConversationOpen;
|
||||
if (nextOpen) {
|
||||
setActiveSidebarPanel(null);
|
||||
if (generationSurface.isTaskSidebarOpen) {
|
||||
generationSurface.toggleTaskSidebar();
|
||||
}
|
||||
if (nextOpen && generationSurface.isTaskSidebarOpen) {
|
||||
generationSurface.toggleTaskSidebar();
|
||||
}
|
||||
setIsAgentConversationOpen(nextOpen);
|
||||
}, [generationSurface, isAgentConversationOpen, setActiveSidebarPanel]);
|
||||
}, [generationSurface, isAgentConversationEnabled, isAgentConversationOpen]);
|
||||
const toggleTaskSidebar = useCallback(() => {
|
||||
if (!generationSurface.isTaskSidebarOpen) {
|
||||
setActiveSidebarPanel(null);
|
||||
if (
|
||||
!generationSurface.isTaskSidebarOpen &&
|
||||
effectiveIsAgentConversationOpen
|
||||
) {
|
||||
setIsAgentConversationOpen(false);
|
||||
}
|
||||
generationSurface.toggleTaskSidebar();
|
||||
}, [generationSurface, setActiveSidebarPanel]);
|
||||
}, [effectiveIsAgentConversationOpen, generationSurface]);
|
||||
const toggleCanvasSidebarPanel = useCallback(
|
||||
(panel: SidebarPanel) => {
|
||||
setIsAgentConversationOpen(false);
|
||||
if (generationSurface.isTaskSidebarOpen) {
|
||||
generationSurface.toggleTaskSidebar();
|
||||
}
|
||||
toggleSidebarPanel(panel);
|
||||
},
|
||||
[generationSurface, toggleSidebarPanel],
|
||||
[toggleSidebarPanel],
|
||||
);
|
||||
useEffect(() => {
|
||||
if (generationSurface.isTaskSidebarOpen && isAgentConversationOpen) {
|
||||
if (
|
||||
(!isAgentConversationEnabled || generationSurface.isTaskSidebarOpen) &&
|
||||
isAgentConversationOpen
|
||||
) {
|
||||
setIsAgentConversationOpen(false);
|
||||
}
|
||||
}, [generationSurface.isTaskSidebarOpen, isAgentConversationOpen]);
|
||||
useEffect(() => {
|
||||
if (activeSidebarPanel && isAgentConversationOpen) {
|
||||
setIsAgentConversationOpen(false);
|
||||
}
|
||||
}, [activeSidebarPanel, isAgentConversationOpen]);
|
||||
}, [
|
||||
generationSurface.isTaskSidebarOpen,
|
||||
isAgentConversationEnabled,
|
||||
isAgentConversationOpen,
|
||||
]);
|
||||
const {
|
||||
setQuickEditPanel,
|
||||
setCropExpandPanel,
|
||||
@@ -1923,7 +1934,8 @@ export function ImageCanvasEditorView({
|
||||
isToolbarGuideVisible,
|
||||
taskListRefreshKey: generationSurface.taskListRefreshKey,
|
||||
isTaskSidebarOpen: generationSurface.isTaskSidebarOpen,
|
||||
isAgentConversationOpen,
|
||||
isAgentConversationEnabled,
|
||||
isAgentConversationOpen: effectiveIsAgentConversationOpen,
|
||||
generateDialog,
|
||||
cropExpandPanel: generationSurface.cropExpandPanel,
|
||||
cropExpandSourceLayer: generationSurface.cropExpandSourceLayer,
|
||||
|
||||
@@ -18,6 +18,7 @@ function renderPanelDock(
|
||||
isZoomMenuOpen: false,
|
||||
isBackgroundSettingsOpen: false,
|
||||
activeSidebarPanel: null,
|
||||
isAgentConversationEnabled: true,
|
||||
isAgentConversationOpen: false,
|
||||
isMinimapOpen: false,
|
||||
minimapModel: null,
|
||||
@@ -91,6 +92,12 @@ describe('ImageCanvasPanelDockView', () => {
|
||||
expect(props.onToggleMinimap).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('hides the Agent entry when the Agent sidebar is disabled', () => {
|
||||
renderPanelDock({ isAgentConversationEnabled: false });
|
||||
|
||||
expect(screen.queryByRole('button', { name: '画布 Agent' })).toBeNull();
|
||||
});
|
||||
|
||||
it('renders zoom and background settings with callback wiring', () => {
|
||||
const props = renderPanelDock({
|
||||
viewport: { x: 0, y: 0, scale: 0.5 },
|
||||
|
||||
@@ -35,6 +35,7 @@ type ImageCanvasPanelDockViewProps = {
|
||||
isZoomMenuOpen: boolean;
|
||||
isBackgroundSettingsOpen: boolean;
|
||||
activeSidebarPanel: SidebarPanel | null;
|
||||
isAgentConversationEnabled: boolean;
|
||||
isAgentConversationOpen: boolean;
|
||||
isMinimapOpen: boolean;
|
||||
minimapModel: StageMinimapModel | null;
|
||||
@@ -62,6 +63,7 @@ export function ImageCanvasPanelDockView({
|
||||
isZoomMenuOpen,
|
||||
isBackgroundSettingsOpen,
|
||||
activeSidebarPanel,
|
||||
isAgentConversationEnabled,
|
||||
isAgentConversationOpen,
|
||||
isMinimapOpen,
|
||||
minimapModel,
|
||||
@@ -300,13 +302,15 @@ export function ImageCanvasPanelDockView({
|
||||
pressed={activeSidebarPanel === 'layers'}
|
||||
onClick={() => onToggleSidebarPanel('layers')}
|
||||
/>
|
||||
<EditorIconButton
|
||||
label="画布 Agent"
|
||||
title="画布 Agent"
|
||||
icon={MessageCircle}
|
||||
pressed={isAgentConversationOpen}
|
||||
onClick={onToggleAgentConversation}
|
||||
/>
|
||||
{isAgentConversationEnabled ? (
|
||||
<EditorIconButton
|
||||
label="画布 Agent"
|
||||
title="画布 Agent"
|
||||
icon={MessageCircle}
|
||||
pressed={isAgentConversationOpen}
|
||||
onClick={onToggleAgentConversation}
|
||||
/>
|
||||
) : null}
|
||||
<EditorIconButton
|
||||
label="切换小地图"
|
||||
title="小地图"
|
||||
|
||||
@@ -157,6 +157,7 @@ function SidebarTabsHarness() {
|
||||
isZoomMenuOpen={false}
|
||||
isBackgroundSettingsOpen={false}
|
||||
activeSidebarPanel={chrome.activeSidebarPanel}
|
||||
isAgentConversationEnabled={false}
|
||||
isAgentConversationOpen={false}
|
||||
isMinimapOpen={false}
|
||||
minimapModel={null}
|
||||
|
||||
@@ -62,6 +62,7 @@ export type ImageCanvasStageViewProps = {
|
||||
isToolbarGuideVisible?: boolean;
|
||||
taskListRefreshKey: number;
|
||||
isTaskSidebarOpen: boolean;
|
||||
isAgentConversationEnabled: boolean;
|
||||
isAgentConversationOpen: boolean;
|
||||
generateDialog: GenerateDialogState | null;
|
||||
cropExpandPanel: CropExpandPanelState | null;
|
||||
@@ -212,6 +213,7 @@ export function ImageCanvasStageView({
|
||||
isToolbarGuideVisible = false,
|
||||
taskListRefreshKey,
|
||||
isTaskSidebarOpen,
|
||||
isAgentConversationEnabled,
|
||||
isAgentConversationOpen,
|
||||
generateDialog,
|
||||
cropExpandPanel,
|
||||
@@ -441,6 +443,7 @@ export function ImageCanvasStageView({
|
||||
isZoomMenuOpen={isZoomMenuOpen}
|
||||
isBackgroundSettingsOpen={isBackgroundSettingsOpen}
|
||||
activeSidebarPanel={activeSidebarPanel}
|
||||
isAgentConversationEnabled={isAgentConversationEnabled}
|
||||
isAgentConversationOpen={isAgentConversationOpen}
|
||||
isMinimapOpen={isMinimapOpen}
|
||||
minimapModel={minimapModel}
|
||||
@@ -467,14 +470,16 @@ export function ImageCanvasStageView({
|
||||
onFocusExternalTask={onFocusExternalTask}
|
||||
/>
|
||||
|
||||
<EditorAgentConversationPanelView
|
||||
projectId={projectId}
|
||||
open={isAgentConversationOpen}
|
||||
onToggleOpen={onToggleAgentConversation}
|
||||
layers={layers}
|
||||
assets={editorAgentAssets}
|
||||
onGenerationResult={onEditorAgentGenerationResult}
|
||||
/>
|
||||
{isAgentConversationEnabled ? (
|
||||
<EditorAgentConversationPanelView
|
||||
projectId={projectId}
|
||||
open={isAgentConversationOpen}
|
||||
onToggleOpen={onToggleAgentConversation}
|
||||
layers={layers}
|
||||
assets={editorAgentAssets}
|
||||
onGenerationResult={onEditorAgentGenerationResult}
|
||||
/>
|
||||
) : null}
|
||||
|
||||
{isToolbarGuideVisible ? (
|
||||
<div
|
||||
|
||||
@@ -294,8 +294,7 @@ export function useEditorAgentConversation({
|
||||
let disposed = false;
|
||||
setIsLoadingConversations(true);
|
||||
setErrorMessage(null);
|
||||
client
|
||||
.listConversations(normalizedProjectId)
|
||||
Promise.resolve(client.listConversations(normalizedProjectId) ?? [])
|
||||
.then(async (nextConversations) => {
|
||||
if (disposed) {
|
||||
return;
|
||||
|
||||
Vendored
+1
@@ -2,6 +2,7 @@
|
||||
|
||||
interface ImportMetaEnv {
|
||||
readonly VITE_DEBUG_MODE?: string;
|
||||
readonly VITE_ENABLE_IMAGE_EDITOR_AGENT_SIDEBAR?: string;
|
||||
}
|
||||
|
||||
interface Window {
|
||||
|
||||
Reference in New Issue
Block a user