mirror of
https://github.com/enricoros/big-AGI.git
synced 2026-05-10 21:50:14 -07:00
useDragDropDataTransfer: improve
This commit is contained in:
@@ -1,5 +1,8 @@
|
||||
import * as React from 'react';
|
||||
|
||||
import { SvgIcon } from '@mui/joy';
|
||||
import AttachFileRoundedIcon from '@mui/icons-material/AttachFileRounded';
|
||||
|
||||
import { useDragDropDataTransfer } from '~/common/components/useDragDropDataTransfer';
|
||||
|
||||
|
||||
@@ -40,5 +43,5 @@ export function useComposerDragDrop(
|
||||
|
||||
}, [onDataTransfer]);
|
||||
|
||||
return useDragDropDataTransfer(enabled, 'I will hold on to this for you.', handleComposerDrop);
|
||||
return useDragDropDataTransfer(enabled, 'I will hold on to this for you.', AttachFileRoundedIcon as typeof SvgIcon, 'largeIcon', handleComposerDrop);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import * as React from 'react';
|
||||
|
||||
import type { SxProps } from '@mui/joy/styles/types';
|
||||
import { Card, Typography } from '@mui/joy';
|
||||
import AttachFileRoundedIcon from '@mui/icons-material/AttachFileRounded';
|
||||
import { Card, SvgIcon, Typography } from '@mui/joy';
|
||||
|
||||
|
||||
// constants
|
||||
@@ -39,7 +38,13 @@ const dropCardDraggingCardSx: SxProps = {
|
||||
|
||||
// Drag/Drop that can be used in any component and invokes a DataTransfer callback on success
|
||||
|
||||
export function useDragDropDataTransfer(enabled: boolean, dropText: string, onDropCallback: (dataTransfer: DataTransfer) => Promise<any>) {
|
||||
export function useDragDropDataTransfer(
|
||||
enabled: boolean,
|
||||
dropText: string, // that the button says
|
||||
DropIcon: typeof SvgIcon | null, // icon on the button
|
||||
dropVariant: 'largeIcon' | 'startDecorator',
|
||||
onDropCallback: (dataTransfer: DataTransfer) => Promise<any>,
|
||||
) {
|
||||
|
||||
// state
|
||||
const [isDragging, setIsDragging] = React.useState(false);
|
||||
@@ -86,6 +91,7 @@ export function useDragDropDataTransfer(enabled: boolean, dropText: string, onDr
|
||||
}, [_eatDragEvent, onDropCallback]);
|
||||
|
||||
|
||||
// Standardized component looks, only customized based on `dropText` and `DropIcon`
|
||||
const dropComponent = React.useMemo(() => {
|
||||
if (!enabled) return null;
|
||||
|
||||
@@ -99,13 +105,21 @@ export function useDragDropDataTransfer(enabled: boolean, dropText: string, onDr
|
||||
onDrop={_handleDrop}
|
||||
sx={isDragging ? dropCardDraggingCardSx : dropCardInactiveSx}
|
||||
>
|
||||
{isDragging && <AttachFileRoundedIcon sx={{ width: 36, height: 36, pointerEvents: 'none' }} />}
|
||||
{isDragging && <Typography level='title-sm' sx={{ pointerEvents: 'none' }}>
|
||||
{dropText}
|
||||
</Typography>}
|
||||
{isDragging && dropVariant === 'largeIcon' && !!DropIcon && (
|
||||
<DropIcon sx={{ width: 36, height: 36, pointerEvents: 'none' }} />
|
||||
)}
|
||||
{isDragging && (
|
||||
<Typography
|
||||
level='title-sm'
|
||||
startDecorator={dropVariant === 'startDecorator' && !!DropIcon && <DropIcon />}
|
||||
sx={{ pointerEvents: 'none' }}
|
||||
>
|
||||
{dropText}
|
||||
</Typography>
|
||||
)}
|
||||
</Card>
|
||||
);
|
||||
}, [enabled, isDragging, _handleDragLeave, _handleDragOver, _handleDrop, dropText]);
|
||||
}, [enabled, isDragging, _handleDragLeave, _handleDragOver, _handleDrop, dropVariant, DropIcon, dropText]);
|
||||
|
||||
|
||||
return {
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import * as React from 'react';
|
||||
|
||||
import { Button } from '@mui/joy';
|
||||
import { Box, Button } from '@mui/joy';
|
||||
|
||||
import { TooltipOutlined } from '~/common/components/TooltipOutlined';
|
||||
import { useDragDropDataTransfer } from '~/common/components/useDragDropDataTransfer';
|
||||
|
||||
import { LiveFileChooseIcon, LiveFileIcon } from './liveFile.icons';
|
||||
|
||||
@@ -14,33 +15,53 @@ export function LiveFileSyncButton(props: {
|
||||
handleSyncButtonClicked: () => void;
|
||||
}) {
|
||||
|
||||
const handleDataTransfer = React.useCallback(async (dataTransfer: DataTransfer) => {
|
||||
console.log('LiveFileSyncButton: handleDataTransfer', dataTransfer);
|
||||
}, []);
|
||||
|
||||
const {
|
||||
dragContainerSx,
|
||||
dropComponent,
|
||||
handleContainerDragEnter,
|
||||
handleContainerDragStart,
|
||||
} = useDragDropDataTransfer(true, 'Pair', null, 'startDecorator', handleDataTransfer);
|
||||
|
||||
return <TooltipOutlined
|
||||
title={
|
||||
props.fileHasContent ? 'Click to reload the File and compare.'
|
||||
: props.isPairingValid ? 'Click to compare with the File contents.'
|
||||
: 'Setup LiveFile pairing.'
|
||||
}
|
||||
color={props.fileHasContent ? 'primary' : 'success'}
|
||||
variant={props.fileHasContent ? undefined : 'solid'}
|
||||
>
|
||||
<Button
|
||||
variant='soft'
|
||||
color={props.fileHasContent ? 'primary' : 'success'}
|
||||
size='sm'
|
||||
disabled={props.isSavingFile}
|
||||
onClick={props.handleSyncButtonClicked}
|
||||
startDecorator={
|
||||
props.fileHasContent ? <LiveFileIcon />
|
||||
: (props.isPairingValid ? <LiveFileIcon />
|
||||
: <LiveFileChooseIcon />)
|
||||
}
|
||||
aria-label={props.isPairingValid ? 'Sync File' : 'Choose File'}
|
||||
return (
|
||||
<Box
|
||||
onDragEnter={handleContainerDragEnter}
|
||||
onDragStart={handleContainerDragStart}
|
||||
sx={dragContainerSx}
|
||||
>
|
||||
{props.fileHasContent ? 'Refresh'
|
||||
: props.isPairingValid ? 'Sync File'
|
||||
: 'Pair File'}
|
||||
</Button>
|
||||
</TooltipOutlined>;
|
||||
|
||||
<TooltipOutlined
|
||||
title={
|
||||
props.fileHasContent ? 'Click to reload the File and compare.'
|
||||
: props.isPairingValid ? 'Click to compare with the File contents.'
|
||||
: 'Setup LiveFile pairing.'
|
||||
}
|
||||
color={props.fileHasContent ? 'primary' : 'success'}
|
||||
variant={props.fileHasContent ? undefined : 'solid'}
|
||||
>
|
||||
<Button
|
||||
variant='soft'
|
||||
color={props.fileHasContent ? 'primary' : 'success'}
|
||||
size='sm'
|
||||
disabled={props.isSavingFile}
|
||||
onClick={props.handleSyncButtonClicked}
|
||||
startDecorator={
|
||||
props.fileHasContent ? <LiveFileIcon />
|
||||
: (props.isPairingValid ? <LiveFileIcon />
|
||||
: <LiveFileChooseIcon />)
|
||||
}
|
||||
aria-label={props.isPairingValid ? 'Sync File' : 'Choose File'}
|
||||
>
|
||||
{props.fileHasContent ? 'Refresh'
|
||||
: props.isPairingValid ? 'Sync File'
|
||||
: 'Pair File'}
|
||||
</Button>
|
||||
</TooltipOutlined>
|
||||
|
||||
{dropComponent}
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user