Skip to content

Commit

Permalink
Merge pull request #14 from milad-alizadeh/enhancement-refactor-mybar
Browse files Browse the repository at this point in the history
Optimise my bar fetch and queries
  • Loading branch information
milad-alizadeh authored Dec 26, 2023
2 parents fc17c53 + 4fbf23f commit 1e16996
Show file tree
Hide file tree
Showing 9 changed files with 115 additions and 133 deletions.
25 changes: 17 additions & 8 deletions src/app/(tabs)/my-bar.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { useIsFocused } from '@react-navigation/native'
import { router } from 'expo-router'
import React, { useCallback, useEffect, useRef, useState } from 'react'
import React, { useCallback, useEffect, useState } from 'react'
import { ActivityIndicator, View, ViewStyle } from 'react-native'
import Popover from 'react-native-popover-view'
import {
Expand All @@ -13,7 +14,7 @@ import {
Tabs,
Text,
} from '~/components'
import { useAnalytics, useFetchMatchedRecipes, useSession } from '~/hooks'
import { useAnalytics, useFetchMatchedRecipes, useFetchMyBar, useSession } from '~/hooks'
import { useDetailsModal, useStore } from '~/providers'

export default function MyBarScreen() {
Expand All @@ -23,6 +24,8 @@ export default function MyBarScreen() {
const { capture } = useAnalytics()
const [deleteingItemId, setDeleteingItemId] = useState<string>('')

const isFocused = useIsFocused()

const handleIngredientPress = useCallback((ingredientId: string) => {
setCurrentIngredientId(ingredientId)
}, [])
Expand All @@ -35,22 +38,28 @@ export default function MyBarScreen() {
}
}, [myBarPopoverDismissed])

const { deleteFromMyBar, myBarRefetch, myBarLoading, sectionsData, sectionsHeader, myBarError } =
useFetchMyBar()

const {
deleteFromMyBar,
getRecipeMatch,
myBarRefetch,
myBarLoading,
partialMatchData,
partialMatchRefetch,
sectionsData,
sectionsHeader,
totalMatchData,
totalMatchLoading,
totalMatchRefetch,
myBarError,
totalMatchError,
} = useFetchMatchedRecipes()

useEffect(() => {
if (isFocused) {
// Refetch the data when the tab gains focus
myBarRefetch()
totalMatchRefetch()
partialMatchRefetch()
}
}, [isFocused, myBarRefetch])

const renderIngredientItem = useCallback(
({ item }) => {
if (!item.name) return <View className="w-full h-64 bg-white p-page-spacing" />
Expand Down
26 changes: 0 additions & 26 deletions src/graphql/queries/getIngredientsInMyBar.ts

This file was deleted.

1 change: 0 additions & 1 deletion src/graphql/queries/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ export * from './getEquipmentDetails'
export * from './getFavourites'
export * from './getFilters'
export * from './getIngredientDetails'
export * from './getIngredientsInMyBar'
export * from './getIngtedientsByCategories'
export * from './getMyBar'
export * from './getPartialMatchRecipes'
Expand Down
1 change: 1 addition & 0 deletions src/hooks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export * from './useFetchIngredients'
export * from './useFetchMatchedRecipes'
export * from './useFetchRecipeDetails'
export * from './useFetchRecipes'
export * from './useFetchMybar'
export * from './useHaptics'
export * from './usePeristedState'
export * from './useProtectedRouteListener'
Expand Down
15 changes: 6 additions & 9 deletions src/hooks/useFetchIngredientDetails.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,21 @@ import { useMutation, useQuery } from '@apollo/client'
import { router, useGlobalSearchParams } from 'expo-router'
import { GetRecipesByIngredientQuery } from '~/__generated__/graphql'
import { ADD_TO_MY_BAR, DELETE_FROM_MY_BAR } from '~/graphql/mutations'
import {
GET_INGREDIENTS_IN_MY_BAR,
GET_INGREDIENT_DETAILS,
GET_RECIPES_BY_INGREDIENT,
} from '~/graphql/queries'
import { GET_INGREDIENT_DETAILS, GET_RECIPES_BY_INGREDIENT } from '~/graphql/queries'
import { useDetailsModal } from '~/providers'
import { captureError } from '~/utils/captureError'
import { useFetchMyBar } from './useFetchMybar'
import { useSession } from './useSession'

export const useFetchIngredientDetails = (ingredientId: string, onClosed: () => void) => {
try {
const { ingredientsInMyBar, myBarRefetch } = useFetchMyBar()
const { recipeId } = useGlobalSearchParams()
const { user } = useSession()
const { data, loading } = useQuery(GET_INGREDIENT_DETAILS, {
variables: { ingredientId },
})
const { data: barIngredients, refetch: myBarRefetch } = useQuery(GET_INGREDIENTS_IN_MY_BAR)

const { data: relatedRecipes, loading: recipesLoading } = useQuery(GET_RECIPES_BY_INGREDIENT, {
variables: { ingredientId },
fetchPolicy: 'cache-and-network',
Expand All @@ -28,9 +26,8 @@ export const useFetchIngredientDetails = (ingredientId: string, onClosed: () =>

const [addToMyBar, { loading: addLoading }] = useMutation(ADD_TO_MY_BAR)
const [deleteFromMyBar] = useMutation(DELETE_FROM_MY_BAR)
const myBar =
barIngredients?.profilesIngredientsCollection?.edges.map((e) => e.node?.ingredient?.id) ?? []
const isInMyBar = myBar.includes(ingredientId)

const isInMyBar = !!ingredientsInMyBar.find((i) => i.id === ingredientId)
const ingredient = data?.ingredientsCollection?.edges[0]?.node

const getAvailableRecipes = (relatedRecipes: GetRecipesByIngredientQuery) => {
Expand Down
40 changes: 14 additions & 26 deletions src/hooks/useFetchIngredients.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,18 @@ import { useQuery } from '@apollo/client'
import keyBy from 'lodash/keyBy'
import { useEffect, useState } from 'react'
import { SectionDataType, SectionHeaderType } from '~/components'
import { GET_INGREDIENTS_IN_MY_BAR } from '~/graphql/queries'
import { GET_INGREDIENTS_BY_CATEGORIES } from '~/graphql/queries/getIngtedientsByCategories'
import { useAppContent } from '~/providers'
import { captureError } from '~/utils/captureError'
import { api } from '../services/api'
import { useAnalytics } from './useAnalytics'
import { useFetchMyBar } from './useFetchMybar'

export type SelectedItems = Record<string, { name: string; selected: boolean }>

export const useFetchIngredients = () => {
try {
const { ingredientsInMyBar } = useFetchMyBar()
const { capture } = useAnalytics()
const { ingredient_categories } = useAppContent()
const [searchQuery, setSearchQuery] = useState('')
Expand All @@ -25,6 +26,10 @@ export const useFetchIngredients = () => {
const [sectionsHeader, setSectionsHeader] = useState<SectionHeaderType[]>([])
const [initialSelectedItems, setInitialSelectedItems] = useState<SelectedItems>({})

const { data: categories } = useQuery(GET_INGREDIENTS_BY_CATEGORIES, {
fetchPolicy: 'cache-and-network',
})

/**
* Search for ingredients that match the given search query.
* @param searchQuery - The search query to match against ingredient names.
Expand Down Expand Up @@ -64,14 +69,6 @@ export const useFetchIngredients = () => {
searchIngredients(searchQuery)
}, [searchQuery])

const { data: categories } = useQuery(GET_INGREDIENTS_BY_CATEGORIES, {
fetchPolicy: 'cache-and-network',
})

const { data: selectedIngredients } = useQuery(GET_INGREDIENTS_IN_MY_BAR, {
fetchPolicy: 'cache-and-network',
})

useEffect(() => {
if (!categories) return
const sectionsData: SectionDataType[][] = []
Expand All @@ -89,26 +86,17 @@ export const useFetchIngredients = () => {
}, [categories])

useEffect(() => {
if (!selectedIngredients) return
const initialSelectedItems: SelectedItems = {}
selectedIngredients?.profilesIngredientsCollection?.edges
.filter(({ node }) => node?.ingredient)
.forEach(
({
node: {
ingredient: { id, name },
},
}) => {
initialSelectedItems[id] = {
name,
selected: true,
}
},
)
if (!ingredientsInMyBar) return
ingredientsInMyBar.forEach(({ name, id }) => {
initialSelectedItems[id] = {
name,
selected: true,
}
})

setInitialSelectedItems(initialSelectedItems)
setSelectedItems(initialSelectedItems)
}, [selectedIngredients])
}, [ingredientsInMyBar])

return {
searchQuery,
Expand Down
57 changes: 3 additions & 54 deletions src/hooks/useFetchMatchedRecipes.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,12 @@
import { useMutation, useQuery } from '@apollo/client'
import { useIsFocused } from '@react-navigation/native'
import { useQuery } from '@apollo/client'
import { router } from 'expo-router'
import { useEffect } from 'react'
import { GetPartialMatchRecipesQuery, GetTotalmatchRecipesQuery } from '~/__generated__/graphql'
import { CardProps, SectionDataType, SectionHeaderType } from '~/components'
import { DELETE_FROM_MY_BAR } from '~/graphql/mutations/deleteFromMyBar'
import {
GET_INGREDIENTS_IN_MY_BAR,
GET_MY_BAR,
GET_PARTIAL_MATCH_RECIPES,
GET_TOTAL_MATCH_RECIPES,
} from '~/graphql/queries'
import { useAppContent } from '~/providers'
import { CardProps } from '~/components'
import { GET_PARTIAL_MATCH_RECIPES, GET_TOTAL_MATCH_RECIPES } from '~/graphql/queries'
import { captureError } from '~/utils/captureError'

export const useFetchMatchedRecipes = () => {
try {
const { my_bar } = useAppContent()
const {
data: myBarData,
loading: myBarLoading,
refetch: myBarRefetch,
error: myBarError,
} = useQuery(GET_MY_BAR)

const {
data: totalMatchData,
refetch: totalMatchRefetch,
Expand All @@ -38,17 +21,6 @@ export const useFetchMatchedRecipes = () => {
error: partialMatchError,
} = useQuery(GET_PARTIAL_MATCH_RECIPES)

const isFocused = useIsFocused()

useEffect(() => {
if (isFocused) {
// Refetch the data when the tab gains focus
myBarRefetch()
totalMatchRefetch()
partialMatchRefetch()
}
}, [isFocused, myBarRefetch, totalMatchRefetch, partialMatchRefetch])

const getRecipeMatch = (
matchedData: GetTotalmatchRecipesQuery | GetPartialMatchRecipesQuery,
): CardProps[] => {
Expand All @@ -66,35 +38,12 @@ export const useFetchMatchedRecipes = () => {
)
}

let sectionsData: SectionDataType[][] = []
let sectionsHeader: SectionHeaderType[] = []

const categoriesdIngredients =
myBarData?.myBarCollection?.edges
?.filter(({ node }) => !my_bar?.hidden_category_ids?.includes(node?.id))
?.map(({ node }) => node) ?? []

sectionsData = categoriesdIngredients.map((section) => JSON.parse(section?.data))
sectionsHeader = categoriesdIngredients.map((section) => ({
title: section?.title,
count: section?.count,
id: section?.title,
}))

const [deleteFromMyBar] = useMutation(DELETE_FROM_MY_BAR)

return {
deleteFromMyBar,
getRecipeMatch,
myBarError,
myBarLoading,
myBarRefetch,
partialMatchData,
partialMatchError,
partialMatchLoading,
partialMatchRefetch,
sectionsData,
sectionsHeader,
totalMatchData,
totalMatchError,
totalMatchLoading,
Expand Down
70 changes: 70 additions & 0 deletions src/hooks/useFetchMybar.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { useMutation, useQuery } from '@apollo/client'
import { useEffect, useState } from 'react'
import { SectionDataType, SectionHeaderType } from '~/components'
import { DELETE_FROM_MY_BAR } from '~/graphql/mutations/deleteFromMyBar'
import { GET_MY_BAR } from '~/graphql/queries'
import { useAppContent } from '~/providers'
import { captureError } from '~/utils/captureError'

interface Ingredient {
id: string
name: string
}

export const useFetchMyBar = () => {
try {
const { my_bar } = useAppContent()
const {
data: myBarData,
loading: myBarLoading,
refetch: myBarRefetch,
error: myBarError,
} = useQuery(GET_MY_BAR)

const [sectionsData, setSectionsData] = useState<SectionDataType[][]>([])
const [sectionsHeader, setSectionsHeader] = useState<SectionHeaderType[]>([])
const [ingredientsInMyBar, setIngredientsInMyBar] = useState<Ingredient[]>([])

useEffect(() => {
if (!myBarData) return

let newSectionsData = []
let newSectionsHeader = []
let newIngredientsInMyBar = []

for (let category of myBarData?.myBarCollection?.edges) {
const { node } = category

if (!my_bar?.hidden_category_ids?.includes(node?.id)) {
const data = JSON.parse(node?.data)

newIngredientsInMyBar = newIngredientsInMyBar.concat(data)
newSectionsData.push(data)
newSectionsHeader.push({
title: node?.title,
count: node?.count,
id: node?.title,
})
}
}

setIngredientsInMyBar(newIngredientsInMyBar)
setSectionsData(newSectionsData)
setSectionsHeader(newSectionsHeader)
}, [myBarData, my_bar?.hidden_category_ids])

const [deleteFromMyBar] = useMutation(DELETE_FROM_MY_BAR)

return {
deleteFromMyBar,
myBarError,
myBarLoading,
myBarRefetch,
sectionsData,
sectionsHeader,
ingredientsInMyBar,
}
} catch (error) {
captureError(error)
}
}
Loading

0 comments on commit 1e16996

Please sign in to comment.