Skip to content

Commit

Permalink
feat(mobile): add store data refetching in interval
Browse files Browse the repository at this point in the history
  • Loading branch information
duongdev authored and bkdev98 committed Aug 21, 2024
1 parent 7b7ceee commit 31422e8
Show file tree
Hide file tree
Showing 9 changed files with 121 additions and 41 deletions.
24 changes: 7 additions & 17 deletions apps/mobile/app/(app)/(tabs)/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,10 @@ import { Text } from '@/components/ui/text'
import { useColorScheme } from '@/hooks/useColorScheme'
import { formatDateShort } from '@/lib/date'
import { theme } from '@/lib/theme'
import { walletQueries } from '@/queries/wallet'
import { useTransactionList } from '@/stores/transaction/hooks'
import { dayjsExtended } from '@6pm/utilities'
import { t } from '@lingui/macro'
import { useLingui } from '@lingui/react'
import { useQueryClient } from '@tanstack/react-query'
import { format } from 'date-fns/format'
import { LinearGradient } from 'expo-linear-gradient'
import { groupBy, mapValues, orderBy, sumBy } from 'lodash-es'
Expand All @@ -29,7 +27,6 @@ export default function HomeScreen() {
const { top, bottom } = useSafeAreaInsets()
const { colorScheme } = useColorScheme()
const [walletAccountId, setWalletAccountId] = useState<string | undefined>()
const queryClient = useQueryClient()
const [filter, setFilter] = useState<HomeFilter>(HomeFilter.All)
const [view, setView] = useState<HomeView>(HomeView.SpentThisWeek)
const [customTimeRange, setCustomTimeRange] = useState<{
Expand All @@ -51,18 +48,11 @@ export default function HomeScreen() {
}
}, [customTimeRange, filter])

const { transactions, isLoading, isRefetching, refetch } = useTransactionList(
{
walletAccountId,
categoryId,
...timeRange,
},
)

const handleRefresh = () => {
refetch()
queryClient.invalidateQueries({ queryKey: walletQueries.list._def })
}
const { transactions, isLoading } = useTransactionList({
walletAccountId,
categoryId,
...timeRange,
})

