This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

add bot filter to feed controls

+71 -2
+45 -1
src/webapp/features/feeds/components/feedControls/FeedControls.tsx
··· 37 37 { value: 'following' as const, label: 'Following' }, 38 38 ]; 39 39 40 + const botFilterOptions = [ 41 + { value: false, label: 'Hide bots' }, 42 + { value: true, label: 'Include bots' }, 43 + ]; 44 + 40 45 const activityTypeOptions = [ 41 46 { 42 47 value: ActivityType.CARD_COLLECTED, ··· 66 71 .getAll('activityTypes') 67 72 .map(paramToActivityType) 68 73 .filter((t): t is ActivityType => t !== undefined); 74 + const includeKnownBotsFromUrl = 75 + searchParams.get('includeKnownBots') === 'true'; 69 76 70 77 const [optimisticSource, setOptimisticSource] = 71 78 useOptimistic<ActivitySource | null>(sourceFromUrl); ··· 77 84 ); 78 85 const [optimisticActivityTypes, setOptimisticActivityTypes] = 79 86 useOptimistic<ActivityType[]>(activityTypesFromUrl); 87 + const [optimisticIncludeKnownBots, setOptimisticIncludeKnownBots] = 88 + useOptimistic<boolean>(includeKnownBotsFromUrl); 80 89 81 90 const [typePopoverOpened, setTypePopoverOpened] = useState(false); 82 91 ··· 160 169 }); 161 170 }; 162 171 172 + const handleBotFilterClick = (includeKnownBots: boolean) => { 173 + startTransition(() => { 174 + setOptimisticIncludeKnownBots(includeKnownBots); 175 + 176 + const params = new URLSearchParams(searchParams.toString()); 177 + if (includeKnownBots) { 178 + params.set('includeKnownBots', 'true'); 179 + } else { 180 + params.delete('includeKnownBots'); 181 + } 182 + 183 + router.push(`?${params.toString()}`, { scroll: false }); 184 + }); 185 + }; 186 + 163 187 const hasActiveFilters = 164 188 optimisticSource !== null || 165 189 optimisticFeed !== 'global' || 166 190 optimisticType !== null || 167 - optimisticActivityTypes.length > 0; 191 + optimisticActivityTypes.length > 0 || 192 + optimisticIncludeKnownBots !== false; 168 193 169 194 const handleClear = () => { 170 195 startTransition(() => { ··· 172 197 setOptimisticFeed('global'); 173 198 setOptimisticType(null); 174 199 setOptimisticActivityTypes([]); 200 + setOptimisticIncludeKnownBots(false); 175 201 176 202 router.push('?', { scroll: false }); 177 203 }); ··· 220 246 onClick={() => handleFeedClick(option.value)} 221 247 rightSection={ 222 248 option.value === optimisticFeed ? <IoMdCheckmark /> : null 249 + } 250 + closeMenuOnClick={false} 251 + > 252 + {option.label} 253 + </Menu.Item> 254 + ))} 255 + </> 256 + 257 + <> 258 + <Menu.Label>Accounts</Menu.Label> 259 + {botFilterOptions.map((option) => ( 260 + <Menu.Item 261 + key={String(option.value)} 262 + onClick={() => handleBotFilterClick(option.value)} 263 + rightSection={ 264 + option.value === optimisticIncludeKnownBots ? ( 265 + <IoMdCheckmark /> 266 + ) : null 223 267 } 224 268 closeMenuOnClick={false} 225 269 >
+3
src/webapp/features/feeds/containers/myFeedContainer/MyFeedContainer.tsx
··· 28 28 const selectedSource = searchParams.get('source') as ActivitySource; 29 29 const selectedFeed = 30 30 (searchParams.get('feed') as 'global' | 'following') || 'global'; 31 + const includeKnownBots = searchParams.get('includeKnownBots') === 'true'; 31 32 32 33 // Parse activityTypes from URL params (lowercase) and convert to enum values 33 34 const activityTypesParam = searchParams.getAll('activityTypes'); ··· 48 49 urlType: selectedUrlType, 49 50 source: selectedSource, 50 51 activityTypes: activityTypesFilter, 52 + includeKnownBots, 51 53 }); 52 54 const followingFeed = useFollowingFeed({ 53 55 urlType: selectedUrlType, 54 56 source: selectedSource, 55 57 activityTypes: activityTypesFilter, 58 + includeKnownBots, 56 59 enabled: selectedFeed === 'following', 57 60 }); 58 61
+3
src/webapp/features/feeds/lib/dal.ts
··· 9 9 urlType?: UrlType; 10 10 source?: ActivitySource; 11 11 activityTypes?: ActivityType[]; 12 + includeKnownBots?: boolean; 12 13 } 13 14 14 15 export const getGlobalFeed = cache(async (params?: PageParams) => { ··· 19 20 urlType: params?.urlType, 20 21 source: params?.source, 21 22 activityTypes: params?.activityTypes, 23 + includeKnownBots: params?.includeKnownBots, 22 24 }); 23 25 24 26 return response; ··· 48 50 urlType: params?.urlType, 49 51 source: params?.source, 50 52 activityTypes: params?.activityTypes, 53 + includeKnownBots: params?.includeKnownBots, 51 54 }); 52 55 53 56 return response;
+14 -1
src/webapp/features/feeds/lib/feedKeys.ts
··· 7 7 urlType?: UrlType, 8 8 source?: ActivitySource, 9 9 activityTypes?: ActivityType[], 10 - ) => [...feedKeys.all(), 'infinite', limit, urlType, source, activityTypes], 10 + includeKnownBots?: boolean, 11 + ) => [ 12 + ...feedKeys.all(), 13 + 'infinite', 14 + limit, 15 + urlType, 16 + source, 17 + activityTypes, 18 + includeKnownBots, 19 + ], 11 20 gems: () => [...feedKeys.all(), 'gems'] as const, 12 21 gemsInfinite: ( 13 22 limit?: number, 14 23 urlType?: UrlType, 15 24 source?: ActivitySource, 16 25 activityTypes?: ActivityType[], 26 + includeKnownBots?: boolean, 17 27 ) => [ 18 28 ...feedKeys.gems(), 19 29 [...feedKeys.infinite()], ··· 21 31 limit, 22 32 source, 23 33 activityTypes, 34 + includeKnownBots, 24 35 ], 25 36 following: () => [...feedKeys.all(), 'following'] as const, 26 37 followingInfinite: ( ··· 28 39 urlType?: UrlType, 29 40 source?: ActivitySource, 30 41 activityTypes?: ActivityType[], 42 + includeKnownBots?: boolean, 31 43 ) => 32 44 [ 33 45 ...feedKeys.following(), ··· 36 48 urlType, 37 49 source, 38 50 activityTypes, 51 + includeKnownBots, 39 52 ] as const, 40 53 };
+3
src/webapp/features/feeds/lib/queries/useFollowingFeed.tsx
··· 8 8 urlType?: UrlType; 9 9 source?: ActivitySource; 10 10 activityTypes?: ActivityType[]; 11 + includeKnownBots?: boolean; 11 12 enabled?: boolean; 12 13 } 13 14 ··· 21 22 props?.urlType, 22 23 props?.source, 23 24 props?.activityTypes, 25 + props?.includeKnownBots, 24 26 ), 25 27 staleTime: 10000, 26 28 initialPageParam: 1, ··· 33 35 urlType: props?.urlType, 34 36 source: props?.source, 35 37 activityTypes: props?.activityTypes, 38 + includeKnownBots: props?.includeKnownBots, 36 39 }); 37 40 }, 38 41 getNextPageParam: (lastPage) => {
+3
src/webapp/features/feeds/lib/queries/useGlobalFeed.tsx
··· 8 8 urlType?: UrlType; 9 9 source?: ActivitySource; 10 10 activityTypes?: ActivityType[]; 11 + includeKnownBots?: boolean; 11 12 } 12 13 13 14 export default function useGlobalFeed(props?: Props) { ··· 19 20 props?.urlType, 20 21 props?.source, 21 22 props?.activityTypes, 23 + props?.includeKnownBots, 22 24 ), 23 25 staleTime: 10000, 24 26 initialPageParam: 1, ··· 30 32 urlType: props?.urlType, 31 33 source: props?.source, 32 34 activityTypes: props?.activityTypes, 35 + includeKnownBots: props?.includeKnownBots, 33 36 }); 34 37 }, 35 38 getNextPageParam: (lastPage) => {