diff --git a/src/apps/chat/components/message/fragments-attachment-doc/DocumentAttachmentFragments.tsx b/src/apps/chat/components/message/fragments-attachment-doc/DocumentAttachmentFragments.tsx index 6af489f24..469972376 100644 --- a/src/apps/chat/components/message/fragments-attachment-doc/DocumentAttachmentFragments.tsx +++ b/src/apps/chat/components/message/fragments-attachment-doc/DocumentAttachmentFragments.tsx @@ -60,6 +60,17 @@ export function DocumentAttachmentFragments(props: { }, []); + // memos + const buttonsSx = React.useMemo(() => ({ + // layout + display: 'flex', + flexWrap: 'wrap', + gap: 1, + justifyContent: props.messageRole === 'assistant' ? 'flex-start' : 'flex-end', + ...selectedFragment && { mb: 1 }, + }), [props.messageRole, selectedFragment]); + + return ( - {/* Horizontally scrollable Document buttons */} - + {/* Document buttons */} + {props.attachmentFragments.map((attachmentFragment) => *:not(:first-child)': { + // '& > *:not(:first-of-type)': { // borderTop: '1px solid', // borderTopColor: 'background.level3', // }, diff --git a/src/modules/blocks/blocks.styles.ts b/src/modules/blocks/blocks.styles.ts index 9b870f221..74025ae24 100644 --- a/src/modules/blocks/blocks.styles.ts +++ b/src/modules/blocks/blocks.styles.ts @@ -11,10 +11,20 @@ import type { AutoBlocksCodeRenderVariant } from './AutoBlocksRenderer'; export function useScaledCodeSx(fromAssistant: boolean, contentScaling: ContentScaling, codeRenderVariant: AutoBlocksCodeRenderVariant): SxProps { return React.useMemo(() => ({ - my: codeRenderVariant === 'plain' ? 0 : themeScalingMap[contentScaling]?.blockCodeMarginY ?? 0, - backgroundColor: codeRenderVariant === 'plain' ? 'background.surface' : fromAssistant ? 'neutral.plainHoverBg' : 'primary.plainActiveBg', - boxShadow: codeRenderVariant === 'plain' ? undefined : 'inset 2px 0px 5px -4px var(--joy-palette-background-backdrop)', // was 'xs' + my: + (codeRenderVariant === 'plain' || codeRenderVariant === 'enhanced') ? 0 + : themeScalingMap[contentScaling]?.blockCodeMarginY ?? 0, + backgroundColor: + codeRenderVariant === 'plain' ? 'background.surface' + : fromAssistant ? 'neutral.plainHoverBg' : 'primary.plainActiveBg', + boxShadow: + codeRenderVariant === 'plain' ? undefined + : 'inset 2px 0px 5px -4px var(--joy-palette-background-backdrop)', // was 'xs' borderRadius: 'sm', + ...(codeRenderVariant === 'enhanced' && { + borderTopLeftRadius: 0, + borderTopRightRadius: 0, + }), fontFamily: 'code', fontSize: themeScalingMap[contentScaling]?.blockCodeFontSize ?? '0.875rem', fontWeight: 'md', // JetBrains Mono has a lighter weight, so we need that extra bump diff --git a/src/modules/blocks/code/EnhancedRenderCode.tsx b/src/modules/blocks/code/EnhancedRenderCode.tsx index d6e0417e1..0bdebf756 100644 --- a/src/modules/blocks/code/EnhancedRenderCode.tsx +++ b/src/modules/blocks/code/EnhancedRenderCode.tsx @@ -1,16 +1,60 @@ import * as React from 'react'; +import { useShallow } from 'zustand/react/shallow'; import type { SxProps } from '@mui/joy/styles/types'; -import { Box, ColorPaletteProp, Typography } from '@mui/joy'; +import { Box, ColorPaletteProp, ListItemDecorator, MenuItem, Typography } from '@mui/joy'; +import CheckRoundedIcon from '@mui/icons-material/CheckRounded'; import CodeIcon from '@mui/icons-material/Code'; import type { ContentScaling } from '~/common/app.theme'; +import { CloseableMenu } from '~/common/components/CloseableMenu'; import { TooltipOutlined } from '~/common/components/TooltipOutlined'; +import { useUXLabsStore } from '~/common/state/store-ux-labs'; import { RenderCodeMemo } from './RenderCode'; import { enhancedCodePanelTitleTooltipSx, RenderCodePanelFrame } from './panel/RenderCodePanelFrame'; +/** + * Small hidden context menu to toggle the code enhancer, globally. + */ +function CodeEnhancerMenu(props: { anchor: HTMLElement, onClose: () => void }) { + + // state + const { labsEnhanceCodeBlocks, setLabsEnhanceCodeBlocks } = useUXLabsStore(useShallow(state => ({ + labsEnhanceCodeBlocks: state.labsEnhanceCodeBlocks, + setLabsEnhanceCodeBlocks: state.setLabsEnhanceCodeBlocks, + }))); + + const toggleEnhanceCodeBlocks = React.useCallback(() => { + // turn blocks on (may not even be called, ever) + if (!labsEnhanceCodeBlocks) { + setLabsEnhanceCodeBlocks(true); + return; + } + // ask to turn the blocks off + // showPromisedOverlay('') ... + setLabsEnhanceCodeBlocks(false); + }, [labsEnhanceCodeBlocks, setLabsEnhanceCodeBlocks]); + + return ( + + + {/* A mix in between UxLabsSettings (labsEnhanceCodeBlocks) and the ChatDrawer MenuItems */} + + {labsEnhanceCodeBlocks && } + Enhance Legacy Code + + + + ); +} + + export function EnhancedRenderCode(props: { semiStableId: string | undefined, @@ -33,6 +77,7 @@ export function EnhancedRenderCode(props: { }) { // state + const [contextMenuAnchor, setContextMenuAnchor] = React.useState(null); // const [isCopied, setIsCopied] = React.useState(false); @@ -59,8 +104,8 @@ export function EnhancedRenderCode(props: { {/* This is what we have */}
Title
{props.title}
-
Language
-
{props.language}
+ {/*
Language
*/} + {/*
{props.language}
*/}
Code Length
{props.code.length} characters
Code Lines
@@ -81,7 +126,7 @@ export function EnhancedRenderCode(props: { {/*
Text Buffer Id
*/} {/*
{fragmentId}
*/}
- ), [props.code, props.language, props.semiStableId, props.title]); + ), [props.code, props.semiStableId, props.title]); const headerRow = React.useMemo(() => <> @@ -135,23 +180,24 @@ export function EnhancedRenderCode(props: { // , [props.onLiveFileCreate]); - const patchedCodeSx = React.useMemo((): SxProps => ({ - ...props.codeSx, - my: undefined, - borderTopLeftRadius: 0, - borderTopRightRadius: 0, - }), [props.codeSx]); + const handleCloseContextMenu = React.useCallback(() => setContextMenuAnchor(null), []); + + const handleToggleContextMenu = React.useCallback((event: React.MouseEvent) => { + event.preventDefault(); // added for the Right mouse click (to prevent the menu) + setContextMenuAnchor(anchor => anchor ? null : event.currentTarget); + }, []); return ( + {/* Context Menu */} + {contextMenuAnchor && ( + + )} + ); } \ No newline at end of file diff --git a/src/modules/blocks/code/panel/RenderCodePanelFrame.tsx b/src/modules/blocks/code/panel/RenderCodePanelFrame.tsx index 4ff959e18..d8e2472f2 100644 --- a/src/modules/blocks/code/panel/RenderCodePanelFrame.tsx +++ b/src/modules/blocks/code/panel/RenderCodePanelFrame.tsx @@ -3,7 +3,7 @@ import * as React from 'react'; import type { SxProps } from '@mui/joy/styles/types'; import { Box, ColorPaletteProp, Sheet, useColorScheme } from '@mui/joy'; -import type { ContentScaling } from '~/common/app.theme'; +import { ContentScaling, themeScalingMap } from '~/common/app.theme'; export const enhancedCodePanelTitleTooltipSx: SxProps = { @@ -22,12 +22,13 @@ export const enhancedCodePanelTitleTooltipSx: SxProps = { export function RenderCodePanelFrame(props: { color: ColorPaletteProp; toolbarColor?: ColorPaletteProp; - noShadow?: boolean; - frameVariant?: 'solid'; + gutterBlock?: boolean; + noOuterShadow?: boolean; contentScaling: ContentScaling; - headerRow?: React.ReactNode; + headerRow: React.ReactNode; subHeaderInline?: React.ReactNode; toolbarRow?: React.ReactNode; + onContextMenu?: (event: React.MouseEvent) => void; children: React.ReactNode; }) { @@ -37,12 +38,16 @@ export function RenderCodePanelFrame(props: { const [frameSx, headersBlockSx, headerRowSx, subHeaderContainedSx, toolbarRowSx] = React.useMemo((): SxProps[] => [ { // frame - mt: 0.5, - backgroundColor: 'background.surface', + // add top margin (gutter) only of this is not the first block in the sequence + ...(props.gutterBlock && { + '&:not(:first-of-type)': { mt: themeScalingMap[props.contentScaling]?.blockCodeMarginY ?? 1 }, + '&:not(:last-of-type)': { mb: themeScalingMap[props.contentScaling]?.blockCodeMarginY ?? 1 }, + }), + backgroundColor: /*props.noOuterShadow ? 'background.popup' :*/ 'background.surface', border: '1px solid', borderColor: `${props.color}.outlinedBorder`, borderRadius: 'sm', - ...(!props.noShadow && { boxShadow: 'sm' }), + ...(!props.noOuterShadow && { boxShadow: 'sm' }), // boxShadow: 'inset 2px 0px 5px -4px var(--joy-palette-background-backdrop)', // contain: 'paint', }, @@ -53,8 +58,15 @@ export function RenderCodePanelFrame(props: { }, { // header row 1 - minHeight: props.contentScaling === 'xs' ? undefined : props.contentScaling === 'sm' ? '2.25rem' : '2.5rem', - mx: 1, + // see DocAttachmentFragmentButton.buttonSx for the same scaling + minHeight: props.contentScaling === 'xs' ? '2.25rem' : props.contentScaling === 'sm' ? '2.375rem' : '2.5rem', + px: 1, + // borderRadius: 'sm', + // borderBottomLeftRadius: 0, + // borderBottomRightRadius: 0, + // '&:hover': { + // backgroundColor: `background.popup`, + // }, // layout display: 'flex', flexWrap: 'wrap', @@ -78,24 +90,22 @@ export function RenderCodePanelFrame(props: { gap: 1, }, - ], [isDarkMode, props.color, props.contentScaling, props.noShadow, props.toolbarColor]); + ], [isDarkMode, props.color, props.contentScaling, props.gutterBlock, props.noOuterShadow, props.toolbarColor]); return ( {/* header(s) */} - {(props.headerRow || props.subHeaderInline) && ( - - - {props.headerRow} - - {props.subHeaderInline && ( - - {props.subHeaderInline} - - )} + + + {props.headerRow} - )} + {props.subHeaderInline && ( + + {props.subHeaderInline} + + )} + {/* toolbar */} {props.toolbarRow && (