const handleSetFilter = (filter: HomeFilter) => {
if (filter === HomeFilter.ByDay) {
Expand Down Expand Up @@ -134,8 +124,8 @@ export default function HomeScreen() {
}
className="flex-1 bg-card"
contentContainerStyle={{ paddingBottom: bottom + 32 }}
refreshing={isRefetching}
onRefresh={handleRefresh}
// refreshing={isRefetching}
// onRefresh={handleRefresh}
sections={transactionsGroupByDate}
keyExtractor={(item) => item.id}
renderItem={({ item: transaction }) => (
Expand Down
2 changes: 1 addition & 1 deletion apps/mobile/app/_layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import { useWarmUpBrowser } from '@/hooks/use-warm-up-browser'
import { useColorScheme } from '@/hooks/useColorScheme'
import { queryClient } from '@/lib/client'
import { LocaleProvider } from '@/locales/provider'
import { StoreProvider } from '@/stores/store-provider'
import { StoreProvider } from '@/stores/core/store-provider'
import { BottomSheetModalProvider } from '@gorhom/bottom-sheet'
import AsyncStorage from '@react-native-async-storage/async-storage'
import NetInfo from '@react-native-community/netinfo'
Expand Down
18 changes: 14 additions & 4 deletions apps/mobile/stores/category/hooks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,27 @@ import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import { keyBy, omit } from 'lodash-es'
import { useMemo } from 'react'
import { z } from 'zod'
import type { StoreHookQueryOptions } from '../core/stores'
import { categoryQueries } from './queries'
import { useCategoryStore } from './store'

export const useCategoryList = () => {
export const useCategoryListQueryOptions = (
queryOptions?: StoreHookQueryOptions,
) => {
const categories = useCategoryStore().categories
const setCategoriesState = useCategoryStore((state) => state.setCategories)

const query = useQuery({
return {
...categoryQueries.all({ setCategoriesState }),
initialData: categories?.length > 0 ? categories : undefined,
})
...queryOptions,
}
}

export const useCategoryList = (queryOptions?: StoreHookQueryOptions) => {
const categories = useCategoryStore().categories
const queryOpts = useCategoryListQueryOptions(queryOptions)

const query = useQuery(queryOpts)

const { categoriesDict, incomeCategories, expenseCategories } =
useMemo(() => {
Expand Down
30 changes: 30 additions & 0 deletions apps/mobile/stores/core/store-interval-update.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { useSuspenseQueries } from '@tanstack/react-query'
import type { FC } from 'react'
import { useCategoryListQueryOptions } from '../category/hooks'
import { useTransactionListQueryOptions } from '../transaction/hooks'
import type { StoreHookQueryOptions } from './stores'
import { STORE_SYNC_INTERVAL } from './stores.const'

export type StoreIntervalUpdateProps = {
interval?: number
}

export const StoreIntervalUpdate: FC<StoreIntervalUpdateProps> = ({
interval = STORE_SYNC_INTERVAL,
}) => {
const queryOptions: StoreHookQueryOptions = {
refetchInterval: interval,
refetchIntervalInBackground: true,
}
const categoryListQueryOptions = useCategoryListQueryOptions(queryOptions)
const transactionListQueryOptions = useTransactionListQueryOptions(
undefined,
queryOptions,
)

useSuspenseQueries({
queries: [{ ...categoryListQueryOptions }, transactionListQueryOptions],
})

return null
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
useEffect,
useState,
} from 'react'
import { StoreIntervalUpdate } from './store-interval-update'
import { useResetAllStores } from './use-reset-all-stores'

export type StoreProviderProps = {
Expand Down Expand Up @@ -60,5 +61,10 @@ export const StoreProvider: FC<StoreProviderProps> = ({ children }) => {
return null
}

return children
return (
<>
<StoreIntervalUpdate />
{children}
</>
)
}
1 change: 1 addition & 0 deletions apps/mobile/stores/core/stores.const.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const STORE_SYNC_INTERVAL = 1000 * 5 // 5 seconds
4 changes: 4 additions & 0 deletions apps/mobile/stores/core/stores.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export type StoreHookQueryOptions = {
refetchInterval?: number
refetchIntervalInBackground?: boolean
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useCallback } from 'react'
import { useBudgetStore } from './budget/store'
import { useCategoryStore } from './category/store'
import { useTransactionStore } from './transaction/store'
import { useBudgetStore } from '../budget/store'
import { useCategoryStore } from '../category/store'
import { useTransactionStore } from '../transaction/store'

export const useResetAllStores = () => {
const resetBudgetStore = useBudgetStore((state) => state._reset)
Expand Down
69 changes: 54 additions & 15 deletions apps/mobile/stores/transaction/hooks.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { UNCATEGORIZED_ID } from '@/components/home/category-chart'
import { getHonoClient } from '@/lib/client'
import { useMeQuery } from '@/queries/auth'
import { dayjsExtended } from '@6pm/utilities'
import {
type TransactionFormValues,
type TransactionPopulated,
Expand All @@ -12,22 +13,28 @@ import { keyBy } from 'lodash-es'
import { useMemo } from 'react'
import { z } from 'zod'
import { useCategoryList } from '../category/hooks'
import type { StoreHookQueryOptions } from '../core/stores'
import { transactionQueries } from './queries'
import { useTransactionStore } from './store'

export function useTransactionList({
from,
to,
walletAccountId,
budgetId,
categoryId,
}: {
from: Date
to: Date
walletAccountId?: string
budgetId?: string
categoryId?: string
}) {
// TODO: Update params here
const DEFAULT_FROM = dayjsExtended()
.subtract(10, 'year')
.startOf('year')
.toDate()
const DEFAULT_TO = dayjsExtended().add(10, 'year').endOf('year').toDate()

export const useTransactionListQueryOptions = (
{
// FIXME: This should be dynamic @bkdev98
from = DEFAULT_FROM,
to = DEFAULT_TO,
}: {
from?: Date
to?: Date
} = {},
queryOptions?: StoreHookQueryOptions,
) => {
const transactionsInRangeFromStore =
useTransactionStore().transactions.filter(
(t) =>
Expand All @@ -36,7 +43,7 @@ export function useTransactionList({
const updateTransactionsByRange = useTransactionStore(
(state) => state.updateTransactionsByRange,
)
const query = useQuery({
return {
...transactionQueries.list({
filters: { from, to },
updateTransactionsByRangeInStore: updateTransactionsByRange,
Expand All @@ -45,7 +52,39 @@ export function useTransactionList({
transactionsInRangeFromStore.length > 0
? transactionsInRangeFromStore
: undefined,
})
...queryOptions,
}
}

export function useTransactionList(
{
// FIXME: This should be dynamic @bkdev98
from = DEFAULT_FROM,
to = DEFAULT_TO,
walletAccountId,
budgetId,
categoryId,
}: {
from?: Date
to?: Date
walletAccountId?: string
budgetId?: string
categoryId?: string
} = {},
queryOptions?: StoreHookQueryOptions,
) {
const transactionsInRangeFromStore =
useTransactionStore().transactions.filter(
(t) => new Date(t.date) >= from && new Date(t.date) <= to,
)
const queryOpts = useTransactionListQueryOptions(
{
from,
to,
},
queryOptions,
)
const query = useQuery(queryOpts)

const { transactions, transactionDict, totalExpense, totalIncome } =
useMemo(() => {
Expand Down

0 comments on commit 31422e8

Please sign in to comment.