重构作品分享链路

统一发布分享弹窗为作品分享卡片

支持下载分享卡与小程序九宫切图保存

小程序复制链接改为可直达作品详情的 web-view 路径

修复本地 dev Rust 构建绕过损坏 sccache

补充分享链路与 dev 启动文档和测试
This commit is contained in:
2026-06-11 21:32:29 +08:00
parent ccb5023197
commit c5763fdf25
37 changed files with 1958 additions and 305 deletions

View File

@@ -1093,6 +1093,9 @@ test('creation hub published share icon opens unified share payload without open
title: '沉钟拼图',
publicWorkCode: 'PZ-PROFILE1',
stage: 'puzzle-gallery-detail',
workTypeLabel: '拼图',
coverImageSrc: null,
fallbackCoverImageSrc: '/creation-type-references/puzzle.webp',
});
expect(onOpenPuzzleDetail).not.toHaveBeenCalled();
});

View File

@@ -8,10 +8,10 @@ import type { JumpHopWorkSummaryResponse } from '../../../packages/shared/src/co
import type { Match3DWorkSummary } from '../../../packages/shared/src/contracts/match3dWorks';
import type { PuzzleClearWorkSummaryResponse } from '../../../packages/shared/src/contracts/puzzleClear';
import type { PuzzleWorkSummary } from '../../../packages/shared/src/contracts/puzzleWorkSummary';
import type { WoodenFishWorkSummaryResponse } from '../../../packages/shared/src/contracts/woodenFish';
import type { CustomWorldLibraryEntry } from '../../../packages/shared/src/contracts/runtime';
import type { SquareHoleWorkSummary } from '../../../packages/shared/src/contracts/squareHoleWorks';
import type { VisualNovelWorkSummary } from '../../../packages/shared/src/contracts/visualNovel';
import type { WoodenFishWorkSummaryResponse } from '../../../packages/shared/src/contracts/woodenFish';
import { resolveSelectionStageFromPath } from '../../routing/appPageRoutes';
import type { CreationEntryConfig } from '../../services/creationEntryConfigService';
import type { CustomWorldProfile } from '../../types';
@@ -23,10 +23,12 @@ import type {
import { isPlatformCreationTypeVisible } from '../platform-entry/platformEntryCreationTypes';
import {
buildCreationWorkShelfItems,
getCreationWorkShelfItemTime,
CREATION_WORK_KIND_FALLBACK_COVER,
type CreationWorkShelfItem,
type CreationWorkShelfMetricId,
type CreationWorkShelfRuntimeState,
describeCreationWorkShelfKind,
getCreationWorkShelfItemTime,
} from './creationWorkShelf';
import {
CustomWorldCreationStartCard,
@@ -202,6 +204,9 @@ function buildCreationWorkShelfSharePayload(
title: item.title,
publicWorkCode,
stage,
workTypeLabel: describeCreationWorkShelfKind(item.kind),
coverImageSrc: item.coverImageSrc,
fallbackCoverImageSrc: CREATION_WORK_KIND_FALLBACK_COVER[item.kind],
};
}
@@ -351,6 +356,7 @@ export function CustomWorldCreationHub({
puzzleClearItems,
puzzleItems,
rpgLibraryEntries,
squareHoleItems,
onOpenJumpHopDetail,
jumpHopItems,
woodenFishItems,

View File

@@ -7,8 +7,8 @@ import {
Trash2,
} from 'lucide-react';
import {
default as React,
type CSSProperties,
default as React,
type KeyboardEvent as ReactKeyboardEvent,
type PointerEvent as ReactPointerEvent,
type TouchEvent as ReactTouchEvent,
@@ -24,9 +24,9 @@ import {
formatPlatformWorkDisplayTag,
} from '../rpg-entry/rpgEntryWorldPresentation';
import {
CREATION_WORK_KIND_FALLBACK_COVER,
type CreationWorkShelfBadgeTone,
type CreationWorkShelfItem,
type CreationWorkShelfKind,
type CreationWorkShelfMetric,
type CreationWorkShelfMetricId,
formatCreationMetricCount,
@@ -55,21 +55,6 @@ const SWIPE_ACTION_WIDTH_PX = 76;
const SWIPE_REVEAL_THRESHOLD_PX = 42;
const SWIPE_DIRECTION_LOCK_PX = 8;
const EMPTY_PUBLISHED_METRICS: CreationWorkShelfMetric[] = [];
const CREATION_WORK_KIND_FALLBACK_COVER: Record<CreationWorkShelfKind, string> =
{
rpg: '/creation-type-references/rpg.webp',
'big-fish': '/creation-type-references/big-fish.webp',
match3d: '/creation-type-references/match3d.webp',
'square-hole': '/creation-type-references/square-hole.webp',
'jump-hop': '/creation-type-references/jump-hop.webp',
'wooden-fish': '/wooden-fish/default-hit-object.png',
'puzzle-clear': '/creation-type-references/puzzle.webp',
puzzle: '/creation-type-references/puzzle.webp',
'baby-object-match': '/creation-type-references/creative-agent.webp',
'bark-battle': '/creation-type-references/bark-battle.webp',
'visual-novel': '/creation-type-references/visual-novel.webp',
};
function easeOutCubic(progress: number) {
return 1 - (1 - progress) ** 3;
}

View File

@@ -2,20 +2,20 @@ import type { BarkBattleWorkSummary } from '../../../packages/shared/src/contrac
import type { BigFishWorkSummary } from '../../../packages/shared/src/contracts/bigFishWorkSummary';
import type { CustomWorldWorkSummary } from '../../../packages/shared/src/contracts/customWorldAgent';
import type { BabyObjectMatchDraft } from '../../../packages/shared/src/contracts/edutainmentBabyObject';
import type { JumpHopWorkSummaryResponse } from '../../../packages/shared/src/contracts/jumpHop';
import type { Match3DWorkSummary } from '../../../packages/shared/src/contracts/match3dWorks';
import type { PuzzleClearWorkSummaryResponse } from '../../../packages/shared/src/contracts/puzzleClear';
import type { PuzzleWorkSummary } from '../../../packages/shared/src/contracts/puzzleWorkSummary';
import type { CustomWorldLibraryEntry } from '../../../packages/shared/src/contracts/runtime';
import type { SquareHoleWorkSummary } from '../../../packages/shared/src/contracts/squareHoleWorks';
import type { VisualNovelWorkSummary } from '../../../packages/shared/src/contracts/visualNovel';
import type { JumpHopWorkSummaryResponse } from '../../../packages/shared/src/contracts/jumpHop';
import type { WoodenFishWorkSummaryResponse } from '../../../packages/shared/src/contracts/woodenFish';
import { buildPublicWorkStagePath } from '../../routing/appPageRoutes';
import {
buildBabyObjectMatchPublicWorkCode,
buildCustomWorldPublicWorkCode,
buildBarkBattlePublicWorkCode,
buildBigFishPublicWorkCode,
buildCustomWorldPublicWorkCode,
buildJumpHopPublicWorkCode,
buildMatch3DPublicWorkCode,
buildPuzzleClearPublicWorkCode,
@@ -44,6 +44,50 @@ export type CreationWorkShelfKind =
| 'baby-object-match'
| 'bark-battle'
| 'visual-novel';
export const CREATION_WORK_KIND_FALLBACK_COVER: Record<
CreationWorkShelfKind,
string
> = {
rpg: '/creation-type-references/rpg.webp',
'big-fish': '/creation-type-references/big-fish.webp',
match3d: '/creation-type-references/match3d.webp',
'square-hole': '/creation-type-references/square-hole.webp',
'jump-hop': '/creation-type-references/jump-hop.webp',
'wooden-fish': '/wooden-fish/default-hit-object.png',
'puzzle-clear': '/creation-type-references/puzzle.webp',
puzzle: '/creation-type-references/puzzle.webp',
'baby-object-match': '/creation-type-references/creative-agent.webp',
'bark-battle': '/creation-type-references/bark-battle.webp',
'visual-novel': '/creation-type-references/visual-novel.webp',
};
export function describeCreationWorkShelfKind(kind: CreationWorkShelfKind) {
switch (kind) {
case 'rpg':
return 'RPG世界';
case 'big-fish':
return '大鱼吃小鱼';
case 'match3d':
return '抓大鹅';
case 'square-hole':
return '方洞挑战';
case 'jump-hop':
return '跳一跳';
case 'wooden-fish':
return '敲木鱼';
case 'puzzle-clear':
return '拼消消';
case 'puzzle':
return '拼图';
case 'baby-object-match':
return '宝贝识物';
case 'bark-battle':
return '汪汪声浪';
case 'visual-novel':
return '视觉小说';
}
}
export type CreationWorkShelfStatus = 'draft' | 'published';
export type CreationWorkShelfBadgeTone = 'warm' | 'success' | 'neutral';