feat: complete bark battle playable demo
This commit is contained in:
@@ -2,9 +2,9 @@ import type { BigFishWorkSummary } from '../../../packages/shared/src/contracts/
|
||||
import type { CustomWorldWorkSummary } from '../../../packages/shared/src/contracts/customWorldAgent';
|
||||
import type { Match3DWorkSummary } from '../../../packages/shared/src/contracts/match3dWorks';
|
||||
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 { CustomWorldLibraryEntry } from '../../../packages/shared/src/contracts/runtime';
|
||||
import { buildPublicWorkStagePath } from '../../routing/appPageRoutes';
|
||||
import {
|
||||
buildBigFishPublicWorkCode,
|
||||
@@ -79,6 +79,12 @@ export type CreationWorkShelfSource =
|
||||
item: VisualNovelWorkSummary;
|
||||
};
|
||||
|
||||
export type CreationWorkShelfActions = {
|
||||
open: () => void;
|
||||
delete?: () => void;
|
||||
claimPointIncentive?: () => void;
|
||||
};
|
||||
|
||||
export type CreationWorkShelfItem = {
|
||||
id: string;
|
||||
kind: CreationWorkShelfKind;
|
||||
@@ -97,6 +103,7 @@ export type CreationWorkShelfItem = {
|
||||
badges: CreationWorkShelfBadge[];
|
||||
metrics: CreationWorkShelfMetric[];
|
||||
pointIncentive?: CreationWorkShelfPointIncentive;
|
||||
actions: CreationWorkShelfActions;
|
||||
source: CreationWorkShelfSource;
|
||||
};
|
||||
|
||||
@@ -114,6 +121,20 @@ export function buildCreationWorkShelfItems(params: {
|
||||
canDeleteSquareHole?: boolean;
|
||||
canDeletePuzzle?: boolean;
|
||||
canDeleteVisualNovel?: boolean;
|
||||
onOpenRpgDraft?: (item: CustomWorldWorkSummary) => void;
|
||||
onEnterRpgPublished?: (profileId: string) => void;
|
||||
onDeleteRpg?: (item: CustomWorldWorkSummary) => void;
|
||||
onOpenBigFishDetail?: (item: BigFishWorkSummary) => void;
|
||||
onDeleteBigFish?: (item: BigFishWorkSummary) => void;
|
||||
onOpenMatch3DDetail?: (item: Match3DWorkSummary) => void;
|
||||
onDeleteMatch3D?: (item: Match3DWorkSummary) => void;
|
||||
onOpenSquareHoleDetail?: (item: SquareHoleWorkSummary) => void;
|
||||
onDeleteSquareHole?: (item: SquareHoleWorkSummary) => void;
|
||||
onOpenPuzzleDetail?: (item: PuzzleWorkSummary) => void;
|
||||
onDeletePuzzle?: (item: PuzzleWorkSummary) => void;
|
||||
onClaimPuzzlePointIncentive?: (item: PuzzleWorkSummary) => void;
|
||||
onOpenVisualNovelDetail?: (item: VisualNovelWorkSummary) => void;
|
||||
onDeleteVisualNovel?: (item: VisualNovelWorkSummary) => void;
|
||||
}) {
|
||||
const {
|
||||
rpgItems,
|
||||
@@ -129,26 +150,60 @@ export function buildCreationWorkShelfItems(params: {
|
||||
canDeleteSquareHole = false,
|
||||
canDeletePuzzle = false,
|
||||
canDeleteVisualNovel = false,
|
||||
onOpenRpgDraft,
|
||||
onEnterRpgPublished,
|
||||
onDeleteRpg,
|
||||
onOpenBigFishDetail,
|
||||
onDeleteBigFish,
|
||||
onOpenMatch3DDetail,
|
||||
onDeleteMatch3D,
|
||||
onOpenSquareHoleDetail,
|
||||
onDeleteSquareHole,
|
||||
onOpenPuzzleDetail,
|
||||
onDeletePuzzle,
|
||||
onClaimPuzzlePointIncentive,
|
||||
onOpenVisualNovelDetail,
|
||||
onDeleteVisualNovel,
|
||||
} = params;
|
||||
|
||||
return [
|
||||
...rpgItems.map((item) =>
|
||||
mapRpgWorkToShelfItem(item, canDeleteRpg, rpgLibraryEntries),
|
||||
mapRpgWorkToShelfItem(item, canDeleteRpg, rpgLibraryEntries, {
|
||||
onOpenDraft: onOpenRpgDraft,
|
||||
onEnterPublished: onEnterRpgPublished,
|
||||
onDelete: onDeleteRpg,
|
||||
}),
|
||||
),
|
||||
...bigFishItems.map((item) =>
|
||||
mapBigFishWorkToShelfItem(item, canDeleteBigFish),
|
||||
mapBigFishWorkToShelfItem(item, canDeleteBigFish, {
|
||||
onOpen: onOpenBigFishDetail,
|
||||
onDelete: onDeleteBigFish,
|
||||
}),
|
||||
),
|
||||
...match3dItems.map((item) =>
|
||||
mapMatch3DWorkToShelfItem(item, canDeleteMatch3D),
|
||||
mapMatch3DWorkToShelfItem(item, canDeleteMatch3D, {
|
||||
onOpen: onOpenMatch3DDetail,
|
||||
onDelete: onDeleteMatch3D,
|
||||
}),
|
||||
),
|
||||
...squareHoleItems.map((item) =>
|
||||
mapSquareHoleWorkToShelfItem(item, canDeleteSquareHole),
|
||||
mapSquareHoleWorkToShelfItem(item, canDeleteSquareHole, {
|
||||
onOpen: onOpenSquareHoleDetail,
|
||||
onDelete: onDeleteSquareHole,
|
||||
}),
|
||||
),
|
||||
...puzzleItems.map((item) =>
|
||||
mapPuzzleWorkToShelfItem(item, canDeletePuzzle),
|
||||
mapPuzzleWorkToShelfItem(item, canDeletePuzzle, {
|
||||
onOpen: onOpenPuzzleDetail,
|
||||
onDelete: onDeletePuzzle,
|
||||
onClaimPointIncentive: onClaimPuzzlePointIncentive,
|
||||
}),
|
||||
),
|
||||
...visualNovelItems.map((item) =>
|
||||
mapVisualNovelWorkToShelfItem(item, canDeleteVisualNovel),
|
||||
mapVisualNovelWorkToShelfItem(item, canDeleteVisualNovel, {
|
||||
onOpen: onOpenVisualNovelDetail,
|
||||
onDelete: onDeleteVisualNovel,
|
||||
}),
|
||||
),
|
||||
].sort(
|
||||
(left, right) =>
|
||||
@@ -156,10 +211,26 @@ export function buildCreationWorkShelfItems(params: {
|
||||
);
|
||||
}
|
||||
|
||||
type RpgWorkShelfAdapter = {
|
||||
onOpenDraft?: (item: CustomWorldWorkSummary) => void;
|
||||
onEnterPublished?: (profileId: string) => void;
|
||||
onDelete?: (item: CustomWorldWorkSummary) => void;
|
||||
};
|
||||
|
||||
type WorkShelfAdapter<TItem> = {
|
||||
onOpen?: (item: TItem) => void;
|
||||
onDelete?: (item: TItem) => void;
|
||||
};
|
||||
|
||||
type PuzzleWorkShelfAdapter = WorkShelfAdapter<PuzzleWorkSummary> & {
|
||||
onClaimPointIncentive?: (item: PuzzleWorkSummary) => void;
|
||||
};
|
||||
|
||||
function mapRpgWorkToShelfItem(
|
||||
item: CustomWorldWorkSummary,
|
||||
canDelete: boolean,
|
||||
libraryEntries: CustomWorldLibraryEntry<CustomWorldProfile>[],
|
||||
adapter: RpgWorkShelfAdapter,
|
||||
): CreationWorkShelfItem {
|
||||
const isDraft = item.status === 'draft';
|
||||
const libraryEntry = item.profileId
|
||||
@@ -200,6 +271,7 @@ function mapRpgWorkToShelfItem(
|
||||
: '查看详情',
|
||||
canDelete,
|
||||
canShare: item.status === 'published' && Boolean(publicWorkCode),
|
||||
actions: buildRpgWorkShelfActions(item, adapter),
|
||||
badges,
|
||||
metrics: isDraft ? [] : metrics,
|
||||
source: { kind: 'rpg', item },
|
||||
@@ -209,6 +281,7 @@ function mapRpgWorkToShelfItem(
|
||||
function mapBigFishWorkToShelfItem(
|
||||
item: BigFishWorkSummary,
|
||||
canDelete: boolean,
|
||||
adapter: WorkShelfAdapter<BigFishWorkSummary>,
|
||||
): CreationWorkShelfItem {
|
||||
const isPublished = item.status === 'published';
|
||||
const publicWorkCode = isPublished
|
||||
@@ -233,6 +306,7 @@ function mapBigFishWorkToShelfItem(
|
||||
openActionLabel: item.status === 'draft' ? '继续创作' : '查看详情',
|
||||
canDelete,
|
||||
canShare: isPublished && Boolean(publicWorkCode),
|
||||
actions: buildWorkShelfActions(item, adapter),
|
||||
badges: [
|
||||
buildStatusBadge(item.status),
|
||||
{ id: 'type', label: '大鱼', tone: 'neutral' },
|
||||
@@ -251,6 +325,7 @@ function mapBigFishWorkToShelfItem(
|
||||
function mapMatch3DWorkToShelfItem(
|
||||
item: Match3DWorkSummary,
|
||||
canDelete: boolean,
|
||||
adapter: WorkShelfAdapter<Match3DWorkSummary>,
|
||||
): CreationWorkShelfItem {
|
||||
const status = item.publicationStatus === 'published' ? 'published' : 'draft';
|
||||
const publicWorkCode =
|
||||
@@ -274,6 +349,7 @@ function mapMatch3DWorkToShelfItem(
|
||||
openActionLabel: status === 'published' ? '查看详情' : '继续创作',
|
||||
canDelete,
|
||||
canShare: status === 'published' && Boolean(publicWorkCode),
|
||||
actions: buildWorkShelfActions(item, adapter),
|
||||
badges: [
|
||||
buildStatusBadge(status),
|
||||
{ id: 'type', label: '抓鹅', tone: 'neutral' },
|
||||
@@ -293,6 +369,7 @@ function mapMatch3DWorkToShelfItem(
|
||||
function mapPuzzleWorkToShelfItem(
|
||||
item: PuzzleWorkSummary,
|
||||
canDelete: boolean,
|
||||
adapter: PuzzleWorkShelfAdapter,
|
||||
): CreationWorkShelfItem {
|
||||
const status = item.publicationStatus;
|
||||
const publicWorkCode =
|
||||
@@ -320,6 +397,7 @@ function mapPuzzleWorkToShelfItem(
|
||||
status === 'published' && !item.sourceSessionId ? '查看详情' : '继续创作',
|
||||
canDelete,
|
||||
canShare: status === 'published' && Boolean(publicWorkCode),
|
||||
actions: buildPuzzleWorkShelfActions(item, adapter),
|
||||
badges: [
|
||||
buildStatusBadge(status),
|
||||
{ id: 'type', label: '拼图', tone: 'neutral' },
|
||||
@@ -354,6 +432,7 @@ function mapPuzzleWorkToShelfItem(
|
||||
function mapVisualNovelWorkToShelfItem(
|
||||
item: VisualNovelWorkSummary,
|
||||
canDelete: boolean,
|
||||
adapter: WorkShelfAdapter<VisualNovelWorkSummary>,
|
||||
): CreationWorkShelfItem {
|
||||
const status =
|
||||
item.publishStatus === 'published' ? 'published' : 'draft';
|
||||
@@ -394,6 +473,7 @@ function mapVisualNovelWorkToShelfItem(
|
||||
likeCount: 0,
|
||||
})
|
||||
: [],
|
||||
actions: buildWorkShelfActions(item, adapter),
|
||||
source: { kind: 'visual-novel', item },
|
||||
};
|
||||
}
|
||||
@@ -401,6 +481,7 @@ function mapVisualNovelWorkToShelfItem(
|
||||
function mapSquareHoleWorkToShelfItem(
|
||||
item: SquareHoleWorkSummary,
|
||||
canDelete: boolean,
|
||||
adapter: WorkShelfAdapter<SquareHoleWorkSummary>,
|
||||
): CreationWorkShelfItem {
|
||||
const status = item.publicationStatus === 'published' ? 'published' : 'draft';
|
||||
const publicWorkCode =
|
||||
@@ -438,10 +519,65 @@ function mapSquareHoleWorkToShelfItem(
|
||||
likeCount: 0,
|
||||
})
|
||||
: [],
|
||||
actions: buildWorkShelfActions(item, adapter),
|
||||
source: { kind: 'square-hole', item },
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
function buildWorkShelfActions<TItem>(
|
||||
item: TItem,
|
||||
adapter: WorkShelfAdapter<TItem>,
|
||||
): CreationWorkShelfActions {
|
||||
return {
|
||||
open: () => {
|
||||
adapter.onOpen?.(item);
|
||||
},
|
||||
delete: adapter.onDelete
|
||||
? () => {
|
||||
adapter.onDelete?.(item);
|
||||
}
|
||||
: undefined,
|
||||
};
|
||||
}
|
||||
|
||||
function buildPuzzleWorkShelfActions(
|
||||
item: PuzzleWorkSummary,
|
||||
adapter: PuzzleWorkShelfAdapter,
|
||||
): CreationWorkShelfActions {
|
||||
return {
|
||||
...buildWorkShelfActions(item, adapter),
|
||||
claimPointIncentive: adapter.onClaimPointIncentive
|
||||
? () => {
|
||||
adapter.onClaimPointIncentive?.(item);
|
||||
}
|
||||
: undefined,
|
||||
};
|
||||
}
|
||||
|
||||
function buildRpgWorkShelfActions(
|
||||
item: CustomWorldWorkSummary,
|
||||
adapter: RpgWorkShelfAdapter,
|
||||
): CreationWorkShelfActions {
|
||||
return {
|
||||
open: () => {
|
||||
if (item.status === 'draft') {
|
||||
adapter.onOpenDraft?.(item);
|
||||
return;
|
||||
}
|
||||
|
||||
if (item.profileId) {
|
||||
adapter.onEnterPublished?.(item.profileId);
|
||||
}
|
||||
},
|
||||
delete: adapter.onDelete
|
||||
? () => {
|
||||
adapter.onDelete?.(item);
|
||||
}
|
||||
: undefined,
|
||||
};
|
||||
}
|
||||
|
||||
function buildPublishedMetrics(params: {
|
||||
playCount?: number | null;
|
||||
remixCount?: number | null;
|
||||
|
||||
Reference in New Issue
Block a user