Merge branch 'master' into codex/ddd
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import { ArrowRight } from 'lucide-react';
|
||||
|
||||
import { NEW_WORK_ENTRY_CONFIG } from '../../config/newWorkEntryConfig';
|
||||
import { UnifiedModal } from '../common/UnifiedModal';
|
||||
import { getVisiblePlatformCreationTypes } from './platformEntryCreationTypes';
|
||||
|
||||
@@ -86,8 +87,8 @@ export function PlatformEntryCreationTypeModal({
|
||||
return (
|
||||
<UnifiedModal
|
||||
open={isOpen}
|
||||
title="选择创作类型"
|
||||
description="先选玩法类型,再进入对应创作工作台。"
|
||||
title={NEW_WORK_ENTRY_CONFIG.typeModal.title}
|
||||
description={NEW_WORK_ENTRY_CONFIG.typeModal.description}
|
||||
onClose={onClose}
|
||||
closeDisabled={isBusy}
|
||||
size="lg"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -122,6 +122,24 @@ test('PlatformWorkDetailView calls like handler', () => {
|
||||
expect(onLike).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
test('PlatformWorkDetailView switches remix action label for owned work edit', () => {
|
||||
render(
|
||||
<PlatformWorkDetailView
|
||||
entry={createPuzzleEntry()}
|
||||
actionMode="edit"
|
||||
isBusy={false}
|
||||
error={null}
|
||||
onBack={vi.fn()}
|
||||
onLike={vi.fn()}
|
||||
onStart={vi.fn()}
|
||||
onRemix={vi.fn()}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(screen.getByRole('button', { name: '作品编辑' })).toBeTruthy();
|
||||
expect(screen.queryByRole('button', { name: '作品改造' })).toBeNull();
|
||||
});
|
||||
|
||||
test('PlatformWorkDetailView cycles puzzle level cover slides', () => {
|
||||
vi.useFakeTimers();
|
||||
const { container } = render(
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
Gamepad2,
|
||||
GitFork,
|
||||
Heart,
|
||||
PencilLine,
|
||||
Play,
|
||||
Share2,
|
||||
} from 'lucide-react';
|
||||
@@ -38,6 +39,7 @@ export interface PlatformWorkDetailViewProps {
|
||||
onLike: () => void;
|
||||
onStart: () => void;
|
||||
onRemix: () => void;
|
||||
actionMode?: 'remix' | 'edit';
|
||||
}
|
||||
|
||||
function formatCompactCount(value: number) {
|
||||
@@ -78,6 +80,7 @@ export function PlatformWorkDetailView({
|
||||
onLike,
|
||||
onStart,
|
||||
onRemix,
|
||||
actionMode = 'remix',
|
||||
}: PlatformWorkDetailViewProps) {
|
||||
const coverSlides = useMemo(
|
||||
() => resolvePlatformWorldCoverSlides(entry),
|
||||
@@ -111,6 +114,8 @@ export function PlatformWorkDetailView({
|
||||
[entry],
|
||||
);
|
||||
const stats = resolvePlatformWorldStats(entry);
|
||||
const workActionLabel = actionMode === 'edit' ? '作品编辑' : '作品改造';
|
||||
const WorkActionIcon = actionMode === 'edit' ? PencilLine : GitFork;
|
||||
const statItems = [
|
||||
{
|
||||
label: '游玩',
|
||||
@@ -425,8 +430,8 @@ export function PlatformWorkDetailView({
|
||||
onClick={onRemix}
|
||||
disabled={isBusy}
|
||||
>
|
||||
<GitFork className="h-5 w-5" />
|
||||
作品改造
|
||||
<WorkActionIcon className="h-5 w-5" />
|
||||
{workActionLabel}
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
import { expect, test } from 'vitest';
|
||||
|
||||
import { NEW_WORK_ENTRY_CONFIG } from '../../config/newWorkEntryConfig';
|
||||
import {
|
||||
getVisiblePlatformCreationTypes,
|
||||
isPlatformCreationTypeVisible,
|
||||
PLATFORM_CREATION_TYPES,
|
||||
} from './platformEntryCreationTypes';
|
||||
|
||||
test('platform creation types are derived from new work entry config', () => {
|
||||
const puzzleConfig = NEW_WORK_ENTRY_CONFIG.creationTypes.find(
|
||||
(item) => item.id === 'puzzle',
|
||||
);
|
||||
|
||||
expect(puzzleConfig).toBeTruthy();
|
||||
expect(PLATFORM_CREATION_TYPES).toContainEqual(
|
||||
expect.objectContaining({
|
||||
id: 'puzzle',
|
||||
title: puzzleConfig?.title,
|
||||
subtitle: puzzleConfig?.subtitle,
|
||||
badge: puzzleConfig?.badge,
|
||||
locked: false,
|
||||
hidden: false,
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
test('new work entry config controls visibility and open order', () => {
|
||||
const visibleIds = getVisiblePlatformCreationTypes().map((item) => item.id);
|
||||
|
||||
expect(isPlatformCreationTypeVisible('big-fish')).toBe(false);
|
||||
expect(visibleIds).not.toContain('big-fish');
|
||||
expect(visibleIds[0]).toBe('rpg');
|
||||
expect(visibleIds).toEqual([
|
||||
'rpg',
|
||||
'puzzle',
|
||||
'match3d',
|
||||
'airp',
|
||||
'visual-novel',
|
||||
]);
|
||||
});
|
||||
@@ -1,10 +1,9 @@
|
||||
export type PlatformCreationTypeId =
|
||||
| 'rpg'
|
||||
| 'big-fish'
|
||||
| 'match3d'
|
||||
| 'puzzle'
|
||||
| 'airp'
|
||||
| 'visual-novel';
|
||||
import {
|
||||
NEW_WORK_ENTRY_CONFIG,
|
||||
type NewWorkEntryCreationTypeId,
|
||||
} from '../../config/newWorkEntryConfig';
|
||||
|
||||
export type PlatformCreationTypeId = NewWorkEntryCreationTypeId;
|
||||
|
||||
export type PlatformCreationTypeCard = {
|
||||
id: PlatformCreationTypeId;
|
||||
@@ -39,51 +38,15 @@ export function isPlatformCreationTypeVisible(id: PlatformCreationTypeId) {
|
||||
}
|
||||
|
||||
/**
|
||||
* 创作页与类型弹层共用同一份模板元数据,避免多入口文案和可用状态漂移。
|
||||
* 创作页与类型弹层共用同一份新建作品入口配置,避免多入口文案和开放状态漂移。
|
||||
* `hidden` 只控制平台入口是否展示,不影响既有玩法链路和路由能力。
|
||||
*/
|
||||
export const PLATFORM_CREATION_TYPES: PlatformCreationTypeCard[] = [
|
||||
{
|
||||
id: 'rpg',
|
||||
title: '角色扮演',
|
||||
subtitle: '敬请期待',
|
||||
badge: '敬请期待',
|
||||
locked: true,
|
||||
},
|
||||
{
|
||||
id: 'big-fish',
|
||||
title: '大鱼吃小鱼',
|
||||
subtitle: '实时成长玩法',
|
||||
badge: '可创建',
|
||||
locked: false,
|
||||
hidden: true,
|
||||
},
|
||||
{
|
||||
id: 'puzzle',
|
||||
title: '拼图',
|
||||
subtitle: '创意礼物,生活分享',
|
||||
badge: '可创建',
|
||||
locked: false,
|
||||
},
|
||||
{
|
||||
id: 'match3d',
|
||||
title: '抓大鹅',
|
||||
subtitle: '经典消除玩法',
|
||||
badge: '可创建',
|
||||
locked: false,
|
||||
},
|
||||
{
|
||||
id: 'airp',
|
||||
title: 'AIRP',
|
||||
subtitle: '敬请期待',
|
||||
badge: '敬请期待',
|
||||
locked: true,
|
||||
},
|
||||
{
|
||||
id: 'visual-novel',
|
||||
title: '视觉小说',
|
||||
subtitle: '敬请期待',
|
||||
badge: '敬请期待',
|
||||
locked: true,
|
||||
},
|
||||
];
|
||||
export const PLATFORM_CREATION_TYPES: PlatformCreationTypeCard[] =
|
||||
NEW_WORK_ENTRY_CONFIG.creationTypes.map((item) => ({
|
||||
id: item.id,
|
||||
title: item.title,
|
||||
subtitle: item.subtitle,
|
||||
badge: item.badge,
|
||||
locked: !item.open,
|
||||
hidden: !item.visible,
|
||||
}));
|
||||
|
||||
Reference in New Issue
Block a user