diff --git a/apps/ai-game-creator-shell/src/features/project-workspace/ProjectSupervisorView.tsx b/apps/ai-game-creator-shell/src/features/project-workspace/ProjectSupervisorView.tsx index aff12a648..0e4117a59 100644 --- a/apps/ai-game-creator-shell/src/features/project-workspace/ProjectSupervisorView.tsx +++ b/apps/ai-game-creator-shell/src/features/project-workspace/ProjectSupervisorView.tsx @@ -1,8 +1,7 @@ -import { ArrowUp, Loader2 } from 'lucide-react'; +import { ArrowUp, AtSign, Loader2 } from 'lucide-react'; import type { ComponentProps, FormEventHandler, - Ref, RefObject, UIEventHandler, } from 'react'; @@ -70,7 +69,7 @@ type ProjectSupervisorViewProps = RuntimePanelProps & { chatInput: string; chatReferences: ChatReference[]; chatProjectAssets: import('../../../../../packages/shared/src/contracts/gameCreationApp').GameCreationAppAssetManifestEntry[]; - composerRef?: Ref; + composerRef?: RefObject; directCodex?: boolean; directStatus?: GameCreatorDirectTurnUpdateStatus | null; directProcessDetail?: string; @@ -162,6 +161,24 @@ export function ProjectSupervisorView({ const [modelValidating, setModelValidating] = useState(false); const modelSelectRef = useRef(null); const modelValidateInFlightRef = useRef(false); + const submitButton = ( + + ); return (
) : null}
{ if (!directCodex) { onSubmit(event); @@ -371,6 +390,7 @@ export function ProjectSupervisorView({ rows={3} value={chatInput} references={chatReferences} + showTriggerButton={!directCodex} placeholder={ directCodex ? '告诉陶泥儿接下来要做什么,或输入 @ 选择资源' @@ -379,31 +399,28 @@ export function ProjectSupervisorView({ onChange={onChatInputChange} /> {directCodex ? ( - - ) : null} - +
+ + + {submitButton} +
+ ) : ( + submitButton + )} {projectWorkspaceStatusForDisplay(workspaceStatus)} diff --git a/apps/ai-game-creator-shell/src/features/project-workspace/ResourceReferenceInput.tsx b/apps/ai-game-creator-shell/src/features/project-workspace/ResourceReferenceInput.tsx index 96f1998f9..7e87f6804 100644 --- a/apps/ai-game-creator-shell/src/features/project-workspace/ResourceReferenceInput.tsx +++ b/apps/ai-game-creator-shell/src/features/project-workspace/ResourceReferenceInput.tsx @@ -84,11 +84,13 @@ type ResourceReferenceInputProps = { ariaLabel: string; multiline?: boolean; rows?: number; + showTriggerButton?: boolean; inputRef?: RefObject; }; export type ResourceReferenceInputHandle = { insertReferences: (references: ChatReference[]) => void; + openPicker: () => void; focus: () => void; }; @@ -184,6 +186,7 @@ function ResourceReferenceEditor({ ariaLabel, multiline, rows, + showTriggerButton = true, inputRef, composerRef, }: ResourceReferenceInputProps & { @@ -254,13 +257,21 @@ function ResourceReferenceEditor({ [editor], ); + const openPicker = useCallback(() => { + setPickerQuery(''); + setPickerFilter('all'); + setSelectedResourceIds([]); + setPickerOpen(true); + }, []); + useImperativeHandle( composerRef, () => ({ insertReferences, + openPicker, focus: () => editor.focus(), }), - [editor, insertReferences], + [editor, insertReferences, openPicker], ); useEffect(() => { @@ -459,24 +470,21 @@ function ResourceReferenceEditor({ } ErrorBoundary={LexicalErrorBoundary} /> -
- -
+ {showTriggerButton ? ( +
+ +
+ ) : null} options={mentionOptions} triggerFn={triggerFn} diff --git a/apps/ai-game-creator-shell/src/styles.css b/apps/ai-game-creator-shell/src/styles.css index c27173650..1b58aa49c 100644 --- a/apps/ai-game-creator-shell/src/styles.css +++ b/apps/ai-game-creator-shell/src/styles.css @@ -9032,6 +9032,80 @@ iframe.preview-frame { background: #fff; font-size: 12px; +/* Direct Codex composer: keep the editor and its actions in one vertical + structure instead of positioning each control independently. */ +.game-workbench-chat + .project-supervisor-surface.is-direct-codex + .project-supervisor-composer.is-direct-codex { + display: grid; + grid-template-columns: minmax(0, 1fr); + grid-template-rows: auto auto; + gap: 8px; + align-items: stretch; + position: absolute; + right: 0; + bottom: 0; + left: 0; + z-index: 5; + padding: 0; + background: transparent; + pointer-events: none; +} + +.game-workbench-chat + .project-supervisor-surface.is-direct-codex + .project-supervisor-composer.is-direct-codex + .resource-reference-input { + width: 100%; + min-height: 72px; + padding: 12px 15px 10px; + pointer-events: auto; +} + +.game-workbench-chat + .project-supervisor-surface.is-direct-codex + .project-supervisor-composer.is-direct-codex + .project-supervisor-composer-controls { + display: flex; + align-items: center; + justify-content: flex-end; + gap: 8px; + min-width: 0; + pointer-events: auto; +} + +.game-workbench-chat + .project-supervisor-surface.is-direct-codex + .project-supervisor-composer.is-direct-codex + .project-supervisor-composer-controls + .conversation-model-select { + position: static !important; + right: auto !important; + bottom: auto !important; + max-width: min(220px, 40%); +} + +.game-workbench-chat + .project-supervisor-surface.is-direct-codex + .project-supervisor-composer.is-direct-codex + .project-supervisor-composer-controls + > button { + position: static !important; + right: auto !important; + bottom: auto !important; + display: grid; + width: 30px; + min-width: 30px; + height: 30px; + min-height: 30px; + padding: 0; + border: 0; + border-radius: 9px; + background: var(--platform-button-primary-fill); + color: var(--platform-button-primary-text); + place-items: center; +} + .project-supervisor-composer .resource-reference-input { min-height: 72px; }