fix: color scheme handling on mobile (#1902)
This commit is contained in:
19
packages/mobile/src/ColorSchemeObserverService.ts
Normal file
19
packages/mobile/src/ColorSchemeObserverService.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import { AbstractService, InternalEventBus, ReactNativeToWebEvent } from '@standardnotes/snjs'
|
||||
import { Appearance, NativeEventSubscription } from 'react-native'
|
||||
|
||||
export class ColorSchemeObserverService extends AbstractService<ReactNativeToWebEvent> {
|
||||
private removeListener: NativeEventSubscription
|
||||
|
||||
constructor() {
|
||||
const internalEventBus = new InternalEventBus()
|
||||
super(internalEventBus)
|
||||
|
||||
this.removeListener = Appearance.addChangeListener(() => {
|
||||
void this.notifyEvent(ReactNativeToWebEvent.ColorSchemeChanged)
|
||||
})
|
||||
}
|
||||
|
||||
deinit() {
|
||||
this.removeListener.remove()
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,18 @@ import {
|
||||
TransferPayload,
|
||||
UuidString,
|
||||
} from '@standardnotes/snjs'
|
||||
import { Alert, AppState, AppStateStatus, Linking, PermissionsAndroid, Platform, StatusBar } from 'react-native'
|
||||
import { ColorSchemeObserverService } from 'ColorSchemeObserverService'
|
||||
import {
|
||||
Alert,
|
||||
Appearance,
|
||||
AppState,
|
||||
AppStateStatus,
|
||||
ColorSchemeName,
|
||||
Linking,
|
||||
PermissionsAndroid,
|
||||
Platform,
|
||||
StatusBar,
|
||||
} from 'react-native'
|
||||
import FileViewer from 'react-native-file-viewer'
|
||||
import FingerprintScanner from 'react-native-fingerprint-scanner'
|
||||
import FlagSecure from 'react-native-flag-secure-android'
|
||||
@@ -85,6 +96,7 @@ export class MobileDevice implements MobileDeviceInterface {
|
||||
constructor(
|
||||
private stateObserverService?: AppStateObserverService,
|
||||
private androidBackHandlerService?: AndroidBackHandlerService,
|
||||
private colorSchemeService?: ColorSchemeObserverService,
|
||||
) {}
|
||||
|
||||
deinit() {
|
||||
@@ -92,6 +104,8 @@ export class MobileDevice implements MobileDeviceInterface {
|
||||
;(this.stateObserverService as unknown) = undefined
|
||||
this.androidBackHandlerService?.deinit()
|
||||
;(this.androidBackHandlerService as unknown) = undefined
|
||||
this.colorSchemeService?.deinit()
|
||||
;(this.colorSchemeService as unknown) = undefined
|
||||
}
|
||||
|
||||
consoleLog(...args: any[]): void {
|
||||
@@ -616,4 +630,8 @@ export class MobileDevice implements MobileDeviceInterface {
|
||||
async getAppState(): Promise<AppStateStatus> {
|
||||
return AppState.currentState
|
||||
}
|
||||
|
||||
async getColorScheme(): Promise<ColorSchemeName> {
|
||||
return Appearance.getColorScheme()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { ReactNativeToWebEvent } from '@standardnotes/snjs'
|
||||
import { ColorSchemeObserverService } from './ColorSchemeObserverService'
|
||||
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
||||
import { Keyboard, Platform } from 'react-native'
|
||||
import VersionInfo from 'react-native-version-info'
|
||||
@@ -28,9 +29,10 @@ const MobileWebAppContents = ({ destroyAndReload }: { destroyAndReload: () => vo
|
||||
const sourceUri = (Platform.OS === 'android' ? 'file:///android_asset/' : '') + 'Web.bundle/src/index.html'
|
||||
const stateService = useMemo(() => new AppStateObserverService(), [])
|
||||
const androidBackHandlerService = useMemo(() => new AndroidBackHandlerService(), [])
|
||||
const colorSchemeService = useMemo(() => new ColorSchemeObserverService(), [])
|
||||
const device = useMemo(
|
||||
() => new MobileDevice(stateService, androidBackHandlerService),
|
||||
[androidBackHandlerService, stateService],
|
||||
() => new MobileDevice(stateService, androidBackHandlerService, colorSchemeService),
|
||||
[androidBackHandlerService, colorSchemeService, stateService],
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
@@ -44,6 +46,10 @@ const MobileWebAppContents = ({ destroyAndReload }: { destroyAndReload: () => vo
|
||||
},
|
||||
)
|
||||
|
||||
const removeColorSchemeServiceListener = colorSchemeService.addEventObserver((event: ReactNativeToWebEvent) => {
|
||||
webViewRef.current?.postMessage(JSON.stringify({ reactNativeEvent: event, messageType: 'event' }))
|
||||
})
|
||||
|
||||
const keyboardShowListener = Keyboard.addListener('keyboardWillShow', () => {
|
||||
device.reloadStatusBarStyle(false)
|
||||
})
|
||||
@@ -55,10 +61,11 @@ const MobileWebAppContents = ({ destroyAndReload }: { destroyAndReload: () => vo
|
||||
return () => {
|
||||
removeStateServiceListener()
|
||||
removeBackHandlerServiceListener()
|
||||
removeColorSchemeServiceListener()
|
||||
keyboardShowListener.remove()
|
||||
keyboardHideListener.remove()
|
||||
}
|
||||
}, [webViewRef, stateService, device, androidBackHandlerService])
|
||||
}, [webViewRef, stateService, device, androidBackHandlerService, colorSchemeService])
|
||||
|
||||
useEffect(() => {
|
||||
const observer = device.addMobileWebEventReceiver((event) => {
|
||||
|
||||
Reference in New Issue
Block a user