From 0bd931e47e95544a303bc0aee7a206f8b22ac056 Mon Sep 17 00:00:00 2001 From: Kevin Gozali Date: Mon, 15 Apr 2019 12:07:04 -0700 Subject: [PATCH] TM: Added TurboModuleExample in RNTester Summary: This showcases SampleTurboModule usage in RNTester. Notes: * iOS only for now, and you must use cocoapods version. * You cannot use Chrome debugger when loading this specific example. As illustrated in the example, the callsite should access `NativeSampleTurboModule` to access the native side. {F155901711} Reviewed By: cpojer Differential Revision: D14932537 fbshipit-source-id: a733e1cd3b642b9e572d5ac6347f4775d495578a --- .../react-native-implementation.js | 3 + RNTester/js/RNTesterList.ios.js | 5 + RNTester/js/SampleTurboModuleExample.js | 177 ++++++++++++++++++ RNTester/js/TurboModuleExample.js | 26 +++ 4 files changed, 211 insertions(+) create mode 100644 RNTester/js/SampleTurboModuleExample.js create mode 100644 RNTester/js/TurboModuleExample.js diff --git a/Libraries/react-native/react-native-implementation.js b/Libraries/react-native/react-native-implementation.js index 143eb9df8f..6303313b02 100644 --- a/Libraries/react-native/react-native-implementation.js +++ b/Libraries/react-native/react-native-implementation.js @@ -301,6 +301,9 @@ module.exports = { get ToastAndroid() { return require('ToastAndroid'); }, + get TurboModuleRegistry() { + return require('TurboModuleRegistry'); + }, get TVEventHandler() { return require('TVEventHandler'); }, diff --git a/RNTester/js/RNTesterList.ios.js b/RNTester/js/RNTesterList.ios.js index 55436071f1..b5d38ee0c1 100644 --- a/RNTester/js/RNTesterList.ios.js +++ b/RNTester/js/RNTesterList.ios.js @@ -311,6 +311,11 @@ const APIExamples: Array = [ module: require('./TransformExample'), supportsTVOS: true, }, + { + key: 'TurboModuleExample', + module: require('./TurboModuleExample'), + supportsTVOS: false, + }, { key: 'TVEventHandlerExample', module: require('./TVEventHandlerExample'), diff --git a/RNTester/js/SampleTurboModuleExample.js b/RNTester/js/SampleTurboModuleExample.js new file mode 100644 index 0000000000..257aa0f206 --- /dev/null +++ b/RNTester/js/SampleTurboModuleExample.js @@ -0,0 +1,177 @@ +/** + * 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 NativeSampleTurboModule from 'NativeSampleTurboModule'; +import { + StyleSheet, + Text, + View, + FlatList, + Platform, + TouchableOpacity, +} from 'react-native'; +import * as React from 'react'; + +type State = {| + testResults: {[string]: {type: string, value: mixed}}, +|}; + +class SampleTurboModuleExample extends React.Component<{||}, State> { + state: State = { + testResults: {}, + }; + + // Add calls to methods in TurboModule here + _tests = { + callback: () => + NativeSampleTurboModule.getValueWithCallback(callbackValue => + this._setResult('callback', callbackValue), + ), + promise: () => + NativeSampleTurboModule.getValueWithPromise(false).then(valuePromise => + this._setResult('promise', valuePromise), + ), + rejectPromise: () => + NativeSampleTurboModule.getValueWithPromise(true) + .then(() => {}) + .catch(e => this._setResult('rejectPromise', e.message)), + getConstants: () => NativeSampleTurboModule.getConstants(), + voidFunc: () => NativeSampleTurboModule.voidFunc(), + getBool: () => NativeSampleTurboModule.getBool(true), + getNumber: () => NativeSampleTurboModule.getNumber(99.95), + getString: () => NativeSampleTurboModule.getString('Hello'), + getArray: () => + NativeSampleTurboModule.getArray([ + {a: 1, b: 'foo'}, + {a: 2, b: 'bar'}, + null, + ]), + getObject: () => + NativeSampleTurboModule.getObject({a: 1, b: 'foo', c: null}), + getValue: () => + NativeSampleTurboModule.getValue(5, 'test', {a: 1, b: 'foo'}), + }; + + _setResult(name, result) { + this.setState(({testResults}) => ({ + testResults: { + ...testResults, + [name]: {value: result, type: typeof result}, + }, + })); + } + + _renderResult(name) { + const result = this.state.testResults[name] || {}; + return ( + + {JSON.stringify(result.value)} + {result.type} + + ); + } + + componentDidMount() { + if (global.__turboModuleProxy == null) { + throw new Error( + 'Cannot load this example because TurboModule is not configured.', + ); + } + if (Platform.OS === 'ios') { + // iOS is fully implemented, so show all results immediately. + Object.keys(this._tests).forEach(item => + this._setResult(item, this._tests[item]()), + ); + } + } + + render(): React.Node { + return ( + + + + Object.keys(this._tests).forEach(item => + this._setResult(item, this._tests[item]()), + ) + }> + Run all tests + + this.setState({testResults: {}})} + style={[styles.column, styles.button]}> + Clear results + + + item} + renderItem={({item}) => ( + + this._setResult(item, this._tests[item]())}> + {item} + + {this._renderResult(item)} + + )} + /> + + ); + } +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + }, + item: { + flexDirection: 'row', + margin: 6, + }, + column: { + flex: 2, + justifyContent: 'center', + padding: 3, + }, + result: { + alignItems: 'stretch', + justifyContent: 'space-between', + }, + value: { + fontFamily: Platform.OS === 'ios' ? 'Menlo' : 'monospace', + fontSize: 12, + }, + type: { + color: '#333', + fontSize: 10, + }, + button: { + borderColor: '#444', + padding: 3, + flex: 1, + }, + buttonTextLarge: { + textAlign: 'center', + color: 'rgb(0,122,255)', + fontSize: 16, + padding: 6, + }, + buttonText: { + color: 'rgb(0,122,255)', + textAlign: 'center', + }, +}); + +module.exports = SampleTurboModuleExample; diff --git a/RNTester/js/TurboModuleExample.js b/RNTester/js/TurboModuleExample.js new file mode 100644 index 0000000000..9b841e9bca --- /dev/null +++ b/RNTester/js/TurboModuleExample.js @@ -0,0 +1,26 @@ +/** + * 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'; + +const React = require('react'); +const SampleTurboModuleExample = require('SampleTurboModuleExample'); + +exports.displayName = (undefined: ?string); +exports.title = 'TurboModule'; +exports.description = 'Usage of TurboModule'; +exports.examples = [ + { + title: 'SampleTurboModule', + render: function(): React.Element { + return ; + }, + }, +];