sforkowany z mirror/soapbox
				
			Improve error handling for Groups Discover page
							rodzic
							
								
									e7b3af5260
								
							
						
					
					
						commit
						287fda6d6c
					
				|  | @ -1,4 +1,5 @@ | |||
| import React, { useState } from 'react'; | ||||
| import { FormattedMessage } from 'react-intl'; | ||||
| 
 | ||||
| import { Carousel, Stack, Text } from 'soapbox/components/ui'; | ||||
| import PlaceholderGroupDiscover from 'soapbox/features/placeholder/components/placeholder-group-discover'; | ||||
|  | @ -7,46 +8,59 @@ import { usePopularGroups } from 'soapbox/queries/groups'; | |||
| import Group from './group'; | ||||
| 
 | ||||
| const PopularGroups = () => { | ||||
|   const { groups, isFetching } = usePopularGroups(); | ||||
|   const { groups, isFetching, isFetched, isError } = usePopularGroups(); | ||||
|   const isEmpty = (isFetched && groups.length === 0) || isError; | ||||
| 
 | ||||
|   const [groupCover, setGroupCover] = useState<HTMLDivElement | null>(null); | ||||
| 
 | ||||
|   return ( | ||||
|     <Stack space={4}> | ||||
|       <Text size='xl' weight='bold'> | ||||
|         Popular Groups | ||||
|         <FormattedMessage | ||||
|           id='groups.discover.popular.title' | ||||
|           defaultMessage='Popular Groups' | ||||
|         /> | ||||
|       </Text> | ||||
| 
 | ||||
|       <Carousel | ||||
|         itemWidth={250} | ||||
|         itemCount={groups.length} | ||||
|         controlsHeight={groupCover?.clientHeight} | ||||
|       > | ||||
|         {({ width }: { width: number }) => ( | ||||
|           <> | ||||
|             {isFetching ? ( | ||||
|               new Array(20).fill(0).map((_, idx) => ( | ||||
|                 <div | ||||
|                   className='relative flex shrink-0 flex-col space-y-2 px-0.5' | ||||
|                   style={{ width: width || 'auto' }} | ||||
|                   key={idx} | ||||
|                 > | ||||
|                   <PlaceholderGroupDiscover /> | ||||
|                 </div> | ||||
|               )) | ||||
|             ) : ( | ||||
|               groups.map((group) => ( | ||||
|                 <Group | ||||
|                   key={group.id} | ||||
|                   group={group} | ||||
|                   width={width} | ||||
|                   ref={setGroupCover} | ||||
|                 /> | ||||
|               )) | ||||
|             )} | ||||
|           </> | ||||
|         )} | ||||
|       </Carousel> | ||||
|       {isEmpty ? ( | ||||
|         <Text theme='muted'> | ||||
|           <FormattedMessage | ||||
|             id='groups.discover.popular.empty' | ||||
|             defaultMessage='Unable to fetch popular groups at this time. Please check back later.' | ||||
|           /> | ||||
|         </Text> | ||||
|       ) : ( | ||||
|         <Carousel | ||||
|           itemWidth={250} | ||||
|           itemCount={groups.length} | ||||
|           controlsHeight={groupCover?.clientHeight} | ||||
|         > | ||||
|           {({ width }: { width: number }) => ( | ||||
|             <> | ||||
|               {isFetching ? ( | ||||
|                 new Array(20).fill(0).map((_, idx) => ( | ||||
|                   <div | ||||
|                     className='relative flex shrink-0 flex-col space-y-2 px-0.5' | ||||
|                     style={{ width: width || 'auto' }} | ||||
|                     key={idx} | ||||
|                   > | ||||
|                     <PlaceholderGroupDiscover /> | ||||
|                   </div> | ||||
|                 )) | ||||
|               ) : ( | ||||
|                 groups.map((group) => ( | ||||
|                   <Group | ||||
|                     key={group.id} | ||||
|                     group={group} | ||||
|                     width={width} | ||||
|                     ref={setGroupCover} | ||||
|                   /> | ||||
|                 )) | ||||
|               )} | ||||
|             </> | ||||
|           )} | ||||
|         </Carousel> | ||||
|       )} | ||||
|     </Stack> | ||||
|   ); | ||||
| }; | ||||
|  |  | |||
|  | @ -0,0 +1,20 @@ | |||
| import React from 'react'; | ||||
| 
 | ||||
| import { Stack, Text } from 'soapbox/components/ui'; | ||||
| 
 | ||||
| interface Props { | ||||
|   title: React.ReactNode | string | ||||
|   subtitle: React.ReactNode | string | ||||
| } | ||||
| 
 | ||||
