diff --git a/app/components/sheets/RoutesList.tsx b/app/components/sheets/RoutesList.tsx index 86a8ca9..e7de7b2 100644 --- a/app/components/sheets/RoutesList.tsx +++ b/app/components/sheets/RoutesList.tsx @@ -11,6 +11,7 @@ import SheetHeader from "../ui/SheetHeader"; import IconPill from "../ui/IconPill"; import { useAuthToken, useBaseData, usePatternPaths, useRoutes } from "app/data/api_query"; import { useDefaultRouteGroup, useFavorites } from "app/data/storage_query"; +import { useQueryClient } from "@tanstack/react-query"; interface SheetProps { sheetRef: React.RefObject @@ -30,7 +31,8 @@ const RoutesList: React.FC = ({ sheetRef }) => { const [shouldUpdateData, setShouldUpdateData] = useState(false); - const { data: routes, isLoading: isRoutesLoading } = useRoutes(); + const queryClient = useQueryClient(); + const { data: routes, isLoading: isRoutesLoading, isRefetching: isRefreshing } = useRoutes(); const { data: favorites, isLoading: isFavoritesLoading, isError: isFavoritesError } = useFavorites(shouldUpdateData); const { data: defaultGroup, refetch: refetchDefaultGroup } = useDefaultRouteGroup(shouldUpdateData); @@ -161,6 +163,12 @@ const RoutesList: React.FC = ({ sheetRef }) => { data={filterRoutes()} keyExtractor={(route: IMapRoute) => route.key} style={{ marginLeft: 16 }} + refreshing={isRefreshing} + onRefresh={() => { + queryClient.invalidateQueries({ queryKey: ["baseData"] }); + queryClient.invalidateQueries({ queryKey: ["patternPaths"] }); + queryClient.invalidateQueries({ queryKey: ["routes"] }); + }} renderItem={({item: route}) => { return ( handleRouteSelected(route)}> diff --git a/app/data/api_query.ts b/app/data/api_query.ts index d9347a0..1ad497c 100644 --- a/app/data/api_query.ts +++ b/app/data/api_query.ts @@ -12,7 +12,7 @@ export const useAuthToken = () => { queryFn: async () => { return await getAuthentication(); }, - staleTime: Infinity + staleTime: 2 * 3600 * 1000, // keep for 2 hours }); return query; @@ -36,7 +36,10 @@ export const useBaseData = () => { return baseData; }, enabled: authTokenQuery.isSuccess, - staleTime: Infinity, + staleTime: 8 * 3600 * 1000, // persist for 8 hours + meta: { + persist: true + } }); return query; @@ -58,7 +61,10 @@ export const usePatternPaths = () => { return patternPaths; }, enabled: baseDataQuery.isSuccess, - staleTime: Infinity + staleTime: 8 * 3600 * 1000, // persist for 8 hours + meta: { + persist: true + } }); return query @@ -99,7 +105,10 @@ export const useRoutes = () => { return routes; }, enabled: patternPathsQuery.isSuccess && baseDataQuery.isSuccess, - staleTime: Infinity + staleTime: 8 * 3600 * 1000, // persist for 8 hours + meta: { + persist: true + } }); return query; diff --git a/app/data/storage_query.ts b/app/data/storage_query.ts index 7b03b8c..ea6a96e 100644 --- a/app/data/storage_query.ts +++ b/app/data/storage_query.ts @@ -88,7 +88,6 @@ export const addFavoriteMutation = () => { }, onSuccess: () => { queryClient.invalidateQueries({ queryKey: ["favorites"] }); - queryClient.invalidateQueries({ queryKey: ["favorite"] }); } }); diff --git a/app/index.tsx b/app/index.tsx index 8a7dcc9..fe09529 100644 --- a/app/index.tsx +++ b/app/index.tsx @@ -11,10 +11,13 @@ import StopTimetable from './components/sheets/StopTimetable'; import Settings from './components/sheets/Settings'; import { darkMode, lightMode } from './theme'; import { GestureHandlerRootView } from 'react-native-gesture-handler'; -import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; +import { Query, QueryClient } from '@tanstack/react-query'; import { getColorScheme } from './utils'; import InputRoute from './components/sheets/route_planning/InputRoute'; import TripPlanDetail from './components/sheets/route_planning/TripPlanDetail'; +import { createAsyncStoragePersister } from '@tanstack/query-async-storage-persister' +import AsyncStorage from '@react-native-async-storage/async-storage'; +import { PersistQueryClientProvider } from '@tanstack/react-query-persist-client'; const Home = () => { const setPresentSheet = useAppStore((state) => state.setPresentSheet); @@ -73,9 +76,23 @@ const Home = () => { }, []) const queryClient = new QueryClient() + const asyncStoragePersister = createAsyncStoragePersister({ + storage: AsyncStorage, + }) return ( - + { + // only persist queries who ask for it and are successful + return query.meta?.persist as boolean && query.state.status === 'success' + }, + } + }} + > @@ -96,7 +113,7 @@ const Home = () => { - + ) } diff --git a/package-lock.json b/package-lock.json index 37d4c7f..4bd0dd7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,7 +14,9 @@ "@gorhom/bottom-sheet": "^4.6.4", "@react-native-async-storage/async-storage": "1.23.1", "@react-native-segmented-control/segmented-control": "2.5.2", + "@tanstack/query-async-storage-persister": "^5.53.1", "@tanstack/react-query": "^5.22.2", + "@tanstack/react-query-persist-client": "^5.53.1", "aggie-spirit-api": "^1.1.0", "expo": "^51.0.31", "expo-constants": "~16.0.2", @@ -8103,28 +8105,73 @@ "@sinonjs/commons": "^3.0.0" } }, + "node_modules/@tanstack/query-async-storage-persister": { + "version": "5.53.1", + "resolved": "https://registry.npmjs.org/@tanstack/query-async-storage-persister/-/query-async-storage-persister-5.53.1.tgz", + "integrity": "sha512-c/0cfEN7PX+nzvziy/psRD0zJgEfB8Nxy+greiGSbP0iT5gcxnAhkHz2biCTOVQwGIlod/rCjKnz+q4u4+Cv9g==", + "license": "MIT", + "dependencies": { + "@tanstack/query-persist-client-core": "5.53.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, "node_modules/@tanstack/query-core": { - "version": "5.22.2", - "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.22.2.tgz", - "integrity": "sha512-z3PwKFUFACMUqe1eyesCIKg3Jv1mysSrYfrEW5ww5DCDUD4zlpTKBvUDaEjsfZzL3ULrFLDM9yVUxI/fega1Qg==", + "version": "5.53.1", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.53.1.tgz", + "integrity": "sha512-mvLG7s4Zy3Yvc2LsKm8BVafbmPrsReKgqwhmp4XKVmRW9us3KbWRqu3qBBfhVavcUUEHfNK7PvpTchvQpVdFpw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/query-persist-client-core": { + "version": "5.53.1", + "resolved": "https://registry.npmjs.org/@tanstack/query-persist-client-core/-/query-persist-client-core-5.53.1.tgz", + "integrity": "sha512-2cR3sfziXWRKNdX7GUimA+pF3wF1aY+Z0PzOL6426bpx/b5V/eSEw+JWmRSFeY/s6J6flqnqenKlL+pRPpGTog==", + "license": "MIT", + "dependencies": { + "@tanstack/query-core": "5.53.1" + }, "funding": { "type": "github", "url": "https://github.com/sponsors/tannerlinsley" } }, "node_modules/@tanstack/react-query": { - "version": "5.22.2", - "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.22.2.tgz", - "integrity": "sha512-TaxJDRzJ8/NWRT4lY2jguKCrNI6MRN+67dELzPjNUlvqzTxGANlMp68l7aC7hG8Bd1uHNxHl7ihv7MT50i/43A==", + "version": "5.53.1", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.53.1.tgz", + "integrity": "sha512-35HU4836Ey1/W74BxmS8p9KHXcDRGPdkw6w3VX0Tc5S9v5acFl80oi/yc6nsmoLhu68wQkWMyX0h7y7cOtY5OA==", + "license": "MIT", + "dependencies": { + "@tanstack/query-core": "5.53.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": "^18 || ^19" + } + }, + "node_modules/@tanstack/react-query-persist-client": { + "version": "5.53.1", + "resolved": "https://registry.npmjs.org/@tanstack/react-query-persist-client/-/react-query-persist-client-5.53.1.tgz", + "integrity": "sha512-2ntl2ZcU5MqQmf7LCIpfSk0se/Nh49Zfk+qVcxJ3ILZKUtOamJBewHNbcI58o9GfUYUg7k9GOQsDT2gZdPFKQA==", + "license": "MIT", "dependencies": { - "@tanstack/query-core": "5.22.2" + "@tanstack/query-persist-client-core": "5.53.1" }, "funding": { "type": "github", "url": "https://github.com/sponsors/tannerlinsley" }, "peerDependencies": { - "react": "^18.0.0" + "@tanstack/react-query": "^5.53.1", + "react": "^18 || ^19" } }, "node_modules/@testing-library/jest-native": { diff --git a/package.json b/package.json index 1e56f4a..fba2acb 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,9 @@ "@gorhom/bottom-sheet": "^4.6.4", "@react-native-async-storage/async-storage": "1.23.1", "@react-native-segmented-control/segmented-control": "2.5.2", + "@tanstack/query-async-storage-persister": "^5.53.1", "@tanstack/react-query": "^5.22.2", + "@tanstack/react-query-persist-client": "^5.53.1", "aggie-spirit-api": "^1.1.0", "expo": "^51.0.31", "expo-constants": "~16.0.2",