Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Appearance: Manage Native Listener Count (Android) #46121

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
124 changes: 56 additions & 68 deletions packages/react-native/Libraries/Utilities/Appearance.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
*/

import NativeEventEmitter from '../EventEmitter/NativeEventEmitter';
import Platform from '../Utilities/Platform';
import EventEmitter, {
type EventSubscription,
} from '../vendor/emitter/EventEmitter';
Expand All @@ -29,79 +28,68 @@ type NativeAppearanceEventDefinitions = {
appearanceChanged: [AppearancePreferences],
};

if (NativeAppearance) {
const nativeEventEmitter =
new NativeEventEmitter<NativeAppearanceEventDefinitions>(
// T88715063: NativeEventEmitter only used this parameter on iOS. Now it uses it on all platforms, so this code was modified automatically to preserve its behavior
// If you want to use the native module on other platforms, please remove this condition and test its behavior
Platform.OS !== 'ios' ? null : NativeAppearance,
if (NativeAppearance != null) {
new NativeEventEmitter<NativeAppearanceEventDefinitions>(
NativeAppearance,
).addListener('appearanceChanged', (newAppearance: AppearancePreferences) => {
const {colorScheme} = newAppearance;
invariant(
colorScheme === 'dark' || colorScheme === 'light' || colorScheme == null,
"Unrecognized color scheme. Did you mean 'dark' or 'light'?",
);
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});
},
);
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 {
if (__DEV__) {
if (isAsyncDebugging) {
// Hard code light theme when using the async debugger as
// sync calls aren't supported
return 'light';
}
/**
* 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.
*/
export function getColorScheme(): ?ColorSchemeName {
if (__DEV__) {
if (isAsyncDebugging) {
// Hard code light theme when using the async debugger as
// sync calls aren't supported
return 'light';
}
}

// 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;
},
// 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;
}

setColorScheme(colorScheme: ?ColorSchemeName): void {
const nativeColorScheme = colorScheme == null ? 'unspecified' : colorScheme;
export function setColorScheme(colorScheme: ?ColorSchemeName): void {
const nativeColorScheme = colorScheme == null ? 'unspecified' : colorScheme;

invariant(
colorScheme === 'dark' || colorScheme === 'light' || colorScheme == null,
"Unrecognized color scheme. Did you mean 'dark', 'light' or null?",
);
invariant(
colorScheme === 'dark' || colorScheme === 'light' || colorScheme == null,
"Unrecognized color scheme. Did you mean 'dark', 'light' or null?",
);

if (NativeAppearance != null && NativeAppearance.setColorScheme != null) {
NativeAppearance.setColorScheme(nativeColorScheme);
}
},
if (NativeAppearance != null && NativeAppearance.setColorScheme != null) {
NativeAppearance.setColorScheme(nativeColorScheme);
}
}

/**
* Add an event handler that is fired when appearance preferences change.
*/
addChangeListener(listener: AppearanceListener): EventSubscription {
return eventEmitter.addListener('change', listener);
},
};
/**
* Add an event handler that is fired when appearance preferences change.
*/
export function addChangeListener(
listener: AppearanceListener,
): EventSubscription {
return eventEmitter.addListener('change', listener);
}
6 changes: 2 additions & 4 deletions packages/react-native/Libraries/Utilities/DevLoadingView.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
*/

import processColor from '../StyleSheet/processColor';
import Appearance from './Appearance';
import {getColorScheme} from './Appearance';
import NativeDevLoadingView from './NativeDevLoadingView';

const COLOR_SCHEME = {
Expand Down Expand Up @@ -39,9 +39,7 @@ module.exports = {
showMessage(message: string, type: 'load' | 'refresh') {
if (NativeDevLoadingView) {
const colorScheme =
Appearance.getColorScheme() === 'dark'
? COLOR_SCHEME.dark
: COLOR_SCHEME.default;
getColorScheme() === 'dark' ? COLOR_SCHEME.dark : COLOR_SCHEME.default;

const colorSet = colorScheme[type];

Expand Down
6 changes: 3 additions & 3 deletions packages/react-native/Libraries/Utilities/useColorScheme.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@

import type {ColorSchemeName} from './NativeAppearance';

import Appearance from './Appearance';
import {addChangeListener, getColorScheme} from './Appearance';
import {useSyncExternalStore} from 'react';

const subscribe = (onStoreChange: () => void) => {
const appearanceSubscription = Appearance.addChangeListener(onStoreChange);
const appearanceSubscription = addChangeListener(onStoreChange);
return () => appearanceSubscription.remove();
};

export default function useColorScheme(): ?ColorSchemeName {
return useSyncExternalStore(subscribe, Appearance.getColorScheme);
return useSyncExternalStore(subscribe, getColorScheme);
}
Original file line number Diff line number Diff line change
Expand Up @@ -9156,11 +9156,11 @@ declare export default typeof UTFSequence;

exports[`public API should not change unintentionally Libraries/Utilities/Appearance.js 1`] = `
"type AppearanceListener = (preferences: AppearancePreferences) => void;
declare module.exports: {
getColorScheme(): ?ColorSchemeName,
setColorScheme(colorScheme: ?ColorSchemeName): void,
addChangeListener(listener: AppearanceListener): EventSubscription,
};
declare export function getColorScheme(): ?ColorSchemeName;
declare export function setColorScheme(colorScheme: ?ColorSchemeName): void;
declare export function addChangeListener(
listener: AppearanceListener
): EventSubscription;
"
`;

Expand Down
2 changes: 1 addition & 1 deletion packages/react-native/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ import typeof StyleSheet from './Libraries/StyleSheet/StyleSheet';
import typeof Text from './Libraries/Text/Text';
import typeof * as TurboModuleRegistry from './Libraries/TurboModule/TurboModuleRegistry';
import typeof UTFSequence from './Libraries/UTFSequence';
import typeof Appearance from './Libraries/Utilities/Appearance';
import typeof * as Appearance from './Libraries/Utilities/Appearance';
import typeof BackHandler from './Libraries/Utilities/BackHandler';
import typeof DeviceInfo from './Libraries/Utilities/DeviceInfo';
import typeof DevSettings from './Libraries/Utilities/DevSettings';
Expand Down
Loading