added button to remove staged asset

This commit is contained in:
Roland Osborne 2024-12-16 15:16:40 -08:00
parent 9f78c7b54b
commit 2cd0cde5fc
10 changed files with 65 additions and 19 deletions

View File

@ -134,18 +134,16 @@ export function Conversation() {
const media = state.assets.map((asset, index: number) => { const media = state.assets.map((asset, index: number) => {
if (asset.type === 'image') { if (asset.type === 'image') {
return <ImageFile key={index} source={asset.file} /> return <ImageFile key={index} source={asset.file} disabled={sending} remove={() => actions.removeAsset(index)} />
} else if (asset.type === 'video') { } else if (asset.type === 'video') {
return <VideoFile key={index} source={asset.file} thumbPosition={(position: number) => actions.setThumbPosition(index, position)} disabled={sending} /> return <VideoFile key={index} source={asset.file} thumbPosition={(position: number) => actions.setThumbPosition(index, position)} disabled={sending} remove={() => actions.removeAsset(index)}/>
} else if (asset.type === 'audio') { } else if (asset.type === 'audio') {
return <AudioFile key={index} source={asset.file} updateLabel={(label: string) => actions.setLabel(index, label)} disabled={sending} /> return <AudioFile key={index} source={asset.file} updateLabel={(label: string) => actions.setLabel(index, label)} disabled={sending} remove={() => actions.removeAsset(index)} />
} else { } else {
return <BinaryFile key={index} source={asset.file} /> return <BinaryFile key={index} source={asset.file} disabled={sending} remove={() => actions.removeAsset(index)} />
} }
}); });
console.log("HIIGHT: ", height);
return ( return (
<div className={classes.conversation}> <div className={classes.conversation}>
<div className={classes.header}> <div className={classes.header}>
@ -209,7 +207,7 @@ console.log("HIIGHT: ", height);
<div className={classes.progress} style={{ width: `${state.progress}%` }}/> <div className={classes.progress} style={{ width: `${state.progress}%` }}/>
)} )}
</div> </div>
<AnimateHeight className={classes.add} duration={500} height={height}> <AnimateHeight className={classes.add} duration={333} height={height ? height : 132}>
<div ref={ref} className={classes.staging}> <div ref={ref} className={classes.staging}>
<input type='file' name="asset" accept="image/*" ref={attachImage} onChange={e => addImage(e.target?.files?.[0])} style={{display: 'none'}}/> <input type='file' name="asset" accept="image/*" ref={attachImage} onChange={e => addImage(e.target?.files?.[0])} style={{display: 'none'}}/>
<input type='file' name="asset" accept="video/*" ref={attachVideo} onChange={e => addVideo(e.target?.files?.[0])} style={{display: 'none'}}/> <input type='file' name="asset" accept="video/*" ref={attachVideo} onChange={e => addVideo(e.target?.files?.[0])} style={{display: 'none'}}/>

View File

@ -1,6 +1,9 @@
.asset { .asset {
padding-top: 16px; margin-top: 16px;
position: relative; position: relative;
display: flex;
align-items: center;
justify-content: center;
.thumb { .thumb {
width: auto; width: auto;
@ -8,14 +11,17 @@
} }
.label { .label {
padding-top: 16px;
padding-left: 2px; padding-left: 2px;
padding-right: 2px; padding-right: 2px;
position: absolute; position: absolute;
font-size: 8px; font-size: 8px;
bottom: 0;
}
.close {
position: absolute;
right: 0;
top: 0; top: 0;
left: 0;
height: 67%;
} }
} }

View File

@ -1,10 +1,11 @@
import React from 'react'; import React from 'react';
import { Image, Textarea } from '@mantine/core' import { ActionIcon, Image, Textarea } from '@mantine/core'
import { useAudioFile } from './useAudioFile.hook'; import { useAudioFile } from './useAudioFile.hook';
import classes from './AudioFile.module.css' import classes from './AudioFile.module.css'
import audio from '../../images/audio.png' import audio from '../../images/audio.png'
import { IconX } from '@tabler/icons-react'
export function AudioFile({ source, updateLabel, disabled }: {source: File, updateLabel: (label: string)=>void, disabled: boolean}) { export function AudioFile({ source, updateLabel, disabled, remove }: {source: File, updateLabel: (label: string)=>void, disabled: boolean, remove: ()=>void}) {
const { state, actions } = useAudioFile(source); const { state, actions } = useAudioFile(source);
const setLabel = (label: string) => { const setLabel = (label: string) => {
@ -16,6 +17,9 @@ export function AudioFile({ source, updateLabel, disabled }: {source: File, upda
<div className={classes.asset}> <div className={classes.asset}>
<Image radius="sm" className={classes.thumb} src={audio} /> <Image radius="sm" className={classes.thumb} src={audio} />
<Textarea className={classes.label} size="xs" value={state.label} onChange={(event) => setLabel(event.currentTarget.value)} disabled={disabled} /> <Textarea className={classes.label} size="xs" value={state.label} onChange={(event) => setLabel(event.currentTarget.value)} disabled={disabled} />
<ActionIcon className={classes.close} variant="subtle" disabled={disabled} onClick={remove}>
<IconX />
</ActionIcon>
</div> </div>
); );
} }

View File

@ -26,5 +26,11 @@
width: 100%; width: 100%;
text-align: center; text-align: center;
} }
.close {
position: absolute;
right: 0;
top: 0;
}
} }

