Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: allows OTP to be approved from a cold start #1256

Merged
merged 6 commits into from
Aug 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import theme from './lib/theme'
import Main from './Main'
import { PrefsProvider } from './context/PrefsContext'
import { PendingNotificationsProvider } from './context/PendingNotificationsContext'
import { InitialLoadingProvider } from './context/InitalLoadingContext'

export default function App() {
return (
Expand All @@ -18,10 +19,12 @@ export default function App() {
<SecretsProvider>
<PrefsProvider>
<PendingNotificationsProvider>
<PaperProvider theme={theme}>
<Main />
<StatusBar style="auto" />
</PaperProvider>
<InitialLoadingProvider>
<PaperProvider theme={theme}>
<Main />
<StatusBar style="auto" />
</PaperProvider>
</InitialLoadingProvider>
</PendingNotificationsProvider>
</PrefsProvider>
</SecretsProvider>
Expand Down
40 changes: 40 additions & 0 deletions src/context/InitalLoadingContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import React, {
createContext,
useContext,
useState,
useMemo,
useCallback,
} from 'react'

const initialContext = {
initialLoadingComplete: false,
markInitialLoadingComplete: () => {
// set in context provider construction
},
}

const InitialLoadingContext = createContext(initialContext)

export const useInitialLoading = () => useContext(InitialLoadingContext)

export const InitialLoadingProvider = ({ children }) => {
const [initialLoadingComplete, setInitialLoadingComplete] = useState(false)

const markInitialLoadingComplete = useCallback(() => {
setInitialLoadingComplete(true)
}, [setInitialLoadingComplete])

const value = useMemo(
() => ({
initialLoadingComplete,
markInitialLoadingComplete,
}),
[initialLoadingComplete, markInitialLoadingComplete]
)

return (
<InitialLoadingContext.Provider value={value}>
{children}
</InitialLoadingContext.Provider>
)
}
1 change: 1 addition & 0 deletions src/screens/HomeScreen.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ jest.mock('expo-notifications', () => ({
addNotificationReceivedListener: jest.fn(),
addNotificationResponseReceivedListener: jest.fn(),
removeNotificationSubscription: jest.fn(),
useLastNotificationResponse: jest.fn(),
}))

jest.mock('../lib/api')
Expand Down
35 changes: 35 additions & 0 deletions src/screens/HomeScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import Toast from 'react-native-root-toast'
import { usePendingNotifications } from '../context/PendingNotificationsContext'
import { useSecrets } from '../context/SecretsContext'
import { useAuth } from '../context/AuthContext'
import { useInitialLoading } from '../context/InitalLoadingContext'
import apiFactory from '../lib/api'
import { NoSecrets } from '../components/NoSecrets'
import { Actions } from '../components/Actions'
Expand Down Expand Up @@ -47,6 +48,9 @@ export const HomeScreen: React.FC<HomeScreenProps> = ({ navigation }) => {
const isFocused = useIsFocused()
const notificationListener = useRef<Subscription>()
const responseListener = useRef<Subscription>()
const lastNotificationResponse = Notifications.useLastNotificationResponse()
const { initialLoadingComplete, markInitialLoadingComplete } =
useInitialLoading()

const api = useMemo(() => apiFactory({ idToken: user.idToken }), [user])

Expand Down Expand Up @@ -125,6 +129,37 @@ export const HomeScreen: React.FC<HomeScreenProps> = ({ navigation }) => {
}
}, [onNotification, onNotificationResponse])

useEffect(() => {
// runs callbacks when notification is pressed from a cold start
if (
!initialLoadingComplete &&
!secretsLoading &&
lastNotificationResponse
) {
const request = lastNotificationResponse.notification
.request as Notifications.NotificationRequest & {
content: { data: NotificationData }
}
const opticNotification: OpticNotification = {
date: lastNotificationResponse.notification.date,
request: request,
}

onNotificationResponse(lastNotificationResponse)
onNotification(opticNotification)

// prevents the cold start callbacks from being called again after this conditional has been triggered
markInitialLoadingComplete()
}
}, [
initialLoadingComplete,
lastNotificationResponse,
markInitialLoadingComplete,
onNotification,
onNotificationResponse,
secretsLoading,
])

if (secretsLoading) {
return null
}
Expand Down
Loading