继续收口平台分段与泥点确认
新增泥点确认状态机共享 hook 并接入拼图与抓大鹅工作台 将首页发现页与个人中心剩余切换条收口到 PlatformSegmentedTabs 统一平台弹窗 header 关闭入口并补齐相关测试 更新前端组件收口文档与团队决策记录
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { Loader2, Sparkles, WandSparkles } from 'lucide-react';
|
||||
import { useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||
|
||||
import type {
|
||||
CreateMatch3DSessionRequest,
|
||||
@@ -9,12 +9,13 @@ import type {
|
||||
} from '../../../../packages/shared/src/contracts/match3dAgent';
|
||||
import { PlatformActionButton } from '../../common/PlatformActionButton';
|
||||
import { PlatformFieldLabel } from '../../common/PlatformFieldLabel';
|
||||
import { PlatformMudPointConfirmDialog } from '../../common/PlatformMudPointConfirmDialog';
|
||||
import { PlatformPillBadge } from '../../common/PlatformPillBadge';
|
||||
import { PlatformSegmentedTabs } from '../../common/PlatformSegmentedTabs';
|
||||
import { PlatformStatusMessage } from '../../common/PlatformStatusMessage';
|
||||
import { PlatformSubpanel } from '../../common/PlatformSubpanel';
|
||||
import { PlatformTextField } from '../../common/PlatformTextField';
|
||||
import { PlatformMudPointConfirmDialog } from '../../common/PlatformMudPointConfirmDialog';
|
||||
import { useMudPointConfirmController } from '../../common/useMudPointConfirmController';
|
||||
|
||||
type Match3DCreationWorkspaceProps = {
|
||||
session: Match3DAgentSessionSnapshot | null;
|
||||
@@ -131,7 +132,6 @@ export function Match3DCreationWorkspace({
|
||||
const [formState, setFormState] = useState<Match3DFormState>(() =>
|
||||
resolveInitialFormState(session, initialFormPayload),
|
||||
);
|
||||
const [isPointCostConfirmOpen, setIsPointCostConfirmOpen] = useState(false);
|
||||
const appliedInitialFormKeyRef = useRef<string | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -143,7 +143,6 @@ export function Match3DCreationWorkspace({
|
||||
|
||||
appliedInitialFormKeyRef.current = nextInitialFormKey;
|
||||
setFormState(resolveInitialFormState(session, initialFormPayload));
|
||||
setIsPointCostConfirmOpen(false);
|
||||
}, [initialFormPayload, session]);
|
||||
|
||||
const themeText = formState.themeText.trim();
|
||||
@@ -165,32 +164,40 @@ export function Match3DCreationWorkspace({
|
||||
[selectedDifficultyOption, themeText],
|
||||
);
|
||||
|
||||
const submitForm = () => {
|
||||
if (!canSubmit) {
|
||||
return;
|
||||
}
|
||||
|
||||
setIsPointCostConfirmOpen(true);
|
||||
};
|
||||
|
||||
const executeSubmitForm = () => {
|
||||
const executeSubmitForm = useCallback(() => {
|
||||
if (!canSubmit) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (onCreateFromForm) {
|
||||
setIsPointCostConfirmOpen(false);
|
||||
onCreateFromForm(formPayload);
|
||||
return;
|
||||
}
|
||||
|
||||
if (session) {
|
||||
setIsPointCostConfirmOpen(false);
|
||||
onExecuteAction({
|
||||
action: 'match3d_compile_draft',
|
||||
generateClickSound: false,
|
||||
});
|
||||
}
|
||||
}, [canSubmit, formPayload, onCreateFromForm, onExecuteAction, session]);
|
||||
const {
|
||||
open: isPointCostConfirmOpen,
|
||||
requestOpen: requestPointCostConfirm,
|
||||
close: closePointCostConfirm,
|
||||
confirm: confirmPointCostConfirm,
|
||||
} = useMudPointConfirmController(executeSubmitForm);
|
||||
|
||||
useEffect(() => {
|
||||
closePointCostConfirm();
|
||||
}, [closePointCostConfirm, initialFormPayload, session]);
|
||||
|
||||
const submitForm = () => {
|
||||
if (!canSubmit) {
|
||||
return;
|
||||
}
|
||||
|
||||
requestPointCostConfirm();
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -354,8 +361,8 @@ export function Match3DCreationWorkspace({
|
||||
<PlatformMudPointConfirmDialog
|
||||
open={isPointCostConfirmOpen}
|
||||
points={mudPointCost}
|
||||
onClose={() => setIsPointCostConfirmOpen(false)}
|
||||
onConfirm={executeSubmitForm}
|
||||
onClose={closePointCostConfirm}
|
||||
onConfirm={confirmPointCostConfirm}
|
||||
confirmDisabled={!canSubmit}
|
||||
overlayClassName="platform-modal-backdrop z-[80]"
|
||||
panelClassName="platform-remap-surface max-w-xs rounded-[1.35rem] shadow-[0_24px_70px_rgba(15,23,42,0.22)]"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { ArrowLeft } from 'lucide-react';
|
||||
import { useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||
|
||||
import type { PuzzleAgentActionRequest } from '../../../../packages/shared/src/contracts/puzzleAgentActions';
|
||||
import type {
|
||||
@@ -19,6 +19,7 @@ import {
|
||||
type CreativeImageInputReferenceImage,
|
||||
} from '../../common/CreativeImageInputPanel';
|
||||
import { PlatformActionButton } from '../../common/PlatformActionButton';
|
||||
import { PlatformMudPointConfirmDialog } from '../../common/PlatformMudPointConfirmDialog';
|
||||
import { PlatformPillBadge } from '../../common/PlatformPillBadge';
|
||||
import { SquareImageCropModal } from '../../common/SquareImageCropModal';
|
||||
import {
|
||||
@@ -26,7 +27,7 @@ import {
|
||||
clampSquareImageCropRect,
|
||||
type SquareImageCropRect,
|
||||
} from '../../common/squareImageCropModel';
|
||||
import { PlatformMudPointConfirmDialog } from '../../common/PlatformMudPointConfirmDialog';
|
||||
import { useMudPointConfirmController } from '../../common/useMudPointConfirmController';
|
||||
import PuzzleHistoryAssetPickerDialog from '../shared/PuzzleHistoryAssetPickerDialog';
|
||||
import {
|
||||
normalizePuzzleImageModel,
|
||||
@@ -254,7 +255,6 @@ export function PuzzleCreationWorkspace({
|
||||
);
|
||||
const [cropState, setCropState] = useState<PuzzleImageCropState | null>(null);
|
||||
const [isHistoryPickerOpen, setIsHistoryPickerOpen] = useState(false);
|
||||
const [isPointCostConfirmOpen, setIsPointCostConfirmOpen] = useState(false);
|
||||
const previousSessionIdRef = useRef<string | null>(
|
||||
session?.sessionId ?? null,
|
||||
);
|
||||
@@ -284,7 +284,6 @@ export function PuzzleCreationWorkspace({
|
||||
setReferenceImageError(null);
|
||||
setCropState(null);
|
||||
setIsHistoryPickerOpen(false);
|
||||
setIsPointCostConfirmOpen(false);
|
||||
}, [initialFormPayload, session]);
|
||||
|
||||
const pictureDescription = formState.pictureDescription.trim();
|
||||
@@ -476,6 +475,71 @@ export function PuzzleCreationWorkspace({
|
||||
setReferenceImageError(null);
|
||||
};
|
||||
|
||||
const executeSubmitForm = useCallback(() => {
|
||||
if (!canSubmit) {
|
||||
return;
|
||||
}
|
||||
|
||||
const payloadPictureDescription = formState.aiRedraw
|
||||
? pictureDescription
|
||||
: pictureDescription || formState.referenceImageLabel || '上传拼图图片';
|
||||
const payload = {
|
||||
seedText: payloadPictureDescription,
|
||||
workDescription: payloadPictureDescription,
|
||||
pictureDescription: payloadPictureDescription,
|
||||
referenceImageSrc: mainReferenceImageSrcForPayload,
|
||||
referenceImageSrcs: promptReferenceImageSrcsForPayload,
|
||||
referenceImageAssetObjectId:
|
||||
formState.referenceImageAssetObjectId || null,
|
||||
referenceImageAssetObjectIds: promptReferenceAssetObjectIds,
|
||||
imageModel: formState.imageModel,
|
||||
aiRedraw: formState.aiRedraw,
|
||||
};
|
||||
|
||||
if (!session && onCreateFromForm) {
|
||||
onCreateFromForm(payload);
|
||||
return;
|
||||
}
|
||||
|
||||
onExecuteAction({
|
||||
action: 'compile_puzzle_draft',
|
||||
promptText: payloadPictureDescription,
|
||||
workDescription: payloadPictureDescription,
|
||||
pictureDescription: payloadPictureDescription,
|
||||
referenceImageSrc: mainReferenceImageSrcForPayload,
|
||||
referenceImageSrcs: promptReferenceImageSrcsForPayload,
|
||||
referenceImageAssetObjectId:
|
||||
formState.referenceImageAssetObjectId || null,
|
||||
referenceImageAssetObjectIds: promptReferenceAssetObjectIds,
|
||||
imageModel: formState.imageModel,
|
||||
aiRedraw: formState.aiRedraw,
|
||||
candidateCount: 1,
|
||||
});
|
||||
}, [
|
||||
canSubmit,
|
||||
formState.aiRedraw,
|
||||
formState.imageModel,
|
||||
formState.referenceImageAssetObjectId,
|
||||
formState.referenceImageLabel,
|
||||
mainReferenceImageSrcForPayload,
|
||||
onCreateFromForm,
|
||||
onExecuteAction,
|
||||
pictureDescription,
|
||||
promptReferenceAssetObjectIds,
|
||||
promptReferenceImageSrcsForPayload,
|
||||
session,
|
||||
]);
|
||||
const {
|
||||
open: isPointCostConfirmOpen,
|
||||
requestOpen: requestPointCostConfirm,
|
||||
close: closePointCostConfirm,
|
||||
confirm: confirmPointCostConfirm,
|
||||
} = useMudPointConfirmController(executeSubmitForm);
|
||||
|
||||
useEffect(() => {
|
||||
closePointCostConfirm();
|
||||
}, [closePointCostConfirm, initialFormPayload, session]);
|
||||
|
||||
const updateCropState = (nextCrop: {
|
||||
x: number;
|
||||
y: number;
|
||||
@@ -538,56 +602,12 @@ export function PuzzleCreationWorkspace({
|
||||
}
|
||||
|
||||
if (formState.aiRedraw) {
|
||||
setIsPointCostConfirmOpen(true);
|
||||
requestPointCostConfirm();
|
||||
return;
|
||||
}
|
||||
|
||||
executeSubmitForm();
|
||||
};
|
||||
|
||||
const executeSubmitForm = () => {
|
||||
if (!canSubmit) {
|
||||
return;
|
||||
}
|
||||
|
||||
const payloadPictureDescription = formState.aiRedraw
|
||||
? pictureDescription
|
||||
: pictureDescription || formState.referenceImageLabel || '上传拼图图片';
|
||||
const payload = {
|
||||
seedText: payloadPictureDescription,
|
||||
workDescription: payloadPictureDescription,
|
||||
pictureDescription: payloadPictureDescription,
|
||||
referenceImageSrc: mainReferenceImageSrcForPayload,
|
||||
referenceImageSrcs: promptReferenceImageSrcsForPayload,
|
||||
referenceImageAssetObjectId:
|
||||
formState.referenceImageAssetObjectId || null,
|
||||
referenceImageAssetObjectIds: promptReferenceAssetObjectIds,
|
||||
imageModel: formState.imageModel,
|
||||
aiRedraw: formState.aiRedraw,
|
||||
};
|
||||
|
||||
if (!session && onCreateFromForm) {
|
||||
setIsPointCostConfirmOpen(false);
|
||||
onCreateFromForm(payload);
|
||||
return;
|
||||
}
|
||||
|
||||
setIsPointCostConfirmOpen(false);
|
||||
onExecuteAction({
|
||||
action: 'compile_puzzle_draft',
|
||||
promptText: payloadPictureDescription,
|
||||
workDescription: payloadPictureDescription,
|
||||
pictureDescription: payloadPictureDescription,
|
||||
referenceImageSrc: mainReferenceImageSrcForPayload,
|
||||
referenceImageSrcs: promptReferenceImageSrcsForPayload,
|
||||
referenceImageAssetObjectId:
|
||||
formState.referenceImageAssetObjectId || null,
|
||||
referenceImageAssetObjectIds: promptReferenceAssetObjectIds,
|
||||
imageModel: formState.imageModel,
|
||||
aiRedraw: formState.aiRedraw,
|
||||
candidateCount: 1,
|
||||
});
|
||||
};
|
||||
const removeReferenceImage = () => {
|
||||
setFormState((current) => ({
|
||||
...current,
|
||||
@@ -750,8 +770,8 @@ export function PuzzleCreationWorkspace({
|
||||
<PlatformMudPointConfirmDialog
|
||||
open={isPointCostConfirmOpen}
|
||||
points={mudPointCost}
|
||||
onClose={() => setIsPointCostConfirmOpen(false)}
|
||||
onConfirm={executeSubmitForm}
|
||||
onClose={closePointCostConfirm}
|
||||
onConfirm={confirmPointCostConfirm}
|
||||
confirmDisabled={!canSubmit}
|
||||
overlayClassName="platform-modal-backdrop z-[80]"
|
||||
panelClassName="platform-remap-surface max-w-xs rounded-[1.35rem] shadow-[0_24px_70px_rgba(15,23,42,0.22)]"
|
||||
|
||||
Reference in New Issue
Block a user