This commit is contained in:
Enrico Ros
2024-06-23 00:17:44 -07:00
parent 959edf6010
commit af722e09f8
7 changed files with 41 additions and 28 deletions
@@ -474,14 +474,15 @@ export function ChatMessage(props: {
{/* [aside A] Editing: Apply */}
{isEditingText && (
<Box sx={messageAsideColumnSx}>
{/*<Typography level='body-xs'>&nbsp;</Typography>*/}
<Tooltip arrow disableInteractive title='Apply Edits'>
<IconButton variant='solid' color='warning' onClick={handleEditsApply}>
<IconButton size='sm' variant='solid' color='warning' onClick={handleEditsApply} sx={{ mt: 0.25 }}>
<CheckRoundedIcon />
</IconButton>
</Tooltip>
{/*<Typography level='body-xs' sx={{ overflowWrap: 'anywhere' }}>*/}
{/* Save*/}
{/*</Typography>*/}
<Typography level='body-xs' sx={{ overflowWrap: 'anywhere', mt: 0.25 }}>
Done
</Typography>
</Box>
)}
@@ -583,11 +584,8 @@ export function ChatMessage(props: {
{/* If editing and there's no content, have a button to create a new TextContentFragment */}
{isEditingText && !contentFragments.length && (
<Button variant='plain' color='neutral' onClick={handleFragmentNew} sx={{
ml: fromAssistant ? undefined : 'auto',
mr: fromAssistant ? 'auto' : undefined,
}}>
Add text
<Button variant='plain' color='neutral' onClick={handleFragmentNew} sx={{ justifyContent: 'flex-start' }}>
add text ...
</Button>
)}
@@ -618,14 +616,15 @@ export function ChatMessage(props: {
{/* Editing: Cancel */}
{isEditingText && (
<Box sx={messageAsideColumnSx}>
{/*<Typography level='body-xs'>&nbsp;</Typography>*/}
<Tooltip arrow disableInteractive title='Discard Edits'>
<IconButton onClick={handleEditsCancel}>
<IconButton size='md' onClick={handleEditsCancel}>
<CloseRoundedIcon />
</IconButton>
</Tooltip>
{/*<Typography level='body-xs' sx={{ overflowWrap: 'anywhere' }}>*/}
{/* Close*/}
{/*</Typography>*/}
<Typography level='body-xs' sx={{ overflowWrap: 'anywhere' }}>
Cancel
</Typography>
</Box>
)}
@@ -13,7 +13,7 @@ import type { DMessageRole } from '~/common/stores/chat/chat.message';
import { createTextAttachmentFragment, DMessageAttachmentFragment, DMessageFragmentId } from '~/common/stores/chat/chat.fragments';
import { marshallWrapText } from '~/common/stores/chat/chat.tokens';
import { ContentPartTextEdit } from '../fragments-content/ContentPartTextEdit';
import { PartTextEdit } from '../fragments-content/PartTextEdit';
export function DocumentFragmentEditor(props: {
@@ -85,8 +85,8 @@ export function DocumentFragmentEditor(props: {
{isEditing ? (
// Document Editor
<ContentPartTextEdit
textPart={part}
<PartTextEdit
textPartText={part.text}
fragmentId={fragmentId}
contentScaling={props.contentScaling}
editedText={props.editedText}
@@ -11,7 +11,7 @@ import type { ChatMessageTextPartEditState } from '../ChatMessage';
import { ContentPartImageRef } from './ContentPartImageRef';
import { ContentPartPlaceholder } from './ContentPartPlaceholder';
import { ContentPartText } from './ContentPartText';
import { ContentPartTextEdit } from './ContentPartTextEdit';
import { PartTextEdit } from './PartTextEdit';
const editLayoutSx: SxProps = {
@@ -66,6 +66,10 @@ export function ContentFragments(props: {
const isEditingText = !!props.textEditsState;
const isMonoFragment = props.fragments.length < 2;
// if no fragments, don't box them
if (!props.fragments.length)
return null;
return <Box aria-label='message body' sx={isEditingText ? editLayoutSx : fromAssistant ? startLayoutSx : endLayoutSx}>
{props.fragments.map((fragment) => {
@@ -76,9 +80,9 @@ export function ContentFragments(props: {
switch (fragment.part.pt) {
case 'text':
return props.textEditsState ? (
<ContentPartTextEdit
<PartTextEdit
key={'edit-' + fragment.fId}
textPart={fragment.part}
textPartText={fragment.part.text}
fragmentId={fragment.fId}
contentScaling={props.contentScaling}
editedText={props.textEditsState[fragment.fId]}
@@ -125,12 +129,22 @@ export function ContentFragments(props: {
messageRole={props.messageRole}
contentScaling={props.contentScaling}
showAsItalic
// showAsProgress
/>
);
case 'error':
return (
return props.textEditsState ? (
<PartTextEdit
key={'edit-' + fragment.fId}
textPartText={fragment.part.error}
fragmentId={fragment.fId}
contentScaling={props.contentScaling}
editedText={props.textEditsState[fragment.fId]}
setEditedText={props.setEditedText}
onEnterPressed={props.onEditsApply}
onEscapePressed={props.onEditsCancel}
/>
) : (
<ContentPartPlaceholder
key={fragment.fId}
placeholderText={fragment.part.error}
@@ -6,7 +6,7 @@ import { Textarea } from '@mui/joy';
import { blocksRendererSx } from '~/modules/blocks/BlocksRenderer';
import type { ContentScaling } from '~/common/app.theme';
import type { DMessageFragmentId, DMessageTextPart } from '~/common/stores/chat/chat.fragments';
import type { DMessageFragmentId } from '~/common/stores/chat/chat.fragments';
const textEditAreaSx: SxProps = {
@@ -26,9 +26,9 @@ const textEditAreaSx: SxProps = {
* Very similar to <InlineTextArea /> but with externally controlled state rather than internal.
* Made it for as the editing alternative for <ContentPartText />.
*/
export function ContentPartTextEdit(props: {
export function PartTextEdit(props: {
// current value
textPart: DMessageTextPart,
textPartText: string,
fragmentId: DMessageFragmentId,
// visual
@@ -77,7 +77,7 @@ export function ContentPartTextEdit(props: {
size={props.contentScaling !== 'md' ? 'sm' : undefined}
value={(props.editedText !== undefined)
? props.editedText /* self-text */
: props.textPart.text /* DMessageTextPart text */
: props.textPartText /* DMessageTextPart text */
}
onChange={handleEditTextChanged}
onKeyDown={handleEditKeyDown}
+1 -1
View File
@@ -33,7 +33,7 @@ export async function runImageGenerationUpdatingState(cHandler: ConversationHand
imageText = imageText.replace(/x(\d+)$|\[(\d+)]$/, '').trim(); // Remove the "xN" or "[N]" part from the imageText
const { assistantMessageId, placeholderFragmentId } = cHandler.messageAppendAssistantPlaceholder(
`Give me ${t2iProvider.vendor === 'openai' ? 'a dozen' : 'a few'} seconds while I draw ${imageText?.length > 20 ? 'that' : '"' + imageText + '"'}...`,
`Give me ${t2iProvider.vendor === 'openai' ? 'a minute' : 'a few seconds'} while I draw ${imageText?.length > 20 ? 'that' : '"' + imageText + '"'} with ${t2iProvider.painter}...`,
{ originLLM: t2iProvider.painter },
);
+1 -1
View File
@@ -188,7 +188,7 @@ export const themeScalingMap: Record<ContentScaling, ContentScalingOptions> = {
blockFontSize: 'xs',
blockImageGap: 1,
blockLineHeight: 1.666667,
chatMessagePadding: 1.25,
chatMessagePadding: 1,
fragmentButtonFontSize: 'xs',
chatDrawerItemSx: { '--ListItem-minHeight': '2.25rem', fontSize: 'sm' }, // 36px
chatDrawerItemFolderSx: { '--ListItem-minHeight': '2.5rem', fontSize: 'sm' }, // 40px
+1 -1
View File
@@ -366,7 +366,7 @@ export const useChatStore = create<ConversationsStore>()(devtools(
// replace the Content.Pl[part.pt='ph'] fragments with Error fragments, to show the aborted ops (instead of just empty blocks)
message.fragments = message.fragments.map((fragment: DMessageFragment): DMessageFragment =>
(isContentFragment(fragment) && fragment.part.pt === 'ph')
? createErrorContentFragment(`Interrupted: ${fragment.part.pText}`)
? createErrorContentFragment(`${fragment.part.pText} (did not complete)`)
: fragment,
);
// cleanup pre-v4 properties