mirror of
https://github.com/enricoros/big-AGI.git
synced 2026-05-10 21:50:14 -07:00
Style cleanups.
This commit is contained in:
@@ -662,7 +662,7 @@ export function Composer(props: {
|
||||
variant='outlined'
|
||||
color={isDraw ? 'warning' : isReAct ? 'success' : undefined}
|
||||
autoFocus
|
||||
minRows={isMobile ? 4 : showChatInReferenceTo ? 4 : 5}
|
||||
minRows={isMobile ? 4 : agiAttachmentPrompts.hasData ? 3 : showChatInReferenceTo ? 4 : 5}
|
||||
maxRows={isMobile ? 8 : 10}
|
||||
placeholder={textPlaceholder}
|
||||
value={composeText}
|
||||
@@ -691,7 +691,7 @@ export function Composer(props: {
|
||||
}}
|
||||
sx={{
|
||||
backgroundColor: 'background.level1',
|
||||
'&:focus-within': { backgroundColor: 'background.popup', '.in-reference-to-bubble': { backgroundColor: 'background.popup' } },
|
||||
'&:focus-within': { backgroundColor: 'background.popup', '.within-composer-focus': { backgroundColor: 'background.popup' } },
|
||||
lineHeight: lineHeightTextareaMd,
|
||||
}} />
|
||||
|
||||
|
||||
@@ -117,7 +117,7 @@ export function LLMAttachmentsList(props: {
|
||||
<Box sx={{ position: 'relative' }}>
|
||||
|
||||
{/* Horizontally scrollable */}
|
||||
<Box sx={{ display: 'flex', overflowX: 'auto', gap: 1, height: '100%', pr: 5 }}>
|
||||
<Box sx={{ height: '100%', pr: 5, overflowX: 'auto', display: 'flex', alignItems: 'center', gap: 1 }}>
|
||||
|
||||
{/* AI Suggestion Button */}
|
||||
{(agiAttachmentPrompts.isVisible || agiAttachmentPrompts.hasData) && (
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
import * as React from 'react';
|
||||
|
||||
import { CircularProgress, IconButton, Tooltip } from '@mui/joy';
|
||||
import type { SxProps } from '@mui/joy/styles/types';
|
||||
import { Box, CircularProgress, IconButton, Tooltip } from '@mui/joy';
|
||||
import AutoFixHighIcon from '@mui/icons-material/AutoFixHigh';
|
||||
|
||||
import type { AgiAttachmentPromptsData } from '~/modules/aifn/attachmentprompts/useAgiAttachmentPrompts';
|
||||
import { SxProps } from '@mui/joy/styles/types';
|
||||
|
||||
import { AgiSquircleIcon } from '~/common/components/icons/AgiSquircleIcon';
|
||||
|
||||
import { AGI_SUGGESTIONS_COLOR } from '../textarea/ComposerTextAreaActions';
|
||||
|
||||
|
||||
@@ -12,21 +15,26 @@ export const LLMAttachmentsPromptsButtonMemo = React.memo(LLMAttachmentsPromptsB
|
||||
|
||||
|
||||
const promptGenIconButtonSx: SxProps = {
|
||||
minWidth: 40,
|
||||
// minWidth: 40,
|
||||
backgroundColor: 'background.level1',
|
||||
boxShadow: `inset 0 4px 6px -4px rgb(var(--joy-palette-${AGI_SUGGESTIONS_COLOR}-darkChannel) / 40%)`,
|
||||
borderRadius: '2rem',
|
||||
borderBottomLeftRadius: 0,
|
||||
borderColor: `${AGI_SUGGESTIONS_COLOR}.outlinedColor`,
|
||||
// borderColor: `${AGI_SUGGESTIONS_COLOR}.outlinedBorder`,
|
||||
// '&:hover': {
|
||||
// backgroundColor: 'background.level1',
|
||||
// },
|
||||
'&:hover': {
|
||||
backgroundColor: `${AGI_SUGGESTIONS_COLOR}.solidBg`,
|
||||
borderColor: `${AGI_SUGGESTIONS_COLOR}.solidBg`,
|
||||
color: `${AGI_SUGGESTIONS_COLOR}.solidColor`,
|
||||
},
|
||||
};
|
||||
|
||||
const brightenSx: SxProps = {
|
||||
...promptGenIconButtonSx,
|
||||
backgroundColor: 'background.popup',
|
||||
boxShadow: undefined,
|
||||
boxShadow: 'xs',
|
||||
};
|
||||
|
||||
function LLMAttachmentsPromptsButton({ data }: { data: AgiAttachmentPromptsData }) {
|
||||
@@ -34,8 +42,8 @@ function LLMAttachmentsPromptsButton({ data }: { data: AgiAttachmentPromptsData
|
||||
const tooltipTitle =
|
||||
data.error ? (data.error.message || 'Error guessing actions')
|
||||
: data.isFetching ? null
|
||||
: data.isPending ? 'What to do?'
|
||||
: 'Guess more';
|
||||
: data.isPending ? <Box sx={{ display: 'flex', gap: 1 }}><AgiSquircleIcon inverted sx={{ color: 'white', borderRadius: '1rem' }} /> What to do?</Box>
|
||||
: 'Give me more ideas';
|
||||
|
||||
const button = (
|
||||
<IconButton
|
||||
@@ -44,7 +52,8 @@ function LLMAttachmentsPromptsButton({ data }: { data: AgiAttachmentPromptsData
|
||||
size='sm'
|
||||
disabled={data.isFetching}
|
||||
onClick={data.refetch}
|
||||
sx={data.hasData ? brightenSx : promptGenIconButtonSx}
|
||||
// onClick={data.hasData ? data.clear : data.refetch}
|
||||
sx={(data.hasData && !data.isFetching) ? brightenSx : promptGenIconButtonSx}
|
||||
>
|
||||
{data.isFetching ? (
|
||||
<CircularProgress size='sm' color='neutral' />
|
||||
@@ -55,7 +64,7 @@ function LLMAttachmentsPromptsButton({ data }: { data: AgiAttachmentPromptsData
|
||||
);
|
||||
|
||||
return !tooltipTitle ? button : (
|
||||
<Tooltip variant='outlined' disableInteractive placement='top-end' arrow title={tooltipTitle}>
|
||||
<Tooltip variant='outlined' disableInteractive placement='left' arrow title={tooltipTitle}>
|
||||
{button}
|
||||
</Tooltip>
|
||||
);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import * as React from 'react';
|
||||
|
||||
import type { SxProps } from '@mui/joy/styles/types';
|
||||
import { Box, ColorPaletteProp, Sheet } from '@mui/joy';
|
||||
import { Box, Button, ColorPaletteProp } from '@mui/joy';
|
||||
|
||||
import type { AgiAttachmentPromptsData } from '~/modules/aifn/attachmentprompts/useAgiAttachmentPrompts';
|
||||
|
||||
@@ -11,20 +11,18 @@ import { InReferenceToBubble } from '../../message/InReferenceToBubble';
|
||||
|
||||
|
||||
// configuration
|
||||
export const AGI_SUGGESTIONS_COLOR: ColorPaletteProp = 'primary';
|
||||
export const AGI_SUGGESTIONS_COLOR: ColorPaletteProp = 'success';
|
||||
|
||||
// Styles
|
||||
|
||||
const textAreaSx: SxProps = {
|
||||
flex: 1,
|
||||
// marginBottom: 0.5,
|
||||
// margin: 1,
|
||||
// marginTop: 0,
|
||||
|
||||
// layout
|
||||
display: 'grid',
|
||||
justifyItems: 'start',
|
||||
gap: 1,
|
||||
gap: 0.5,
|
||||
mb: 0.625,
|
||||
|
||||
// Buttons
|
||||
[`& button`]: {
|
||||
@@ -35,21 +33,31 @@ const textAreaSx: SxProps = {
|
||||
};
|
||||
|
||||
|
||||
const suggestedPromptSx: SxProps = {
|
||||
const promptButtonSx: SxProps = {
|
||||
minHeight: '2rem',
|
||||
placeSelf: 'start',
|
||||
// width: '100%',
|
||||
|
||||
color: `${AGI_SUGGESTIONS_COLOR}.softActiveColor`,
|
||||
backgroundColor: 'background.surface',
|
||||
border: '1px solid',
|
||||
borderColor: `${AGI_SUGGESTIONS_COLOR}.outlinedColor`,
|
||||
borderColor: `${AGI_SUGGESTIONS_COLOR}.outlinedBorder`,
|
||||
borderRadius: '1rem',
|
||||
borderBottomLeftRadius: 0,
|
||||
px: 1.5,
|
||||
boxShadow: 'xs',
|
||||
pl: 1.5,
|
||||
pr: 2,
|
||||
py: 0.5,
|
||||
fontSize: 'sm',
|
||||
fontWeight: 'normal',
|
||||
cursor: 'pointer',
|
||||
transition: 'none',
|
||||
textAlign: 'start',
|
||||
// whiteSpace: 'balance',
|
||||
'&:hover': {
|
||||
backgroundColor: `${AGI_SUGGESTIONS_COLOR}.solidBg`,
|
||||
borderColor: `${AGI_SUGGESTIONS_COLOR}.solidBg`,
|
||||
color: `${AGI_SUGGESTIONS_COLOR}.solidColor`,
|
||||
transition: 'none',
|
||||
},
|
||||
};
|
||||
|
||||
@@ -75,21 +83,22 @@ export function ComposerTextAreaActions(props: {
|
||||
key={index}
|
||||
item={item}
|
||||
onRemove={props.onRemoveReferenceTo}
|
||||
className='in-reference-to-bubble'
|
||||
className='within-composer-focus'
|
||||
/>
|
||||
))}
|
||||
|
||||
{/* Auto-Prompts from attachments */}
|
||||
{agiAttachmentPrompts.prompts.map((candidate, index) =>
|
||||
<Sheet
|
||||
<Button
|
||||
key={index}
|
||||
color={AGI_SUGGESTIONS_COLOR}
|
||||
variant='soft'
|
||||
variant='plain'
|
||||
onClick={() => props.onAppendAndSend(candidate)}
|
||||
sx={suggestedPromptSx}
|
||||
className='within-composer-focus'
|
||||
sx={promptButtonSx}
|
||||
>
|
||||
{candidate}
|
||||
</Sheet>,
|
||||
</Button>,
|
||||
)}
|
||||
|
||||
{/* Guess Action Button */}
|
||||
|
||||
@@ -581,7 +581,6 @@ export function ChatMessage(props: {
|
||||
key={'irt-' + index}
|
||||
item={item}
|
||||
bubbleVariant='message'
|
||||
className='in-reference-to-bubble'
|
||||
/>
|
||||
))}
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
.agi-border-4 > * {
|
||||
clip-path: inset(var(--border-width));
|
||||
border-radius: var(--border-radius);
|
||||
opacity: 0.92;
|
||||
opacity: 0.94;
|
||||
}
|
||||
|
||||
.agi-border-4::before {
|
||||
|
||||
@@ -17,6 +17,7 @@ export interface AgiAttachmentPromptsData {
|
||||
isFetching: boolean;
|
||||
isPending: boolean;
|
||||
refetch: () => Promise<any>;
|
||||
clear: () => void;
|
||||
}
|
||||
|
||||
const noPrompts: string[] = [];
|
||||
@@ -24,6 +25,7 @@ const noPrompts: string[] = [];
|
||||
export function useAgiAttachmentPrompts(canAutoTrigger: boolean, attachmentDrafts: AttachmentDraft[]): AgiAttachmentPromptsData {
|
||||
|
||||
// state
|
||||
const [isCleared, setIsCleared] = React.useState(false);
|
||||
const [alreadyRan, setAlreadyRan] = React.useState(false);
|
||||
|
||||
// derived
|
||||
@@ -35,14 +37,18 @@ export function useAgiAttachmentPrompts(canAutoTrigger: boolean, attachmentDraft
|
||||
const { data, error, isPending, isFetching, refetch } = useQuery({
|
||||
enabled: canAutoTrigger && hasEnoughInput && !alreadyRan,
|
||||
queryKey: ['aifn-prompts-attachments', ...fragments.map(f => f.fId).sort()],
|
||||
queryFn: async ({ signal }) => agiAttachmentPrompts(fragments, signal),
|
||||
queryFn: async ({ signal }) => {
|
||||
const data = await agiAttachmentPrompts(fragments, signal);
|
||||
setIsCleared(false);
|
||||
return data;
|
||||
},
|
||||
staleTime: 1000 * 60 * 10, // 10 minutes
|
||||
// placeholderData: inputCount ? keepPreviousData : undefined,
|
||||
});
|
||||
|
||||
React.useEffect(() => {
|
||||
console.log('refetch diff');
|
||||
}, [refetch]);
|
||||
const clear = React.useCallback(() => {
|
||||
setIsCleared(true);
|
||||
}, []);
|
||||
|
||||
// derived state
|
||||
const isVisible = hasEnoughInput;
|
||||
@@ -58,11 +64,12 @@ export function useAgiAttachmentPrompts(canAutoTrigger: boolean, attachmentDraft
|
||||
|
||||
return useShallowStable({
|
||||
isVisible,
|
||||
hasData,
|
||||
prompts: data || noPrompts,
|
||||
hasData: hasData && !isCleared,
|
||||
prompts: isCleared ? noPrompts : data || noPrompts,
|
||||
error,
|
||||
isFetching,
|
||||
isPending,
|
||||
refetch,
|
||||
clear,
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user