This commit is contained in:
2026-04-22 23:44:57 +08:00
parent 76ac9d22a5
commit 84dc92646a
484 changed files with 9598 additions and 9135 deletions

View File

@@ -23,8 +23,12 @@ type CustomWorldCreationHubProps = {
onCreateType: (type: PlatformCreationTypeId) => void;
onOpenDraft: (item: CustomWorldWorkSummary) => void;
onEnterPublished: (profileId: string) => void;
onDeletePublished?: ((item: CustomWorldWorkSummary) => void) | null;
deletingWorkId?: string | null;
onExperienceRpg?: ((item: CustomWorldWorkSummary) => void) | null;
puzzleItems?: PuzzleWorkSummary[];
onOpenPuzzleDetail?: (profileId: string) => void;
onExperiencePuzzle?: ((profileId: string) => void) | null;
};
function EmptyState({ title }: { title: string }) {
@@ -47,8 +51,12 @@ export function CustomWorldCreationHub({
onCreateType,
onOpenDraft,
onEnterPublished,
onDeletePublished = null,
deletingWorkId = null,
onExperienceRpg = null,
puzzleItems = [],
onOpenPuzzleDetail,
onExperiencePuzzle = null,
}: CustomWorldCreationHubProps) {
const [activeFilter, setActiveFilter] =
useState<CustomWorldWorkFilter>('all');
@@ -134,7 +142,7 @@ export function CustomWorldCreationHub({
<CustomWorldWorkCard
key={`${item.kind}-${item.item.workId}`}
item={item}
onClick={() => {
onOpen={() => {
if (item.kind === 'puzzle') {
onOpenPuzzleDetail?.(item.item.profileId);
return;
@@ -152,6 +160,29 @@ export function CustomWorldCreationHub({
onEnterPublished(item.item.profileId);
}
}}
onExperience={
item.kind === 'puzzle'
? item.item.publicationStatus === 'published'
? () => {
onExperiencePuzzle?.(item.item.profileId);
}
: null
: item.item.status === 'published' && item.item.canEnterWorld
? () => {
onExperienceRpg?.(item.item);
}
: null
}
onDelete={
item.kind === 'rpg' &&
item.item.status === 'published' &&
item.item.profileId
? () => {
onDeletePublished?.(item.item);
}
: null
}
deleteBusy={deletingWorkId === item.item.workId}
/>
))}
</div>

View File

@@ -28,25 +28,31 @@ export type UnifiedCreationWorkItem =
type CustomWorldWorkCardProps = {
item: UnifiedCreationWorkItem;
onClick: () => void;
onOpen: () => void;
onExperience?: (() => void) | null;
onDelete?: (() => void) | null;
deleteBusy?: boolean;
};
export function CustomWorldWorkCard({
item,
onClick,
onOpen,
onExperience = null,
onDelete = null,
deleteBusy = false,
}: CustomWorldWorkCardProps) {
const isPuzzle = item.kind === 'puzzle';
const isDraft =
item.kind === 'puzzle'
? item.item.publicationStatus === 'draft'
: item.item.status === 'draft';
const actionLabel = isPuzzle
const openActionLabel = isPuzzle
? '查看详情'
: isDraft
? item.item.playableNpcCount > 0 || item.item.landmarkCount > 0
? '继续完善'
: '继续创作'
: '进入世界';
: '查看详情';
const title = isPuzzle ? item.item.levelName : item.item.title;
const subtitle = isPuzzle ? item.item.authorDisplayName : item.item.subtitle;
const summary = item.item.summary;
@@ -153,13 +159,34 @@ export function CustomWorldWorkCard({
</>
)}
</div>
<button
type="button"
onClick={onClick}
className="platform-button platform-button--primary min-h-0 shrink-0 rounded-full px-4 py-2 text-sm"
>
{actionLabel}
</button>
<div className="flex flex-wrap gap-2 sm:justify-end">
<button
type="button"
onClick={onOpen}
className="platform-button platform-button--primary min-h-0 shrink-0 rounded-full px-4 py-2 text-sm"
>
{openActionLabel}
</button>
{onExperience ? (
<button
type="button"
onClick={onExperience}
className="platform-button platform-button--secondary min-h-0 shrink-0 rounded-full px-4 py-2 text-sm"
>
</button>
) : null}
{onDelete ? (
<button
type="button"
onClick={onDelete}
disabled={deleteBusy}
className="platform-button platform-button--danger min-h-0 shrink-0 rounded-full px-4 py-2 text-sm disabled:cursor-not-allowed disabled:opacity-55"
>
{deleteBusy ? '删除中...' : '删除'}
</button>
) : null}
</div>
</div>
</div>
</div>