| export default ({ title, subtitle }: Props) => ( | ||||
|   <Stack space={2} className='px-4 py-2' data-testid='no-results'> | ||||
|     <Text weight='bold' size='lg'> | ||||
|       {title} | ||||
|     </Text> | ||||
| 
 | ||||
|     <Text theme='muted'> | ||||
|       {subtitle} | ||||
|     </Text> | ||||
|   </Stack> | ||||
| ); | ||||
|  | @ -1,22 +0,0 @@ | |||
| import React from 'react'; | ||||
| import { FormattedMessage } from 'react-intl'; | ||||
| 
 | ||||
| import { Stack, Text } from 'soapbox/components/ui'; | ||||
| 
 | ||||
| export default () => ( | ||||
|   <Stack space={2} className='px-4 py-2' data-testid='no-results'> | ||||
|     <Text weight='bold' size='lg'> | ||||
|       <FormattedMessage | ||||
|         id='groups.discover.search.no_results.title' | ||||
|         defaultMessage='No matches found' | ||||
|       /> | ||||
|     </Text> | ||||
| 
 | ||||
|     <Text theme='muted'> | ||||
|       <FormattedMessage | ||||
|         id='groups.discover.search.no_results.subtitle' | ||||
|         defaultMessage='Try searching for another group.' | ||||
|       /> | ||||
|     </Text> | ||||
|   </Stack> | ||||
| ); | ||||
|  | @ -1,4 +1,5 @@ | |||
| import React, { useEffect } from 'react'; | ||||
| import { FormattedMessage } from 'react-intl'; | ||||
| 
 | ||||
| import { Stack } from 'soapbox/components/ui'; | ||||
| import PlaceholderGroupSearch from 'soapbox/features/placeholder/components/placeholder-group-search'; | ||||
|  | @ -6,7 +7,7 @@ import { useDebounce, useOwnAccount } from 'soapbox/hooks'; | |||
| import { useGroupSearch } from 'soapbox/queries/groups/search'; | ||||
| import { saveGroupSearch } from 'soapbox/utils/groups'; | ||||
| 
 | ||||
| import NoResultsBlankslate from './no-results-blankslate'; | ||||
| import Blankslate from './blankslate'; | ||||
| import RecentSearches from './recent-searches'; | ||||
| import Results from './results'; | ||||
| 
 | ||||
