Implementing AccessibilityInfo.DisplayOptions ex: isInvertColorsEnabled (#455)

* Attempting to add isVoiceOverEnabled to macOS

* removing console.log

* Removed Merge conflicts

* Resolved merge conflict

* Removed comments/notes

* Removed comments/notes

* Added Features and encorporated into test app

* Removed logging

* Fixed mistakes in PR

* Changing name to DisplayOptions

* Removing extra newlines

* Adding linting fixes

* Added Notifaction unsubscribe to dealloc

* Lowercased selector to fit obj-c convention

* uncommented unsubscription

* Added TODOs around diff

* Put ScreenReaderStatus back in it's own component

* Lint fix
This commit is contained in:
Matthew Gray 2020-06-18 18:19:18 -07:00 коммит произвёл GitHub
Родитель c896feff73
Коммит 84f277ab23
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
3 изменённых файлов: 199 добавлений и 6 удалений

Просмотреть файл

@ -20,11 +20,17 @@ import NativeAccessibilityManager from './NativeAccessibilityManager';
const warning = require('fbjs/lib/warning');
const CHANGE_EVENT_NAME = {
invertColorsChanged: 'invertColorsChanged',
reduceMotionChanged: 'reduceMotionChanged',
reduceTransparencyChanged: 'reduceTransparencyChanged',
screenReaderChanged: 'screenReaderChanged',
};
type ChangeEventName = $Keys<{
change: string,
invertColorsChanged: string,
reduceMotionChanged: string,
reduceTransparencyChanged: string,
screenReaderChanged: string,
}>;
@ -45,24 +51,60 @@ const AccessibilityInfo = {
},
/**
* iOS only
* Query whether inverted colors are currently enabled.
*
* Returns a promise which resolves to a boolean.
* The result is `true` when invert color is enabled and `false` otherwise.
*
* See http://facebook.github.io/react-native/docs/accessibilityinfo.html#isInvertColorsEnabled
*/
isInvertColorsEnabled: function(): Promise<boolean> {
return Promise.resolve(false);
return new Promise((resolve, reject) => {
if (NativeAccessibilityManager) {
NativeAccessibilityManager.getCurrentInvertColorsState(resolve, reject);
} else {
reject(reject);
}
});
},
/**
* Android and iOS only
* Query whether reduced motion is currently enabled.
*
* Returns a promise which resolves to a boolean.
* The result is `true` when a reduce motion is enabled and `false` otherwise.
*
* See http://facebook.github.io/react-native/docs/accessibilityinfo.html#isReduceMotionEnabled
*/
isReduceMotionEnabled: function(): Promise<boolean> {
return Promise.resolve(false);
return new Promise((resolve, reject) => {
if (NativeAccessibilityManager) {
NativeAccessibilityManager.getCurrentReduceMotionState(resolve, reject);
} else {
reject(reject);
}
});
},
/**
* iOS only
* Query whether reduced transparency is currently enabled.
*
* Returns a promise which resolves to a boolean.
* The result is `true` when a reduce transparency is enabled and `false` otherwise.
*
* See http://facebook.github.io/react-native/docs/accessibilityinfo.html#isReduceTransparencyEnabled
*/
isReduceTransparencyEnabled: function(): Promise<boolean> {
return Promise.resolve(false);
return new Promise((resolve, reject) => {
if (NativeAccessibilityManager) {
NativeAccessibilityManager.getCurrentReduceTransparencyState(
resolve,
reject,
);
} else {
reject(reject);
}
});
},
/**

Просмотреть файл

@ -553,7 +553,101 @@ class ScreenReaderStatusExample extends React.Component<{}> {
);
}
}
// [TODO(OSS Candidate ISS#2710739)
class DisplayOptionsStatusExample extends React.Component<{}> {
state = {};
componentDidMount() {
AccessibilityInfo.addEventListener(
'invertColorsChanged',
this._handleInvertColorsToggled,
);
AccessibilityInfo.isInvertColorsEnabled().done(isEnabled => {
this.setState({
invertColorsEnabled: isEnabled,
});
});
AccessibilityInfo.addEventListener(
'reduceMotionChanged',
this._handleReduceMotionToggled,
);
AccessibilityInfo.isReduceMotionEnabled().done(isEnabled => {
this.setState({
reduceMotionEnabled: isEnabled,
});
});
AccessibilityInfo.addEventListener(
'reduceTransparencyChanged',
this._handleReduceTransparencyToggled,
);
AccessibilityInfo.isReduceTransparencyEnabled().done(isEnabled => {
this.setState({
reduceTransparencyEnabled: isEnabled,
});
});
}
componentWillUnmount() {
AccessibilityInfo.removeEventListener(
'invertColorsChanged',
this._handleInvertColorsToggled,
);
AccessibilityInfo.removeEventListener(
'reduceMotionChanged',
this._handleReduceMotionToggled,
);
AccessibilityInfo.removeEventListener(
'reduceTransparencyChanged',
this._handleReduceTransparencyToggled,
);
}
_handleInvertColorsToggled = isEnabled => {
this.setState({
invertColorsEnabled: isEnabled,
});
};
_handleReduceMotionToggled = isEnabled => {
this.setState({
reduceMotionEnabled: isEnabled,
});
};
_handleReduceTransparencyToggled = isEnabled => {
this.setState({
reduceTransparencyEnabled: isEnabled,
});
};
render() {
return (
<View>
<View>
<Text>
Invert colors is{' '}
{this.state.invertColorsEnabled ? 'enabled' : 'disabled'}.
</Text>
</View>
<View>
<Text>
Reduce motion is{' '}
{this.state.reduceMotionEnabled ? 'enabled' : 'disabled'}.
</Text>
</View>
<View>
<Text>
Reduce transparency is{' '}
{this.state.reduceTransparencyEnabled ? 'enabled' : 'disabled'}.
</Text>
</View>
</View>
);
}
}
// ]TODO(OSS Candidate ISS#2710739)
class AnnounceForAccessibility extends React.Component<{}> {
_handleOnPress = () =>
AccessibilityInfo.announceForAccessibility('Announcement Test');
@ -617,6 +711,14 @@ exports.examples = [
return <ScreenReaderStatusExample />;
},
},
// [TODO(OSS Candidate ISS#2710739)
{
title: 'Check if the display options are enabled',
render(): React.Element<typeof DisplayOptionsStatusExample> {
return <DisplayOptionsStatusExample />;
},
},
// ]TODO(OSS Candidate ISS#2710739)
{
title: 'Check if the screen reader announces',
render(): React.Element<typeof AnnounceForAccessibility> {

Просмотреть файл

@ -35,7 +35,15 @@ static void *AccessibilityVoiceOverChangeContext = &AccessibilityVoiceOverChange
forKeyPath:@"voiceOverEnabled"
options:(NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld)
context:AccessibilityVoiceOverChangeContext];
[[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self
selector:@selector(accessibilityDisplayOptionsChange:)
name:NSWorkspaceAccessibilityDisplayOptionsDidChangeNotification
object:nil];
_isInvertColorsEnabled = [[NSWorkspace sharedWorkspace] accessibilityDisplayShouldInvertColors];
_isReduceMotionEnabled = [[NSWorkspace sharedWorkspace] accessibilityDisplayShouldReduceMotion];
_isReduceTransparencyEnabled = [[NSWorkspace sharedWorkspace] accessibilityDisplayShouldReduceTransparency];
_isVoiceOverEnabled = [[NSWorkspace sharedWorkspace] isVoiceOverEnabled];
}
return self;
}
@ -45,6 +53,25 @@ static void *AccessibilityVoiceOverChangeContext = &AccessibilityVoiceOverChange
[[NSWorkspace sharedWorkspace] removeObserver:self
forKeyPath:@"voiceOverEnabled"
context:AccessibilityVoiceOverChangeContext];
[[[NSWorkspace sharedWorkspace] notificationCenter] removeObserver:self];
}
RCT_EXPORT_METHOD(getCurrentInvertColorsState:(RCTResponseSenderBlock)callback
error:(__unused RCTResponseSenderBlock)error)
{
callback(@[@(_isInvertColorsEnabled)]);
}
RCT_EXPORT_METHOD(getCurrentReduceMotionState:(RCTResponseSenderBlock)callback
error:(__unused RCTResponseSenderBlock)error)
{
callback(@[@(_isReduceMotionEnabled)]);
}
RCT_EXPORT_METHOD(getCurrentReduceTransparencyState:(RCTResponseSenderBlock)callback
error:(__unused RCTResponseSenderBlock)error)
{
callback(@[@(_isReduceTransparencyEnabled)]);
}
RCT_EXPORT_METHOD(getCurrentVoiceOverState:(RCTResponseSenderBlock)callback
@ -84,4 +111,26 @@ RCT_EXPORT_METHOD(setAccessibilityFocus:(nonnull NSNumber *)reactTag)
}
}
- (void)accessibilityDisplayOptionsChange:(NSNotification *)notification
{
BOOL newInvertColorsEnabled = [[NSWorkspace sharedWorkspace] accessibilityDisplayShouldInvertColors];
BOOL newReduceMotionEnabled = [[NSWorkspace sharedWorkspace] accessibilityDisplayShouldReduceMotion];
BOOL newReduceTransparencyEnabled = [[NSWorkspace sharedWorkspace] accessibilityDisplayShouldReduceTransparency];
if (_isInvertColorsEnabled != newInvertColorsEnabled) {
_isInvertColorsEnabled = newInvertColorsEnabled;
[_bridge.eventDispatcher sendDeviceEventWithName:@"invertColorsChanged"
body:@(_isInvertColorsEnabled)];
}
if (_isReduceMotionEnabled != newReduceMotionEnabled) {
_isReduceMotionEnabled = newReduceMotionEnabled;
[_bridge.eventDispatcher sendDeviceEventWithName:@"reduceMotionChanged"
body:@(_isReduceMotionEnabled)];
}
if (_isReduceTransparencyEnabled != newReduceTransparencyEnabled) {
_isReduceTransparencyEnabled = newReduceTransparencyEnabled;
[_bridge.eventDispatcher sendDeviceEventWithName:@"reduceTransparencyChanged"
body:@(_isReduceTransparencyEnabled)];
}
}
@end