mirror of
https://github.com/enricoros/big-AGI.git
synced 2026-05-11 14:10:15 -07:00
LiveFile: message
This commit is contained in:
@@ -19,7 +19,8 @@ import WarningRoundedIcon from '@mui/icons-material/WarningRounded';
|
||||
import { RenderImageURL } from '~/modules/blocks/image/RenderImageURL';
|
||||
|
||||
import { GoodTooltip } from '~/common/components/GoodTooltip';
|
||||
import { LiveFileIcon } from '~/common/livefile/LiveFileIcon';
|
||||
import { LiveFileIcon } from '~/common/livefile/LiveFileIcons';
|
||||
import { TooltipOutlined } from '~/common/components/TooltipOutlined';
|
||||
import { ellipsizeFront, ellipsizeMiddle } from '~/common/util/textUtils';
|
||||
import { liveFileInAttachmentFragment } from '~/common/livefile/liveFile';
|
||||
|
||||
@@ -139,9 +140,13 @@ function attachmentIcons(attachmentDraft: AttachmentDraft): React.ReactNode {
|
||||
{/*))}*/}
|
||||
|
||||
{/*{activeConterters.some(c => c.id.startsWith('url-page-')) ? <LanguageIcon sx={{ opacity: 0.2, ml: -2.5 }} /> : null}*/}
|
||||
{activeConterters.map(c => {
|
||||
const Icon = converterTypeToIconMap[c.id] ?? null;
|
||||
return Icon ? <Icon key={c.id} sx={{ width: 20, height: 20 }} /> : null;
|
||||
{activeConterters.map((_converter, idx) => {
|
||||
const Icon = converterTypeToIconMap[_converter.id] ?? null;
|
||||
return !Icon ? null : (
|
||||
<TooltipOutlined key={`${_converter.id}-${idx}`} title={`Attached as ${_converter.name}`} placement='top-start'>
|
||||
<Icon sx={{ width: 20, height: 20 }} />
|
||||
</TooltipOutlined>
|
||||
);
|
||||
})}
|
||||
</Typography>;
|
||||
}
|
||||
@@ -264,7 +269,11 @@ export function LLMAttachmentButton(props: {
|
||||
{isOutputLoading && <CircularProgress color='success' size='sm' />}
|
||||
|
||||
{/* Live file icon */}
|
||||
{hasLiveFile && <LiveFileIcon />}
|
||||
{hasLiveFile && (
|
||||
<TooltipOutlined title='LiveFile is supported' placement='top-end'>
|
||||
<LiveFileIcon />
|
||||
</TooltipOutlined>
|
||||
)}
|
||||
</>}
|
||||
</Button>
|
||||
)}
|
||||
|
||||
@@ -14,7 +14,7 @@ import { showImageDataRefInNewTab } from '~/modules/blocks/image/RenderImageRefD
|
||||
|
||||
import { CloseableMenu } from '~/common/components/CloseableMenu';
|
||||
import { DMessageAttachmentFragment, isDocPart, isImageRefPart } from '~/common/stores/chat/chat.fragments';
|
||||
import { LiveFileIcon } from '~/common/livefile/LiveFileIcon';
|
||||
import { LiveFileIcon } from '~/common/livefile/LiveFileIcons';
|
||||
import { copyToClipboard } from '~/common/util/clipboardUtils';
|
||||
import { liveFileInAttachmentFragment } from '~/common/livefile/liveFile';
|
||||
import { showImageDataURLInNewTab } from '~/common/util/imageUtils';
|
||||
@@ -184,12 +184,6 @@ export function LLMAttachmentMenu(props: {
|
||||
</Typography>
|
||||
) : (
|
||||
<Box sx={{ my: 0.5 }}>
|
||||
{/* LiveFile notice */}
|
||||
{hasLiveFile && !!draftInput && (
|
||||
<Typography level='body-sm' sx={{ mb: 1 }} startDecorator={<LiveFileIcon sx={{ width: 16, height: 16 }} />}>
|
||||
LiveFile is supported
|
||||
</Typography>
|
||||
)}
|
||||
|
||||
{/* <- inputs */}
|
||||
{!!draftInput && (
|
||||
@@ -271,6 +265,14 @@ export function LLMAttachmentMenu(props: {
|
||||
</Typography>
|
||||
)}
|
||||
</Box>
|
||||
|
||||
{/* LiveFile notice */}
|
||||
{hasLiveFile && !!draftInput && (
|
||||
<Typography level='body-sm' sx={{ mt: 1 }} startDecorator={<LiveFileIcon sx={{ width: 16, height: 16 }} />}>
|
||||
LiveFile is supported
|
||||
</Typography>
|
||||
)}
|
||||
|
||||
</Box>
|
||||
)}
|
||||
</MenuItem>
|
||||
|
||||
+5
-4
@@ -1,7 +1,7 @@
|
||||
import * as React from 'react';
|
||||
|
||||
import type { SxProps } from '@mui/joy/styles/types';
|
||||
import { Box, Button, ColorPaletteProp, Tooltip } from '@mui/joy';
|
||||
import { Box, Button, ColorPaletteProp } from '@mui/joy';
|
||||
import AbcIcon from '@mui/icons-material/Abc';
|
||||
import CodeIcon from '@mui/icons-material/Code';
|
||||
import ExpandCircleDownIcon from '@mui/icons-material/ExpandCircleDown';
|
||||
@@ -13,7 +13,8 @@ import TextureIcon from '@mui/icons-material/Texture';
|
||||
|
||||
import { ContentScaling, themeScalingMap } from '~/common/app.theme';
|
||||
import { DMessageAttachmentFragment, DMessageFragmentId, isDocPart } from '~/common/stores/chat/chat.fragments';
|
||||
import { LiveFileIcon } from '~/common/livefile/LiveFileIcon';
|
||||
import { LiveFileIcon } from '~/common/livefile/LiveFileIcons';
|
||||
import { TooltipOutlined } from '~/common/components/TooltipOutlined';
|
||||
import { ellipsizeMiddle } from '~/common/util/textUtils';
|
||||
import { liveFileInAttachmentFragment } from '~/common/livefile/liveFile';
|
||||
|
||||
@@ -124,9 +125,9 @@ export function DocAttachmentFragmentButton(props: {
|
||||
{/*</Box>*/}
|
||||
</Box>
|
||||
{liveFileInAttachmentFragment(fragment) && (
|
||||
<Tooltip color='success' disableInteractive title='Supports LiveFile' placement='top-end' arrow>
|
||||
<TooltipOutlined title='LiveFile is supported' color='success' placement='top-end'>
|
||||
<LiveFileIcon color={isSelected ? undefined : 'success'} sx={{ mr: '0.5rem' }} />
|
||||
</Tooltip>
|
||||
</TooltipOutlined>
|
||||
)}
|
||||
</Button>
|
||||
);
|
||||
|
||||
@@ -2,12 +2,13 @@ import * as React from 'react';
|
||||
import { fileOpen } from 'browser-fs-access';
|
||||
import { cleanupEfficiency, makeDiff } from '@sanity/diff-match-patch';
|
||||
|
||||
import { Alert, Box, Button, CircularProgress, ColorPaletteProp, IconButton, Tooltip } from '@mui/joy';
|
||||
import { Alert, Box, Button, CircularProgress, ColorPaletteProp, IconButton } from '@mui/joy';
|
||||
import CloseRoundedIcon from '@mui/icons-material/CloseRounded';
|
||||
import WarningRoundedIcon from '@mui/icons-material/WarningRounded';
|
||||
|
||||
import type { DMessageAttachmentFragment } from '~/common/stores/chat/chat.fragments';
|
||||
import { LiveFileIcon, LiveFileReloadIcon, LiveFileSaveIcon } from '~/common/livefile/LiveFileIcon';
|
||||
import { LiveFileChooseIcon, LiveFileIcon, LiveFileReloadIcon, LiveFileSaveIcon } from '~/common/livefile/LiveFileIcons';
|
||||
import { TooltipOutlined } from '~/common/components/TooltipOutlined';
|
||||
import { liveFileCreate } from '~/common/livefile/liveFile';
|
||||
|
||||
|
||||
@@ -155,19 +156,37 @@ export function useLiveFile(
|
||||
|
||||
|
||||
const liveFileSyncButton = React.useMemo(() => (
|
||||
<Tooltip disableInteractive enterDelay={600} arrow color={isPreviewMode ? 'primary' : 'success'} placement='top-end' title={!fileSystemFileHandle ? 'Setup LiveFile file association' : <>LiveFile connected.<br />Click to compare with file content.</>}>
|
||||
<TooltipOutlined
|
||||
title={
|
||||
isPreviewMode ? 'Click to update the comparison.'
|
||||
: fileSystemFileHandle ? 'Click compare with the File contents.'
|
||||
: 'Setup LiveFile association.'
|
||||
}
|
||||
color={isPreviewMode ? 'primary' : 'success'}
|
||||
variant={isPreviewMode ? undefined : 'solid'}
|
||||
placement='top-end'
|
||||
>
|
||||
<Button
|
||||
variant='soft'
|
||||
color={isPreviewMode ? 'primary' : 'success'}
|
||||
size='sm'
|
||||
disabled={isWorking}
|
||||
onClick={handleSyncButtonClick}
|
||||
startDecorator={isPreviewMode ? <LiveFileIcon /> : (isWorking ? <CircularProgress sx={{ '--CircularProgress-size': '16px' }} /> : <LiveFileIcon />)}
|
||||
startDecorator={
|
||||
isPreviewMode ? <LiveFileIcon />
|
||||
: (isWorking ? <CircularProgress sx={{ '--CircularProgress-size': '16px' }} />
|
||||
: fileSystemFileHandle ? <LiveFileIcon />
|
||||
: <LiveFileChooseIcon />)
|
||||
}
|
||||
aria-label={fileSystemFileHandle ? 'Sync File' : 'Choose File'}
|
||||
>
|
||||
{isPreviewMode ? 'Refresh' : (fileSystemFileHandle ? 'Sync File' : 'Choose File')}
|
||||
{
|
||||
isPreviewMode ? 'Refresh'
|
||||
: fileSystemFileHandle ? 'Sync File'
|
||||
: 'Pair File'
|
||||
}
|
||||
</Button>
|
||||
</Tooltip>
|
||||
</TooltipOutlined>
|
||||
), [fileSystemFileHandle, handleSyncButtonClick, isPreviewMode, isWorking]);
|
||||
|
||||
|
||||
@@ -195,7 +214,7 @@ export function useLiveFile(
|
||||
>
|
||||
<Box sx={{ display: 'flex', gap: 0.5, alignItems: 'center' }}>
|
||||
{isPreviewMode && !!fileSystemFileHandle && (
|
||||
<IconButton size='sm' color={statusColor} onClick={handleSyncButtonClick}>
|
||||
<IconButton size='sm' onClick={handleSyncButtonClick}>
|
||||
<LiveFileIcon />
|
||||
</IconButton>
|
||||
)}
|
||||
@@ -204,9 +223,10 @@ export function useLiveFile(
|
||||
|
||||
|
||||
<Box sx={{ ml: 'auto', display: 'flex', gap: 1 }}>
|
||||
{/* Load from File */}
|
||||
{(diffSummary && (diffSummary.insertions > 0 || diffSummary.deletions > 0)) && (
|
||||
<Button
|
||||
variant='plain'
|
||||
variant={isMobile ? 'outlined' : 'plain'}
|
||||
color='primary'
|
||||
size='sm'
|
||||
disabled={isWorking}
|
||||
@@ -214,12 +234,14 @@ export function useLiveFile(
|
||||
startDecorator={<LiveFileReloadIcon />}
|
||||
aria-label='Load content from disk'
|
||||
>
|
||||
{isMobile ? 'Load File' : 'Load from File'}
|
||||
{isMobile ? 'Update' : 'Load from File'}
|
||||
</Button>
|
||||
)}
|
||||
|
||||
{/* Save to File */}
|
||||
{(diffSummary && (diffSummary.insertions > 0 || diffSummary.deletions > 0)) && (
|
||||
<Button
|
||||
variant='plain'
|
||||
variant={isMobile ? 'outlined' : 'plain'}
|
||||
color='danger'
|
||||
size='sm'
|
||||
disabled={isWorking}
|
||||
@@ -227,14 +249,23 @@ export function useLiveFile(
|
||||
startDecorator={<LiveFileSaveIcon />}
|
||||
aria-label='Save content to disk'
|
||||
>
|
||||
{isMobile ? 'Save File' : 'Save to File'}
|
||||
{isMobile ? 'Save' : 'Save to File'}
|
||||
</Button>
|
||||
)}
|
||||
|
||||
{/* Reassign File button */}
|
||||
<TooltipOutlined title='Pair a different File.' placement='top-end'>
|
||||
<IconButton size='sm' onClick={associateAndPreviewFile}>
|
||||
<LiveFileChooseIcon />
|
||||
</IconButton>
|
||||
</TooltipOutlined>
|
||||
|
||||
{/* Close button */}
|
||||
<IconButton size='sm' color={statusColor} onClick={resetState}>
|
||||
<CloseRoundedIcon />
|
||||
</IconButton>
|
||||
<TooltipOutlined title='Close LiveFile.' placement='top-end'>
|
||||
<IconButton size='sm' onClick={resetState}>
|
||||
<CloseRoundedIcon />
|
||||
</IconButton>
|
||||
</TooltipOutlined>
|
||||
</Box>
|
||||
</Alert>
|
||||
);
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
import * as React from 'react';
|
||||
|
||||
import { Tooltip, TooltipProps } from '@mui/joy';
|
||||
|
||||
|
||||
export function TooltipOutlined(props: {
|
||||
title: React.ReactNode;
|
||||
color?: TooltipProps['color'];
|
||||
variant?: TooltipProps['variant'];
|
||||
placement?: TooltipProps['placement'];
|
||||
children: React.JSX.Element;
|
||||
}) {
|
||||
return (
|
||||
<Tooltip
|
||||
title={props.title}
|
||||
color={props.color}
|
||||
variant={props.variant ?? 'outlined'}
|
||||
arrow
|
||||
disableInteractive
|
||||
placement={props.placement ?? 'top'}
|
||||
>
|
||||
{props.children}
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
@@ -1,7 +1,13 @@
|
||||
import { styled } from '@mui/joy';
|
||||
import FileOpenOutlinedIcon from '@mui/icons-material/FileOpenOutlined';
|
||||
import MultipleStopIcon from '@mui/icons-material/MultipleStop';
|
||||
import SystemUpdateAltIcon from '@mui/icons-material/SystemUpdateAlt';
|
||||
import UploadFileIcon from '@mui/icons-material/UploadFile';
|
||||
|
||||
export { MultipleStopIcon as LiveFileIcon };
|
||||
export { UploadFileIcon as LiveFileSaveIcon };
|
||||
export const LiveFileIcon = styled(MultipleStopIcon)({
|
||||
rotate: '90deg',
|
||||
});
|
||||
|
||||
export { FileOpenOutlinedIcon as LiveFileChooseIcon };
|
||||
export { SystemUpdateAltIcon as LiveFileReloadIcon };
|
||||
export { UploadFileIcon as LiveFileSaveIcon };
|
||||
Reference in New Issue
Block a user