Refine creation tab UX, generation flow, and bindings
Large changes across frontend, backend and docs to align creation-tab and generation-page behavior with new product UI/UX and Spacetime bindings. Updated hermes decision-log and pitfalls with concrete rules (banner carousel, font sizing, unread-dot tokens, template-card layout, direct card->entry routing, separation of account balance vs prize pools, removal of global page card shell, generation progress milestones and unified circular progress, and background video handling). Added GenerationProgressHero component and media assets, plus generation-related UI/tests updates (CustomWorldGenerationView, BarkBattleGeneratingView, creation hub/cards, platform entry routing, index tests). Backend and contract updates include new category fields in admin API types and admin UI form/list, spacetime-client/module/migration changes and generated bindings script. Misc: many tests adjusted, new docs and plan files added, and several server-rs crate changes to support the updated creation/ generation workflows.
This commit is contained in:
@@ -25,6 +25,14 @@ const testEntryConfig = {
|
||||
title: '选择创作类型',
|
||||
description: '先选玩法类型,再进入对应创作工作台。',
|
||||
},
|
||||
eventBanner: {
|
||||
title: '泥点挑战',
|
||||
description: '创作活动测试横幅。',
|
||||
coverImageSrc: '/creation-type-references/puzzle.webp',
|
||||
prizePoolMudPoints: 1000,
|
||||
startsAtText: '2026-05-01',
|
||||
endsAtText: '2026-05-31',
|
||||
},
|
||||
creationTypes: [
|
||||
{
|
||||
id: 'rpg',
|
||||
@@ -35,6 +43,9 @@ const testEntryConfig = {
|
||||
visible: true,
|
||||
open: true,
|
||||
sortOrder: 10,
|
||||
categoryId: 'recent',
|
||||
categoryLabel: '最近创作',
|
||||
categorySortOrder: 10,
|
||||
updatedAtMicros: 1,
|
||||
},
|
||||
{
|
||||
@@ -46,6 +57,9 @@ const testEntryConfig = {
|
||||
visible: true,
|
||||
open: true,
|
||||
sortOrder: 30,
|
||||
categoryId: 'recent',
|
||||
categoryLabel: '最近创作',
|
||||
categorySortOrder: 10,
|
||||
updatedAtMicros: 1,
|
||||
},
|
||||
{
|
||||
@@ -57,6 +71,9 @@ const testEntryConfig = {
|
||||
visible: true,
|
||||
open: true,
|
||||
sortOrder: 40,
|
||||
categoryId: 'recent',
|
||||
categoryLabel: '最近创作',
|
||||
categorySortOrder: 10,
|
||||
updatedAtMicros: 1,
|
||||
},
|
||||
{
|
||||
@@ -68,6 +85,9 @@ const testEntryConfig = {
|
||||
visible: false,
|
||||
open: true,
|
||||
sortOrder: 50,
|
||||
categoryId: 'recent',
|
||||
categoryLabel: '最近创作',
|
||||
categorySortOrder: 10,
|
||||
updatedAtMicros: 1,
|
||||
},
|
||||
{
|
||||
@@ -79,6 +99,9 @@ const testEntryConfig = {
|
||||
visible: false,
|
||||
open: false,
|
||||
sortOrder: 60,
|
||||
categoryId: 'recent',
|
||||
categoryLabel: '最近创作',
|
||||
categorySortOrder: 10,
|
||||
updatedAtMicros: 1,
|
||||
},
|
||||
{
|
||||
@@ -90,6 +113,9 @@ const testEntryConfig = {
|
||||
visible: true,
|
||||
open: false,
|
||||
sortOrder: 70,
|
||||
categoryId: 'recent',
|
||||
categoryLabel: '最近创作',
|
||||
categorySortOrder: 10,
|
||||
updatedAtMicros: 1,
|
||||
},
|
||||
],
|
||||
@@ -665,17 +691,17 @@ test('creation hub works-only tab filters bark battle draft and published works'
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(screen.getByRole('button', { name: '全部 2' })).toBeTruthy();
|
||||
expect(screen.getByRole('button', { name: '草稿 1' })).toBeTruthy();
|
||||
expect(screen.getByRole('button', { name: '已发布 1' })).toBeTruthy();
|
||||
expect(screen.getByRole('tab', { name: '全部 2' })).toBeTruthy();
|
||||
expect(screen.getByRole('tab', { name: '草稿 1' })).toBeTruthy();
|
||||
expect(screen.getByRole('tab', { name: '已发布 1' })).toBeTruthy();
|
||||
expect(screen.getByText('竖屏声浪草稿')).toBeTruthy();
|
||||
expect(screen.getByText('竖屏声浪已发布')).toBeTruthy();
|
||||
|
||||
await user.click(screen.getByRole('button', { name: '草稿 1' }));
|
||||
await user.click(screen.getByRole('tab', { name: '草稿 1' }));
|
||||
expect(screen.getByText('竖屏声浪草稿')).toBeTruthy();
|
||||
expect(screen.queryByText('竖屏声浪已发布')).toBeNull();
|
||||
|
||||
await user.click(screen.getByRole('button', { name: '已发布 1' }));
|
||||
await user.click(screen.getByRole('tab', { name: '已发布 1' }));
|
||||
expect(screen.queryByText('竖屏声浪草稿')).toBeNull();
|
||||
expect(screen.getByText('竖屏声浪已发布')).toBeTruthy();
|
||||
|
||||
@@ -880,6 +906,38 @@ test('creation hub published share icon is shown directly on the card header', (
|
||||
expect(screen.queryByRole('button', { name: '删除' })).toBeNull();
|
||||
});
|
||||
|
||||
test('creation hub shows RPG published share icon without library entry', () => {
|
||||
render(
|
||||
<CustomWorldCreationHub
|
||||
items={[
|
||||
{
|
||||
...baseDraftItem,
|
||||
workId: 'published:world-public-1',
|
||||
sourceType: 'published_profile',
|
||||
status: 'published',
|
||||
title: '潮雾列岛已发布版',
|
||||
profileId: 'world-public-1',
|
||||
canResume: false,
|
||||
canEnterWorld: true,
|
||||
},
|
||||
]}
|
||||
rpgLibraryEntries={[]}
|
||||
loading={false}
|
||||
error={null}
|
||||
onRetry={() => {}}
|
||||
onCreateType={noopCreateType}
|
||||
onOpenDraft={() => {}}
|
||||
onEnterPublished={() => {}}
|
||||
entryConfig={testEntryConfig}
|
||||
creationTypes={testCreationTypes}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(screen.getByText('潮雾列岛已发布版')).toBeTruthy();
|
||||
expect(screen.getByRole('button', { name: '分享' })).toBeTruthy();
|
||||
expect(screen.queryByText('作者:玩家')).toBeNull();
|
||||
});
|
||||
|
||||
test('creation hub left swipe draft reveals delete without opening card', () => {
|
||||
const onDeletePublished = vi.fn();
|
||||
const onOpenDraft = vi.fn();
|
||||
|
||||
Reference in New Issue
Block a user