From 09d73b1c45e9fff070cf9971225d76fda2b04f33 Mon Sep 17 00:00:00 2001 From: Justin Date: Mon, 12 Sep 2022 16:46:19 -0400 Subject: [PATCH] Refactor chat component naming --- app/soapbox/features/chats/chat-room.tsx | 4 +- ...{chat.test.tsx => chat-list-item.test.tsx} | 14 +- .../features/chats/components/chat-box.tsx | 279 --------------- .../chats/components/chat-list-item.tsx | 70 ++++ .../features/chats/components/chat-list.tsx | 4 +- .../features/chats/components/chat-window.tsx | 4 +- .../features/chats/components/chat.tsx | 317 +++++++++++++++--- app/soapbox/features/chats/index.tsx | 6 +- 8 files changed, 349 insertions(+), 349 deletions(-) rename app/soapbox/features/chats/components/__tests__/{chat.test.tsx => chat-list-item.test.tsx} (77%) delete mode 100644 app/soapbox/features/chats/components/chat-box.tsx create mode 100644 app/soapbox/features/chats/components/chat-list-item.tsx diff --git a/app/soapbox/features/chats/chat-room.tsx b/app/soapbox/features/chats/chat-room.tsx index 520349288..d7cc1cfe7 100644 --- a/app/soapbox/features/chats/chat-room.tsx +++ b/app/soapbox/features/chats/chat-room.tsx @@ -8,7 +8,7 @@ import { makeGetChat } from 'soapbox/selectors'; import { getAcct } from 'soapbox/utils/accounts'; import { displayFqn as getDisplayFqn } from 'soapbox/utils/state'; -import ChatBox from './components/chat-box'; +import Chat from './components/chat'; const getChat = makeGetChat(); @@ -47,7 +47,7 @@ const ChatRoom: React.FC = ({ params }) => { return ( - + ); }; diff --git a/app/soapbox/features/chats/components/__tests__/chat.test.tsx b/app/soapbox/features/chats/components/__tests__/chat-list-item.test.tsx similarity index 77% rename from app/soapbox/features/chats/components/__tests__/chat.test.tsx rename to app/soapbox/features/chats/components/__tests__/chat-list-item.test.tsx index 9a968d514..80eecfbae 100644 --- a/app/soapbox/features/chats/components/__tests__/chat.test.tsx +++ b/app/soapbox/features/chats/components/__tests__/chat-list-item.test.tsx @@ -3,7 +3,7 @@ import React from 'react'; import { IChat } from 'soapbox/queries/chats'; import { render, screen } from '../../../../jest/test-helpers'; -import Chat from '../chat'; +import ChatListItem from '../chat-list-item'; const chat: any = { id: '1', @@ -28,9 +28,9 @@ const chat: any = { }, }; -describe('', () => { +describe('', () => { it('renders correctly', () => { - render(); + render(); expect(screen.getByTestId('chat')).toBeInTheDocument(); expect(screen.getByTestId('chat')).toHaveTextContent(chat.account.display_name); @@ -38,28 +38,28 @@ describe('', () => { describe('last message content', () => { it('renders the last message', () => { - render(); + render(); expect(screen.getByTestId('chat-last-message')).toBeInTheDocument(); }); it('does not render the last message', () => { const changedChat = { ...chat, last_message: null }; - render(); + render(); expect(screen.queryAllByTestId('chat-last-message')).toHaveLength(0); }); describe('unread', () => { it('renders the unread dot', () => { - render(); + render(); expect(screen.getByTestId('chat-unread-indicator')).toBeInTheDocument(); }); it('does not render the unread dot', () => { const changedChat = { ...chat, last_message: { ...chat.last_message, unread: false } }; - render(); + render(); expect(screen.queryAllByTestId('chat-unread-indicator')).toHaveLength(0); }); diff --git a/app/soapbox/features/chats/components/chat-box.tsx b/app/soapbox/features/chats/components/chat-box.tsx deleted file mode 100644 index f701586e9..000000000 --- a/app/soapbox/features/chats/components/chat-box.tsx +++ /dev/null @@ -1,279 +0,0 @@ -import { useMutation } from '@tanstack/react-query'; -import classNames from 'clsx'; -import React, { MutableRefObject, useState } from 'react'; -import { useIntl, defineMessages } from 'react-intl'; - -import { uploadMedia } from 'soapbox/actions/media'; -import { HStack, IconButton, Stack, Text, Textarea } from 'soapbox/components/ui'; -import UploadProgress from 'soapbox/components/upload-progress'; -import UploadButton from 'soapbox/features/compose/components/upload_button'; -import { useAppDispatch, useOwnAccount } from 'soapbox/hooks'; -import { IChat, useChat } from 'soapbox/queries/chats'; -import { queryClient } from 'soapbox/queries/client'; -import { truncateFilename } from 'soapbox/utils/media'; - -import ChatMessageList from './chat-message-list'; - -const messages = defineMessages({ - placeholder: { id: 'chat_box.input.placeholder', defaultMessage: 'Type a message' }, - send: { id: 'chat_box.actions.send', defaultMessage: 'Send' }, -}); - -const fileKeyGen = (): number => Math.floor((Math.random() * 0x10000)); - -interface IChatBox { - chat: IChat, - autosize?: boolean, - inputRef?: MutableRefObject, - className?: string, -} - -/** - * Chat UI with just the messages and textarea. - * Reused between floating desktop chats and fullscreen/mobile chats. - */ -const ChatBox: React.FC = ({ chat, autosize, inputRef, className }) => { - const intl = useIntl(); - const dispatch = useAppDispatch(); - const account = useOwnAccount(); - - const { createChatMessage, acceptChat } = useChat(chat.id); - - const [content, setContent] = useState(''); - const [attachment, setAttachment] = useState(undefined); - const [isUploading, setIsUploading] = useState(false); - const [uploadProgress, setUploadProgress] = useState(0); - const [resetFileKey, setResetFileKey] = useState(fileKeyGen()); - const [hasErrorSubmittingMessage, setErrorSubmittingMessage] = useState(false); - - const isSubmitDisabled = content.length === 0 && !attachment; - - const submitMessage = useMutation(({ chatId, content }: any) => createChatMessage(chatId, content), { - retry: false, - onMutate: async (newMessage: any) => { - // Cancel any outgoing refetches (so they don't overwrite our optimistic update) - await queryClient.cancelQueries(['chats', 'messages', chat.id]); - - // Snapshot the previous value - const prevChatMessages = queryClient.getQueryData(['chats', 'messages', chat.id]); - const prevContent = content; - - // Clear state (content, attachment, etc) - clearState(); - - // Optimistically update to the new value - queryClient.setQueryData(['chats', 'messages', chat.id], (prevResult: any) => { - const newResult = { ...prevResult }; - newResult.pages = newResult.pages.map((page: any, idx: number) => { - if (idx === 0) { - return { - ...page, - result: [...page.result, { - ...newMessage, - id: String(Number(new Date())), - created_at: new Date(), - account_id: account?.id, - pending: true, - }], - }; - } - - return page; - }); - - return newResult; - }); - - // Return a context object with the snapshotted value - return { prevChatMessages, prevContent }; - }, - // If the mutation fails, use the context returned from onMutate to roll back - onError: (_error: any, _newData: any, context: any) => { - setContent(context.prevContent); - queryClient.setQueryData(['chats', 'messages', chat.id], context.prevChatMessages); - setErrorSubmittingMessage(true); - }, - // Always refetch after error or success: - onSuccess: () => { - queryClient.invalidateQueries(['chats', 'messages', chat.id]); - }, - }); - - const clearState = () => { - setContent(''); - setAttachment(undefined); - setIsUploading(false); - setUploadProgress(0); - setResetFileKey(fileKeyGen()); - setErrorSubmittingMessage(false); - }; - - const sendMessage = () => { - if (!isSubmitDisabled && !submitMessage.isLoading) { - const params = { - content, - media_id: attachment && attachment.id, - }; - - submitMessage.mutate({ chatId: chat.id, content }); - if (!chat.accepted) { - acceptChat.mutate(); - } - } - }; - - const insertLine = () => setContent(content + '\n'); - - const handleKeyDown: React.KeyboardEventHandler = (event) => { - markRead(); - - if (event.key === 'Enter' && event.shiftKey) { - event.preventDefault(); - insertLine(); - } else if (event.key === 'Enter') { - event.preventDefault(); - sendMessage(); - } - }; - - const handleContentChange: React.ChangeEventHandler = (event) => { - setContent(event.target.value); - }; - - const handlePaste: React.ClipboardEventHandler = (e) => { - if (isSubmitDisabled && e.clipboardData && e.clipboardData.files.length === 1) { - handleFiles(e.clipboardData.files); - } - }; - - const markRead = () => { - // markAsRead.mutate(); - // dispatch(markChatRead(chatId)); - }; - - const handleMouseOver = () => markRead(); - - const handleRemoveFile = () => { - setAttachment(undefined); - setResetFileKey(fileKeyGen()); - }; - - const onUploadProgress = (e: ProgressEvent) => { - const { loaded, total } = e; - setUploadProgress(loaded / total); - }; - - const handleFiles = (files: FileList) => { - setIsUploading(true); - - const data = new FormData(); - data.append('file', files[0]); - - dispatch(uploadMedia(data, onUploadProgress)).then((response: any) => { - setAttachment(response.data); - setIsUploading(false); - }).catch(() => { - setIsUploading(false); - }); - }; - - const renderAttachment = () => { - if (!attachment) return null; - - return ( -
-
- {truncateFilename(attachment.preview_url, 20)} -
-
- -
-
- ); - }; - - const renderActionButton = () => { - // return canSubmit() ? ( - // - // ) : ( - // - // ); - }; - - return ( - -
- -
- -
- - -