View File

@ -1,10 +1,11 @@
import React from 'react'; import React from 'react';
import { Text, Image } from '@mantine/core' import { ActionIcon, Text, Image } from '@mantine/core'
import { useBinaryFile } from './useBinaryFile.hook'; import { useBinaryFile } from './useBinaryFile.hook';
import classes from './BinaryFile.module.css' import classes from './BinaryFile.module.css'
import binary from '../../images/binary.png' import binary from '../../images/binary.png'
import { IconX } from '@tabler/icons-react'
export function BinaryFile({ source }: {source: File}) { export function BinaryFile({ source, disabled, remove }: {source: File, disabled: boolean, remove: ()=>void}) {
const { state, actions } = useBinaryFile(source); const { state, actions } = useBinaryFile(source);
return ( return (
@ -12,6 +13,9 @@ export function BinaryFile({ source }: {source: File}) {
<Image radius="sm" className={classes.thumb} src={binary} /> <Image radius="sm" className={classes.thumb} src={binary} />
<Text className={classes.name}>{ state.name }</Text> <Text className={classes.name}>{ state.name }</Text>
<Text className={classes.extension}>{ state.extension }</Text> <Text className={classes.extension}>{ state.extension }</Text>
<ActionIcon className={classes.close} variant="subtle" disabled={disabled} onClick={remove}>
<IconX />
</ActionIcon>
</div> </div>
); );
} }

View File

@ -1,9 +1,16 @@
.asset { .asset {
position: relative;
padding-top: 16px; padding-top: 16px;
.thumb { .thumb {
width: auto; width: auto;
height: 92px; height: 92px;
} }
.close {
position: absolute;
top: 16px;
right: 0;
}
} }

View File

@ -1,9 +1,10 @@
import React from 'react'; import React from 'react';
import { Image } from '@mantine/core' import { ActionIcon, Image } from '@mantine/core'
import { useImageFile } from './useImageFile.hook'; import { useImageFile } from './useImageFile.hook';
import classes from './ImageFile.module.css' import classes from './ImageFile.module.css'
import { IconX } from '@tabler/icons-react'
export function ImageFile({ source }: {source: File}) { export function ImageFile({ source, disabled, remove }: {source: File, disabled: boolean, remove: ()=>void}) {
const { state, actions } = useImageFile(source); const { state, actions } = useImageFile(source);
return ( return (
@ -11,6 +12,11 @@ export function ImageFile({ source }: {source: File}) {
{ state.thumbUrl && ( { state.thumbUrl && (
<Image radius="sm" className={classes.thumb} src={state.thumbUrl} /> <Image radius="sm" className={classes.thumb} src={state.thumbUrl} />
)} )}
{ state.thumbUrl && (
<ActionIcon className={classes.close} variant="subtle" disabled={disabled} onClick={remove}>
<IconX />
</ActionIcon>
)}
</div> </div>
); );
} }

View File

@ -207,6 +207,10 @@ export function useConversation() {
setLabel: (index: number, label: string) => { setLabel: (index: number, label: string) => {
updateAsset(index, { label }); updateAsset(index, { label });
}, },
removeAsset: (index: number) => {
state.assets.splice(index, 1);
updateState({ assets: [ ...state.assets ] });
},
more: async () => { more: async () => {
const focus = app.state.focus; const focus = app.state.focus;
if (focus) { if (focus) {

View File

@ -22,5 +22,11 @@
width: auto; width: auto;
height: 64px; height: 64px;
} }
.close {
position: absolute;
right: 0;
top: 0;
}
} }

View File

@ -2,9 +2,9 @@ import React, { useRef, useState } from 'react';
import { ActionIcon, Image } from '@mantine/core' import { ActionIcon, Image } from '@mantine/core'
import { useVideoFile } from './useVideoFile.hook'; import { useVideoFile } from './useVideoFile.hook';
import classes from './VideoFile.module.css' import classes from './VideoFile.module.css'
import { IconChevronLeft, IconChevronRight } from '@tabler/icons-react' import { IconX, IconChevronLeft, IconChevronRight } from '@tabler/icons-react'
export function VideoFile({ source, thumbPosition, disabled }: {source: File, thumbPosition: (position: number)=>void, disabled: boolean}) { export function VideoFile({ source, thumbPosition, disabled, remove }: {source: File, thumbPosition: (position: number)=>void, disabled: boolean, remove: ()=>void}) {
const { state, actions } = useVideoFile(source); const { state, actions } = useVideoFile(source);
const [loaded, setLoaded] = useState(false); const [loaded, setLoaded] = useState(false);
const position = useRef(0); const position = useRef(0);
@ -49,6 +49,11 @@ export function VideoFile({ source, thumbPosition, disabled }: {source: File, th
<IconChevronLeft /> <IconChevronLeft />
</ActionIcon> </ActionIcon>
)} )}
{ loaded && (
<ActionIcon className={classes.close} variant="subtle" disabled={disabled} onClick={remove}>
<IconX />
</ActionIcon>
)}
</div> </div>
); );
} }