Files
standardnotes-app-web/packages/mobile/src/AppStateObserverService.ts
2022-09-19 14:47:15 -05:00

63 lines
2.1 KiB
TypeScript

import { AbstractService, InternalEventBus, ReactNativeToWebEvent } from '@standardnotes/snjs'
import { AppState, AppStateStatus, NativeEventSubscription } from 'react-native'
export class AppStateObserverService extends AbstractService<ReactNativeToWebEvent> {
private mostRecentState?: ReactNativeToWebEvent
private removeListener: NativeEventSubscription
private ignoringStateChanges = false
constructor() {
const bus = new InternalEventBus()
super(bus)
this.removeListener = AppState.addEventListener('change', async (nextAppState: AppStateStatus) => {
if (this.ignoringStateChanges) {
return
}
// if the most recent state is not 'background' ('inactive'), then we're going
// from inactive to active, which doesn't really happen unless you, say, swipe
// notification center in iOS down then back up. We don't want to lock on this state change.
const isResuming = nextAppState === 'active'
const isResumingFromBackground = isResuming && this.mostRecentState === ReactNativeToWebEvent.EnteringBackground
const isEnteringBackground = nextAppState === 'background'
const isLosingFocus = nextAppState === 'inactive'
if (isEnteringBackground) {
this.notifyStateChange(ReactNativeToWebEvent.EnteringBackground)
}
if (isResumingFromBackground || isResuming) {
if (isResumingFromBackground) {
this.notifyStateChange(ReactNativeToWebEvent.ResumingFromBackground)
}
// Notify of GainingFocus even if resuming from background
this.notifyStateChange(ReactNativeToWebEvent.GainingFocus)
return
}
if (isLosingFocus) {
this.notifyStateChange(ReactNativeToWebEvent.LosingFocus)
}
})
}
beginIgnoringStateChanges() {
this.ignoringStateChanges = true
}
stopIgnoringStateChanges() {
this.ignoringStateChanges = false
}
deinit() {
this.removeListener.remove()
}
private notifyStateChange(state: ReactNativeToWebEvent): void {
this.mostRecentState = state
void this.notifyEvent(state)
}
}