Move chat attachments into composer

toast-story
Alex Gleason 2023-01-26 12:30:26 -06:00
rodzic 382e464390
commit 7b32373694
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 7211D1F99744FBB7
4 zmienionych plików z 69 dodań i 10 usunięć

Wyświetl plik

@ -43,6 +43,7 @@ interface IChatComposer extends Pick<React.TextareaHTMLAttributes<HTMLTextAreaEl
onSelectFile: (files: FileList, intl: IntlShape) => void
resetFileKey: number | null
attachments?: Attachment[]
onDeleteAttachment?: () => void
}
/** Textarea input for chats. */
@ -57,6 +58,7 @@ const ChatComposer = React.forwardRef<HTMLTextAreaElement | null, IChatComposer>
resetFileKey,
onPaste,
attachments = [],
onDeleteAttachment,
}, ref) => {
const intl = useIntl();
const dispatch = useAppDispatch();
@ -186,6 +188,7 @@ const ChatComposer = React.forwardRef<HTMLTextAreaElement | null, IChatComposer>
maxRows={5}
disabled={disabled}
attachments={attachments}
onDeleteAttachment={onDeleteAttachment}
/>
{isSuggestionsAvailable ? (
<ComboboxPopover>

Wyświetl plik

@ -3,12 +3,15 @@ import React from 'react';
import { Textarea } from 'soapbox/components/ui';
import { Attachment } from 'soapbox/types/entities';
import ChatUpload from './chat-upload';
interface IChatTextarea extends React.ComponentProps<typeof Textarea> {
attachments?: Attachment[]
onDeleteAttachment?: () => void
}
/** Custom textarea for chats. */
const ChatTextarea: React.FC<IChatTextarea> = ({ attachments, ...rest }) => {
const ChatTextarea: React.FC<IChatTextarea> = ({ attachments, onDeleteAttachment, ...rest }) => {
return (
<div className={`
bg-white
@ -22,14 +25,17 @@ const ChatTextarea: React.FC<IChatTextarea> = ({ attachments, ...rest }) => {
dark:focus-within:ring-primary-500 dark:focus-within:border-primary-500
`}
>
{attachments?.map(attachment => (
<img
className='w-8 h-8'
key={attachment.id}
src={attachment.url}
alt=''
/>
))}
{(!!attachments?.length) && (
<div className='p-3 pb-0'>
{attachments?.map(attachment => (
<ChatUpload
key={attachment.id}
attachment={attachment}
onDelete={onDeleteAttachment}
/>
))}
</div>
)}
<Textarea theme='transparent' {...rest} />
</div>

Wyświetl plik

@ -0,0 +1,50 @@
import React from 'react';
import { Icon } from 'soapbox/components/ui';
import type { Attachment } from 'soapbox/types/entities';
interface IChatUpload {
attachment: Attachment,
onDelete?(): void,
}
/** An attachment uploaded to the chat composer, before sending. */
const ChatUpload: React.FC<IChatUpload> = ({ attachment, onDelete }) => {
return (
<div className='relative inline-block'>
<div className='absolute right-[6px] top-[6px]'>
<RemoveButton onClick={onDelete} />
</div>
<img
className='w-24 h-24 rounded-lg'
key={attachment.id}
src={attachment.url}
alt=''
/>
</div>
);
};
interface IRemoveButton {
onClick?: React.MouseEventHandler<HTMLButtonElement>
}
/** Floating button to remove an attachment. */
const RemoveButton: React.FC<IRemoveButton> = ({ onClick }) => {
return (
<button
type='button'
onClick={onClick}
className='bg-secondary-500 w-5 h-5 p-1 rounded-full flex items-center justify-center'
>
<Icon
className='w-4 h-4'
src={require('@tabler/icons/x.svg')}
/>
</button>
);
};
export default ChatUpload;

Wyświetl plik

@ -5,7 +5,6 @@ import { defineMessages, useIntl } from 'react-intl';
import { uploadMedia } from 'soapbox/actions/media';
import { Stack } from 'soapbox/components/ui';
import Upload from 'soapbox/components/upload';
import UploadProgress from 'soapbox/components/upload-progress';
import { useAppDispatch } from 'soapbox/hooks';
import { normalizeAttachment } from 'soapbox/normalizers';
@ -181,6 +180,7 @@ const Chat: React.FC<ChatInterface> = ({ chat, inputRef, className }) => {
resetFileKey={resetFileKey}
onPaste={handlePaste}
attachments={attachment ? [attachment] : []}
onDeleteAttachment={handleRemoveFile}
/>
</Stack>
);