|  | @ -25,7 +26,7 @@ export default (props: Props) => { | |||
|   const debouncedValueToSave = debounce(searchValue as string, 1000); | ||||
| 
 | ||||
|   const groupSearchResult = useGroupSearch(debouncedValue); | ||||
|   const { groups, isFetching, isFetched } = groupSearchResult; | ||||
|   const { groups, isFetching, isFetched, isError } = groupSearchResult; | ||||
| 
 | ||||
|   const hasSearchResults = isFetched && groups.length > 0; | ||||
|   const hasNoSearchResults = isFetched && groups.length === 0; | ||||
|  | @ -46,8 +47,42 @@ export default (props: Props) => { | |||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   if (isError) { | ||||
|     return ( | ||||
|       <Blankslate | ||||
|         title={ | ||||
|           <FormattedMessage | ||||
|             id='groups.discover.search.error.title' | ||||
|             defaultMessage='An error occurred' | ||||
|           /> | ||||
|         } | ||||
|         subtitle={ | ||||
|           <FormattedMessage | ||||
|             id='groups.discover.search.error.subtitle' | ||||
|             defaultMessage='Please try again later.' | ||||
|           /> | ||||
|         } | ||||
|       /> | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   if (hasNoSearchResults) { | ||||
|     return <NoResultsBlankslate />; | ||||
|     return ( | ||||
|       <Blankslate | ||||
|         title={ | ||||
|           <FormattedMessage | ||||
|             id='groups.discover.search.no_results.title' | ||||
|             defaultMessage='No matches found' | ||||
|           /> | ||||
|         } | ||||
|         subtitle={ | ||||
|           <FormattedMessage | ||||
|             id='groups.discover.search.no_results.subtitle' | ||||
|             defaultMessage='Try searching for another group.' | ||||
|           /> | ||||
|         } | ||||
|       /> | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   if (hasSearchResults) { | ||||
|  |  | |||
|  | @ -1,4 +1,5 @@ | |||
| import React, { useState } from 'react'; | ||||
| import { FormattedMessage } from 'react-intl'; | ||||
| 
 | ||||
| import { Carousel, Stack, Text } from 'soapbox/components/ui'; | ||||
| import PlaceholderGroupDiscover from 'soapbox/features/placeholder/components/placeholder-group-discover'; | ||||
|  | @ -7,46 +8,59 @@ import { useSuggestedGroups } from 'soapbox/queries/groups'; | |||
| import Group from './group'; | ||||
| 
 | ||||
| const SuggestedGroups = () => { | ||||
|   const { groups, isFetching } = useSuggestedGroups(); | ||||
|   const { groups, isFetching, isFetched, isError } = useSuggestedGroups(); | ||||
|   const isEmpty = (isFetched && groups.length === 0) || isError; | ||||
| 
 | ||||
|   const [groupCover, setGroupCover] = useState<HTMLDivElement | null>(null); | ||||
| 
 | ||||
|   return ( | ||||
|     <Stack space={4}> | ||||
|       <Text size='xl' weight='bold'> | ||||
|         Suggested For You | ||||
|         <FormattedMessage | ||||
|           id='groups.discover.suggested.title' | ||||
|           defaultMessage='Suggested For You' | ||||
|         /> | ||||
|       </Text> | ||||
| 
 | ||||
|       <Carousel | ||||
|         itemWidth={250} | ||||
|         itemCount={groups.length} | ||||
|         controlsHeight={groupCover?.clientHeight} | ||||
|       > | ||||
|         {({ width }: { width: number }) => ( | ||||
|           <> | ||||
|             {isFetching ? ( | ||||
|               new Array(20).fill(0).map((_, idx) => ( | ||||
|                 <div | ||||
|                   className='relative flex shrink-0 flex-col space-y-2 px-0.5' | ||||
|                   style={{ width: width || 'auto' }} | ||||
|                   key={idx} | ||||
|                 > | ||||
|                   <PlaceholderGroupDiscover /> | ||||
|                 </div> | ||||
|               )) | ||||
|             ) : ( | ||||
|               groups.map((group) => ( | ||||
|                 <Group | ||||
|                   key={group.id} | ||||
|                   group={group} | ||||
|                   width={width} | ||||
|                   ref={setGroupCover} | ||||
|                 /> | ||||
|               )) | ||||
|             )} | ||||
|           </> | ||||
|         )} | ||||
|       </Carousel> | ||||
|       {isEmpty ? ( | ||||
|         <Text theme='muted'> | ||||
|           <FormattedMessage | ||||
|             id='groups.discover.suggested.empty' | ||||
|             defaultMessage='Unable to fetch suggested groups at this time. Please check back later.' | ||||
|           /> | ||||
|         </Text> | ||||
|       ) : ( | ||||
|         <Carousel | ||||
|           itemWidth={250} | ||||
|           itemCount={groups.length} | ||||
|           controlsHeight={groupCover?.clientHeight} | ||||
|         > | ||||
|           {({ width }: { width: number }) => ( | ||||
|             <> | ||||
|               {isFetching ? ( | ||||
|                 new Array(20).fill(0).map((_, idx) => ( | ||||
|                   <div | ||||
|                     className='relative flex shrink-0 flex-col space-y-2 px-0.5' | ||||
|                     style={{ width: width || 'auto' }} | ||||
|                     key={idx} | ||||
|                   > | ||||
|                     <PlaceholderGroupDiscover /> | ||||
|                   </div> | ||||
|                 )) | ||||
|               ) : ( | ||||
|                 groups.map((group) => ( | ||||
|                   <Group | ||||
|                     key={group.id} | ||||
|                     group={group} | ||||
|                     width={width} | ||||
|                     ref={setGroupCover} | ||||
|                   /> | ||||
|                 )) | ||||
|               )} | ||||
|             </> | ||||
|           )} | ||||
|         </Carousel> | ||||
|       )} | ||||
|     </Stack> | ||||
|   ); | ||||
| }; | ||||
|  |  | |||
|  | @ -803,6 +803,8 @@ | |||
|   "group.user_subheading": "Users", | ||||
|   "groups.discover.search.no_results.subtitle": "Try searching for another group.", | ||||
|   "groups.discover.search.no_results.title": "No matches found", | ||||
|   "groups.discover.search.error.subtitle": "Please try again later.", | ||||
|   "groups.discover.search.error.title": "An error occurred", | ||||
|   "groups.discover.search.placeholder": "Search", | ||||
|   "groups.discover.search.recent_searches.blankslate.subtitle": "Search group names, topics or keywords", | ||||
|   "groups.discover.search.recent_searches.blankslate.title": "No recent searches", | ||||
|  | @ -810,6 +812,10 @@ | |||
|   "groups.discover.search.recent_searches.title": "Recent searches", | ||||
|   "groups.discover.search.results.groups": "Groups", | ||||
|   "groups.discover.search.results.member_count": "{members, plural, one {member} other {members}}", | ||||
|   "groups.discover.popular.title": "Popular Groups", | ||||
|   "groups.discover.popular.empty": "Unable to fetch popular groups at this time. Please check back later.", | ||||
|   "groups.discover.suggested.title": "Suggested For You", | ||||
|   "groups.discover.suggested.empty": "Unable to fetch suggested groups at this time. Please check back later.", | ||||
|   "groups.empty.subtitle": "Start discovering groups to join or create your own.", | ||||
|   "groups.empty.title": "No Groups yet", | ||||
|   "hashtag.column_header.tag_mode.all": "and {additional}", | ||||
|  |  | |||
		Ładowanie…
	
		Reference in New Issue
	
	 Chewbacca
						Chewbacca