拆分图片画布素材拖拽桥接

新增素材拖拽桥接 hook,承接素材拖向画布或文件夹的全局 pointer 监听

恢复认证弹窗 portal 渲染,避免全屏画布遮住账号入口

优化画布背景设置面板,补回当前色、色域、色相、预设、HEX 和恢复默认

补充素材拖拽、认证弹窗和背景面板回归测试并更新文档与 TRACKING
This commit is contained in:
2026-06-17 12:20:04 +08:00
parent 5d6be7fd66
commit cdc823611b
11 changed files with 544 additions and 133 deletions
+27 -1
View File
@@ -2,7 +2,7 @@
import { act, render, screen, waitFor, within } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { useState } from 'react';
import { useEffect, useState } from 'react';
import { afterEach, beforeEach, expect, test, vi } from 'vitest';
import type { AuthSessionSummary, AuthUser } from '../../services/authService';
@@ -250,6 +250,16 @@ function AccountPanelProbe() {
);
}
function AutoOpenLoginProbe() {
const authUi = useAuthUi();
useEffect(() => {
authUi?.openLoginModal();
}, [authUi]);
return <div>编辑器内容</div>;
}
test('auth gate keeps platform content visible when phone login is available', async () => {
authMocks.getAuthLoginOptions.mockResolvedValue({
availableLoginMethods: ['phone'],
@@ -266,6 +276,22 @@ test('auth gate keeps platform content visible when phone login is available', a
expect(screen.queryByText('先登录账号,再同步你的冒险进度。')).toBeNull();
});
test('auth gate portals page-level login requests above fullscreen content', async () => {
const { container } = render(
<AuthGate>
<div className="image-canvas-editor">全屏画布</div>
<AutoOpenLoginProbe />
</AuthGate>,
);
expect(await screen.findByText('编辑器内容')).toBeTruthy();
const dialog = await screen.findByRole('dialog', { name: '账号入口' });
expect(container.querySelector('[role="dialog"]')).toBeNull();
expect(dialog.parentElement?.parentElement).toBe(document.body);
expect(dialog.parentElement?.className).toContain('z-[120]');
});
test('auth gate waits for refresh cookie rotation before exposing restored user content', async () => {
let resolveToken!: (token: string) => void;
const tokenPromise = new Promise<string>((resolve) => {
@@ -8,7 +8,7 @@ import { PlatformAuthModalShell } from './PlatformAuthModalShell';
test('renders auth modal shell with platform theme and auth card chrome', () => {
const onClose = vi.fn();
render(
const { container } = render(
<PlatformAuthModalShell
title="账号入口"
platformTheme="light"
@@ -22,6 +22,8 @@ test('renders auth modal shell with platform theme and auth card chrome', () =>
const dialog = screen.getByRole('dialog', { name: '账号入口' });
expect(container.querySelector('[role="dialog"]')).toBeNull();
expect(document.body.contains(dialog)).toBe(true);
expect(dialog.parentElement?.className).toContain('platform-theme--light');
expect(dialog.className).toContain('platform-modal-shell');
expect(dialog.className).toContain('platform-auth-card');
@@ -55,7 +55,6 @@ export function PlatformAuthModalShell({
closeVariant="platformIcon"
closeOnBackdrop
closeOnEscape={false}
portal={false}
size={size}
showHeader={showHeader}
zIndexClassName={zIndexClassName}