diff options
| author | MohamedBassem <me@mbassem.com> | 2024-03-20 17:56:22 +0000 |
|---|---|---|
| committer | MohamedBassem <me@mbassem.com> | 2024-03-20 17:56:22 +0000 |
| commit | 20d1a90e65d08c16f30d8d9adac005dda7f4dad1 (patch) | |
| tree | 1182180136d0ef8488932e56f807fbb37a2f6f12 /apps | |
| parent | 23285cb5eb44551f8200ebda6b305240d1da09f9 (diff) | |
| download | karakeep-20d1a90e65d08c16f30d8d9adac005dda7f4dad1.tar.zst | |
fix(mobile): Fix flicker on search
Diffstat (limited to 'apps')
| -rw-r--r-- | apps/mobile/app/dashboard/(tabs)/index.tsx | 4 | ||||
| -rw-r--r-- | apps/mobile/app/dashboard/(tabs)/search.tsx | 49 | ||||
| -rw-r--r-- | apps/mobile/app/dashboard/archive.tsx | 4 | ||||
| -rw-r--r-- | apps/mobile/app/dashboard/favourites.tsx | 4 | ||||
| -rw-r--r-- | apps/mobile/app/dashboard/lists/[slug].tsx | 4 | ||||
| -rw-r--r-- | apps/mobile/app/dashboard/tags/[slug].tsx | 4 | ||||
| -rw-r--r-- | apps/mobile/components/bookmarks/BookmarkList.tsx | 54 | ||||
| -rw-r--r-- | apps/mobile/components/bookmarks/UpdatingBookmarkList.tsx | 52 |
8 files changed, 105 insertions, 70 deletions
diff --git a/apps/mobile/app/dashboard/(tabs)/index.tsx b/apps/mobile/app/dashboard/(tabs)/index.tsx index a840ca93..18fb804d 100644 --- a/apps/mobile/app/dashboard/(tabs)/index.tsx +++ b/apps/mobile/app/dashboard/(tabs)/index.tsx @@ -2,7 +2,7 @@ import { Platform, SafeAreaView, View } from "react-native"; import * as Haptics from "expo-haptics"; import * as ImagePicker from "expo-image-picker"; import { useRouter } from "expo-router"; -import BookmarkList from "@/components/bookmarks/BookmarkList"; +import UpdatingBookmarkList from "@/components/bookmarks/UpdatingBookmarkList"; import PageTitle from "@/components/ui/PageTitle"; import useAppSettings from "@/lib/settings"; import { useUploadAsset } from "@/lib/upload"; @@ -80,7 +80,7 @@ function HeaderRight() { export default function Home() { return ( <SafeAreaView> - <BookmarkList + <UpdatingBookmarkList query={{ archived: false }} header={ <View className="flex flex-row justify-between"> diff --git a/apps/mobile/app/dashboard/(tabs)/search.tsx b/apps/mobile/app/dashboard/(tabs)/search.tsx index 25fc53d5..c1bb178b 100644 --- a/apps/mobile/app/dashboard/(tabs)/search.tsx +++ b/apps/mobile/app/dashboard/(tabs)/search.tsx @@ -1,42 +1,49 @@ import { useState } from "react"; import { SafeAreaView, View } from "react-native"; import BookmarkList from "@/components/bookmarks/BookmarkList"; +import FullPageSpinner from "@/components/ui/FullPageSpinner"; import { Input } from "@/components/ui/Input"; +import PageTitle from "@/components/ui/PageTitle"; import { api } from "@/lib/trpc"; import { keepPreviousData } from "@tanstack/react-query"; import { useDebounce } from "use-debounce"; -import PageTitle from "@/components/ui/PageTitle"; export default function Search() { const [search, setSearch] = useState(""); - const [query] = useDebounce(search, 200); + const [query] = useDebounce(search, 10); - const { data } = api.bookmarks.searchBookmarks.useQuery( + const onRefresh = api.useUtils().bookmarks.searchBookmarks.invalidate; + + const { data, isPending } = api.bookmarks.searchBookmarks.useQuery( { text: query }, { placeholderData: keepPreviousData }, ); + if (!data) { + return <FullPageSpinner />; + } + return ( <SafeAreaView> - {data && ( - <BookmarkList - query={{ids: data.bookmarks.map((b) => b.id)}} - header={ - <View> - <PageTitle title="Search" /> - <Input - placeholder="Search" - className="mx-4 bg-white" - value={search} - onChangeText={setSearch} - autoFocus - autoCapitalize="none" - /> - </View> - } - /> - )} + <BookmarkList + bookmarks={data.bookmarks} + header={ + <View> + <PageTitle title="Search" /> + <Input + placeholder="Search" + className="mx-4 bg-white" + value={search} + onChangeText={setSearch} + autoFocus + autoCapitalize="none" + /> + </View> + } + onRefresh={onRefresh} + isRefreshing={isPending} + /> </SafeAreaView> ); } diff --git a/apps/mobile/app/dashboard/archive.tsx b/apps/mobile/app/dashboard/archive.tsx index 98a03631..93841b9d 100644 --- a/apps/mobile/app/dashboard/archive.tsx +++ b/apps/mobile/app/dashboard/archive.tsx @@ -1,11 +1,11 @@ import { SafeAreaView } from "react-native"; -import BookmarkList from "@/components/bookmarks/BookmarkList"; +import UpdatingBookmarkList from "@/components/bookmarks/UpdatingBookmarkList"; import PageTitle from "@/components/ui/PageTitle"; export default function Archive() { return ( <SafeAreaView> - <BookmarkList query={{archived: true}} header={<PageTitle title="🗄️ Archive" />} /> + <UpdatingBookmarkList query={{archived: true}} header={<PageTitle title="🗄️ Archive" />} /> </SafeAreaView> ); } diff --git a/apps/mobile/app/dashboard/favourites.tsx b/apps/mobile/app/dashboard/favourites.tsx index f62d561e..aebf3885 100644 --- a/apps/mobile/app/dashboard/favourites.tsx +++ b/apps/mobile/app/dashboard/favourites.tsx @@ -1,11 +1,11 @@ import { SafeAreaView } from "react-native"; -import BookmarkList from "@/components/bookmarks/BookmarkList"; +import UpdatingBookmarkList from "@/components/bookmarks/UpdatingBookmarkList"; import PageTitle from "@/components/ui/PageTitle"; export default function Favourites() { return ( <SafeAreaView> - <BookmarkList + <UpdatingBookmarkList query={{ archived: false, favourited: true, diff --git a/apps/mobile/app/dashboard/lists/[slug].tsx b/apps/mobile/app/dashboard/lists/[slug].tsx index 8596b49f..2bb5d602 100644 --- a/apps/mobile/app/dashboard/lists/[slug].tsx +++ b/apps/mobile/app/dashboard/lists/[slug].tsx @@ -1,6 +1,6 @@ import { SafeAreaView, View } from "react-native"; import { Stack, useLocalSearchParams } from "expo-router"; -import BookmarkList from "@/components/bookmarks/BookmarkList"; +import UpdatingBookmarkList from "@/components/bookmarks/UpdatingBookmarkList"; import FullPageSpinner from "@/components/ui/FullPageSpinner"; import PageTitle from "@/components/ui/PageTitle"; import { api } from "@/lib/trpc"; @@ -23,7 +23,7 @@ export default function ListView() { /> {list ? ( <View> - <BookmarkList + <UpdatingBookmarkList query={{ archived: false, listId: list.id, diff --git a/apps/mobile/app/dashboard/tags/[slug].tsx b/apps/mobile/app/dashboard/tags/[slug].tsx index cb6e2ef4..52c06129 100644 --- a/apps/mobile/app/dashboard/tags/[slug].tsx +++ b/apps/mobile/app/dashboard/tags/[slug].tsx @@ -1,6 +1,6 @@ import { SafeAreaView, View } from "react-native"; import { Stack, useLocalSearchParams } from "expo-router"; -import BookmarkList from "@/components/bookmarks/BookmarkList"; +import UpdatingBookmarkList from "@/components/bookmarks/UpdatingBookmarkList"; import FullPageSpinner from "@/components/ui/FullPageSpinner"; import PageTitle from "@/components/ui/PageTitle"; import { api } from "@/lib/trpc"; @@ -24,7 +24,7 @@ export default function TagView() { /> {tag ? ( <View> - <BookmarkList + <UpdatingBookmarkList query={{ archived: false, tagId: tag.id, diff --git a/apps/mobile/components/bookmarks/BookmarkList.tsx b/apps/mobile/components/bookmarks/BookmarkList.tsx index 8a19c045..9176f66d 100644 --- a/apps/mobile/components/bookmarks/BookmarkList.tsx +++ b/apps/mobile/components/bookmarks/BookmarkList.tsx @@ -1,53 +1,29 @@ -import { useEffect, useRef, useState } from "react"; +import { useRef } from "react"; import { ActivityIndicator, Keyboard, Text, View } from "react-native"; import Animated, { LinearTransition } from "react-native-reanimated"; -import { api } from "@/lib/trpc"; import { useScrollToTop } from "@react-navigation/native"; -import type { ZGetBookmarksRequest } from "@hoarder/trpc/types/bookmarks"; +import type { ZBookmark } from "@hoarder/trpc/types/bookmarks"; -import FullPageSpinner from "../ui/FullPageSpinner"; import BookmarkCard from "./BookmarkCard"; export default function BookmarkList({ - query, + bookmarks, header, + onRefresh, + fetchNextPage, + isFetchingNextPage, + isRefreshing, }: { - query: ZGetBookmarksRequest; + bookmarks: ZBookmark[]; + onRefresh: () => void, + isRefreshing: boolean, + fetchNextPage?: () => void, header?: React.ReactElement; + isFetchingNextPage?: boolean, }) { - const apiUtils = api.useUtils(); - const [refreshing, setRefreshing] = useState(false); const flatListRef = useRef(null); useScrollToTop(flatListRef); - const { - data, - isPending, - isPlaceholderData, - error, - fetchNextPage, - isFetchingNextPage, - } = api.bookmarks.getBookmarks.useInfiniteQuery(query, { - initialCursor: null, - getNextPageParam: (lastPage) => lastPage.nextCursor, - }); - - useEffect(() => { - setRefreshing(isPending || isPlaceholderData); - }, [isPending, isPlaceholderData]); - - if (error) { - return <Text>{JSON.stringify(error)}</Text>; - } - - if (isPending || !data) { - return <FullPageSpinner />; - } - - const onRefresh = () => { - apiUtils.bookmarks.getBookmarks.invalidate(); - apiUtils.bookmarks.getBookmark.invalidate(); - }; return ( <Animated.FlatList @@ -64,12 +40,12 @@ export default function BookmarkList({ <Text className="text-xl">No Bookmarks</Text> </View> } - data={data.pages.flatMap((p) => p.bookmarks)} - refreshing={refreshing} + data={bookmarks} + refreshing={isRefreshing} onRefresh={onRefresh} onScrollBeginDrag={Keyboard.dismiss} keyExtractor={(b) => b.id} - onEndReached={() => fetchNextPage()} + onEndReached={fetchNextPage} ListFooterComponent={ isFetchingNextPage ? ( <View className="items-center"> diff --git a/apps/mobile/components/bookmarks/UpdatingBookmarkList.tsx b/apps/mobile/components/bookmarks/UpdatingBookmarkList.tsx new file mode 100644 index 00000000..8495ee22 --- /dev/null +++ b/apps/mobile/components/bookmarks/UpdatingBookmarkList.tsx @@ -0,0 +1,52 @@ +import { Text } from "react-native"; +import { api } from "@/lib/trpc"; + +import type { ZGetBookmarksRequest } from "@hoarder/trpc/types/bookmarks"; + +import FullPageSpinner from "../ui/FullPageSpinner"; +import BookmarkList2 from "./BookmarkList"; + +export default function UpdatingBookmarkList({ + query, + header, +}: { + query: ZGetBookmarksRequest; + header?: React.ReactElement; +}) { + const apiUtils = api.useUtils(); + const { + data, + isPending, + isPlaceholderData, + error, + fetchNextPage, + isFetchingNextPage, + } = api.bookmarks.getBookmarks.useInfiniteQuery(query, { + initialCursor: null, + getNextPageParam: (lastPage) => lastPage.nextCursor, + }); + + if (error) { + return <Text>{JSON.stringify(error)}</Text>; + } + + if (isPending || !data) { + return <FullPageSpinner />; + } + + const onRefresh = () => { + apiUtils.bookmarks.getBookmarks.invalidate(); + apiUtils.bookmarks.getBookmark.invalidate(); + }; + + return ( + <BookmarkList2 + bookmarks={data.pages.flatMap((p) => p.bookmarks)} + header={header} + onRefresh={onRefresh} + fetchNextPage={fetchNextPage} + isFetchingNextPage={isFetchingNextPage} + isRefreshing={isPending || isPlaceholderData} + /> + ); +} |
