Skip to content

Commit

Permalink
perf(app): add Zustand store for route parameters management
Browse files Browse the repository at this point in the history
  • Loading branch information
Robert27 committed Dec 7, 2024
1 parent 1c2f454 commit 534b571
Show file tree
Hide file tree
Showing 21 changed files with 155 additions and 138 deletions.
2 changes: 1 addition & 1 deletion android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ android {
applicationId 'app.neuland'
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 241
versionCode 242
versionName "0.11.0"
}
signingConfigs {
Expand Down
2 changes: 1 addition & 1 deletion app.config.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
"android": {
"package": "app.neuland",
"userInterfaceStyle": "automatic",
"versionCode": 241
"versionCode": 242
},
"sdkVersion": "52.0.0",
"experiments": {
Expand Down
Binary file modified bun.lockb
Binary file not shown.
4 changes: 2 additions & 2 deletions ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1718,7 +1718,7 @@ PODS:
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- Yoga
- react-native-view-shot (4.0.2):
- react-native-view-shot (4.0.3):
- DoubleConversion
- glog
- hermes-engine
Expand Down Expand Up @@ -2714,7 +2714,7 @@ SPEC CHECKSUMS:
react-native-pager-view: abc5ef92699233eb726442c7f452cac82f73d0cb
react-native-safe-area-context: 458f6b948437afcb59198016b26bbd02ff9c3b47
react-native-unistyles: 0eb1afdd80a5c6a408e60fb58516d44eb7fea30c
react-native-view-shot: f0b94997decfc338383ba9dc0748985b02934b8c
react-native-view-shot: a643bf261ce8907df3eddf7b66e408bee8ed46f6
react-native-webview: 40b8823be3fac70f0404016e6aed754ef4307517
React-nativeconfig: aeed6e2a8ac02b2df54476afcc7c663416c12bf7
React-NativeModulesApple: c5b7813da94136f50ef084fa1ac077332dcfc658
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,8 @@
"rn-quick-actions": "^0.0.3",
"sanitize-html": "^2.13.1",
"sweet-sfsymbols": "0.7.2",
"swiftui-react-native": "^6.3.3"
"swiftui-react-native": "^6.3.3",
"zustand": "^5.0.2"
},
"devDependencies": {
"@babel/core": "^7.26.0",
Expand Down
7 changes: 4 additions & 3 deletions src/app/(screens)/calendar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ export default function CalendarPage(): JSX.Element {
return (
<View
style={{
...styles.viewVertical,
...styles.viewTop,
...styles.pagerContainer,
}}
>
Expand Down Expand Up @@ -261,6 +261,7 @@ const stylesheet = createStyleSheet((theme) => ({
},
footerContainer: {
marginVertical: 10,
paddingBottom: theme.margins.bottomSafeArea,
},
footerText1: {
color: theme.colors.labelColor,
Expand Down Expand Up @@ -289,7 +290,7 @@ const stylesheet = createStyleSheet((theme) => ({
viewHorizontal: {
paddingHorizontal: theme.margins.page,
},
viewVertical: {
paddingVertical: theme.margins.page,
viewTop: {
paddingTop: theme.margins.page,
},
}))
15 changes: 3 additions & 12 deletions src/app/(screens)/clEvent.tsx
Original file line number Diff line number Diff line change
@@ -1,33 +1,24 @@
import FormList from '@/components/Universal/FormList'
import { linkIcon } from '@/components/Universal/Icon'
import ShareHeaderButton from '@/components/Universal/ShareHeaderButton'
import useCLParamsStore from '@/hooks/useCLParamsStore'
import { type LanguageKey } from '@/localization/i18n'
import { type FormListSections } from '@/types/components'
import { type CLEvents } from '@/types/neuland-api'
import {
formatFriendlyDateTime,
formatFriendlyDateTimeRange,
} from '@/utils/date-utils'
import { trackEvent } from '@aptabase/react-native'
import { Buffer } from 'buffer/'
import {
useFocusEffect,
useLocalSearchParams,
useNavigation,
} from 'expo-router'
import { useFocusEffect, useNavigation } from 'expo-router'
import React, { useCallback } from 'react'
import { useTranslation } from 'react-i18next'
import { Linking, ScrollView, Share, Text, View } from 'react-native'
import { createStyleSheet, useStyles } from 'react-native-unistyles'

export default function ClEventDetail(): JSX.Element {
const { styles } = useStyles(stylesheet)
const { clEventEntry } = useLocalSearchParams<{ clEventEntry: string }>()
const navigation = useNavigation()
const clEvent: CLEvents | undefined =
clEventEntry != null
? JSON.parse(Buffer.from(clEventEntry, 'base64').toString())
: undefined
const clEvent = useCLParamsStore((state) => state.selectedClEvent)

const { t, i18n } = useTranslation('common')
const isMultiDayEvent =
Expand Down
10 changes: 2 additions & 8 deletions src/app/(screens)/exam.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,15 @@
import FormList from '@/components/Universal/FormList'
import useRouteParamsStore from '@/hooks/useRouteParamsStore'
import { type FormListSections } from '@/types/components'
import { type Exam } from '@/types/utils'
import { formatFriendlyDateTime } from '@/utils/date-utils'
import { Buffer } from 'buffer/'
import { useLocalSearchParams } from 'expo-router'
import React from 'react'
import { useTranslation } from 'react-i18next'
import { ScrollView, Text, View } from 'react-native'
import { createStyleSheet, useStyles } from 'react-native-unistyles'

export default function ExamDetail(): JSX.Element {
const { styles } = useStyles(stylesheet)
const { examEntry } = useLocalSearchParams<{ examEntry: string }>()
const exam: Exam | undefined =
examEntry != null
? JSON.parse(Buffer.from(examEntry, 'base64').toString())
: undefined
const exam = useRouteParamsStore((state) => state.selectedExam)
const { t } = useTranslation('common')
const typeSplit =
exam?.type !== undefined
Expand Down
36 changes: 14 additions & 22 deletions src/app/(screens)/lecture.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,12 @@ import ShareCard from '@/components/Timetable/ShareCard'
import FormList from '@/components/Universal/FormList'
import PlatformIcon, { chevronIcon } from '@/components/Universal/Icon'
import ShareHeaderButton from '@/components/Universal/ShareHeaderButton'
import useRouteParamsStore from '@/hooks/useRouteParamsStore'
import { type FormListSections, type SectionGroup } from '@/types/components'
import { type FriendlyTimetableEntry } from '@/types/utils'
import { formatFriendlyDate, formatFriendlyTime } from '@/utils/date-utils'
import { isValidRoom } from '@/utils/timetable-utils'
import { trackEvent } from '@aptabase/react-native'
import { Buffer } from 'buffer/'
import {
useFocusEffect,
useLocalSearchParams,
useNavigation,
useRouter,
} from 'expo-router'
import { useFocusEffect, useNavigation, useRouter } from 'expo-router'
import moment from 'moment'
import React, { useCallback, useRef } from 'react'
import { useTranslation } from 'react-i18next'
Expand All @@ -30,29 +24,27 @@ export default function TimetableDetails(): JSX.Element {
const router = useRouter()
const navigation = useNavigation()
const { styles } = useStyles(stylesheet)
const { lecture: lectureParam } = useLocalSearchParams()
const { t } = useTranslation('timetable')
const lectureString = Array.isArray(lectureParam)
? lectureParam[0]
: lectureParam
const shareRef = useRef<ViewShot>(null)
const lecture: FriendlyTimetableEntry | null =
lectureString === undefined
? null
: JSON.parse(Buffer.from(lectureString, 'base64').toString())
const lecture = useRouteParamsStore((state) => state.selectedLecture)

useFocusEffect(
useCallback(() => {
if (lecture === null) {
return
if (lecture === undefined) {
navigation.setOptions({
headerRight: () => undefined,
})
} else {
navigation.setOptions({
headerRight: () => (
<ShareHeaderButton onPress={shareEvent} />
),
})
}
navigation.setOptions({
headerRight: () => <ShareHeaderButton onPress={shareEvent} />,
})
}, [])
)

if (lecture === null) {
if (lecture === undefined) {
return <ErrorView title="Cannot display lecture" />
}

Expand Down
11 changes: 3 additions & 8 deletions src/app/(screens)/lecturer.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,15 @@
import FormList from '@/components/Universal/FormList'
import useRouteParamsStore from '@/hooks/useRouteParamsStore'
import { type FormListSections } from '@/types/components'
import { type NormalizedLecturer } from '@/types/utils'
import { Buffer } from 'buffer/'
import { router, useLocalSearchParams } from 'expo-router'
import { router } from 'expo-router'
import React from 'react'
import { useTranslation } from 'react-i18next'
import { Linking, ScrollView, Text, View } from 'react-native'
import { createStyleSheet, useStyles } from 'react-native-unistyles'

export default function LecturerDetail(): JSX.Element {
const { styles, theme } = useStyles(stylesheet)
const { lecturerEntry } = useLocalSearchParams<{ lecturerEntry: string }>()
const lecturer: NormalizedLecturer | undefined =
lecturerEntry != null
? JSON.parse(Buffer.from(lecturerEntry, 'base64').toString())
: undefined
const lecturer = useRouteParamsStore((state) => state.selectedLecturer)
const { t } = useTranslation('common')

const validEmail =
Expand Down
6 changes: 2 additions & 4 deletions src/app/(screens)/meal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import { FoodFilterContext, UserKindContext } from '@/components/contexts'
import allergenMap from '@/data/allergens.json'
import { USER_EMPLOYEE, USER_GUEST, USER_STUDENT } from '@/data/constants'
import flagMap from '@/data/mensa-flags.json'
import useRouteParamsStore from '@/hooks/useRouteParamsStore'
import { type LanguageKey } from '@/localization/i18n'
import { type FormListSections } from '@/types/components'
import { type Meal } from '@/types/neuland-api'
import {
formatPrice,
humanLocations,
Expand All @@ -20,13 +20,11 @@ import { router, useFocusEffect, useNavigation } from 'expo-router'
import React, { useCallback, useContext } from 'react'
import { useTranslation } from 'react-i18next'
import { Alert, Linking, ScrollView, Share, Text, View } from 'react-native'
import { useMMKVObject } from 'react-native-mmkv'
import { createStyleSheet, useStyles } from 'react-native-unistyles'

export default function FoodDetail(): JSX.Element {
const [selectedMeal] = useMMKVObject('selectedMeal', undefined)
const meal = useRouteParamsStore((state) => state.selectedMeal)
const { styles, theme } = useStyles(stylesheet)
const meal = selectedMeal as Meal | undefined
const {
preferencesSelection,
allergenSelection,
Expand Down
22 changes: 5 additions & 17 deletions src/app/(screens)/sportsEvent.tsx
Original file line number Diff line number Diff line change
@@ -1,33 +1,21 @@
import {
type UniversitySportsFieldsFragment,
type WeekdayType,
} from '@/__generated__/gql/graphql'
import { type WeekdayType } from '@/__generated__/gql/graphql'
import FormList from '@/components/Universal/FormList'
import ShareHeaderButton from '@/components/Universal/ShareHeaderButton'
import useCLParamsStore from '@/hooks/useCLParamsStore'
import { type LanguageKey } from '@/localization/i18n'
import { type FormListSections } from '@/types/components'
import { formatFriendlyTimeRange } from '@/utils/date-utils'
import { trackEvent } from '@aptabase/react-native'
import { Buffer } from 'buffer/'
import {
useFocusEffect,
useLocalSearchParams,
useNavigation,
} from 'expo-router'
import { useFocusEffect, useNavigation } from 'expo-router'
import React, { useCallback } from 'react'
import { useTranslation } from 'react-i18next'
import { Linking, ScrollView, Share, Text, View } from 'react-native'
import { createStyleSheet, useStyles } from 'react-native-unistyles'

export default function SportsEventDetail(): JSX.Element {
const { styles, theme } = useStyles(stylesheet)
const { sportsEventEntry } = useLocalSearchParams<{
sportsEventEntry: string
}>()
const sportsEvent: UniversitySportsFieldsFragment | undefined =
sportsEventEntry != null
? JSON.parse(Buffer.from(sportsEventEntry, 'base64').toString())
: undefined

const sportsEvent = useCLParamsStore((state) => state.selectedSportsEvent)
const { t, i18n } = useTranslation('common')
const navigation = useNavigation()
useFocusEffect(
Expand Down
6 changes: 4 additions & 2 deletions src/components/Food/MealEntry.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import PlatformIcon from '@/components/Universal/Icon'
import { FoodFilterContext, UserKindContext } from '@/components/contexts'
import { type UserKindContextType } from '@/contexts/userKind'
import { USER_GUEST } from '@/data/constants'
import useRouteParamsStore from '@/hooks/useRouteParamsStore'
import { type LanguageKey } from '@/localization/i18n'
import { type Meal } from '@/types/neuland-api'
import {
Expand All @@ -24,7 +25,6 @@ import React, { useContext, useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { Platform, Pressable, Text, View } from 'react-native'
import ContextMenu from 'react-native-context-menu-view'
import { useMMKVObject } from 'react-native-mmkv'
import { createStyleSheet, useStyles } from 'react-native-unistyles'

/**
Expand Down Expand Up @@ -56,7 +56,9 @@ export const MealEntry = ({
preferencesSelection,
i18n.language
)
const [, setSelectedMeal] = useMMKVObject('selectedMeal', undefined)
const setSelectedMeal = useRouteParamsStore(
(state) => state.setSelectedMeal
)
useEffect(() => {}, [userKind])
const price = getUserSpecificPrice(meal, userKind ?? 'guest')
const label =
Expand Down
11 changes: 5 additions & 6 deletions src/components/Rows/CalendarRow.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import useRouteParamsStore from '@/hooks/useRouteParamsStore'
import { type LanguageKey } from '@/localization/i18n'
import { type Calendar } from '@/types/data'
import { type Exam } from '@/types/utils'
Expand All @@ -8,7 +9,6 @@ import {
formatFriendlyDateTimeRange,
formatFriendlyRelativeTime,
} from '@/utils/date-utils'
import { Buffer } from 'buffer/'
import { router } from 'expo-router'
import React from 'react'
import { useTranslation } from 'react-i18next'
Expand Down Expand Up @@ -56,13 +56,12 @@ const CalendarRow = ({ event }: { event: Calendar }): JSX.Element => {
}

const ExamRow = ({ event }: { event: Exam }): JSX.Element => {
const setExam = useRouteParamsStore((state) => state.setSelectedExam)
const { styles } = useStyles(stylesheet)
const base64Event = Buffer.from(JSON.stringify(event)).toString('base64')

const navigateToPage = (): void => {
router.push({
pathname: '/exam',
params: { examEntry: base64Event },
})
setExam(event)
router.navigate('/exam')
}

const { t } = useTranslation('common')
Expand Down
11 changes: 6 additions & 5 deletions src/components/Rows/EventRow.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { type CampusLifeEventFieldsFragment } from '@/__generated__/gql/graphql'
import useCLParamsStore from '@/hooks/useCLParamsStore'
import { type LanguageKey } from '@/localization/i18n'
import { type CLEvents } from '@/types/neuland-api'
import {
formatFriendlyDateTimeRange,
formatFriendlyRelativeTime,
} from '@/utils/date-utils'
import { Buffer } from 'buffer/'
import { router } from 'expo-router'
import React from 'react'
import { useTranslation } from 'react-i18next'
Expand All @@ -19,6 +20,9 @@ const CLEventRow = ({
event: CampusLifeEventFieldsFragment
}): JSX.Element => {
const { styles } = useStyles(stylesheet)
const setSelectedClEvent = useCLParamsStore(
(state) => state.setSelectedClEvent
)
const { t, i18n } = useTranslation('common')
let begin = null
if (event.startDateTime != null) {
Expand All @@ -27,12 +31,9 @@ const CLEventRow = ({
const end = event.endDateTime != null ? new Date(event.endDateTime) : null

const onPressRow = (): void => {
const base64Event = Buffer.from(JSON.stringify(event)).toString(
'base64'
)
setSelectedClEvent(event as CLEvents)
router.navigate({
pathname: '/clEvent',
params: { clEventEntry: base64Event },
})
}
return (
Expand Down
Loading

0 comments on commit 534b571

Please sign in to comment.