Skip to content

Commit 04a2138

Browse files
authored
Merge pull request #109 from oasisprotocol/lw/block-navigating
Block soft and hard navigating away while creating an app
2 parents 00ad155 + 3628edb commit 04a2138

File tree

3 files changed

+53
-1
lines changed

3 files changed

+53
-1
lines changed

src/backend/api.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { useConfig, useSendTransaction } from 'wagmi'
1111
import { waitForTransactionReceipt } from '@wagmi/core'
1212
import { ViewMetadataState, ViewSecretsState } from '../pages/Dashboard/AppDetails/types'
1313
import { useState } from 'react'
14+
import { useBlockNavigatingAway } from '../pages/CreateApp/useBlockNavigatingAway'
1415

1516
const BACKEND_URL = import.meta.env.VITE_ROFL_APP_BACKEND
1617

@@ -207,6 +208,7 @@ async function waitForBuildResults(taskId: string, token: string, timeout = 600_
207208
}
208209

209210
export function useCreateAndDeployApp() {
211+
const { blockNavigatingAway, allowNavigatingAway } = useBlockNavigatingAway()
210212
const wagmiConfig = useConfig()
211213
const { sendTransactionAsync } = useSendTransaction()
212214
const steps = ['creating', 'building', 'updating', 'deploying'] as const
@@ -227,7 +229,11 @@ export function useCreateAndDeployApp() {
227229
AxiosError<unknown>,
228230
{ token: string; template: Template; appData: AppData; network: 'mainnet' | 'testnet' }
229231
>({
232+
onSettled() {
233+
allowNavigatingAway()
234+
},
230235
mutationFn: async ({ token, template, appData, network }) => {
236+
blockNavigatingAway()
231237
const sapphireRuntimeId =
232238
network === 'mainnet'
233239
? oasis.misc.fromHex('000000000000000000000000000000000000000000000000f80306c9858e7279')

src/contexts/RoflAppBackendAuth/Provider.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ export function RoflAppBackendAuthProvider({ children }: { children: ReactNode }
1414

1515
const [token, _setToken] = useState<string | null>(
1616
// TODO: possibly already expired or from another account. Currently detected by useInterval within a few seconds.
17-
window.localStorage.getItem('jwt')
17+
window.localStorage.getItem('jwt'),
1818
)
1919
const [isLoading, setIsLoading] = useState(false)
2020
const [error, setError] = useState<string | null>(null)
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import { useEffect, useState } from 'react'
2+
import { useBlocker } from 'react-router-dom'
3+
4+
let globalIsBlocking = false // If useBlockNavigatingAway gets destroyed, load state from this.
5+
6+
const beforeUnloadHandler = (event: BeforeUnloadEvent) => {
7+
event.preventDefault()
8+
// Included for legacy support, e.g. Chrome/Edge < 119
9+
event.returnValue = true
10+
}
11+
12+
export function useBlockNavigatingAway() {
13+
const [reactiveIsBlocking, setReactiveIsBlocking] = useState(globalIsBlocking)
14+
const reactRouterBlocker = useBlocker(() => reactiveIsBlocking) // Blocks soft navigation away
15+
// TODO can't have two blockers
16+
17+
function blockNavigatingAway() {
18+
window.addEventListener('beforeunload', beforeUnloadHandler) // Blocks hard navigation away
19+
setReactiveIsBlocking(true)
20+
globalIsBlocking = true
21+
}
22+
23+
function allowNavigatingAway() {
24+
window.removeEventListener('beforeunload', beforeUnloadHandler)
25+
setReactiveIsBlocking(false)
26+
globalIsBlocking = false
27+
}
28+
29+
useEffect(() => {
30+
if (reactRouterBlocker.state === 'blocked') {
31+
if (window.confirm('You are navigating away. Progress you made may not be saved.')) {
32+
reactRouterBlocker.proceed()
33+
allowNavigatingAway()
34+
} else {
35+
reactRouterBlocker.reset()
36+
}
37+
}
38+
// eslint-disable-next-line react-hooks/exhaustive-deps
39+
}, [reactRouterBlocker.state])
40+
41+
return {
42+
isBlockingNavigatingAway: reactiveIsBlocking,
43+
blockNavigatingAway,
44+
allowNavigatingAway,
45+
}
46+
}

0 commit comments

Comments
 (0)