feat: 完善敲木鱼玩法模板链路

This commit is contained in:
2026-05-24 02:49:13 +08:00
parent 2ba4691bc0
commit 8638397faa
402 changed files with 2329 additions and 1781 deletions

View File

@@ -15,7 +15,10 @@ import type {
} from '../../../packages/shared/src/contracts/woodenFish';
import { readPuzzleReferenceImageAsDataUrl } from '../../services/puzzleReferenceImage';
import { woodenFishClient } from '../../services/wooden-fish/woodenFishClient';
import { WOODEN_FISH_DEFAULT_HIT_OBJECT_PROMPT } from '../../services/wooden-fish/woodenFishDefaults';
import {
WOODEN_FISH_DEFAULT_HIT_OBJECT_PROMPT,
WOODEN_FISH_DEFAULT_HIT_SOUND_ASSET,
} from '../../services/wooden-fish/woodenFishDefaults';
import { CreativeImageInputPanel } from '../common/CreativeImageInputPanel';
type WoodenFishWorkspaceProps = {
@@ -34,7 +37,6 @@ type WoodenFishWorkspaceFormState = {
themeTags: string;
hitObjectPrompt: string;
hitObjectReferenceImageSrc: string;
hitSoundPrompt: string;
hitSoundAsset: WoodenFishAudioAsset | null;
floatingWords: string[];
};
@@ -56,7 +58,6 @@ const DEFAULT_FORM_STATE: WoodenFishWorkspaceFormState = {
themeTags: '敲木鱼 解压',
hitObjectPrompt: WOODEN_FISH_DEFAULT_HIT_OBJECT_PROMPT,
hitObjectReferenceImageSrc: '',
hitSoundPrompt: '清脆短促的木鱼敲击声',
hitSoundAsset: null,
floatingWords: DEFAULT_FLOATING_WORDS,
};
@@ -111,16 +112,12 @@ function readAudioFileAsAsset(file: File, source: 'uploaded' | 'recorded') {
function WoodenFishAudioInputPanel({
disabled,
prompt,
asset,
onPromptChange,
onAssetChange,
onError,
}: {
disabled: boolean;
prompt: string;
asset: WoodenFishAudioAsset | null;
onPromptChange: (value: string) => void;
onAssetChange: (asset: WoodenFishAudioAsset | null) => void;
onError: (message: string | null) => void;
}) {
@@ -201,18 +198,6 @@ function WoodenFishAudioInputPanel({
</button>
) : null}
</div>
<label className="block">
<span className="text-xs font-bold tracking-[0.18em] text-[var(--platform-text-soft)]">
</span>
<textarea
value={prompt}
disabled={disabled || Boolean(asset)}
onChange={(event) => onPromptChange(event.target.value)}
rows={2}
className="mt-2 w-full resize-none rounded-[1rem] border border-[var(--platform-subpanel-border)] bg-white/90 px-3 py-3 text-sm leading-6 text-[var(--platform-text-strong)] outline-none"
/>
</label>
<div className="mt-3 flex flex-wrap items-center gap-2">
<label
className={`platform-button platform-button--secondary min-h-10 cursor-pointer gap-2 px-3 py-2 text-sm ${
@@ -270,7 +255,7 @@ function WoodenFishAudioInputPanel({
<audio controls src={asset.audioSrc} className="h-10 max-w-full" />
) : (
<div className="text-xs font-bold text-[var(--platform-text-soft)]">
{asset ? '音效已选择' : '可生成、上传或录制'}
{asset ? '音效已选择' : '默认木鱼音'}
</div>
)}
</div>
@@ -317,10 +302,9 @@ export function WoodenFishWorkspace({
hitObjectPrompt: formState.hitObjectPrompt.trim(),
hitObjectReferenceImageSrc:
formState.hitObjectReferenceImageSrc.trim() || null,
hitSoundPrompt: formState.hitSoundAsset
? null
: formState.hitSoundPrompt.trim() || null,
hitSoundAsset: formState.hitSoundAsset,
hitSoundPrompt: null,
hitSoundAsset:
formState.hitSoundAsset ?? WOODEN_FISH_DEFAULT_HIT_SOUND_ASSET,
floatingWords: normalizedFloatingWords,
};
const response = await woodenFishClient.createSession(payload);
@@ -462,14 +446,7 @@ export function WoodenFishWorkspace({
<WoodenFishAudioInputPanel
disabled={isBusy || isSubmitting}
prompt={formState.hitSoundPrompt}
asset={formState.hitSoundAsset}
onPromptChange={(value) =>
setFormState((current) => ({
...current,
hitSoundPrompt: value,
}))
}
onAssetChange={(asset) =>
setFormState((current) => ({
...current,