diff --git a/app/soapbox/features/chats/components/chat-pane/chat-pane.tsx b/app/soapbox/features/chats/components/chat-pane/chat-pane.tsx index e75efd432..420275227 100644 --- a/app/soapbox/features/chats/components/chat-pane/chat-pane.tsx +++ b/app/soapbox/features/chats/components/chat-pane/chat-pane.tsx @@ -15,7 +15,7 @@ import useAccountSearch from 'soapbox/queries/search'; import ChatList from '../chat-list'; import ChatPaneHeader from '../chat-pane-header'; -import ChatSearch from '../chat-search'; +import ChatSearch from '../chat-search/chat-search'; import ChatWindow from '../chat-window'; import { Pane } from '../ui'; @@ -44,10 +44,11 @@ const ChatPane = () => { const unreadCount = sumBy(chats, (chat) => chat.unread); const hasSearchValue = Number(value?.length) > 0; - console.log('hasSearchValue', hasSearchValue); - - const handleClickChat = (chat: IChat) => setChat(chat); + const handleClickChat = (chat: IChat) => { + setChat(chat); + setValue(undefined); + }; const clearValue = () => { if (hasSearchValue) { @@ -133,7 +134,10 @@ const ChatPane = () => { unreadCount={unreadCount} isOpen={isOpen} onToggle={toggleChatPane} - secondaryAction={() => setSearching(true)} + secondaryAction={() => { + setSearching(true); + setValue(undefined); + }} secondaryActionIcon={require('@tabler/icons/edit.svg')} /> diff --git a/app/soapbox/features/chats/components/__tests__/chat-search.test.tsx b/app/soapbox/features/chats/components/chat-search/__tests__/chat-search.test.tsx similarity index 91% rename from app/soapbox/features/chats/components/__tests__/chat-search.test.tsx rename to app/soapbox/features/chats/components/chat-search/__tests__/chat-search.test.tsx index 4693e6e87..2e9e0b7bd 100644 --- a/app/soapbox/features/chats/components/__tests__/chat-search.test.tsx +++ b/app/soapbox/features/chats/components/chat-search/__tests__/chat-search.test.tsx @@ -4,7 +4,7 @@ import React from 'react'; import { __stub } from 'soapbox/api'; import { ChatProvider } from 'soapbox/contexts/chat-context'; -import { render, screen, waitFor } from '../../../../jest/test-helpers'; +import { render, screen, waitFor } from '../../../../../jest/test-helpers'; import ChatSearch from '../chat-search'; const renderComponent = () => render( @@ -28,7 +28,7 @@ describe('', () => { }); describe('when the pane is open', () => { - beforeEach(async() => { + beforeEach(async () => { renderComponent(); await userEvent.click(screen.getByTestId('icon-button')); }); @@ -50,7 +50,7 @@ describe('', () => { }); }); - it('renders accounts', async() => { + it('renders accounts', async () => { renderComponent(); const user = userEvent.setup(); diff --git a/app/soapbox/features/chats/components/chat-search/blankslate.tsx b/app/soapbox/features/chats/components/chat-search/blankslate.tsx new file mode 100644 index 000000000..54ba3a4b8 --- /dev/null +++ b/app/soapbox/features/chats/components/chat-search/blankslate.tsx @@ -0,0 +1,14 @@ +import React from 'react'; + +import { Stack, Text } from 'soapbox/components/ui'; + +const Blankslate = () => ( + + Search followers + + You can start a conversation with anyone that follows you. + + +); + +export default Blankslate; \ No newline at end of file diff --git a/app/soapbox/features/chats/components/chat-search.tsx b/app/soapbox/features/chats/components/chat-search/chat-search.tsx similarity index 67% rename from app/soapbox/features/chats/components/chat-search.tsx rename to app/soapbox/features/chats/components/chat-search/chat-search.tsx index 2d91d9745..c84bf2d88 100644 --- a/app/soapbox/features/chats/components/chat-search.tsx +++ b/app/soapbox/features/chats/components/chat-search/chat-search.tsx @@ -3,16 +3,19 @@ import { AxiosError } from 'axios'; import React, { useState } from 'react'; import snackbar from 'soapbox/actions/snackbar'; -import { Avatar, HStack, Icon, Input, Stack, Text } from 'soapbox/components/ui'; -import VerificationBadge from 'soapbox/components/verification_badge'; +import { HStack, Icon, Input, Stack, Text } from 'soapbox/components/ui'; import { useChatContext } from 'soapbox/contexts/chat-context'; import { useAppDispatch, useDebounce } from 'soapbox/hooks'; import { useChats } from 'soapbox/queries/chats'; import { queryClient } from 'soapbox/queries/client'; import useAccountSearch from 'soapbox/queries/search'; -import ChatPaneHeader from './chat-pane-header'; -import { Pane } from './ui'; +import ChatPaneHeader from '../chat-pane-header'; +import { Pane } from '../ui'; + +import Blankslate from './blankslate'; +import EmptyResultsBlankslate from './empty-results-blankslate'; +import Results from './results'; const ChatSearch = () => { const debounce = useDebounce; @@ -24,9 +27,10 @@ const ChatSearch = () => { const [value, setValue] = useState(); const debouncedValue = debounce(value as string, 300); - const { data: accounts } = useAccountSearch(debouncedValue); + const { data: accounts, isFetching } = useAccountSearch(debouncedValue); - const hasSearchValue = value && value.length > 0; + const hasSearchValue = debouncedValue && debouncedValue.length > 0; + const hasSearchResults = (accounts || []).length > 0; const handleClickOnSearchResult = useMutation((accountId: string) => { return getOrCreateChatByAccountId(accountId); @@ -41,6 +45,24 @@ const ChatSearch = () => { }, }); + const renderBody = () => { + if (hasSearchResults) { + return ( + { + handleClickOnSearchResult.mutate(id); + clearValue(); + }} + /> + ); + } else if (hasSearchValue && !hasSearchResults && !isFetching) { + return ; + } else { + return ; + } + }; + const clearValue = () => { if (hasSearchValue) { setValue(''); @@ -93,30 +115,7 @@ const ChatSearch = () => { - {(accounts || []).map((account: any) => ( - - ))} + {renderBody()} ) : null} diff --git a/app/soapbox/features/chats/components/chat-search/empty-results-blankslate.tsx b/app/soapbox/features/chats/components/chat-search/empty-results-blankslate.tsx new file mode 100644 index 000000000..15daf9319 --- /dev/null +++ b/app/soapbox/features/chats/components/chat-search/empty-results-blankslate.tsx @@ -0,0 +1,14 @@ +import React from 'react'; + +import { Stack, Text } from 'soapbox/components/ui'; + +const EmptyResultsBlankslate = () => ( + + No matches found + + Try searching for another name. + + +); + +export default EmptyResultsBlankslate; \ No newline at end of file diff --git a/app/soapbox/features/chats/components/chat-search/results.tsx b/app/soapbox/features/chats/components/chat-search/results.tsx new file mode 100644 index 000000000..1a036c2ea --- /dev/null +++ b/app/soapbox/features/chats/components/chat-search/results.tsx @@ -0,0 +1,43 @@ +import React from 'react'; + +import { Avatar, HStack, Stack, Text } from 'soapbox/components/ui'; +import VerificationBadge from 'soapbox/components/verification_badge'; + +interface IResults { + accounts: { + display_name: string + acct: string + id: string + avatar: string + verified: boolean + }[] + onSelect(id: string): void +} + +const Results = ({ accounts, onSelect }: IResults) => ( + <> + {(accounts || []).map((account: any) => ( + + ))} + +); + +export default Results; \ No newline at end of file