Hopefully feature-complete Android Bluesky client written in Expo
atproto bluesky

Add different profile feed filters

Changed files
+42 -2
src
app
(authenticated)
profile
+42 -2
src/app/(authenticated)/profile/[userId].tsx
··· 12 12 import Post from "@/src/components/Post"; 13 13 import { AppBskyLabelerDefs } from "@atcute/bluesky"; 14 14 import Animated, { interpolate, useAnimatedRef, useAnimatedStyle, useScrollOffset } from "react-native-reanimated"; 15 + import { useState } from "react"; 16 + 17 + type AuthorFeedFilters = 18 + | "posts_with_replies" 19 + | "posts_no_replies" 20 + | "posts_with_media" 21 + | "posts_and_author_threads" 22 + | "posts_with_video"; 15 23 16 24 export default function Profile() { 17 25 const { userId } = useLocalSearchParams<{ userId: string }>(); ··· 23 31 24 32 const flashListRef = useAnimatedRef<FlashListRef<any>>(); 25 33 const scrollOffset = useScrollOffset(flashListRef); 34 + 35 + const [feedFilter, setFeedFilter] = useState<AuthorFeedFilters>("posts_and_author_threads"); 26 36 27 37 const profileQuery = useQuery({ 28 38 queryKey: ["profile", userId], ··· 66 76 }); 67 77 68 78 const authorFeedQuery = useInfiniteQuery({ 69 - queryKey: ["authorFeed", userId], 79 + queryKey: ["authorFeed", userId, feedFilter], 70 80 initialPageParam: "", 71 81 queryFn: async ({ signal, pageParam, queryKey }) => { 72 82 const wrapper: FetchHandler = async (pathname, init) => { ··· 94 104 const res = await ok( 95 105 client.get("app.bsky.feed.getAuthorFeed", { 96 106 signal, 97 - params: { actor: queryKey[1] as ActorIdentifier, cursor: pageParam, filter: "posts_and_author_threads" }, 107 + params: { actor: queryKey[1] as ActorIdentifier, cursor: pageParam, filter: queryKey[2] }, 98 108 headers: { "atproto-accept-labelers": labelersDids.join(", ") }, 99 109 }) 100 110 ); ··· 310 320 .filter((val) => val)} 311 321 </View> 312 322 )} 323 + </View> 324 + <View style={{ flexDirection: "row" }}> 325 + <Pressable 326 + style={{ padding: 8 }} 327 + onPress={() => { 328 + setFeedFilter("posts_and_author_threads"); 329 + }} 330 + > 331 + <Text style={{ fontWeight: 700, color: colorScheme === "light" ? "black" : "white" }}>Posts</Text> 332 + </Pressable> 333 + 334 + <Pressable 335 + style={{ padding: 8 }} 336 + onPress={() => { 337 + setFeedFilter("posts_with_replies"); 338 + }} 339 + > 340 + <Text style={{ fontWeight: 700, color: colorScheme === "light" ? "black" : "white" }}> 341 + Replies 342 + </Text> 343 + </Pressable> 344 + 345 + <Pressable 346 + style={{ padding: 8 }} 347 + onPress={() => { 348 + setFeedFilter("posts_with_media"); 349 + }} 350 + > 351 + <Text style={{ fontWeight: 700, color: colorScheme === "light" ? "black" : "white" }}>Media</Text> 352 + </Pressable> 313 353 </View> 314 354 </View> 315 355 );