diff --git a/src/apps/chat/components/composer/Composer.tsx b/src/apps/chat/components/composer/Composer.tsx index fe61e7039..c1064dfe5 100644 --- a/src/apps/chat/components/composer/Composer.tsx +++ b/src/apps/chat/components/composer/Composer.tsx @@ -68,6 +68,7 @@ import { ButtonAttachScreenCaptureMemo } from './buttons/ButtonAttachScreenCaptu import { ButtonAttachWebMemo } from './buttons/ButtonAttachWeb'; import { ButtonBeamMemo } from './buttons/ButtonBeam'; import { ButtonCallMemo } from './buttons/ButtonCall'; +import { ButtonGroupDrawRepeat } from './buttons/ButtonGroupDrawRepeat'; import { ButtonMicContinuationMemo } from './buttons/ButtonMicContinuation'; import { ButtonMicMemo } from './buttons/ButtonMic'; import { ButtonMultiChatMemo } from './buttons/ButtonMultiChat'; @@ -115,6 +116,7 @@ export function Composer(props: { // state const [composeText, debouncedText, setComposeText] = useDebouncer('', 300, 1200, true); + const [drawRepeat, setDrawRepeat] = React.useState(1); const [micContinuation, setMicContinuation] = React.useState(false); const [speechInterimResult, setSpeechInterimResult] = React.useState(null); const [sendStarted, setSendStarted] = React.useState(false); @@ -210,6 +212,8 @@ export function Composer(props: { const noConversation = !targetConversationId; const showChatAttachments = chatExecuteModeCanAttach(chatExecuteMode); + const composerTextSuffix = chatExecuteMode === 'generate-image' && isDesktop && drawRepeat > 1 ? ` x${drawRepeat}` : ''; + const micIsRunning = !!speechInterimResult; // more mic way below, as we use complex hooks @@ -298,7 +302,7 @@ export function Composer(props: { // prepare the fragments: content (if any) and attachments (if allowed, and any) const fragments: (DMessageContentFragment | DMessageAttachmentFragment)[] = []; if (composerText) - fragments.push(createTextContentFragment(composerText)); + fragments.push(createTextContentFragment(composerText + composerTextSuffix)); const canAttach = chatExecuteModeCanAttach(_chatExecuteMode); if (canAttach) { @@ -319,7 +323,7 @@ export function Composer(props: { if (enqueued) _handleClearText(); return enqueued; - }, [attachmentsTakeAllFragments, confirmProceedIfAttachmentsNotSupported, _handleClearText, inReferenceTo, onAction, targetConversationId]); + }, [attachmentsTakeAllFragments, composerTextSuffix, confirmProceedIfAttachmentsNotSupported, _handleClearText, inReferenceTo, onAction, targetConversationId]); const handleSendAction = React.useCallback(async (chatExecuteMode: ChatExecuteMode, composerText: string): Promise => { setSendStarted(true); @@ -1060,6 +1064,9 @@ export function Composer(props: { + {/* [desktop] Draw mode N buttons */} + {isDesktop && isDraw && } + {/* [desktop] Multicast switch (under the Chat button) */} {isDesktop && props.isMulticast !== null && } diff --git a/src/apps/chat/components/composer/buttons/ButtonGroupDrawRepeat.tsx b/src/apps/chat/components/composer/buttons/ButtonGroupDrawRepeat.tsx new file mode 100644 index 000000000..71c1e2a0b --- /dev/null +++ b/src/apps/chat/components/composer/buttons/ButtonGroupDrawRepeat.tsx @@ -0,0 +1,67 @@ +import * as React from 'react'; + +import { Box, FormControl, IconButton } from '@mui/joy'; + + +const _styles = { + control: { + gap: 1, + mt: 1, + } as const, + + buttonGroup: { + display: 'flex', + justifyContent: 'space-evenly', + } as const, + + button: { + borderRadius: 'sm', + // boxShadow: drawRepeat === n ? '0px 2px 8px 0px rgb(var(--joy-palette-warning-mainChannel) / 40%)' : 'none', + // fontWeight: drawRepeat === n ? 'xl' : 400, /* reset, from 600 */ + transition: 'transform 0.14s, box-shadow 0.14s', + '&:hover': { + transform: 'translateY(-1px)', + // backgroundColor: drawRepeat === n ? 'background.popup' : 'background.surface', + // boxShadow: '0 0 8px 1px rgb(var(--joy-palette-warning-mainChannel) / 40%)', + } as const, + } as const, + + text: { + mx: 'auto', + fontSize: 'xs', + opacity: '0.5', + } as const, +} as const; + + +export function ButtonGroupDrawRepeat(props: { + drawRepeat: number, + setDrawRepeat: (n: number) => void, +}) { + + const { drawRepeat, setDrawRepeat } = props; + + return ( + + + {[1, 2, 4, 5, 10].map((n) => ( + setDrawRepeat(n)} + sx={_styles.button} + > + {n} + + ))} + + + {drawRepeat > 1 + ? `Create ${drawRepeat} Images` + : 'Number of Images'} + + + ); +} \ No newline at end of file