Move chat attachments into the chat composer

environments/review-chat-compo-mzhk1s/deployments/2436
Alex Gleason 2023-01-25 15:45:33 -06:00
rodzic a68b794476
commit 382e464390
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 7211D1F99744FBB7
4 zmienionych plików z 57 dodań i 22 usunięć

Wyświetl plik

@ -26,6 +26,8 @@ interface ITextarea extends Pick<React.TextareaHTMLAttributes<HTMLTextAreaElemen
hasError?: boolean,
/** Whether or not you can resize the teztarea */
isResizeable?: boolean,
/** Textarea theme. */
theme?: 'default' | 'transparent',
}
/** Textarea with custom styles. */
@ -37,6 +39,7 @@ const Textarea = React.forwardRef(({
autoGrow = false,
maxRows = 10,
minRows = 1,
theme = 'default',
...props
}: ITextarea, ref: React.ForwardedRef<HTMLTextAreaElement>) => {
const [rows, setRows] = useState<number>(autoGrow ? 1 : 4);
@ -72,9 +75,10 @@ const Textarea = React.forwardRef(({
ref={ref}
rows={rows}
onChange={handleChange}
className={classNames({
'bg-white dark:bg-transparent shadow-sm block w-full sm:text-sm rounded-md text-gray-900 dark:text-gray-100 placeholder:text-gray-600 dark:placeholder:text-gray-600 border-gray-400 dark:border-gray-800 dark:ring-1 dark:ring-gray-800 focus:ring-primary-500 focus:border-primary-500 dark:focus:ring-primary-500 dark:focus:border-primary-500':
true,
className={classNames('block w-full rounded-md sm:text-sm text-gray-900 dark:text-gray-100 placeholder:text-gray-600 dark:placeholder:text-gray-600', {
'bg-white dark:bg-transparent shadow-sm border-gray-400 dark:border-gray-800 dark:ring-1 dark:ring-gray-800 focus:ring-primary-500 focus:border-primary-500 dark:focus:ring-primary-500 dark:focus:border-primary-500':
theme === 'default',
'bg-transparent border-0 focus:border-0 focus:ring-0': theme === 'transparent',
'font-mono': isCodeEditor,
'text-red-600 border-red-600': hasError,
'resize-none': !isResizeable,

Wyświetl plik

@ -3,13 +3,16 @@ import { defineMessages, IntlShape, useIntl } from 'react-intl';
import { unblockAccount } from 'soapbox/actions/accounts';
import { openModal } from 'soapbox/actions/modals';
import { Button, Combobox, ComboboxInput, ComboboxList, ComboboxOption, ComboboxPopover, HStack, IconButton, Stack, Text, Textarea } from 'soapbox/components/ui';
import { Button, Combobox, ComboboxInput, ComboboxList, ComboboxOption, ComboboxPopover, HStack, IconButton, Stack, Text } from 'soapbox/components/ui';
import { useChatContext } from 'soapbox/contexts/chat-context';
import UploadButton from 'soapbox/features/compose/components/upload-button';
import { search as emojiSearch } from 'soapbox/features/emoji/emoji-mart-search-light';
import { useAppDispatch, useAppSelector, useFeatures } from 'soapbox/hooks';
import { Attachment } from 'soapbox/types/entities';
import { textAtCursorMatchesToken } from 'soapbox/utils/suggestions';
import ChatTextarea from './chat-textarea';
const messages = defineMessages({
placeholder: { id: 'chat.input.placeholder', defaultMessage: 'Type a message' },
send: { id: 'chat.actions.send', defaultMessage: 'Send' },
@ -39,7 +42,7 @@ interface IChatComposer extends Pick<React.TextareaHTMLAttributes<HTMLTextAreaEl
errorMessage: string | undefined
onSelectFile: (files: FileList, intl: IntlShape) => void
resetFileKey: number | null
hasAttachment?: boolean
attachments?: Attachment[]
}
/** Textarea input for chats. */
@ -53,7 +56,7 @@ const ChatComposer = React.forwardRef<HTMLTextAreaElement | null, IChatComposer>
onSelectFile,
resetFileKey,
onPaste,
hasAttachment,
attachments = [],
}, ref) => {
const intl = useIntl();
const dispatch = useAppDispatch();
@ -68,6 +71,7 @@ const ChatComposer = React.forwardRef<HTMLTextAreaElement | null, IChatComposer>
const [suggestions, setSuggestions] = useState<Suggestion>(initialSuggestionState);
const isSuggestionsAvailable = suggestions.list.length > 0;
const hasAttachment = attachments.length > 0;
const isOverCharacterLimit = maxCharacterCount && value?.length > maxCharacterCount;
const isSubmitDisabled = disabled || isOverCharacterLimit || (value.length === 0 && !hasAttachment);
@ -167,12 +171,9 @@ const ChatComposer = React.forwardRef<HTMLTextAreaElement | null, IChatComposer>
)}
<Stack grow>
<Combobox
aria-labelledby='demo'
onSelect={onSelectComboboxOption}
>
<Combobox onSelect={onSelectComboboxOption}>
<ComboboxInput
as={Textarea}
as={ChatTextarea}
autoFocus
ref={ref}
placeholder={intl.formatMessage(messages.placeholder)}
@ -184,6 +185,7 @@ const ChatComposer = React.forwardRef<HTMLTextAreaElement | null, IChatComposer>
autoGrow
maxRows={5}
disabled={disabled}
attachments={attachments}
/>
{isSuggestionsAvailable ? (
<ComboboxPopover>

Wyświetl plik

@ -0,0 +1,39 @@
import React from 'react';
import { Textarea } from 'soapbox/components/ui';
import { Attachment } from 'soapbox/types/entities';
interface IChatTextarea extends React.ComponentProps<typeof Textarea> {
attachments?: Attachment[]
}
/** Custom textarea for chats. */
const ChatTextarea: React.FC<IChatTextarea> = ({ attachments, ...rest }) => {
return (
<div className={`
bg-white
dark:bg-transparent
shadow-sm block w-full
sm:text-sm rounded-md
text-gray-900 dark:text-gray-100
border-1
placeholder:text-gray-600 dark:placeholder:text-gray-600 border-gray-400 dark:border-gray-800
dark:ring-1 dark:ring-gray-800 focus-within:ring-primary-500 focus-within:border-primary-500
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=''
/>
))}
<Textarea theme='transparent' {...rest} />
</div>
);
};
export default ChatTextarea;

Wyświetl plik

@ -164,16 +164,6 @@ const Chat: React.FC<ChatInterface> = ({ chat, inputRef, className }) => {
<ChatMessageList chat={chat} />
</div>
{attachment && (
<div className='relative h-48'>
<Upload
media={attachment}
onDelete={handleRemoveFile}
withPreview
/>
</div>
)}
{isUploading && (
<div className='p-4'>
<UploadProgress progress={uploadProgress * 100} />
@ -190,7 +180,7 @@ const Chat: React.FC<ChatInterface> = ({ chat, inputRef, className }) => {
onSelectFile={handleFiles}
resetFileKey={resetFileKey}
onPaste={handlePaste}
hasAttachment={!!attachment}
attachments={attachment ? [attachment] : []}
/>
</Stack>
);