This commit is contained in:
2026-05-02 17:56:42 +08:00
parent 2311edb2e6
commit acc55d0e13
40 changed files with 2582 additions and 931 deletions

View File

@@ -171,6 +171,9 @@ import { getRpgProfilePlayStats } from '../../services/rpg-entry/rpgProfileClien
import { requestRpgRuntimeJson } from '../../services/rpg-runtime/rpgRuntimeRequest';
import type { CustomWorldProfile } from '../../types';
import { useAuthUi } from '../auth/AuthUiContext';
import { PublishShareModal } from '../common/PublishShareModal';
import type { PublishShareModalPayload } from '../common/publishShareModalModel';
import { UnifiedModal } from '../common/UnifiedModal';
import {
isBigFishGalleryEntry,
isMatch3DGalleryEntry,
@@ -227,6 +230,13 @@ type PuzzleSaveArchiveState = {
currentLevelId?: unknown;
};
type DeleteCreationWorkConfirmation = {
id: string;
title: string;
detail: string;
run: () => void;
};
async function resumePuzzleProfileSaveArchiveRaw(worldKey: string) {
return requestRpgRuntimeJson<
ProfileSaveArchiveResumeResponse<PuzzleSaveArchiveState>
@@ -345,7 +355,10 @@ function mapPublicWorkDetailToMatch3DWork(
workId: entry.workId,
profileId: entry.profileId,
ownerUserId: entry.ownerUserId,
sourceSessionId: null,
sourceSessionId:
'sourceSessionId' in entry && typeof entry.sourceSessionId === 'string'
? entry.sourceSessionId
: null,
gameName: entry.worldName,
themeText: entry.themeTags[0] ?? '经典消除',
summary: entry.summaryText,
@@ -403,7 +416,10 @@ function mapPublicWorkDetailToPuzzleWork(
workId: entry.workId,
profileId: entry.profileId,
ownerUserId: entry.ownerUserId,
sourceSessionId: null,
sourceSessionId:
'sourceSessionId' in entry && typeof entry.sourceSessionId === 'string'
? entry.sourceSessionId
: null,
authorDisplayName: entry.authorDisplayName,
levelName: entry.worldName,
summary: entry.summaryText,
@@ -1000,10 +1016,14 @@ export function PlatformEntryFlowShellImpl({
const [deletingCreationWorkId, setDeletingCreationWorkId] = useState<
string | null
>(null);
const [pendingDeleteCreationWork, setPendingDeleteCreationWork] =
useState<DeleteCreationWorkConfirmation | null>(null);
const [
claimingPuzzlePointIncentiveProfileId,
setClaimingPuzzlePointIncentiveProfileId,
] = useState<string | null>(null);
const [publishSharePayload, setPublishSharePayload] =
useState<PublishShareModalPayload | null>(null);
const isBigFishCreationVisible = isPlatformCreationTypeVisible('big-fish');
const [profilePlayStats, setProfilePlayStats] =
useState<ProfilePlayStatsResponse | null>(null);
@@ -1279,6 +1299,50 @@ export function PlatformEntryFlowShellImpl({
() => agentResultPreview?.qualityFindings ?? [],
[agentResultPreview],
);
const openPublishShareModal = useCallback(
(payload: PublishShareModalPayload) => {
const publicWorkCode = payload.publicWorkCode.trim();
if (!publicWorkCode) {
return;
}
setPublishSharePayload({
...payload,
publicWorkCode,
title: payload.title.trim() || '我的作品',
});
},
[],
);
const openRpgPublishShareModal = useCallback(
async (profile: CustomWorldProfile | null | undefined) => {
const profileId = profile?.id?.trim();
if (!profileId) {
return;
}
const profileName = profile?.name?.trim() || '我的作品';
const galleryEntries = await platformBootstrap
.refreshPublishedGallery()
.catch(() => [] as CustomWorldGalleryCard[]);
const galleryEntry = galleryEntries.find(
(entry) => entry.profileId === profileId,
);
const publicWorkCode = galleryEntry?.publicWorkCode?.trim();
if (!publicWorkCode) {
return;
}
openPublishShareModal({
title: galleryEntry?.worldName || profileName,
publicWorkCode,
stage: 'work-detail',
});
},
[openPublishShareModal, platformBootstrap],
);
const agentResultPreviewSourceLabel = useMemo(() => {
if (!agentResultPreview?.source) {
return null;
@@ -1347,6 +1411,13 @@ export function PlatformEntryFlowShellImpl({
const resultViewError =
autosaveCoordinator.customWorldAutoSaveError ??
sessionController.customWorldError;
const isSelectedPublicWorkOwned = Boolean(
authUi?.user?.id &&
selectedPublicWorkDetail?.ownerUserId === authUi.user.id,
);
const selectedPublicWorkActionMode = isSelectedPublicWorkOwned
? 'edit'
: 'remix';
useEffect(() => {
if (
@@ -1374,6 +1445,37 @@ export function PlatformEntryFlowShellImpl({
[authUi],
);
const requestDeleteCreationWork = useCallback(
(confirmation: DeleteCreationWorkConfirmation) => {
if (deletingCreationWorkId) {
return;
}
runProtectedAction(() => {
setPendingDeleteCreationWork(confirmation);
});
},
[deletingCreationWorkId, runProtectedAction],
);
const closeDeleteCreationWorkConfirmation = useCallback(() => {
if (deletingCreationWorkId) {
return;
}
setPendingDeleteCreationWork(null);
}, [deletingCreationWorkId]);
const confirmDeleteCreationWork = useCallback(() => {
const confirmation = pendingDeleteCreationWork;
if (!confirmation || deletingCreationWorkId) {
return;
}
setPendingDeleteCreationWork(null);
confirmation.run();
}, [deletingCreationWorkId, pendingDeleteCreationWork]);
const prepareCreationLaunch = useCallback(() => {
if (sessionController.isCreatingAgentSession) {
return false;
@@ -1433,6 +1535,11 @@ export function PlatformEntryFlowShellImpl({
if (payload.action === 'big_fish_publish_game') {
void refreshBigFishShelf();
void refreshBigFishGallery();
openPublishShareModal({
title: response.session.draft?.title ?? '大鱼吃小鱼',
publicWorkCode: buildBigFishPublicWorkCode(response.session.sessionId),
stage: 'big-fish-runtime',
});
}
if (payload.action !== 'big_fish_compile_draft') {
return;
@@ -1610,6 +1717,11 @@ export function PlatformEntryFlowShellImpl({
buildPuzzlePublicWorkCode(galleryDetail.item.profileId),
),
);
openPublishShareModal({
title: galleryDetail.item.workTitle || galleryDetail.item.levelName,
publicWorkCode: buildPuzzlePublicWorkCode(galleryDetail.item.profileId),
stage: 'puzzle-gallery-detail',
});
}
},
beforeExecuteAction: ({ payload }) => {
@@ -1805,6 +1917,7 @@ export function PlatformEntryFlowShellImpl({
setPuzzleError(null);
setDeletingCreationWorkId(null);
setClaimingPuzzlePointIncentiveProfileId(null);
setPublishSharePayload(null);
setProfilePlayStats(null);
setProfilePlayStatsError(null);
setIsProfilePlayStatsOpen(false);
@@ -2623,6 +2736,46 @@ export function PlatformEntryFlowShellImpl({
],
);
const remodelCurrentPuzzleRuntimeWork = useCallback((profileId: string) => {
const targetProfileId = profileId.trim();
if (!targetProfileId || isPublicWorkDetailBusy || isPuzzleBusy) {
return;
}
runProtectedAction(() => {
setIsPublicWorkDetailBusy(true);
setIsPuzzleBusy(true);
setPuzzleError(null);
setPublicWorkDetailError(null);
void remixPuzzleGalleryWork(targetProfileId)
.then((response) => {
puzzleFlow.setSession(response.session);
setPuzzleOperation(null);
setPuzzleRun(null);
enterCreateTab();
setSelectionStage('puzzle-result');
})
.catch((error) => {
setPuzzleError(resolvePuzzleErrorMessage(error, '改造拼图作品失败。'));
})
.finally(() => {
setIsPublicWorkDetailBusy(false);
setIsPuzzleBusy(false);
});
});
}, [
enterCreateTab,
isPublicWorkDetailBusy,
isPuzzleBusy,
puzzleFlow,
resolvePuzzleErrorMessage,
runProtectedAction,
setIsPuzzleBusy,
setPuzzleError,
setSelectionStage,
]);
const leaveAgentWorkspace = useCallback(() => {
enterCreateTab();
sessionController.resetSessionViewState();
@@ -2696,34 +2849,32 @@ export function PlatformEntryFlowShellImpl({
return;
}
runProtectedAction(() => {
const confirmed = window.confirm(
`确认删除作品《${entry.worldName}》吗?删除后会从你的作品列表和公开广场中移除。`,
);
if (!confirmed) {
return;
}
requestDeleteCreationWork({
id: entry.profileId,
title: entry.worldName,
detail: '删除后会从你的作品列表和公开广场中移除。',
run: () => {
setDeletingCreationWorkId(entry.profileId);
platformBootstrap.setPlatformError(null);
setDeletingCreationWorkId(entry.profileId);
platformBootstrap.setPlatformError(null);
void deleteRpgEntryWorldProfile(entry.profileId)
.then(async (entries) => {
platformBootstrap.setSavedCustomWorldEntries(entries);
await platformBootstrap.refreshCustomWorldWorks().catch(() => []);
await platformBootstrap.refreshPublishedGallery().catch(() => []);
})
.catch((error) => {
platformBootstrap.setPlatformError(
resolveRpgCreationErrorMessage(error, '删除自定义世界失败。'),
);
})
.finally(() => {
setDeletingCreationWorkId(null);
});
void deleteRpgEntryWorldProfile(entry.profileId)
.then(async (entries) => {
platformBootstrap.setSavedCustomWorldEntries(entries);
await platformBootstrap.refreshCustomWorldWorks().catch(() => []);
await platformBootstrap.refreshPublishedGallery().catch(() => []);
})
.catch((error) => {
platformBootstrap.setPlatformError(
resolveRpgCreationErrorMessage(error, '删除自定义世界失败。'),
);
})
.finally(() => {
setDeletingCreationWorkId(null);
});
},
});
},
[deletingCreationWorkId, platformBootstrap, runProtectedAction],
[deletingCreationWorkId, platformBootstrap, requestDeleteCreationWork],
);
const handleDeletePublishedWork = useCallback(
@@ -2732,47 +2883,51 @@ export function PlatformEntryFlowShellImpl({
return;
}
runProtectedAction(() => {
const confirmed = window.confirm(
`确认删除作品《${work.title}》吗?删除后会从你的作品列表和公开广场中移除。`,
);
if (!confirmed) {
return;
}
setDeletingCreationWorkId(work.workId);
platformBootstrap.setPlatformError(null);
requestDeleteCreationWork({
id: work.workId,
title: work.title,
detail:
work.status === 'published'
? '删除后会从你的作品列表和公开广场中移除。'
: '删除后会从你的作品列表中移除。',
run: () => {
setDeletingCreationWorkId(work.workId);
platformBootstrap.setPlatformError(null);
const deleteTask =
work.sourceType === 'published_profile' && work.profileId
? deleteRpgEntryWorldProfile(work.profileId).then(
async (entries) => {
platformBootstrap.setSavedCustomWorldEntries(entries);
await platformBootstrap
.refreshCustomWorldWorks()
.catch(() => []);
},
)
: work.sourceType === 'agent_session' && work.sessionId
? deleteRpgCreationAgentSession(work.sessionId).then((items) => {
platformBootstrap.setCustomWorldWorkEntries(items);
})
: Promise.reject(new Error('当前 RPG 作品缺少可删除 ID。'));
const deleteTask =
work.sourceType === 'published_profile' && work.profileId
? deleteRpgEntryWorldProfile(work.profileId).then(
async (entries) => {
platformBootstrap.setSavedCustomWorldEntries(entries);
await platformBootstrap
.refreshCustomWorldWorks()
.catch(() => []);
},
)
: work.sourceType === 'agent_session' && work.sessionId
? deleteRpgCreationAgentSession(work.sessionId).then(
(items) => {
platformBootstrap.setCustomWorldWorkEntries(items);
},
)
: Promise.reject(new Error('当前 RPG 作品缺少可删除 ID。'));
void deleteTask
.then(async () => {
await platformBootstrap.refreshPublishedGallery().catch(() => []);
})
.catch((error) => {
platformBootstrap.setPlatformError(
resolveRpgCreationErrorMessage(error, '删除自定义世界失败。'),
);
})
.finally(() => {
setDeletingCreationWorkId(null);
});
void deleteTask
.then(async () => {
await platformBootstrap.refreshPublishedGallery().catch(() => []);
})
.catch((error) => {
platformBootstrap.setPlatformError(
resolveRpgCreationErrorMessage(error, '删除自定义世界失败。'),
);
})
.finally(() => {
setDeletingCreationWorkId(null);
});
},
});
},
[deletingCreationWorkId, platformBootstrap, runProtectedAction],
[deletingCreationWorkId, platformBootstrap, requestDeleteCreationWork],
);
const handleDeleteBigFishWork = useCallback(
@@ -2781,37 +2936,39 @@ export function PlatformEntryFlowShellImpl({
return;
}
runProtectedAction(() => {
const confirmed = window.confirm(
`确认删除作品《${work.title}》吗?删除后会从你的作品列表中移除。`,
);
if (!confirmed) {
return;
}
requestDeleteCreationWork({
id: work.workId,
title: work.title,
detail:
work.status === 'published'
? '删除后会从你的作品列表和公开广场中移除。'
: '删除后会从你的作品列表中移除。',
run: () => {
setDeletingCreationWorkId(work.workId);
setBigFishError(null);
setDeletingCreationWorkId(work.workId);
setBigFishError(null);
void deleteBigFishWork(work.sourceSessionId)
.then(async (response) => {
setBigFishWorks(response.items);
await refreshBigFishGallery().catch(() => []);
})
.catch((error) => {
setBigFishError(
resolveBigFishErrorMessage(error, '删除大鱼吃小鱼作品失败。'),
);
})
.finally(() => {
setDeletingCreationWorkId(null);
});
void deleteBigFishWork(work.sourceSessionId)
.then(async (response) => {
setBigFishWorks(response.items);
await refreshBigFishGallery().catch(() => []);
})
.catch((error) => {
setBigFishError(
resolveBigFishErrorMessage(error, '删除大鱼吃小鱼作品失败。'),
);
})
.finally(() => {
setDeletingCreationWorkId(null);
});
},
});
},
[
deletingCreationWorkId,
refreshBigFishGallery,
requestDeleteCreationWork,
resolveBigFishErrorMessage,
runProtectedAction,
setBigFishError,
],
);
@@ -2821,40 +2978,42 @@ export function PlatformEntryFlowShellImpl({
return;
}
runProtectedAction(() => {
const displayName =
work.workTitle?.trim() || work.levelName.trim() || '未命名拼图';
const confirmed = window.confirm(
`确认删除作品《${displayName}》吗?删除后会从你的作品列表和公开广场中移除。`,
);
if (!confirmed) {
return;
}
const displayName =
work.workTitle?.trim() || work.levelName.trim() || '未命名拼图';
requestDeleteCreationWork({
id: work.workId,
title: displayName,
detail:
work.publicationStatus === 'published'
? '删除后会从你的作品列表和公开广场中移除。'
: '删除后会从你的作品列表中移除。',
run: () => {
setDeletingCreationWorkId(work.workId);
setPuzzleFormDraftPayload(null);
setPuzzleError(null);
setDeletingCreationWorkId(work.workId);
setPuzzleFormDraftPayload(null);
setPuzzleError(null);
void deletePuzzleWork(work.profileId)
.then((response) => {
setPuzzleWorks(response.items);
void refreshPuzzleGallery();
})
.catch((error) => {
setPuzzleError(
resolvePuzzleErrorMessage(error, '删除拼图作品失败。'),
);
})
.finally(() => {
setDeletingCreationWorkId(null);
});
void deletePuzzleWork(work.profileId)
.then((response) => {
setPuzzleWorks(response.items);
void refreshPuzzleGallery();
})
.catch((error) => {
setPuzzleError(
resolvePuzzleErrorMessage(error, '删除拼图作品失败。'),
);
})
.finally(() => {
setDeletingCreationWorkId(null);
});
},
});
},
[
deletingCreationWorkId,
refreshPuzzleGallery,
requestDeleteCreationWork,
resolvePuzzleErrorMessage,
runProtectedAction,
setPuzzleError,
],
);
@@ -2864,37 +3023,38 @@ export function PlatformEntryFlowShellImpl({
return;
}
runProtectedAction(() => {
const confirmed = window.confirm(
`确认删除作品《${work.gameName}》吗?删除后会从你的作品列表中移除。`,
);
if (!confirmed) {
return;
}
requestDeleteCreationWork({
id: work.workId,
title: work.gameName,
detail:
work.publicationStatus === 'published'
? '删除后会从你的作品列表和公开广场中移除。'
: '删除后会从你的作品列表中移除。',
run: () => {
setDeletingCreationWorkId(work.workId);
setMatch3DError(null);
setDeletingCreationWorkId(work.workId);
setMatch3DError(null);
void deleteMatch3DWork(work.profileId)
.then((response) => {
setMatch3DWorks(response.items);
void refreshMatch3DGallery();
})
.catch((error) => {
setMatch3DError(
resolveMatch3DErrorMessage(error, '删除抓大鹅作品失败。'),
);
})
.finally(() => {
setDeletingCreationWorkId(null);
});
void deleteMatch3DWork(work.profileId)
.then((response) => {
setMatch3DWorks(response.items);
void refreshMatch3DGallery();
})
.catch((error) => {
setMatch3DError(
resolveMatch3DErrorMessage(error, '删除抓大鹅作品失败。'),
);
})
.finally(() => {
setDeletingCreationWorkId(null);
});
},
});
},
[
deletingCreationWorkId,
refreshMatch3DGallery,
requestDeleteCreationWork,
resolveMatch3DErrorMessage,
runProtectedAction,
setMatch3DError,
],
);
@@ -3326,12 +3486,15 @@ export function PlatformEntryFlowShellImpl({
);
const openMatch3DDraft = useCallback(
async (item: Match3DWorkSummary) => {
async (
item: Match3DWorkSummary,
options: { forceDraft?: boolean } = {},
) => {
setMatch3DRun(null);
setMatch3DError(null);
setMatch3DProfile(null);
if (item.publicationStatus === 'published') {
if (item.publicationStatus === 'published' && !options.forceDraft) {
openPublicWorkDetail(mapMatch3DWorkToPublicWorkDetail(item));
return;
}
@@ -3368,6 +3531,19 @@ export function PlatformEntryFlowShellImpl({
],
);
const openBigFishDraft = useCallback(
async (item: BigFishWorkSummary) => {
setBigFishRun(null);
const restoredSession = await bigFishFlow.restoreDraft(
item.sourceSessionId,
);
if (!restoredSession) {
await refreshBigFishShelf().catch(() => undefined);
}
},
[bigFishFlow, refreshBigFishShelf],
);
const startBigFishRunFromWork = useCallback(
(
item: BigFishWorkSummary,
@@ -3580,12 +3756,94 @@ export function PlatformEntryFlowShellImpl({
],
);
const editOwnedPublicWork = useCallback(
(entry: PlatformPublicGalleryCard) => {
if (isPublicWorkDetailBusy) {
return;
}
runProtectedAction(() => {
setPublicWorkDetailError(null);
// 中文注释:自有公开作品必须恢复原草稿,不能复用 remix 复制链路。
if (isBigFishGalleryEntry(entry)) {
const work = mapPublicWorkDetailToBigFishWork(entry);
if (!work?.sourceSessionId?.trim()) {
setPublicWorkDetailError(
'这份大鱼吃小鱼作品缺少原草稿会话,暂时无法编辑。',
);
return;
}
void openBigFishDraft(work);
return;
}
if (isPuzzleGalleryEntry(entry)) {
const work =
selectedPuzzleDetail?.profileId === entry.profileId
? selectedPuzzleDetail
: mapPublicWorkDetailToPuzzleWork(entry);
if (!work?.sourceSessionId?.trim()) {
setPublicWorkDetailError(
'这份拼图作品缺少原草稿会话,暂时无法编辑。',
);
return;
}
void openPuzzleDraft(work);
return;
}
if (isMatch3DGalleryEntry(entry)) {
const work = mapPublicWorkDetailToMatch3DWork(entry);
if (!work?.sourceSessionId?.trim()) {
setPublicWorkDetailError(
'这份抓大鹅作品缺少原草稿会话,暂时无法编辑。',
);
return;
}
void openMatch3DDraft(work, { forceDraft: true });
return;
}
const editEntry =
selectedDetailEntry?.profileId === entry.profileId
? selectedDetailEntry
: null;
if (!editEntry) {
setPublicWorkDetailError('作品详情尚未读取完成。');
return;
}
void detailNavigation.openSavedCustomWorldEditor(editEntry);
});
},
[
detailNavigation,
isPublicWorkDetailBusy,
openBigFishDraft,
openMatch3DDraft,
openPuzzleDraft,
runProtectedAction,
selectedDetailEntry,
selectedPuzzleDetail,
],
);
const remixSelectedPublicWork = useCallback(() => {
if (!selectedPublicWorkDetail) {
return;
}
if (isSelectedPublicWorkOwned) {
editOwnedPublicWork(selectedPublicWorkDetail);
return;
}
remixPublicWork(selectedPublicWorkDetail);
}, [remixPublicWork, selectedPublicWorkDetail]);
}, [
editOwnedPublicWork,
isSelectedPublicWorkOwned,
remixPublicWork,
selectedPublicWorkDetail,
]);
const handlePublicCodeSearch = useCallback(
async (keyword: string) => {
@@ -3906,19 +4164,6 @@ export function PlatformEntryFlowShellImpl({
void handlePublicCodeSearch(publicWorkCode);
}, [handlePublicCodeSearch, initialPublicWorkCode]);
const openBigFishDraft = useCallback(
async (item: BigFishWorkSummary) => {
setBigFishRun(null);
const restoredSession = await bigFishFlow.restoreDraft(
item.sourceSessionId,
);
if (!restoredSession) {
await refreshBigFishShelf().catch(() => undefined);
}
},
[bigFishFlow, refreshBigFishShelf],
);
useEffect(() => {
if (selectionStage === 'platform') {
if (isBigFishCreationVisible) {
@@ -4209,6 +4454,7 @@ export function PlatformEntryFlowShellImpl({
isMatch3DBusy
}
error={publicWorkDetailError}
actionMode={selectedPublicWorkActionMode}
visibleCoverCount={resolveVisiblePuzzleDetailCoverCount(
selectedPublicWorkDetail,
puzzleRun,
@@ -4250,6 +4496,9 @@ export function PlatformEntryFlowShellImpl({
}
isBusy={detailNavigation.isMutatingDetail}
error={detailNavigation.detailError}
actionMode={
detailNavigation.isSelectedWorldOwned ? 'edit' : 'remix'
}
onBack={() => {
detailNavigation.setDetailError(null);
clearSelectedPublicWorkAuthor();
@@ -4262,9 +4511,13 @@ export function PlatformEntryFlowShellImpl({
}}
onStart={handleStartSelectedWorld}
onRemix={() => {
remixPublicWork(
mapRpgGalleryCardToPublicWorkDetail(selectedDetailEntry),
);
const publicWorkEntry =
mapRpgGalleryCardToPublicWorkDetail(selectedDetailEntry);
if (detailNavigation.isSelectedWorldOwned) {
editOwnedPublicWork(publicWorkEntry);
return;
}
remixPublicWork(publicWorkEntry);
}}
/>
) : (
@@ -4574,6 +4827,13 @@ export function PlatformEntryFlowShellImpl({
openPublicWorkDetail(
mapMatch3DWorkToPublicWorkDetail(profile),
);
openPublishShareModal({
title: profile.gameName,
publicWorkCode: buildMatch3DPublicWorkCode(
profile.profileId,
),
stage: 'work-detail',
});
}}
onStartTestRun={(profile) => {
setMatch3DProfile(profile);
@@ -4840,6 +5100,11 @@ export function PlatformEntryFlowShellImpl({
onBack={() => {
setSelectionStage(puzzleRuntimeReturnStage);
}}
onRemodelWork={
selectedPuzzleDetail?.publicationStatus === 'published'
? remodelCurrentPuzzleRuntimeWork
: undefined
}
onSwapPieces={(payload) => {
void swapPuzzlePiecesInRun(payload);
}}
@@ -4980,7 +5245,9 @@ export function PlatformEntryFlowShellImpl({
sessionController.agentSession?.stage !== 'published'
? async () => {
try {
await enterWorldCoordinator.publishCurrentResult();
const publishedProfile =
await enterWorldCoordinator.publishCurrentResult();
void openRpgPublishShareModal(publishedProfile);
} catch (error) {
sessionController.setCustomWorldError(
resolveRpgCreationErrorMessage(
@@ -5144,6 +5411,48 @@ export function PlatformEntryFlowShellImpl({
});
}}
/>
<PublishShareModal
open={Boolean(publishSharePayload)}
payload={publishSharePayload}
onClose={() => setPublishSharePayload(null)}
/>
<UnifiedModal
open={Boolean(pendingDeleteCreationWork)}
title="删除作品"
description={
pendingDeleteCreationWork
? `确认删除《${pendingDeleteCreationWork.title}》吗?`
: undefined
}
onClose={closeDeleteCreationWorkConfirmation}
closeDisabled={Boolean(deletingCreationWorkId)}
closeOnBackdrop={!deletingCreationWorkId}
size="sm"
footer={
<>
<button
type="button"
onClick={closeDeleteCreationWorkConfirmation}
disabled={Boolean(deletingCreationWorkId)}
className="platform-button platform-button--ghost min-h-0 rounded-full px-4 py-2 text-sm"
>
</button>
<button
type="button"
onClick={confirmDeleteCreationWork}
disabled={Boolean(deletingCreationWorkId)}
className="platform-button platform-button--danger min-h-0 rounded-full px-4 py-2 text-sm disabled:cursor-not-allowed disabled:opacity-55"
>
{deletingCreationWorkId ? '删除中' : '确认删除'}
</button>
</>
}
>
<div className="text-sm leading-6 text-[var(--platform-text-base)]">
{pendingDeleteCreationWork?.detail}
</div>
</UnifiedModal>
<AnimatePresence>
{(searchedPublicUser || publicSearchError) && (
<motion.div