收口前端平台组件库能力
新增 PlatformUiKit 通用弹窗、按钮、状态、空态、媒体、表单和标签等公共组件 迁移结果页、创作工作台、认证入口、RPG 暗色面板和运行态弹窗的重复 UI chrome 补充组件测试、页面回归测试、技术文档和 Hermes 共享决策记录
This commit is contained in:
@@ -363,26 +363,24 @@ import {
|
||||
} from '../../services/wooden-fish/woodenFishClient';
|
||||
import type { CustomWorldProfile } from '../../types';
|
||||
import { useAuthUi } from '../auth/AuthUiContext';
|
||||
import { PlatformActionButton } from '../common/PlatformActionButton';
|
||||
import { PlatformModalCloseButton } from '../common/PlatformModalCloseButton';
|
||||
import { PublishShareModal } from '../common/PublishShareModal';
|
||||
import type { PublishShareModalPayload } from '../common/publishShareModalModel';
|
||||
import { UnifiedModal } from '../common/UnifiedModal';
|
||||
import { UnifiedConfirmDialog } from '../common/UnifiedConfirmDialog';
|
||||
import { resolveCreativeAgentTargetSelectionStage } from '../creative-agent/creativeAgentViewModel';
|
||||
import {
|
||||
buildCreationWorkShelfItems,
|
||||
type CreationWorkShelfItem,
|
||||
isPersistedBarkBattleDraftGenerating,
|
||||
} from '../custom-world-home/creationWorkShelf';
|
||||
import {
|
||||
selectAdjacentPlatformRecommendEntry,
|
||||
} from '../rpg-entry/rpgEntryPublicGalleryViewModel';
|
||||
import { selectAdjacentPlatformRecommendEntry } from '../rpg-entry/rpgEntryPublicGalleryViewModel';
|
||||
import {
|
||||
isBigFishGalleryEntry,
|
||||
isEdutainmentGalleryEntry,
|
||||
isJumpHopGalleryEntry,
|
||||
isPuzzleGalleryEntry,
|
||||
isPuzzleClearGalleryEntry,
|
||||
mapPuzzleClearWorkToPlatformGalleryCard,
|
||||
mapPuzzleWorkToPlatformGalleryCard,
|
||||
type PlatformPublicGalleryCard,
|
||||
resolvePlatformPublicWorkCode,
|
||||
} from '../rpg-entry/rpgEntryWorldPresentation';
|
||||
@@ -525,7 +523,6 @@ import { PlatformEntryWorldDetailView } from './PlatformEntryWorldDetailView';
|
||||
import { PlatformErrorDialog } from './PlatformErrorDialog';
|
||||
import { PlatformFeedbackView } from './PlatformFeedbackView';
|
||||
import { resolvePlatformGenerationProgressTickDecision } from './platformGenerationProgressTickModel';
|
||||
import { buildPlatformRecommendedEntries } from './platformRecommendation';
|
||||
import {
|
||||
buildMatch3DProfileFromSession,
|
||||
hasMatch3DRuntimeAsset,
|
||||
@@ -636,6 +633,7 @@ import {
|
||||
buildPuzzleResultWorkId,
|
||||
} from './platformPuzzleIdentityModel';
|
||||
import { mergePuzzleServiceRuntimeState } from './platformPuzzleRuntimeStateModel';
|
||||
import { buildPlatformRecommendedEntries } from './platformRecommendation';
|
||||
import {
|
||||
type PlatformPuzzleRuntimeAuthMode,
|
||||
resolvePlatformRecommendRuntimeAuthPlan,
|
||||
@@ -764,6 +762,11 @@ type DeleteCreationWorkConfirmation = {
|
||||
run: () => void;
|
||||
};
|
||||
|
||||
type WorkNotFoundRecoveryDialogState = {
|
||||
message: string;
|
||||
nextPath: '/';
|
||||
};
|
||||
|
||||
async function resumePuzzleProfileSaveArchiveRaw(worldKey: string) {
|
||||
return requestRpgRuntimeJson<
|
||||
ProfileSaveArchiveResumeResponse<PuzzleSaveArchiveState>
|
||||
@@ -992,22 +995,22 @@ function isMissingPuzzleWorkError(error: unknown) {
|
||||
);
|
||||
}
|
||||
|
||||
function maybeAlertWorkNotFoundAndReturnHome() {
|
||||
function resolveWorkNotFoundRecoveryDialogState(): WorkNotFoundRecoveryDialogState | null {
|
||||
if (typeof window === 'undefined') {
|
||||
return false;
|
||||
return null;
|
||||
}
|
||||
|
||||
const recoveryAction = resolveWorkNotFoundRecoveryAction(
|
||||
window.location.pathname,
|
||||
);
|
||||
if (!recoveryAction) {
|
||||
return false;
|
||||
return null;
|
||||
}
|
||||
|
||||
// 中文注释:直接打开公开详情或运行态深链失效时,确认提示后必须离开空详情页。
|
||||
window.alert('作品不存在或已下架,将返回首页。');
|
||||
pushAppHistoryPath(recoveryAction.nextPath);
|
||||
return true;
|
||||
return {
|
||||
message: '作品不存在或已下架,将返回首页。',
|
||||
nextPath: recoveryAction.nextPath,
|
||||
};
|
||||
}
|
||||
|
||||
function hasSeenPuzzleOnboarding() {
|
||||
@@ -1194,7 +1197,9 @@ const PuzzleClearResultView = lazy(async () => {
|
||||
});
|
||||
|
||||
const PuzzleClearRuntimeShell = lazy(async () => {
|
||||
const module = await import('../puzzle-clear-runtime/PuzzleClearRuntimeShell');
|
||||
const module = await import(
|
||||
'../puzzle-clear-runtime/PuzzleClearRuntimeShell'
|
||||
);
|
||||
return {
|
||||
default: module.PuzzleClearRuntimeShell,
|
||||
};
|
||||
@@ -1372,13 +1377,13 @@ function CreationResultRecoveryPanel({
|
||||
<div className="mt-2 text-sm leading-6 text-[var(--platform-text-base)]">
|
||||
{message}
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
<PlatformActionButton
|
||||
onClick={onAction}
|
||||
className="platform-button platform-button--primary mt-4 min-h-11 justify-center px-4 py-3 text-sm"
|
||||
size="md"
|
||||
className="mt-4 min-h-11"
|
||||
>
|
||||
{actionLabel}
|
||||
</button>
|
||||
</PlatformActionButton>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
@@ -1690,6 +1695,8 @@ export function PlatformEntryFlowShellImpl({
|
||||
>(null);
|
||||
const [pendingDeleteCreationWork, setPendingDeleteCreationWork] =
|
||||
useState<DeleteCreationWorkConfirmation | null>(null);
|
||||
const [workNotFoundRecoveryDialog, setWorkNotFoundRecoveryDialog] =
|
||||
useState<WorkNotFoundRecoveryDialogState | null>(null);
|
||||
const [
|
||||
claimingPuzzlePointIncentiveProfileId,
|
||||
setClaimingPuzzlePointIncentiveProfileId,
|
||||
@@ -2130,10 +2137,20 @@ export function PlatformEntryFlowShellImpl({
|
||||
const returnPlatformHomeAfterMissingWork = useCallback(() => {
|
||||
setPlatformTab('home');
|
||||
setSelectionStage('platform');
|
||||
if (!maybeAlertWorkNotFoundAndReturnHome()) {
|
||||
pushAppHistoryPath('/');
|
||||
const recoveryDialog = resolveWorkNotFoundRecoveryDialogState();
|
||||
if (recoveryDialog) {
|
||||
setWorkNotFoundRecoveryDialog(recoveryDialog);
|
||||
return;
|
||||
}
|
||||
pushAppHistoryPath('/');
|
||||
}, [setPlatformTab, setSelectionStage]);
|
||||
const confirmWorkNotFoundRecovery = useCallback(() => {
|
||||
const nextPath = workNotFoundRecoveryDialog?.nextPath ?? '/';
|
||||
setWorkNotFoundRecoveryDialog(null);
|
||||
setPlatformTab('home');
|
||||
setSelectionStage('platform');
|
||||
pushAppHistoryPath(nextPath);
|
||||
}, [setPlatformTab, setSelectionStage, workNotFoundRecoveryDialog]);
|
||||
|
||||
useEffect(() => {
|
||||
if (selectionStage === 'profile-feedback') {
|
||||
@@ -2899,8 +2916,10 @@ export function PlatformEntryFlowShellImpl({
|
||||
woodenFishGalleryEntries,
|
||||
],
|
||||
);
|
||||
const { featuredEntries: featuredGalleryEntries, latestEntries: latestGalleryEntries } =
|
||||
publicGalleryFeeds;
|
||||
const {
|
||||
featuredEntries: featuredGalleryEntries,
|
||||
latestEntries: latestGalleryEntries,
|
||||
} = publicGalleryFeeds;
|
||||
const recommendRuntimeEntries = useMemo(
|
||||
() =>
|
||||
buildPlatformRecommendedEntries({
|
||||
@@ -3083,23 +3102,22 @@ export function PlatformEntryFlowShellImpl({
|
||||
]);
|
||||
|
||||
useEffect(() => {
|
||||
const progressTickDecision =
|
||||
resolvePlatformGenerationProgressTickDecision({
|
||||
selectionStage,
|
||||
miniGameStates: {
|
||||
puzzle: puzzleGenerationState,
|
||||
match3d: match3dGenerationState,
|
||||
'big-fish': bigFishGenerationState,
|
||||
'square-hole': squareHoleGenerationState,
|
||||
'jump-hop': jumpHopGenerationState,
|
||||
'wooden-fish': woodenFishGenerationState,
|
||||
'baby-object-match': babyObjectMatchGenerationState,
|
||||
},
|
||||
visualNovel: {
|
||||
startedAtMs: visualNovelGenerationStartedAtMs,
|
||||
phase: visualNovelGenerationPhase,
|
||||
},
|
||||
});
|
||||
const progressTickDecision = resolvePlatformGenerationProgressTickDecision({
|
||||
selectionStage,
|
||||
miniGameStates: {
|
||||
puzzle: puzzleGenerationState,
|
||||
match3d: match3dGenerationState,
|
||||
'big-fish': bigFishGenerationState,
|
||||
'square-hole': squareHoleGenerationState,
|
||||
'jump-hop': jumpHopGenerationState,
|
||||
'wooden-fish': woodenFishGenerationState,
|
||||
'baby-object-match': babyObjectMatchGenerationState,
|
||||
},
|
||||
visualNovel: {
|
||||
startedAtMs: visualNovelGenerationStartedAtMs,
|
||||
phase: visualNovelGenerationPhase,
|
||||
},
|
||||
});
|
||||
|
||||
if (!progressTickDecision.shouldTick) {
|
||||
return undefined;
|
||||
@@ -3602,7 +3620,11 @@ export function PlatformEntryFlowShellImpl({
|
||||
markPendingDraftFailed('match3d', session.sessionId);
|
||||
markDraftFailed(
|
||||
'match3d',
|
||||
[session.draft?.profileId, session.publishedProfileId, session.sessionId],
|
||||
[
|
||||
session.draft?.profileId,
|
||||
session.publishedProfileId,
|
||||
session.sessionId,
|
||||
],
|
||||
errorMessage,
|
||||
);
|
||||
try {
|
||||
@@ -3884,7 +3906,11 @@ export function PlatformEntryFlowShellImpl({
|
||||
markPendingDraftFailed('square-hole', session.sessionId);
|
||||
markDraftFailed(
|
||||
'square-hole',
|
||||
[session.draft?.profileId, session.publishedProfileId, session.sessionId],
|
||||
[
|
||||
session.draft?.profileId,
|
||||
session.publishedProfileId,
|
||||
session.sessionId,
|
||||
],
|
||||
errorMessage,
|
||||
);
|
||||
void refreshSquareHoleShelf().catch(() => undefined);
|
||||
@@ -3964,15 +3990,18 @@ export function PlatformEntryFlowShellImpl({
|
||||
if (!isPuzzleCompileActionReady(response.session)) {
|
||||
const nextPayload =
|
||||
formPayload ?? buildPuzzleFormPayloadFromSession(response.session);
|
||||
const fallbackGenerationState = createPuzzleDraftGenerationStateFromPayload(
|
||||
nextPayload,
|
||||
response.session,
|
||||
);
|
||||
const nextGenerationState = mergePuzzleSessionProgressIntoGenerationState(
|
||||
puzzleGenerationState ?? fallbackGenerationState,
|
||||
response.session,
|
||||
);
|
||||
activePuzzleGenerationSessionIdRef.current = response.session.sessionId;
|
||||
const fallbackGenerationState =
|
||||
createPuzzleDraftGenerationStateFromPayload(
|
||||
nextPayload,
|
||||
response.session,
|
||||
);
|
||||
const nextGenerationState =
|
||||
mergePuzzleSessionProgressIntoGenerationState(
|
||||
puzzleGenerationState ?? fallbackGenerationState,
|
||||
response.session,
|
||||
);
|
||||
activePuzzleGenerationSessionIdRef.current =
|
||||
response.session.sessionId;
|
||||
setSelectionStage('puzzle-generating');
|
||||
markDraftGenerating('puzzle', [
|
||||
response.session.sessionId,
|
||||
@@ -7648,8 +7677,7 @@ export function PlatformEntryFlowShellImpl({
|
||||
...current.filter(
|
||||
(item) =>
|
||||
item.workId !== response.work!.summary.workId &&
|
||||
item.sourceSessionId !==
|
||||
response.work!.summary.sourceSessionId,
|
||||
item.sourceSessionId !== response.work!.summary.sourceSessionId,
|
||||
),
|
||||
]);
|
||||
markPendingDraftReady(
|
||||
@@ -7771,7 +7799,8 @@ export function PlatformEntryFlowShellImpl({
|
||||
workTitle: puzzleClearSession.draft?.workTitle,
|
||||
workDescription: puzzleClearSession.draft?.workDescription,
|
||||
themePrompt: puzzleClearSession.draft?.themePrompt,
|
||||
boardBackgroundPrompt: puzzleClearSession.draft?.boardBackgroundPrompt,
|
||||
boardBackgroundPrompt:
|
||||
puzzleClearSession.draft?.boardBackgroundPrompt,
|
||||
generateBoardBackground:
|
||||
puzzleClearSession.draft?.generateBoardBackground,
|
||||
boardBackgroundAsset: puzzleClearSession.draft?.boardBackgroundAsset,
|
||||
@@ -7796,11 +7825,9 @@ export function PlatformEntryFlowShellImpl({
|
||||
);
|
||||
setPuzzleClearError(errorMessage);
|
||||
setPuzzleClearGenerationState(
|
||||
resolveFinishedMiniGameDraftGenerationState(
|
||||
generationState,
|
||||
'failed',
|
||||
{ error: errorMessage },
|
||||
),
|
||||
resolveFinishedMiniGameDraftGenerationState(generationState, 'failed', {
|
||||
error: errorMessage,
|
||||
}),
|
||||
);
|
||||
} finally {
|
||||
setIsPuzzleClearBusy(false);
|
||||
@@ -7827,7 +7854,9 @@ export function PlatformEntryFlowShellImpl({
|
||||
setPuzzleClearWork(response.item);
|
||||
setPuzzleClearWorks((current) => [
|
||||
response.item.summary,
|
||||
...current.filter((item) => item.workId !== response.item.summary.workId),
|
||||
...current.filter(
|
||||
(item) => item.workId !== response.item.summary.workId,
|
||||
),
|
||||
]);
|
||||
void refreshPuzzleClearShelf();
|
||||
void refreshPuzzleClearGallery();
|
||||
@@ -7840,7 +7869,9 @@ export function PlatformEntryFlowShellImpl({
|
||||
setPublicWorkDetailError(null);
|
||||
selectionStageRef.current = 'work-detail';
|
||||
setSelectionStage('work-detail');
|
||||
pushAppHistoryPath(buildPublicWorkStagePath('work-detail', publicWorkCode));
|
||||
pushAppHistoryPath(
|
||||
buildPublicWorkStagePath('work-detail', publicWorkCode),
|
||||
);
|
||||
openPublishShareModal({
|
||||
title: response.item.summary.workTitle || '拼消消',
|
||||
publicWorkCode,
|
||||
@@ -7942,7 +7973,9 @@ export function PlatformEntryFlowShellImpl({
|
||||
return;
|
||||
}
|
||||
setPuzzleClearError(null);
|
||||
setPuzzleClearRun(retryPuzzleClearLocalLevel(puzzleClearRun, puzzleClearWork));
|
||||
setPuzzleClearRun(
|
||||
retryPuzzleClearLocalLevel(puzzleClearRun, puzzleClearWork),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -10816,6 +10849,7 @@ export function PlatformEntryFlowShellImpl({
|
||||
[
|
||||
openPublicWorkDetail,
|
||||
platformBootstrap.platformTab,
|
||||
returnPlatformHomeAfterMissingWork,
|
||||
resolvePuzzleErrorMessage,
|
||||
setIsPuzzleBusy,
|
||||
setPuzzleError,
|
||||
@@ -10971,7 +11005,8 @@ export function PlatformEntryFlowShellImpl({
|
||||
notices: draftGenerationNotices,
|
||||
generation: {
|
||||
activeSessionId: jumpHopSession?.sessionId,
|
||||
hasActiveGenerationFailure: jumpHopGenerationState?.phase === 'failed',
|
||||
hasActiveGenerationFailure:
|
||||
jumpHopGenerationState?.phase === 'failed',
|
||||
},
|
||||
});
|
||||
markDraftNoticeSeen(openIntent.noticeKeys);
|
||||
@@ -11055,7 +11090,9 @@ export function PlatformEntryFlowShellImpl({
|
||||
try {
|
||||
const detail = await puzzleClearClient.getRuntimeWorkDetail(profileId);
|
||||
setPuzzleClearWork(detail.item);
|
||||
openPublicWorkDetail(mapPuzzleClearWorkToPlatformGalleryCard(detail.item));
|
||||
openPublicWorkDetail(
|
||||
mapPuzzleClearWorkToPlatformGalleryCard(detail.item),
|
||||
);
|
||||
} catch (error) {
|
||||
setPublicWorkDetailError(
|
||||
resolveRpgCreationErrorMessage(error, '读取拼消消详情失败。'),
|
||||
@@ -11322,11 +11359,7 @@ export function PlatformEntryFlowShellImpl({
|
||||
setPuzzleRuntimeAuthMode('default');
|
||||
setPuzzleError(null);
|
||||
setPublicWorkDetailError(null);
|
||||
setPlatformTab('home');
|
||||
setSelectionStage('platform');
|
||||
if (!maybeAlertWorkNotFoundAndReturnHome()) {
|
||||
pushAppHistoryPath('/');
|
||||
}
|
||||
returnPlatformHomeAfterMissingWork();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -11357,8 +11390,7 @@ export function PlatformEntryFlowShellImpl({
|
||||
notices: draftGenerationNotices,
|
||||
generation: {
|
||||
activeSessionId: puzzleSession?.sessionId,
|
||||
hasActiveGenerationFailure:
|
||||
activeGenerationState?.phase === 'failed',
|
||||
hasActiveGenerationFailure: activeGenerationState?.phase === 'failed',
|
||||
hasActiveGenerationRunning: isMiniGameDraftGenerating(
|
||||
activeGenerationState ?? null,
|
||||
),
|
||||
@@ -11405,9 +11437,8 @@ export function PlatformEntryFlowShellImpl({
|
||||
const failedError = backgroundTask?.error ?? openIntent.errorMessage;
|
||||
if (!failedSession) {
|
||||
try {
|
||||
const { session: latestSession } = await getPuzzleAgentSession(
|
||||
sourceSessionId,
|
||||
);
|
||||
const { session: latestSession } =
|
||||
await getPuzzleAgentSession(sourceSessionId);
|
||||
failedSession = latestSession;
|
||||
failedPayload = buildPuzzleFormPayloadFromSession(latestSession);
|
||||
} catch {
|
||||
@@ -11490,9 +11521,8 @@ export function PlatformEntryFlowShellImpl({
|
||||
|
||||
if (openIntent.type === 'restore-generating') {
|
||||
try {
|
||||
const { session: latestSession } = await getPuzzleAgentSession(
|
||||
sourceSessionId,
|
||||
);
|
||||
const { session: latestSession } =
|
||||
await getPuzzleAgentSession(sourceSessionId);
|
||||
const payload = buildPuzzleFormPayloadFromSession(latestSession);
|
||||
const startedAtMs = resolveMiniGameDraftGenerationStartedAtMs(
|
||||
latestSession.updatedAt,
|
||||
@@ -11541,9 +11571,7 @@ export function PlatformEntryFlowShellImpl({
|
||||
|
||||
markDraftNoticeSeen(noticeKeys);
|
||||
|
||||
const restoredSession = await puzzleFlow.restoreDraft(
|
||||
sourceSessionId,
|
||||
);
|
||||
const restoredSession = await puzzleFlow.restoreDraft(sourceSessionId);
|
||||
if (!restoredSession) {
|
||||
await refreshPuzzleShelf().catch(() => undefined);
|
||||
return;
|
||||
@@ -11591,8 +11619,7 @@ export function PlatformEntryFlowShellImpl({
|
||||
forceDraft: options.forceDraft,
|
||||
generation: {
|
||||
activeSessionId: match3dSession?.sessionId,
|
||||
hasActiveGenerationFailure:
|
||||
activeGenerationState?.phase === 'failed',
|
||||
hasActiveGenerationFailure: activeGenerationState?.phase === 'failed',
|
||||
hasActiveGenerationRunning: isMiniGameDraftGenerating(
|
||||
activeGenerationState ?? null,
|
||||
),
|
||||
@@ -11787,9 +11814,7 @@ export function PlatformEntryFlowShellImpl({
|
||||
|
||||
markDraftNoticeSeen(noticeKeys);
|
||||
|
||||
const restoredSession = await match3dFlow.restoreDraft(
|
||||
sourceSessionId,
|
||||
);
|
||||
const restoredSession = await match3dFlow.restoreDraft(sourceSessionId);
|
||||
if (!restoredSession) {
|
||||
await refreshMatch3DShelf().catch(() => undefined);
|
||||
return;
|
||||
@@ -13238,8 +13263,7 @@ export function PlatformEntryFlowShellImpl({
|
||||
activeRecommendEntryKey && !isDesktopLayout
|
||||
? (recommendRuntimeEntries.find(
|
||||
(entry) =>
|
||||
getPlatformPublicGalleryEntryKey(entry) ===
|
||||
activeRecommendEntryKey,
|
||||
getPlatformPublicGalleryEntryKey(entry) === activeRecommendEntryKey,
|
||||
) ?? null)
|
||||
: null;
|
||||
const isActiveRecommendRuntimeReady =
|
||||
@@ -13255,7 +13279,8 @@ export function PlatformEntryFlowShellImpl({
|
||||
hasVisualNovelRun: Boolean(visualNovelRun),
|
||||
hasWoodenFishRun: Boolean(woodenFishRun),
|
||||
puzzleRunEntryProfileId: puzzleRun?.entryProfileId ?? null,
|
||||
puzzleRunCurrentLevelProfileId: puzzleRun?.currentLevel?.profileId ?? null,
|
||||
puzzleRunCurrentLevelProfileId:
|
||||
puzzleRun?.currentLevel?.profileId ?? null,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
@@ -13620,10 +13645,7 @@ export function PlatformEntryFlowShellImpl({
|
||||
const detailEntry = mapPuzzleClearWorkToPlatformGalleryCard(entry);
|
||||
return (
|
||||
canExposePublicWork(detailEntry) &&
|
||||
isSamePuzzleClearPublicWorkCode(
|
||||
normalizedKeyword,
|
||||
entry.profileId,
|
||||
)
|
||||
isSamePuzzleClearPublicWorkCode(normalizedKeyword, entry.profileId)
|
||||
);
|
||||
});
|
||||
|
||||
@@ -14044,7 +14066,9 @@ export function PlatformEntryFlowShellImpl({
|
||||
jumpHopItems: isJumpHopCreationVisible ? jumpHopShelfItems : [],
|
||||
woodenFishItems: woodenFishShelfItems,
|
||||
match3dItems: match3dShelfItems,
|
||||
squareHoleItems: isSquareHoleCreationVisible ? squareHoleShelfItems : [],
|
||||
squareHoleItems: isSquareHoleCreationVisible
|
||||
? squareHoleShelfItems
|
||||
: [],
|
||||
puzzleItems: puzzleShelfItems,
|
||||
babyObjectMatchItems: isBabyObjectMatchVisible
|
||||
? babyObjectMatchDrafts
|
||||
@@ -14276,7 +14300,7 @@ export function PlatformEntryFlowShellImpl({
|
||||
puzzleShelfError ??
|
||||
puzzleError ??
|
||||
(isVisualNovelCreationOpen ? visualNovelError : null) ??
|
||||
babyObjectMatchError ??
|
||||
babyObjectMatchError ??
|
||||
puzzleClearError ??
|
||||
barkBattleError)
|
||||
}
|
||||
@@ -14652,8 +14676,20 @@ export function PlatformEntryFlowShellImpl({
|
||||
onDelete={
|
||||
detailNavigation.isSelectedWorldOwned
|
||||
? () => {
|
||||
runProtectedAction(() => {
|
||||
void detailNavigation.handleDeleteSelectedWorld();
|
||||
const deleteModel =
|
||||
resolvePlatformCreationWorkDeleteConfirmationModel({
|
||||
kind: 'rpg-library',
|
||||
entry: selectedDetailEntry,
|
||||
});
|
||||
requestDeleteCreationWork({
|
||||
id: deleteModel.id,
|
||||
title: deleteModel.title,
|
||||
detail: deleteModel.detail,
|
||||
run: () => {
|
||||
runProtectedAction(() => {
|
||||
void detailNavigation.handleDeleteSelectedWorld();
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
: null
|
||||
@@ -15684,7 +15720,9 @@ export function PlatformEntryFlowShellImpl({
|
||||
profile={jumpHopWork}
|
||||
isBusy={isJumpHopBusy}
|
||||
error={jumpHopError}
|
||||
runtimeRequestOptions={jumpHopRuntimeRequestOptions ?? undefined}
|
||||
runtimeRequestOptions={
|
||||
jumpHopRuntimeRequestOptions ?? undefined
|
||||
}
|
||||
onBack={() => {
|
||||
setSelectionStage(jumpHopRuntimeReturnStage);
|
||||
}}
|
||||
@@ -16144,7 +16182,9 @@ export function PlatformEntryFlowShellImpl({
|
||||
<UnifiedCreationPage
|
||||
spec={getUnifiedSpec('visual-novel')}
|
||||
onBack={leaveVisualNovelFlow}
|
||||
isBackDisabled={isVisualNovelBusy || isVisualNovelStreamingReply}
|
||||
isBackDisabled={
|
||||
isVisualNovelBusy || isVisualNovelStreamingReply
|
||||
}
|
||||
>
|
||||
<VisualNovelAgentWorkspace
|
||||
session={visualNovelSession}
|
||||
@@ -16842,29 +16882,19 @@ export function PlatformEntryFlowShellImpl({
|
||||
}}
|
||||
/>
|
||||
) : null}
|
||||
<UnifiedModal
|
||||
<UnifiedConfirmDialog
|
||||
open={Boolean(draftGenerationPointNotice)}
|
||||
title={draftGenerationPointNotice?.title ?? '泥点提示'}
|
||||
description={draftGenerationPointNoticeDescription}
|
||||
onClose={() => setDraftGenerationPointNotice(null)}
|
||||
confirmLabel="知道了"
|
||||
closeOnBackdrop
|
||||
size="sm"
|
||||
overlayClassName={`platform-theme ${platformThemeClass} !items-center`}
|
||||
panelClassName="platform-remap-surface rounded-[1.75rem]"
|
||||
footer={
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setDraftGenerationPointNotice(null)}
|
||||
className="platform-button platform-button--primary min-h-0 rounded-full px-4 py-2 text-sm"
|
||||
>
|
||||
知道了
|
||||
</button>
|
||||
}
|
||||
>
|
||||
<div className="text-sm leading-6 text-[var(--platform-text-base)]">
|
||||
{draftGenerationPointNotice?.message}
|
||||
</div>
|
||||
</UnifiedModal>
|
||||
{draftGenerationPointNotice?.message}
|
||||
</UnifiedConfirmDialog>
|
||||
<PublishShareModal
|
||||
open={Boolean(publishSharePayload)}
|
||||
payload={publishSharePayload}
|
||||
@@ -16882,7 +16912,19 @@ export function PlatformEntryFlowShellImpl({
|
||||
overlayClassName={`platform-theme ${platformThemeClass} !items-center`}
|
||||
panelClassName="platform-remap-surface rounded-[1.5rem]"
|
||||
/>
|
||||
<UnifiedModal
|
||||
<UnifiedConfirmDialog
|
||||
open={Boolean(workNotFoundRecoveryDialog)}
|
||||
title="作品不可用"
|
||||
onClose={confirmWorkNotFoundRecovery}
|
||||
confirmLabel="知道了"
|
||||
closeOnBackdrop
|
||||
size="sm"
|
||||
overlayClassName={`platform-theme ${platformThemeClass} !items-center`}
|
||||
panelClassName="platform-remap-surface rounded-[1.75rem]"
|
||||
>
|
||||
{workNotFoundRecoveryDialog?.message}
|
||||
</UnifiedConfirmDialog>
|
||||
<UnifiedConfirmDialog
|
||||
open={Boolean(pendingDeleteCreationWork)}
|
||||
title="删除作品"
|
||||
description={
|
||||
@@ -16891,36 +16933,19 @@ export function PlatformEntryFlowShellImpl({
|
||||
: undefined
|
||||
}
|
||||
onClose={closeDeleteCreationWorkConfirmation}
|
||||
closeDisabled={Boolean(deletingCreationWorkId)}
|
||||
busy={Boolean(deletingCreationWorkId)}
|
||||
closeOnBackdrop={!deletingCreationWorkId}
|
||||
size="sm"
|
||||
overlayClassName={`platform-theme ${platformThemeClass} !items-center`}
|
||||
panelClassName="platform-remap-surface rounded-[1.75rem]"
|
||||
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>
|
||||
</>
|
||||
}
|
||||
showCancel
|
||||
confirmLabel="确认删除"
|
||||
busyConfirmLabel="删除中"
|
||||
confirmTone="danger"
|
||||
onConfirm={confirmDeleteCreationWork}
|
||||
>
|
||||
<div className="text-sm leading-6 text-[var(--platform-text-base)]">
|
||||
{pendingDeleteCreationWork?.detail}
|
||||
</div>
|
||||
</UnifiedModal>
|
||||
{pendingDeleteCreationWork?.detail}
|
||||
</UnifiedConfirmDialog>
|
||||
<AnimatePresence>
|
||||
{(searchedPublicUser || publicSearchError) && (
|
||||
<motion.div
|
||||
@@ -16939,17 +16964,14 @@ export function PlatformEntryFlowShellImpl({
|
||||
{publicSearchError ? '未找到结果' : '命中用户'}
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
<PlatformModalCloseButton
|
||||
onClick={() => {
|
||||
setSearchedPublicUser(null);
|
||||
setPublicSearchError(null);
|
||||
}}
|
||||
className="platform-icon-button"
|
||||
aria-label="关闭搜索结果"
|
||||
>
|
||||
×
|
||||
</button>
|
||||
label="关闭搜索结果"
|
||||
variant="platformIcon"
|
||||
/>
|
||||
</div>
|
||||
{publicSearchError ? (
|
||||
<div className="mt-4 text-sm leading-6 text-[var(--platform-text-soft)]">
|
||||
|
||||
Reference in New Issue
Block a user