Files
react-native/Libraries/Utilities/Appearance.js
T
Kevin Gozali f15309fa15 Appearance: stop caching colorScheme in JS
Summary:
At times, the OS updates the color scheme without any active listener on RN side, e.g. if all RCTRootView's in iOS have been deallocated, no one will tell JS that the color scheme changes. So let's just always ask native side for the latest value.

Changelog: [Internal]

Reviewed By: yungsters

Differential Revision: D18117334

fbshipit-source-id: e8564fb284c5720061592ba72e5b4907e5b48853
2019-10-24 11:09:10 -07:00

79 lines
2.4 KiB
JavaScript

/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
* @flow
*/
'use strict';
import EventEmitter from '../vendor/emitter/EventEmitter';
import NativeEventEmitter from '../EventEmitter/NativeEventEmitter';
import NativeAppearance, {
type AppearancePreferences,
type ColorSchemeName,
} from './NativeAppearance';
import invariant from 'invariant';
type AppearanceListener = (preferences: AppearancePreferences) => void;
const eventEmitter = new EventEmitter();
if (NativeAppearance) {
const nativeEventEmitter = new NativeEventEmitter(NativeAppearance);
nativeEventEmitter.addListener(
'appearanceChanged',
(newAppearance: AppearancePreferences) => {
const {colorScheme} = newAppearance;
invariant(
colorScheme === 'dark' ||
colorScheme === 'light' ||
colorScheme == null,
"Unrecognized color scheme. Did you mean 'dark' or 'light'?",
);
eventEmitter.emit('change', {colorScheme});
},
);
}
module.exports = {
/**
* Note: Although color scheme is available immediately, it may change at any
* time. Any rendering logic or styles that depend on this should try to call
* this function on every render, rather than caching the value (for example,
* using inline styles rather than setting a value in a `StyleSheet`).
*
* Example: `const colorScheme = Appearance.getColorScheme();`
*
* @returns {?ColorSchemeName} Value for the color scheme preference.
*/
getColorScheme(): ?ColorSchemeName {
// TODO: (hramos) T52919652 Use ?ColorSchemeName once codegen supports union
const nativeColorScheme: ?string =
NativeAppearance == null
? null
: NativeAppearance.getColorScheme() || null;
invariant(
nativeColorScheme === 'dark' ||
nativeColorScheme === 'light' ||
nativeColorScheme == null,
"Unrecognized color scheme. Did you mean 'dark' or 'light'?",
);
return nativeColorScheme;
},
/**
* Add an event handler that is fired when appearance preferences change.
*/
addChangeListener(listener: AppearanceListener): void {
eventEmitter.addListener('change', listener);
},
/**
* Remove an event handler.
*/
removeChangeListener(listener: AppearanceListener): void {
eventEmitter.removeListener('change', listener);
},
};