one
Version:
One is a React framework for web, iOS, and Android apps.
61 lines (53 loc) • 1.85 kB
text/typescript
import { useEffect, useState } from 'react'
import { NitroModules } from 'react-native-nitro-modules'
import { rethrowNativeError } from '../nativeError'
import type { OneNetwork } from '../specs/OneNetwork.nitro'
import type { NetworkState, NetworkStateSubscription } from './types'
import { assertStateListener } from './validate'
export type { NetworkState, NetworkStateSubscription, NetworkStateType } from './types'
// connection state matching expo-network: a one-shot read plus a change
// listener, backed by the OneNetwork nitro hybrid object (created on first
// use and cached). the first listener starts the native monitor, so the
// first event can never race the subscription.
let hybrid: OneNetwork | undefined
function native(): OneNetwork {
hybrid ??= NitroModules.createHybridObject<OneNetwork>('OneNetwork')
return hybrid
}
function getState(): Promise<NetworkState> {
return native().getState().catch(rethrowNativeError)
}
function addStateListener(
listener: (state: NetworkState) => void
): NetworkStateSubscription {
assertStateListener(listener)
const remove = native().addStateListener(listener)
return { remove: () => remove() }
}
function useNetworkState(): NetworkState {
const [state, setState] = useState<NetworkState>({
type: 'unknown',
isConnected: false,
isInternetReachable: false,
})
useEffect(() => {
let active = true
let sawEvent = false
getState()
.then((next) => {
if (active && !sawEvent) setState(next)
})
.catch(() => {})
const subscription = addStateListener((next) => {
sawEvent = true
if (active) setState(next)
})
return () => {
active = false
subscription.remove()
}
}, [])
return state
}
export const Network = Object.freeze({ getState, addStateListener })
export { useNetworkState }