mirror of
https://github.com/enricoros/big-AGI.git
synced 2026-05-11 06:00:15 -07:00
AppChat: Draw: inline enhancements
This commit is contained in:
@@ -2,10 +2,9 @@ import * as React from 'react';
|
||||
import { useShallow } from 'zustand/react/shallow';
|
||||
import type { FileWithHandle } from 'browser-fs-access';
|
||||
|
||||
import { Box, Button, ButtonGroup, Card, Dropdown, Grid, IconButton, Menu, MenuButton, MenuItem, Textarea, Tooltip, Typography } from '@mui/joy';
|
||||
import { Box, Button, ButtonGroup, Card, Dropdown, Grid, IconButton, Menu, MenuButton, MenuItem, Textarea, Typography } from '@mui/joy';
|
||||
import { ColorPaletteProp, SxProps, VariantProp } from '@mui/joy/styles/types';
|
||||
import AddCircleOutlineIcon from '@mui/icons-material/AddCircleOutline';
|
||||
import AutoAwesomeIcon from '@mui/icons-material/AutoAwesome';
|
||||
import ExpandLessIcon from '@mui/icons-material/ExpandLess';
|
||||
import FormatPaintTwoToneIcon from '@mui/icons-material/FormatPaintTwoTone';
|
||||
import PsychologyIcon from '@mui/icons-material/Psychology';
|
||||
@@ -74,6 +73,7 @@ import { ButtonMicMemo } from './buttons/ButtonMic';
|
||||
import { ButtonMultiChatMemo } from './buttons/ButtonMultiChat';
|
||||
import { ButtonOptionsDraw } from './buttons/ButtonOptionsDraw';
|
||||
import { ComposerTextAreaActions } from './textarea/ComposerTextAreaActions';
|
||||
import { ComposerTextAreaDrawActions } from './textarea/ComposerTextAreaDrawActions';
|
||||
import { StatusBarMemo } from '../StatusBar';
|
||||
import { TokenBadgeMemo } from './tokens/TokenBadge';
|
||||
import { TokenProgressbarMemo } from './tokens/TokenProgressbar';
|
||||
@@ -832,7 +832,7 @@ export function Composer(props: {
|
||||
variant='outlined'
|
||||
color={isDraw ? 'warning' : isReAct ? 'success' : undefined}
|
||||
autoFocus
|
||||
minRows={isMobile ? 4 : agiAttachmentPrompts.hasData ? 3 : showChatInReferenceTo ? 4 : 5}
|
||||
minRows={isMobile ? 4 : isDraw ? 4 : agiAttachmentPrompts.hasData ? 3 : showChatInReferenceTo ? 4 : 5}
|
||||
maxRows={isMobile ? 8 : 10}
|
||||
placeholder={textPlaceholder}
|
||||
value={composeText}
|
||||
@@ -841,8 +841,12 @@ export function Composer(props: {
|
||||
onPasteCapture={handleAttachCtrlV}
|
||||
// onFocusCapture={handleFocusModeOn}
|
||||
// onBlurCapture={handleFocusModeOff}
|
||||
endDecorator={
|
||||
<ComposerTextAreaActions
|
||||
endDecorator={isDraw
|
||||
? <ComposerTextAreaDrawActions
|
||||
composerText={composeText}
|
||||
onReplaceText={setComposeText}
|
||||
/>
|
||||
: <ComposerTextAreaActions
|
||||
agiAttachmentPrompts={agiAttachmentPrompts}
|
||||
inReferenceTo={inReferenceTo}
|
||||
onAppendAndSend={handleAppendTextAndSend}
|
||||
@@ -1027,11 +1031,12 @@ export function Composer(props: {
|
||||
{/*</Tooltip>}*/}
|
||||
|
||||
{/* [Draw] Imagine */}
|
||||
{isDraw && !!composeText && <Tooltip title='Generate an image prompt'>
|
||||
<IconButton variant='outlined' disabled={noConversation || noLLM} onClick={handleTextImagineClicked}>
|
||||
<AutoAwesomeIcon />
|
||||
</IconButton>
|
||||
</Tooltip>}
|
||||
{/* NOTE: disabled: as we have prompt enhancement in the TextArea (Draw Mode) already */}
|
||||
{/*{isDraw && !!composeText && <Tooltip title='Generate an image prompt'>*/}
|
||||
{/* <IconButton variant='outlined' disabled={noConversation || noLLM} onClick={handleTextImagineClicked}>*/}
|
||||
{/* <AutoAwesomeIcon />*/}
|
||||
{/* </IconButton>*/}
|
||||
{/*</Tooltip>}*/}
|
||||
|
||||
{/* Mode expander */}
|
||||
<IconButton
|
||||
|
||||
@@ -15,7 +15,7 @@ export const AGI_SUGGESTIONS_COLOR: ColorPaletteProp = 'success';
|
||||
|
||||
// Styles
|
||||
|
||||
const textAreaSx: SxProps = {
|
||||
export const composerTextAreaSx: SxProps = {
|
||||
flex: 1,
|
||||
|
||||
// layout
|
||||
@@ -29,8 +29,8 @@ const textAreaSx: SxProps = {
|
||||
'--Button-gap': '1.2rem',
|
||||
transition: 'background-color 0.2s, color 0.2s',
|
||||
// minWidth: 160,
|
||||
},
|
||||
};
|
||||
} as const,
|
||||
} as const;
|
||||
|
||||
|
||||
const promptButtonSx: SxProps = {
|
||||
@@ -75,7 +75,7 @@ export function ComposerTextAreaActions(props: {
|
||||
return null;
|
||||
|
||||
return (
|
||||
<Box sx={textAreaSx}>
|
||||
<Box sx={composerTextAreaSx}>
|
||||
|
||||
{/* In-Reference-To bubbles */}
|
||||
{props.inReferenceTo?.map((item, index) => (
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
import * as React from 'react';
|
||||
|
||||
import { Box, Button } from '@mui/joy';
|
||||
import AutoFixHighIcon from '@mui/icons-material/AutoFixHigh';
|
||||
|
||||
import { composerTextAreaSx } from './ComposerTextAreaActions';
|
||||
import { imaginePromptFromTextOrThrow } from '~/modules/aifn/imagine/imaginePromptFromText';
|
||||
|
||||
|
||||
const _style = {
|
||||
enhance: {
|
||||
minWidth: 170,
|
||||
mx: 0.625,
|
||||
pr: 2,
|
||||
border: '1px solid',
|
||||
borderColor: 'warning.outlinedBorder',
|
||||
boxShadow: '0px 4px 4px -4px rgb(var(--joy-palette-warning-darkChannel) / 20%)',
|
||||
transition: 'background-color 0.14s',
|
||||
justifyContent: 'space-between',
|
||||
} as const,
|
||||
gone: {
|
||||
visibility: 'hidden',
|
||||
} as const,
|
||||
} as const;
|
||||
|
||||
export function ComposerTextAreaDrawActions(props: {
|
||||
composerText: string,
|
||||
onReplaceText: (text: string) => void,
|
||||
}) {
|
||||
|
||||
// state
|
||||
const [isSimpleEnhancing, setIsSimpleEnhancing] = React.useState(false);
|
||||
|
||||
|
||||
// derived
|
||||
const trimmedPrompt = props.composerText.trim();
|
||||
const userHasText = !!trimmedPrompt;
|
||||
|
||||
|
||||
const { onReplaceText } = props;
|
||||
|
||||
const handleSimpleEnhance = React.useCallback(async () => {
|
||||
if (!trimmedPrompt || isSimpleEnhancing) return;
|
||||
setIsSimpleEnhancing(true);
|
||||
const improvedPrompt = await imaginePromptFromTextOrThrow(trimmedPrompt, 'DEV')
|
||||
.catch(console.error);
|
||||
if (improvedPrompt)
|
||||
onReplaceText(improvedPrompt);
|
||||
setIsSimpleEnhancing(false);
|
||||
}, [isSimpleEnhancing, onReplaceText, trimmedPrompt]);
|
||||
|
||||
|
||||
return (
|
||||
<Box sx={composerTextAreaSx}>
|
||||
|
||||
{/* Enhance button */}
|
||||
<Button
|
||||
size='sm'
|
||||
variant={isSimpleEnhancing ? 'soft' : 'soft'}
|
||||
color='warning'
|
||||
disabled={!userHasText}
|
||||
loading={isSimpleEnhancing}
|
||||
loadingPosition='end'
|
||||
// className={promptButtonClass}
|
||||
endDecorator={<AutoFixHighIcon sx={{ fontSize: '20px' }} />}
|
||||
onClick={handleSimpleEnhance}
|
||||
sx={!userHasText ? _style.gone : _style.enhance}
|
||||
>
|
||||
{isSimpleEnhancing ? 'Enhancing...' : 'Enhance Prompt'}
|
||||
</Button>
|
||||
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user