Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3a223e970e | ||
|
|
6f48d9a30d | ||
|
|
46aa9c60db | ||
|
|
7b5c140328 | ||
|
|
915a2c4b5f | ||
|
|
e8753caf75 | ||
|
|
0b76e2a436 | ||
|
|
444712052a | ||
|
|
035c181e77 |
@@ -1,13 +0,0 @@
|
||||
|
||||
[android]
|
||||
target = android-31
|
||||
|
||||
[download]
|
||||
max_number_of_retries = 3
|
||||
|
||||
[maven_repositories]
|
||||
central = https://repo1.maven.org/maven2
|
||||
google = https://maven.google.com/
|
||||
|
||||
[alias]
|
||||
rntester = //packages/rn-tester/android/app:app
|
||||
@@ -1 +0,0 @@
|
||||
-Xmx512m -XX:+HeapDumpOnOutOfMemoryError
|
||||
@@ -1,2 +0,0 @@
|
||||
BUNDLE_PATH: "vendor/bundle"
|
||||
BUNDLE_FORCE_RUBY_PLATFORM: 1
|
||||
@@ -1,81 +0,0 @@
|
||||
# Docker Test Environment
|
||||
|
||||
This is a high-level overview of the test configuration using Docker.
|
||||
It explains how to run the tests locally.
|
||||
|
||||
## Docker Installation
|
||||
|
||||
It is required to have Docker running on your machine in order to build and run the tests in the Dockerfiles.
|
||||
See <https://docs.docker.com/engine/installation/> for more information on how to install.
|
||||
|
||||
## Convenience Scripts
|
||||
|
||||
We have added a number of default run scripts to the `package.json` file to simplify building and running your tests.
|
||||
|
||||
### Configuring Docker Images
|
||||
|
||||
The following two scripts need to be run first before you can move on to testing:
|
||||
|
||||
- `yarn run docker-setup-android`: Pulls down the React Native Community Android image that serves as a base image when building the actual test image.
|
||||
|
||||
- `yarn run docker-build-android`: Builds a test image with the latest dependencies and React Native library code, including a compiled Android test app.
|
||||
|
||||
### Running Tests
|
||||
|
||||
Once the test image has been built, it can be used to run our Android tests.
|
||||
|
||||
- `yarn run test-android-run-unit` runs the unit tests, as defined in `scripts/run-android-docker-unit-tests.sh`.
|
||||
- `yarn run test-android-run-e2e` runs the end to end tests, as defined in `scripts/run-ci-e2e-tests.sh`.
|
||||
- `yarn run test-android-run-instrumentation` runs the instrumentation tests, as defined in `scripts/run-android-docker-instrumentation-tests.sh`.
|
||||
|
||||
#### Instrumentation Tests
|
||||
|
||||
The instrumentation test script accepts the following flags in order to customize the execution of the tests:
|
||||
|
||||
`--filter` - A regex that filters which instrumentation tests will be run. (Defaults to .*)
|
||||
|
||||
`--package` - Name of the java package containing the instrumentation tests (Defaults to com.facebook.react.tests)
|
||||
|
||||
`--path` - Path to the directory containing the instrumentation tests. (Defaults to ./ReactAndroid/src/androidTest/java/com/facebook/react/tests)
|
||||
|
||||
`--retries` - Number of times to retry a failed test before declaring a failure (Defaults to 2)
|
||||
|
||||
For example, if locally you only wanted to run the InitialPropsTestCase, you could do the following:
|
||||
`yarn run test-android-run-instrumentation -- --filter="InitialPropsTestCase"`
|
||||
|
||||
## Detailed Android Setup
|
||||
|
||||
There are two Dockerfiles for use with the Android codebase.
|
||||
The base image used to build `reactnativecommunity/react-native-android` is located in the https://github.com/react-native-community/docker-android GitHub repository.
|
||||
It contains all the necessary prerequisites required to run the React Android tests.
|
||||
It is separated out into a separate Dockerfile because these are dependencies that rarely change and also because it is quite a beastly image since it contains all the Android dependencies for running Android and the emulators (~9GB).
|
||||
|
||||
The good news is you should rarely have to build or pull down the base image!
|
||||
All iterative code updates happen as part of the `Dockerfile.android` image build.
|
||||
|
||||
Lets break it down...
|
||||
|
||||
First, you'll need to pull the base image.
|
||||
You can use `docker pull` to grab the latest version of the `reactnativecommunity/react-native-android` base image.
|
||||
This is what you get when you run `yarn run docker-setup-android`.
|
||||
|
||||
This will take quite some time depending on your connection and you need to ensure you have ~10GB of free disk space.
|
||||
|
||||
Once you have downloaded the base image, the test image can be built using `docker build -t reactnativeci/android -f ./.circleci/Dockerfiles/Dockerfile.android .`. This is what `yarn run docker-build-android` does. Note that the `-t` flag is how you tell Docker what to name this image locally. You can then use `docker run -t reactnativeci/android` to run this image.
|
||||
|
||||
Now that you've built the test image, you can run unit tests using what you've learned so far:
|
||||
|
||||
```bash
|
||||
docker run --cap-add=SYS_ADMIN -it reactnativeci/android bash .circleci/Dockerfiles/scripts/run-android-docker-unit-tests.sh
|
||||
```
|
||||
|
||||
> Note: `--cap-add=SYS_ADMIN` flag is required for the `.circleci/Dockerfiles/scripts/run-android-docker-unit-tests.sh` and `.circleci/Dockerfiles/scripts/run-android-docker-instrumentation-tests.sh` in order to allow the remounting of `/dev/shm` as writeable so the `buck` build system may write temporary output to that location.
|
||||
|
||||
Every time you make any modifications to the codebase, including changes to the test scripts inside `.circleci/Dockerfiles/scripts`, you should re-run the `docker build ...` command in order for your updates to be included in your local docker test image.
|
||||
|
||||
For rapid iteration, it's useful to keep in mind that Docker can pass along arbitrary commands to an image.
|
||||
For example, you can alternatively use Gradle in this manner:
|
||||
|
||||
```bash
|
||||
docker run --cap-add=SYS_ADMIN -it reactnativeci/android ./gradlew RNTester:android:app:assembleRelease
|
||||
```
|
||||
@@ -1,54 +0,0 @@
|
||||
# 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.
|
||||
#
|
||||
# This image builds upon the React Native Community Android image:
|
||||
# https://github.com/react-native-community/docker-android
|
||||
#
|
||||
# The base image is expected to remain relatively stable, and only
|
||||
# needs to be updated when major dependencies such as the Android
|
||||
# SDK or NDK are updated.
|
||||
#
|
||||
# In this Android Test image, we download the latest dependencies
|
||||
# and build a Android application that can be used to run the
|
||||
# tests specified in the scripts/ directory.
|
||||
#
|
||||
FROM reactnativecommunity/react-native-android:5.2
|
||||
|
||||
LABEL Description="React Native Android Test Image"
|
||||
LABEL maintainer="Héctor Ramos <hector@fb.com>"
|
||||
|
||||
# set default environment variables
|
||||
ENV GRADLE_OPTS="-Dorg.gradle.daemon=false -Dorg.gradle.jvmargs=\"-Xmx512m -XX:+HeapDumpOnOutOfMemoryError\""
|
||||
ENV JAVA_TOOL_OPTIONS="-Dfile.encoding=UTF8"
|
||||
|
||||
ADD .buckconfig /app/.buckconfig
|
||||
ADD .buckjavaargs /app/.buckjavaargs
|
||||
ADD BUCK /app/BUCK
|
||||
ADD Libraries /app/Libraries
|
||||
ADD ReactAndroid /app/ReactAndroid
|
||||
ADD ReactCommon /app/ReactCommon
|
||||
ADD React /app/React
|
||||
ADD keystores /app/keystores
|
||||
ADD packages/react-native-codegen /app/packages/react-native-codegen
|
||||
ADD tools /app/tools
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
RUN buck fetch ReactAndroid/src/test/java/com/facebook/react/modules
|
||||
RUN buck fetch ReactAndroid/src/main/java/com/facebook/react
|
||||
RUN buck fetch ReactAndroid/src/main/java/com/facebook/react/shell
|
||||
RUN buck fetch ReactAndroid/src/test/...
|
||||
RUN buck fetch ReactAndroid/src/androidTest/...
|
||||
|
||||
RUN buck build ReactAndroid/src/main/java/com/facebook/react
|
||||
RUN buck build ReactAndroid/src/main/java/com/facebook/react/shell
|
||||
|
||||
ADD . /app
|
||||
|
||||
RUN yarn
|
||||
|
||||
RUN ./gradlew :ReactAndroid:downloadBoost :ReactAndroid:downloadDoubleConversion :ReactAndroid:downloadFolly :ReactAndroid:downloadGlog
|
||||
|
||||
RUN ./gradlew :ReactAndroid:packageReactNdkLibsForBuck -Pjobs=1
|
||||
@@ -1,159 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* This script runs instrumentation tests one by one with retries
|
||||
* Instrumentation tests tend to be flaky, so rerunning them individually increases
|
||||
* chances for success and reduces total average execution time.
|
||||
*
|
||||
* We assume that all instrumentation tests are flat in one folder
|
||||
* Available arguments:
|
||||
* --path - path to all .java files with tests
|
||||
* --package - com.facebook.react.tests
|
||||
* --retries [num] - how many times to retry possible flaky commands: npm install and running tests, default 1
|
||||
*/
|
||||
|
||||
const argv = require('yargs').argv;
|
||||
const async = require('async');
|
||||
const child_process = require('child_process');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const colors = {
|
||||
GREEN: '\x1b[32m',
|
||||
RED: '\x1b[31m',
|
||||
RESET: '\x1b[0m',
|
||||
};
|
||||
|
||||
const test_opts = {
|
||||
FILTER: new RegExp(argv.filter || '.*', 'i'),
|
||||
IGNORE: argv.ignore || null,
|
||||
PACKAGE: argv.package || 'com.facebook.react.tests',
|
||||
PATH: argv.path || './ReactAndroid/src/androidTest/java/com/facebook/react/tests',
|
||||
RETRIES: parseInt(argv.retries || 2, 10),
|
||||
|
||||
TEST_TIMEOUT: parseInt(argv['test-timeout'] || 1000 * 60 * 10, 10),
|
||||
|
||||
OFFSET: argv.offset,
|
||||
COUNT: argv.count,
|
||||
};
|
||||
|
||||
let max_test_class_length = Number.NEGATIVE_INFINITY;
|
||||
|
||||
let testClasses = fs.readdirSync(path.resolve(process.cwd(), test_opts.PATH))
|
||||
.filter((file) => {
|
||||
return file.endsWith('.java');
|
||||
}).map((clazz) => {
|
||||
return path.basename(clazz, '.java');
|
||||
});
|
||||
|
||||
if (test_opts.IGNORE) {
|
||||
test_opts.IGNORE = new RegExp(test_opts.IGNORE, 'i');
|
||||
testClasses = testClasses.filter(className => {
|
||||
return !test_opts.IGNORE.test(className);
|
||||
});
|
||||
}
|
||||
|
||||
testClasses = testClasses.map((clazz) => {
|
||||
return test_opts.PACKAGE + '.' + clazz;
|
||||
}).filter((clazz) => {
|
||||
return test_opts.FILTER.test(clazz);
|
||||
});
|
||||
|
||||
// only process subset of the tests at corresponding offset and count if args provided
|
||||
if (test_opts.COUNT != null && test_opts.OFFSET != null) {
|
||||
const start = test_opts.COUNT * test_opts.OFFSET;
|
||||
const end = start + test_opts.COUNT;
|
||||
|
||||
if (start >= testClasses.length) {
|
||||
testClasses = [];
|
||||
} else if (end >= testClasses.length) {
|
||||
testClasses = testClasses.slice(start);
|
||||
} else {
|
||||
testClasses = testClasses.slice(start, end);
|
||||
}
|
||||
}
|
||||
|
||||
async.mapSeries(testClasses, (clazz, callback) => {
|
||||
if (clazz.length > max_test_class_length) {
|
||||
max_test_class_length = clazz.length;
|
||||
}
|
||||
|
||||
return async.retry(test_opts.RETRIES, (retryCb) => {
|
||||
const test_process = child_process.spawn('./.circleci/Dockerfiles/scripts/run-instrumentation-tests-via-adb-shell.sh', [test_opts.PACKAGE, clazz], {
|
||||
stdio: 'inherit',
|
||||
});
|
||||
|
||||
const timeout = setTimeout(() => {
|
||||
test_process.kill();
|
||||
}, test_opts.TEST_TIMEOUT);
|
||||
|
||||
test_process.on('error', (err) => {
|
||||
clearTimeout(timeout);
|
||||
retryCb(err);
|
||||
});
|
||||
|
||||
test_process.on('exit', (code) => {
|
||||
clearTimeout(timeout);
|
||||
|
||||
if (code !== 0) {
|
||||
return retryCb(new Error(`Process exited with code: ${code}`));
|
||||
}
|
||||
|
||||
return retryCb();
|
||||
});
|
||||
}, (err) => {
|
||||
return callback(null, {
|
||||
name: clazz,
|
||||
status: err ? 'failure' : 'success',
|
||||
});
|
||||
});
|
||||
}, (err, results) => {
|
||||
print_test_suite_results(results);
|
||||
|
||||
const failures = results.filter((test) => {
|
||||
return test.status === 'failure';
|
||||
});
|
||||
|
||||
return failures.length === 0 ? process.exit(0) : process.exit(1);
|
||||
});
|
||||
|
||||
function print_test_suite_results(results) {
|
||||
console.log('\n\nTest Suite Results:\n');
|
||||
|
||||
let color;
|
||||
let failing_suites = 0;
|
||||
let passing_suites = 0;
|
||||
|
||||
function pad_output(num_chars) {
|
||||
let i = 0;
|
||||
|
||||
while (i < num_chars) {
|
||||
process.stdout.write(' ');
|
||||
i++;
|
||||
}
|
||||
}
|
||||
results.forEach((test) => {
|
||||
if (test.status === 'success') {
|
||||
color = colors.GREEN;
|
||||
passing_suites++;
|
||||
} else if (test.status === 'failure') {
|
||||
color = colors.RED;
|
||||
failing_suites++;
|
||||
}
|
||||
|
||||
process.stdout.write(color);
|
||||
process.stdout.write(test.name);
|
||||
pad_output((max_test_class_length - test.name.length) + 8);
|
||||
process.stdout.write(test.status);
|
||||
process.stdout.write(`${colors.RESET}\n`);
|
||||
});
|
||||
|
||||
console.log(`\n${passing_suites} passing, ${failing_suites} failing!`);
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
#!/bin/bash
|
||||
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
#
|
||||
# This source code is licensed under the MIT license found in the
|
||||
# LICENSE file in the root directory of this source tree.
|
||||
|
||||
# for buck gen
|
||||
mount -o remount,exec /dev/shm
|
||||
|
||||
AVD_UUID=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 8 | head -n 1)
|
||||
|
||||
# create virtual device
|
||||
echo no | android create avd -n "$AVD_UUID" -f -t android-21 --abi default/armeabi-v7a
|
||||
|
||||
# emulator setup
|
||||
emulator64-arm -avd $AVD_UUID -no-skin -no-audio -no-window -no-boot-anim &
|
||||
bootanim=""
|
||||
until [[ "$bootanim" =~ "stopped" ]]; do
|
||||
sleep 5
|
||||
bootanim=$(adb -e shell getprop init.svc.bootanim 2>&1)
|
||||
echo "boot animation status=$bootanim"
|
||||
done
|
||||
|
||||
set -x
|
||||
|
||||
# solve issue with max user watches limit
|
||||
echo 65536 | tee -a /proc/sys/fs/inotify/max_user_watches
|
||||
watchman shutdown-server
|
||||
|
||||
# integration tests
|
||||
# build JS bundle for instrumentation tests
|
||||
node cli.js bundle --platform android --dev true --entry-file ReactAndroid/src/androidTest/js/TestBundle.js --bundle-output ReactAndroid/src/androidTest/assets/AndroidTestBundle.js
|
||||
|
||||
# build test APK
|
||||
# shellcheck disable=SC1091
|
||||
source ./scripts/android-setup.sh && NO_BUCKD=1 retry3 buck install ReactAndroid/src/androidTest/buck-runner:instrumentation-tests --config build.threads=1
|
||||
|
||||
# run installed apk with tests
|
||||
node ./.circleci/Dockerfiles/scripts/run-android-ci-instrumentation-tests.js "$*"
|
||||
exit $?
|
||||
@@ -1,16 +0,0 @@
|
||||
#!/bin/bash
|
||||
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
#
|
||||
# This source code is licensed under the MIT license found in the
|
||||
# LICENSE file in the root directory of this source tree.
|
||||
|
||||
# set default environment variables
|
||||
UNIT_TESTS_BUILD_THREADS="${UNIT_TESTS_BUILD_THREADS:-1}"
|
||||
|
||||
# for buck gen
|
||||
mount -o remount,exec /dev/shm
|
||||
|
||||
set -x
|
||||
|
||||
# run unit tests
|
||||
buck test ReactAndroid/src/test/... --config build.threads="$UNIT_TESTS_BUILD_THREADS"
|
||||
@@ -1,251 +0,0 @@
|
||||
#!/bin/bash
|
||||
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
#
|
||||
# This source code is licensed under the MIT license found in the
|
||||
# LICENSE file in the root directory of this source tree.
|
||||
|
||||
set -ex
|
||||
|
||||
# set default environment variables
|
||||
ROOT=$(pwd)
|
||||
SCRIPTS=$(pwd)/scripts
|
||||
|
||||
RUN_ANDROID=0
|
||||
RUN_CLI_INSTALL=1
|
||||
RUN_IOS=0
|
||||
RUN_JS=0
|
||||
|
||||
RETRY_COUNT=${RETRY_COUNT:-2}
|
||||
AVD_UUID=$(< /dev/urandom tr -dc 'a-zA-Z0-9' | fold -w 8 | head -n 1)
|
||||
ANDROID_NPM_DEPS="appium@1.5.1 mocha@2.4.5 wd@0.3.11 colors@1.0.3 pretty-data2@0.40.1"
|
||||
CLI_PACKAGE="$ROOT/react-native-cli/react-native-cli-*.tgz"
|
||||
PACKAGE="$ROOT/react-native-*.tgz"
|
||||
|
||||
# solve issue with max user watches limit
|
||||
echo 65536 | tee -a /proc/sys/fs/inotify/max_user_watches
|
||||
watchman shutdown-server
|
||||
|
||||
# retries command on failure
|
||||
# $1 -- max attempts
|
||||
# $2 -- command to run
|
||||
function retry() {
|
||||
local -r -i max_attempts="$1"; shift
|
||||
local -r cmd="$*"
|
||||
local -i attempt_num=1
|
||||
|
||||
until $cmd; do
|
||||
if (( attempt_num == max_attempts )); then
|
||||
echo "Execution of '$cmd' failed; no more attempts left"
|
||||
return 1
|
||||
else
|
||||
(( attempt_num++ ))
|
||||
echo "Execution of '$cmd' failed; retrying for attempt number $attempt_num..."
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# parse command line args & flags
|
||||
while :; do
|
||||
case "$1" in
|
||||
--android)
|
||||
RUN_ANDROID=1
|
||||
shift
|
||||
;;
|
||||
|
||||
--ios)
|
||||
RUN_IOS=1
|
||||
shift
|
||||
;;
|
||||
|
||||
--js)
|
||||
RUN_JS=1
|
||||
shift
|
||||
;;
|
||||
|
||||
--skip-cli-install)
|
||||
RUN_CLI_INSTALL=0
|
||||
shift
|
||||
;;
|
||||
|
||||
*)
|
||||
break
|
||||
esac
|
||||
done
|
||||
|
||||
function e2e_suite() {
|
||||
cd "$ROOT"
|
||||
|
||||
if [ $RUN_ANDROID -eq 0 ] && [ $RUN_IOS -eq 0 ] && [ $RUN_JS -eq 0 ]; then
|
||||
echo "No e2e tests specified!"
|
||||
return 0
|
||||
fi
|
||||
|
||||
# create temp dir
|
||||
TEMP_DIR=$(mktemp -d /tmp/react-native-XXXXXXXX)
|
||||
|
||||
# To make sure we actually installed the local version
|
||||
# of react-native, we will create a temp file inside the template
|
||||
# and check that it exists after `react-native init
|
||||
IOS_MARKER="$(mktemp "$ROOT"/template/ios/HelloWorld/XXXXXXXX)"
|
||||
ANDROID_MARKER="$(mktemp "$ROOT"/template/android/XXXXXXXX)"
|
||||
|
||||
# install CLI
|
||||
cd react-native-cli
|
||||
npm pack
|
||||
cd ..
|
||||
|
||||
# can skip cli install for non sudo mode
|
||||
if [ $RUN_CLI_INSTALL -ne 0 ]; then
|
||||
if ! npm install -g "$CLI_PACKAGE"
|
||||
then
|
||||
echo "Could not install react-native-cli globally, please run in su mode"
|
||||
echo "Or with --skip-cli-install to skip this step"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ $RUN_ANDROID -ne 0 ]; then
|
||||
set +ex
|
||||
|
||||
# create virtual device
|
||||
if ! android list avd | grep "$AVD_UUID" > /dev/null; then
|
||||
echo no | android create avd -n "$AVD_UUID" -f -t android-21 --abi default/armeabi-v7a
|
||||
fi
|
||||
|
||||
# newline at end of adb devices call and first line is headers
|
||||
DEVICE_COUNT=$(adb devices | wc -l)
|
||||
((DEVICE_COUNT -= 2))
|
||||
|
||||
# will always kill an existing emulator if one exists for fresh setup
|
||||
if [[ $DEVICE_COUNT -ge 1 ]]; then
|
||||
adb emu kill
|
||||
fi
|
||||
|
||||
# emulator setup
|
||||
emulator64-arm -avd "$AVD_UUID" -no-skin -no-audio -no-window -no-boot-anim &
|
||||
|
||||
bootanim=""
|
||||
# shellcheck disable=SC2076
|
||||
until [[ "$bootanim" =~ "stopped" ]]; do
|
||||
sleep 5
|
||||
bootanim=$(adb -e shell getprop init.svc.bootanim 2>&1)
|
||||
echo "boot animation status=$bootanim"
|
||||
done
|
||||
|
||||
set -ex
|
||||
|
||||
if ! ./gradlew :ReactAndroid:installArchives -Pjobs=1 -Dorg.gradle.jvmargs="-Xmx512m -XX:+HeapDumpOnOutOfMemoryError"
|
||||
then
|
||||
echo "Failed to compile Android binaries"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if ! npm pack
|
||||
then
|
||||
echo "Failed to pack react-native"
|
||||
return 1
|
||||
fi
|
||||
|
||||
cd "$TEMP_DIR"
|
||||
|
||||
if ! retry "$RETRY_COUNT" react-native init EndToEndTest --version "$PACKAGE" --npm
|
||||
then
|
||||
echo "Failed to execute react-native init"
|
||||
echo "Most common reason is npm registry connectivity, try again"
|
||||
return 1
|
||||
fi
|
||||
|
||||
cd EndToEndTest
|
||||
|
||||
# android tests
|
||||
if [ $RUN_ANDROID -ne 0 ]; then
|
||||
echo "Running an Android e2e test"
|
||||
echo "Installing e2e framework"
|
||||
|
||||
if ! retry "$RETRY_COUNT" npm install --save-dev "$ANDROID_NPM_DEPS" --silent >> /dev/null
|
||||
then
|
||||
echo "Failed to install appium"
|
||||
echo "Most common reason is npm registry connectivity, try again"
|
||||
return 1
|
||||
fi
|
||||
|
||||
cp "$SCRIPTS/android-e2e-test.js" android-e2e-test.js
|
||||
|
||||
(
|
||||
cd android || exit
|
||||
echo "Downloading Maven deps"
|
||||
./gradlew :app:copyDownloadableDepsToLibs
|
||||
)
|
||||
|
||||
keytool -genkey -v -keystore android/keystores/debug.keystore -storepass android -alias androiddebugkey -keypass android -dname "CN=Android Debug,O=Android,C=US"
|
||||
|
||||
node ./node_modules/.bin/appium >> /dev/null &
|
||||
APPIUM_PID=$!
|
||||
echo "Starting appium server $APPIUM_PID"
|
||||
|
||||
echo "Building app"
|
||||
buck build android/app
|
||||
|
||||
# hack to get node unhung (kill buckd)
|
||||
if ! kill -9 "$(pgrep java)"
|
||||
then
|
||||
echo "could not execute Buck build, is it installed and in PATH?"
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo "Starting Metro"
|
||||
npm start >> /dev/null &
|
||||
SERVER_PID=$!
|
||||
sleep 15
|
||||
|
||||
echo "Executing android e2e test"
|
||||
if ! retry "$RETRY_COUNT" node node_modules/.bin/_mocha android-e2e-test.js
|
||||
then
|
||||
echo "Failed to run Android e2e tests"
|
||||
echo "Most likely the code is broken"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# kill packager process
|
||||
if kill -0 "$SERVER_PID"; then
|
||||
echo "Killing packager $SERVER_PID"
|
||||
kill -9 "$SERVER_PID"
|
||||
fi
|
||||
|
||||
# kill appium process
|
||||
if kill -0 "$APPIUM_PID"; then
|
||||
echo "Killing appium $APPIUM_PID"
|
||||
kill -9 "$APPIUM_PID"
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
# ios tests
|
||||
if [ $RUN_IOS -ne 0 ]; then
|
||||
echo "Running ios e2e tests not yet implemented for docker!"
|
||||
fi
|
||||
|
||||
# js tests
|
||||
if [ $RUN_JS -ne 0 ]; then
|
||||
# Check the packager produces a bundle (doesn't throw an error)
|
||||
if ! react-native bundle --max-workers 1 --platform android --dev true --entry-file index.js --bundle-output android-bundle.js
|
||||
then
|
||||
echo "Could not build android bundle"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! react-native bundle --max-workers 1 --platform ios --dev true --entry-file index.js --bundle-output ios-bundle.js
|
||||
then
|
||||
echo "Could not build iOS bundle"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# directory cleanup
|
||||
rm "$IOS_MARKER"
|
||||
rm "$ANDROID_MARKER"
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
retry "$RETRY_COUNT" e2e_suite
|
||||
@@ -1,70 +0,0 @@
|
||||
#!/bin/bash
|
||||
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
#
|
||||
# This source code is licensed under the MIT license found in the
|
||||
# LICENSE file in the root directory of this source tree.
|
||||
|
||||
# shellcheck disable=SC1117
|
||||
# Python script to run instrumentation tests, copied from https://github.com/circleci/circle-dummy-android
|
||||
# Example: ./scripts/run-android-instrumentation-tests.sh com.facebook.react.tests com.facebook.react.tests.ReactPickerTestCase
|
||||
#
|
||||
export PATH="$ANDROID_HOME/platform-tools:$ANDROID_HOME/tools:$PATH"
|
||||
|
||||
# clear the logs
|
||||
adb logcat -c
|
||||
|
||||
# run tests and check output
|
||||
python - "$1" "$2" << END
|
||||
|
||||
import re
|
||||
import subprocess as sp
|
||||
import sys
|
||||
import threading
|
||||
import time
|
||||
|
||||
done = False
|
||||
|
||||
test_app = sys.argv[1]
|
||||
test_class = None
|
||||
|
||||
if len(sys.argv) > 2:
|
||||
test_class = sys.argv[2]
|
||||
|
||||
def update():
|
||||
# prevent CircleCI from killing the process for inactivity
|
||||
while not done:
|
||||
time.sleep(5)
|
||||
print "Running in background. Waiting for 'adb' command response..."
|
||||
|
||||
t = threading.Thread(target=update)
|
||||
t.dameon = True
|
||||
t.start()
|
||||
|
||||
def run():
|
||||
sp.Popen(['adb', 'wait-for-device']).communicate()
|
||||
if (test_class != None):
|
||||
p = sp.Popen('adb shell am instrument -w -e class %s %s/android.support.test.runner.AndroidJUnitRunner'
|
||||
% (test_class, test_app), shell=True, stdout=sp.PIPE, stderr=sp.PIPE, stdin=sp.PIPE)
|
||||
else :
|
||||
p = sp.Popen('adb shell am instrument -w %s/android.support.test.runner.AndroidJUnitRunner'
|
||||
% (test_app), shell=True, stdout=sp.PIPE, stderr=sp.PIPE, stdin=sp.PIPE)
|
||||
return p.communicate()
|
||||
|
||||
success = re.compile(r'OK \(\d+ test(s)?\)')
|
||||
stdout, stderr = run()
|
||||
|
||||
done = True
|
||||
print stderr
|
||||
print stdout
|
||||
|
||||
if success.search(stderr + stdout):
|
||||
sys.exit(0)
|
||||
else:
|
||||
# dump the logs
|
||||
sp.Popen(['adb', 'logcat', '-d']).communicate()
|
||||
sys.exit(1) # make sure we fail if the test failed
|
||||
END
|
||||
|
||||
RETVAL=$?
|
||||
|
||||
exit $RETVAL
|
||||
@@ -1,5 +0,0 @@
|
||||
# Circle CI
|
||||
|
||||
This directory is home to the Circle CI configuration file. Circle is our continuous integration service provider. You can see the overall status of React Native's builds at https://circleci.com/gh/facebook/react-native
|
||||
|
||||
You may also see an individual PR's build status by scrolling down to the Checks section in the PR.
|
||||
@@ -1,989 +0,0 @@
|
||||
version: 2.1
|
||||
|
||||
# -------------------------
|
||||
# ORBS
|
||||
# -------------------------
|
||||
|
||||
orbs:
|
||||
win: circleci/windows@2.4.0
|
||||
|
||||
# -------------------------
|
||||
# DEFAULTS
|
||||
# -------------------------
|
||||
defaults: &defaults
|
||||
working_directory: ~/react-native
|
||||
environment:
|
||||
- GIT_COMMIT_DESC: git log --format=oneline -n 1 $CIRCLE_SHA1
|
||||
# The public github tokens are publicly visible by design
|
||||
- PUBLIC_PULLBOT_GITHUB_TOKEN_A: &github_pullbot_token_a "a6edf8e8d40ce4e8b11a"
|
||||
- PUBLIC_PULLBOT_GITHUB_TOKEN_B: &github_pullbot_token_b "150e1341f4dd9c944d2a"
|
||||
- PUBLIC_ANALYSISBOT_GITHUB_TOKEN_A: &github_analysisbot_token_a "312d354b5c36f082cfe9"
|
||||
- PUBLIC_ANALYSISBOT_GITHUB_TOKEN_B: &github_analysisbot_token_b "07973d757026bdd9f196"
|
||||
|
||||
# -------------------------
|
||||
# EXECUTORS
|
||||
# -------------------------
|
||||
executors:
|
||||
nodelts:
|
||||
<<: *defaults
|
||||
docker:
|
||||
# Note: Version set separately for Windows builds, see below.
|
||||
- image: circleci/node:16
|
||||
nodeprevlts:
|
||||
<<: *defaults
|
||||
docker:
|
||||
- image: circleci/node:14
|
||||
reactnativeandroid:
|
||||
<<: *defaults
|
||||
docker:
|
||||
- image: reactnativecommunity/react-native-android:5.2
|
||||
resource_class: "large"
|
||||
environment:
|
||||
- TERM: "dumb"
|
||||
- ADB_INSTALL_TIMEOUT: 10
|
||||
- GRADLE_OPTS: '-Dorg.gradle.daemon=false -Dorg.gradle.jvmargs="-XX:+HeapDumpOnOutOfMemoryError"'
|
||||
- BUILD_THREADS: 2
|
||||
# Repeated here, as the environment key in this executor will overwrite the one in defaults
|
||||
- PUBLIC_ANALYSISBOT_GITHUB_TOKEN_A: *github_analysisbot_token_a
|
||||
- PUBLIC_ANALYSISBOT_GITHUB_TOKEN_B: *github_analysisbot_token_b
|
||||
- PUBLIC_PULLBOT_GITHUB_TOKEN_A: *github_pullbot_token_a
|
||||
- PUBLIC_PULLBOT_GITHUB_TOKEN_B: *github_pullbot_token_b
|
||||
reactnativeios:
|
||||
<<: *defaults
|
||||
macos:
|
||||
xcode: &_XCODE_VERSION "13.0.0"
|
||||
|
||||
# -------------------------
|
||||
# COMMANDS
|
||||
# -------------------------
|
||||
commands:
|
||||
|
||||
setup_artifacts:
|
||||
steps:
|
||||
- run:
|
||||
name: Initial Setup
|
||||
command: mkdir -p ./reports/{buck,build,junit,outputs}
|
||||
|
||||
setup_ruby:
|
||||
steps:
|
||||
- restore_cache:
|
||||
key: 1-gems-{{ checksum "Gemfile.lock" }}
|
||||
- run: bundle check || bundle install --path vendor/bundle --clean
|
||||
- save_cache:
|
||||
key: 1-gems-{{ checksum "Gemfile.lock" }}
|
||||
paths:
|
||||
- vendor/bundle
|
||||
|
||||
run_yarn:
|
||||
steps:
|
||||
- restore_cache:
|
||||
keys:
|
||||
- v5-yarn-cache-{{ .Environment.CIRCLE_JOB }}-{{ arch }}-{{ checksum "yarn.lock" }}
|
||||
- v5-yarn-cache-{{ .Environment.CIRCLE_JOB }}-{{ arch }}
|
||||
- v5-yarn-cache-{{ .Environment.CIRCLE_JOB }}
|
||||
- run:
|
||||
name: "Yarn: Install Dependencies"
|
||||
command: |
|
||||
# Skip yarn install on metro bump commits as the package is not yet
|
||||
# available on npm
|
||||
if [[ $(echo "$GIT_COMMIT_DESC" | grep -c "Bump metro@") -eq 0 ]]; then
|
||||
yarn install --non-interactive --cache-folder ~/.cache/yarn
|
||||
fi
|
||||
- save_cache:
|
||||
paths:
|
||||
- ~/.cache/yarn
|
||||
key: v5-yarn-cache-{{ .Environment.CIRCLE_JOB }}-{{ arch }}-{{ checksum "yarn.lock" }}
|
||||
|
||||
install_buck_tooling:
|
||||
steps:
|
||||
- restore_cache:
|
||||
keys:
|
||||
- v3-buck-v2019.01.10.01-{{ checksum "scripts/circleci/buck_fetch.sh" }}}
|
||||
- run:
|
||||
name: Install BUCK
|
||||
command: |
|
||||
buck --version
|
||||
# Install related tooling
|
||||
if [[ ! -e ~/okbuck ]]; then
|
||||
git clone https://github.com/uber/okbuck.git ~/okbuck --depth=1
|
||||
fi
|
||||
- save_cache:
|
||||
paths:
|
||||
- ~/buck
|
||||
- ~/okbuck
|
||||
key: v3-buck-v2019.01.10.01-{{ checksum "scripts/circleci/buck_fetch.sh" }}
|
||||
|
||||
install_github_bot_deps:
|
||||
steps:
|
||||
- run:
|
||||
name: "Yarn: Install dependencies (GitHub bots)"
|
||||
command: cd bots && yarn install --non-interactive --cache-folder ~/.cache/yarn
|
||||
|
||||
brew_install:
|
||||
parameters:
|
||||
package:
|
||||
description: Homebrew package to install
|
||||
type: string
|
||||
steps:
|
||||
- run:
|
||||
name: "Brew: Install << parameters.package >>"
|
||||
command: HOMEBREW_NO_AUTO_UPDATE=1 brew install << parameters.package >> >/dev/null
|
||||
|
||||
with_brew_cache_span:
|
||||
parameters:
|
||||
steps:
|
||||
type: steps
|
||||
steps:
|
||||
- restore_cache:
|
||||
keys:
|
||||
- v4-brew
|
||||
- steps: << parameters.steps >>
|
||||
- save_cache:
|
||||
paths:
|
||||
- /usr/local/Homebrew
|
||||
- ~/Library/Caches/Homebrew
|
||||
key: v4-brew
|
||||
|
||||
with_rntester_pods_cache_span:
|
||||
parameters:
|
||||
steps:
|
||||
type: steps
|
||||
steps:
|
||||
- run:
|
||||
name: Setup CocoaPods cache
|
||||
# Copy packages/rn-tester/Podfile.lock since it can be changed by pod install
|
||||
command: cp packages/rn-tester/Podfile.lock packages/rn-tester/Podfile.lock.bak
|
||||
- restore_cache:
|
||||
keys:
|
||||
# The committed lockfile is generated using USE_FRAMEWORKS=0 and USE_HERMES=0 so it could load an outdated cache if a change
|
||||
# only affects the frameworks or hermes config. To help prevent this also cache based on the content of Podfile.
|
||||
- v3-pods-{{ .Environment.CIRCLE_JOB }}-{{ checksum "packages/rn-tester/Podfile.lock.bak" }}-{{ checksum "packages/rn-tester/Podfile" }}
|
||||
- steps: << parameters.steps >>
|
||||
- save_cache:
|
||||
paths:
|
||||
- packages/rn-tester/Pods
|
||||
key: v3-pods-{{ .Environment.CIRCLE_JOB }}-{{ checksum "packages/rn-tester/Podfile.lock.bak" }}-{{ checksum "packages/rn-tester/Podfile" }}
|
||||
|
||||
download_gradle_dependencies:
|
||||
steps:
|
||||
- restore_cache:
|
||||
keys:
|
||||
- v1-gradle-{{ checksum "gradle/wrapper/gradle-wrapper.properties" }}-{{ checksum "ReactAndroid/gradle.properties" }}
|
||||
- run:
|
||||
name: Download Dependencies Using Gradle
|
||||
command: ./scripts/circleci/gradle_download_deps.sh
|
||||
- save_cache:
|
||||
paths:
|
||||
- ~/.gradle
|
||||
- ReactAndroid/build/downloads
|
||||
- ReactAndroid/build/third-party-ndk
|
||||
key: v1-gradle-{{ checksum "gradle/wrapper/gradle-wrapper.properties" }}-{{ checksum "ReactAndroid/gradle.properties" }}
|
||||
|
||||
download_buck_dependencies:
|
||||
steps:
|
||||
- run:
|
||||
name: Download Dependencies Using Buck
|
||||
command: ./scripts/circleci/buck_fetch.sh
|
||||
|
||||
run_e2e:
|
||||
parameters:
|
||||
platform:
|
||||
description: Target platform
|
||||
type: enum
|
||||
enum: ["android", "ios", "js"]
|
||||
default: "js"
|
||||
retries:
|
||||
description: How many times the job should try to run these tests
|
||||
type: integer
|
||||
default: 3
|
||||
steps:
|
||||
- run:
|
||||
name: "Run Tests: << parameters.platform >> End-to-End Tests"
|
||||
command: node ./scripts/run-ci-e2e-tests.js --<< parameters.platform >> --retries << parameters.retries >>
|
||||
|
||||
report_bundle_size:
|
||||
parameters:
|
||||
platform:
|
||||
description: Target platform
|
||||
type: enum
|
||||
enum: ["android", "ios"]
|
||||
steps:
|
||||
- install_github_bot_deps
|
||||
- run:
|
||||
name: Report size of RNTester.app (analysis-bot)
|
||||
command: GITHUB_TOKEN="$PUBLIC_ANALYSISBOT_GITHUB_TOKEN_A""$PUBLIC_ANALYSISBOT_GITHUB_TOKEN_B" scripts/circleci/report-bundle-size.sh << parameters.platform >> || true
|
||||
|
||||
# -------------------------
|
||||
# JOBS
|
||||
# -------------------------
|
||||
jobs:
|
||||
# -------------------------
|
||||
# JOBS: Analyze PR
|
||||
# -------------------------
|
||||
# Analyze pull request and raise any lint/flow issues.
|
||||
# Issues will be posted to the PR itself via GitHub bots.
|
||||
# This workflow should only fail if the bots fail to run.
|
||||
analyze_pr:
|
||||
executor: reactnativeandroid
|
||||
steps:
|
||||
- checkout
|
||||
- run_yarn
|
||||
|
||||
- install_github_bot_deps
|
||||
|
||||
# Note: The yarn gpg key needs to be refreshed to work around https://github.com/yarnpkg/yarn/issues/7866
|
||||
- run:
|
||||
name: Install additional GitHub bot dependencies
|
||||
# TEMP: Added workaround from https://github.com/nodesource/distributions/issues/1266#issuecomment-932583579
|
||||
command: |
|
||||
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
|
||||
apt update && apt install -y shellcheck jq
|
||||
apt-get -y install openssl ca-certificates
|
||||
update-ca-certificates
|
||||
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
|
||||
apt update && apt install -y shellcheck jq
|
||||
|
||||
- run:
|
||||
name: Run linters against modified files (analysis-bot)
|
||||
command: GITHUB_TOKEN="$PUBLIC_ANALYSISBOT_GITHUB_TOKEN_A""$PUBLIC_ANALYSISBOT_GITHUB_TOKEN_B" yarn lint-ci
|
||||
when: always
|
||||
|
||||
- run:
|
||||
name: Analyze Pull Request (pull-bot)
|
||||
command: |
|
||||
cd bots
|
||||
DANGER_GITHUB_API_TOKEN="$PUBLIC_PULLBOT_GITHUB_TOKEN_A""$PUBLIC_PULLBOT_GITHUB_TOKEN_B" yarn danger ci --use-github-checks
|
||||
when: always
|
||||
|
||||
# -------------------------
|
||||
# JOBS: Analyze Code
|
||||
# -------------------------
|
||||
analyze_code:
|
||||
executor: reactnativeandroid
|
||||
steps:
|
||||
- checkout
|
||||
- setup_artifacts
|
||||
- run_yarn
|
||||
|
||||
- run:
|
||||
name: Lint code
|
||||
command: scripts/circleci/exec_swallow_error.sh yarn lint --format junit -o ./reports/junit/eslint/results.xml
|
||||
when: always
|
||||
|
||||
- run:
|
||||
name: Lint Java
|
||||
command: scripts/circleci/exec_swallow_error.sh yarn lint-java --check
|
||||
when: always
|
||||
|
||||
- run:
|
||||
name: Check for errors in code using Flow (iOS)
|
||||
command: yarn flow-check-ios
|
||||
when: always
|
||||
|
||||
- run:
|
||||
name: Check for errors in code using Flow (Android)
|
||||
command: yarn flow-check-android
|
||||
when: always
|
||||
|
||||
- run:
|
||||
name: Sanity checks
|
||||
command: |
|
||||
./scripts/circleci/check_license.sh
|
||||
./scripts/circleci/validate_yarn_lockfile.sh
|
||||
when: always
|
||||
|
||||
- run:
|
||||
name: Check formatting
|
||||
command: yarn run format-check
|
||||
when: always
|
||||
|
||||
- store_test_results:
|
||||
path: ./reports/junit
|
||||
|
||||
# -------------------------
|
||||
# JOBS: Test JavaScript
|
||||
# -------------------------
|
||||
test_js:
|
||||
parameters:
|
||||
executor:
|
||||
type: executor
|
||||
default: nodelts
|
||||
run_disabled_tests:
|
||||
type: boolean
|
||||
default: false
|
||||
executor: << parameters.executor >>
|
||||
steps:
|
||||
- checkout
|
||||
- setup_artifacts
|
||||
- run_yarn
|
||||
- run:
|
||||
name: Install rsync
|
||||
command: sudo apt-get install rsync
|
||||
|
||||
# -------------------------
|
||||
# Run JavaScript tests
|
||||
- run:
|
||||
name: "Run Tests: JavaScript Tests"
|
||||
command: node ./scripts/run-ci-javascript-tests.js --maxWorkers 2
|
||||
- run_e2e:
|
||||
platform: js
|
||||
|
||||
# Optionally, run disabled tests
|
||||
- when:
|
||||
condition: << parameters.run_disabled_tests >>
|
||||
steps:
|
||||
- run: echo "Failing tests may be moved here temporarily."
|
||||
# -------------------------
|
||||
|
||||
- store_test_results:
|
||||
path: ./reports/junit
|
||||
|
||||
# -------------------------
|
||||
# JOBS: Test iOS
|
||||
# -------------------------
|
||||
test_ios:
|
||||
executor: reactnativeios
|
||||
parameters:
|
||||
use_frameworks:
|
||||
type: boolean
|
||||
default: false
|
||||
use_hermes:
|
||||
type: boolean
|
||||
default: false
|
||||
run_unit_tests:
|
||||
description: Specifies whether unit tests should run.
|
||||
type: boolean
|
||||
default: false
|
||||
run_disabled_tests:
|
||||
description: Specifies whether disabled tests should run. Set this to true to debug failing tests.
|
||||
type: boolean
|
||||
default: false
|
||||
environment:
|
||||
- REPORTS_DIR: "./reports/junit"
|
||||
steps:
|
||||
- checkout
|
||||
- setup_artifacts
|
||||
- setup_ruby
|
||||
- run_yarn
|
||||
|
||||
- run: |
|
||||
cd packages/rn-tester
|
||||
bundle check || bundle install
|
||||
- run:
|
||||
name: Boot iPhone Simulator
|
||||
command: source scripts/.tests.env && xcrun simctl boot "$IOS_DEVICE" || true
|
||||
|
||||
- run:
|
||||
name: Configure Environment Variables
|
||||
command: |
|
||||
echo 'export PATH=/usr/local/opt/node@16/bin:$PATH' >> $BASH_ENV
|
||||
source $BASH_ENV
|
||||
|
||||
- with_brew_cache_span:
|
||||
steps:
|
||||
- brew_install:
|
||||
package: watchman
|
||||
- run:
|
||||
name: "Brew: Tap wix/brew"
|
||||
command: HOMEBREW_NO_AUTO_UPDATE=1 brew tap wix/brew >/dev/null
|
||||
- brew_install:
|
||||
package: applesimutils
|
||||
|
||||
- run:
|
||||
name: Configure Node
|
||||
# Sourcing find-node.sh will ensure nvm is set up.
|
||||
# It also helps future invocation of find-node.sh prevent permission issue with nvm.sh.
|
||||
command: source scripts/find-node.sh && nvm install 16 && nvm alias default 16
|
||||
|
||||
- run:
|
||||
name: Configure Watchman
|
||||
command: echo "{}" > .watchmanconfig
|
||||
|
||||
- when:
|
||||
condition: << parameters.use_frameworks >>
|
||||
steps:
|
||||
- run:
|
||||
name: Set USE_FRAMEWORKS=1
|
||||
command: echo "export USE_FRAMEWORKS=1" >> $BASH_ENV
|
||||
|
||||
- when:
|
||||
condition: << parameters.use_hermes >>
|
||||
steps:
|
||||
- run:
|
||||
name: Set USE_HERMES=1
|
||||
command: echo "export USE_HERMES=1" >> $BASH_ENV
|
||||
|
||||
- run:
|
||||
name: Setup the CocoaPods environment
|
||||
command: bundle exec pod setup
|
||||
|
||||
- with_rntester_pods_cache_span:
|
||||
steps:
|
||||
- run:
|
||||
name: Generate RNTesterPods Workspace
|
||||
command: cd packages/rn-tester && bundle exec pod install --verbose
|
||||
|
||||
# -------------------------
|
||||
# Runs iOS unit tests
|
||||
- when:
|
||||
condition: << parameters.run_unit_tests >>
|
||||
steps:
|
||||
- run:
|
||||
name: "Run Tests: iOS Unit and Integration Tests"
|
||||
command: yarn test-ios
|
||||
|
||||
# Optionally, run disabled tests
|
||||
- when:
|
||||
condition: << parameters.run_disabled_tests >>
|
||||
steps:
|
||||
- run: echo "Failing tests may be moved here temporarily."
|
||||
- run:
|
||||
name: "Run Tests: CocoaPods"
|
||||
command: ./scripts/process-podspecs.sh
|
||||
- run:
|
||||
name: Free up port 8081 for iOS End-to-End Tests
|
||||
command: |
|
||||
# free up port 8081 for the packager before running tests
|
||||
set +eo pipefail
|
||||
lsof -i tcp:8081 | awk 'NR!=1 {print $2}' | xargs kill
|
||||
set -eo pipefail
|
||||
- run_e2e:
|
||||
platform: ios
|
||||
# -------------------------
|
||||
|
||||
# Collect Results
|
||||
- report_bundle_size:
|
||||
platform: ios
|
||||
- store_test_results:
|
||||
path: ./reports/junit
|
||||
|
||||
# -------------------------
|
||||
# JOBS: Test Android
|
||||
# -------------------------
|
||||
test_android:
|
||||
executor: reactnativeandroid
|
||||
parameters:
|
||||
run_disabled_tests:
|
||||
type: boolean
|
||||
default: false
|
||||
steps:
|
||||
- checkout
|
||||
- setup_artifacts
|
||||
- run_yarn
|
||||
|
||||
# Validate Android SDK installation and packages
|
||||
- run:
|
||||
name: Validate Android SDK Install
|
||||
command: ./scripts/validate-android-sdk.sh
|
||||
|
||||
# Starting emulator in advance as it takes some time to boot.
|
||||
- run:
|
||||
name: Create Android Virtual Device
|
||||
command: source scripts/android-setup.sh && createAVD
|
||||
- run:
|
||||
name: Launch Android Virtual Device in Background
|
||||
command: source scripts/android-setup.sh && launchAVD
|
||||
background: true
|
||||
|
||||
# Install Buck
|
||||
- install_buck_tooling
|
||||
|
||||
# Validate Android test environment (including Buck)
|
||||
- run:
|
||||
name: Validate Android Test Environment
|
||||
command: ./scripts/validate-android-test-env.sh
|
||||
|
||||
- download_buck_dependencies
|
||||
- download_gradle_dependencies
|
||||
|
||||
# Build and compile
|
||||
- run:
|
||||
name: Build Android App
|
||||
command: |
|
||||
buck build ReactAndroid/src/main/java/com/facebook/react
|
||||
buck build ReactAndroid/src/main/java/com/facebook/react/shell
|
||||
- run:
|
||||
name: Compile Native Libs for Unit and Integration Tests
|
||||
command: ./gradlew :ReactAndroid:packageReactNdkLibsForBuck -Pjobs=$BUILD_THREADS
|
||||
no_output_timeout: 30m
|
||||
|
||||
# Build JavaScript Bundle for instrumentation tests
|
||||
- run:
|
||||
name: Build JavaScript Bundle
|
||||
command: node cli.js bundle --max-workers 2 --platform android --dev true --entry-file ReactAndroid/src/androidTest/js/TestBundle.js --bundle-output ReactAndroid/src/androidTest/assets/AndroidTestBundle.js
|
||||
|
||||
# Wait for AVD to finish booting before running tests
|
||||
- run:
|
||||
name: Wait for Android Virtual Device
|
||||
command: source scripts/android-setup.sh && waitForAVD
|
||||
|
||||
- run:
|
||||
name: Assemble RNTester App
|
||||
command: ./gradlew packages:rn-tester:android:app:assembleRelease
|
||||
|
||||
# -------------------------
|
||||
# Run Android tests
|
||||
- run:
|
||||
name: "Run Tests: Android Unit Tests"
|
||||
command: buck test ReactAndroid/src/test/... --config build.threads=$BUILD_THREADS --xml ./reports/buck/all-results-raw.xml
|
||||
- run:
|
||||
name: "Build Tests: Android Instrumentation Tests"
|
||||
# Here, just build the instrumentation tests. There is a known issue with installing the APK to android-21+ emulator.
|
||||
command: |
|
||||
if [[ ! -e ReactAndroid/src/androidTest/assets/AndroidTestBundle.js ]]; then
|
||||
echo "JavaScript bundle missing, cannot run instrumentation tests. Verify Build JavaScript Bundle step completed successfully."; exit 1;
|
||||
fi
|
||||
source scripts/android-setup.sh && NO_BUCKD=1 retry3 timeout 300 buck build ReactAndroid/src/androidTest/buck-runner:instrumentation-tests --config build.threads=$BUILD_THREADS
|
||||
|
||||
# Optionally, run disabled tests
|
||||
- when:
|
||||
condition: << parameters.run_disabled_tests >>
|
||||
steps:
|
||||
- run: echo "Failing tests may be moved here temporarily."
|
||||
- run_e2e:
|
||||
platform: android
|
||||
# -------------------------
|
||||
|
||||
# Collect Results
|
||||
- report_bundle_size:
|
||||
platform: android
|
||||
- run:
|
||||
name: Collect Test Results
|
||||
command: |
|
||||
find . -type f -regex ".*/build/test-results/debug/.*xml" -exec cp {} ./reports/build/ \;
|
||||
find . -type f -regex ".*/outputs/androidTest-results/connected/.*xml" -exec cp {} ./reports/outputs/ \;
|
||||
find . -type f -regex ".*/buck-out/gen/ReactAndroid/src/test/.*/.*xml" -exec cp {} ./reports/buck/ \;
|
||||
if [ -f ~/react-native/reports/buck/all-results-raw.xml ]; then
|
||||
cd ~/okbuck
|
||||
./tooling/junit/buck_to_junit.sh ~/react-native/reports/buck/all-results-raw.xml ~/react-native/reports/junit/results.xml
|
||||
fi
|
||||
when: always
|
||||
- store_test_results:
|
||||
path: ./reports/junit
|
||||
|
||||
# -------------------------
|
||||
# JOBS: Test Android Template
|
||||
# -------------------------
|
||||
test_android_template:
|
||||
executor: reactnativeandroid
|
||||
steps:
|
||||
- checkout
|
||||
- run_yarn
|
||||
- attach_workspace:
|
||||
at: .
|
||||
|
||||
- run:
|
||||
name: Create Android template project
|
||||
command: |
|
||||
REPO_ROOT=$(pwd)
|
||||
PACKAGE=$(cat build/react-native-package-version)
|
||||
PATH_TO_PACKAGE="$REPO_ROOT/build/$PACKAGE"
|
||||
cd template
|
||||
npm add $PATH_TO_PACKAGE
|
||||
npm install
|
||||
|
||||
- run:
|
||||
name: Build the template application
|
||||
command: cd template/android/ && ./gradlew assembleDebug
|
||||
|
||||
# -------------------------
|
||||
# JOBS: Test iOS Template
|
||||
# -------------------------
|
||||
test_ios_template:
|
||||
executor: reactnativeios
|
||||
environment:
|
||||
- PROJECT_NAME: "iOSTemplateProject"
|
||||
|
||||
steps:
|
||||
- checkout
|
||||
- run_yarn
|
||||
- attach_workspace:
|
||||
at: .
|
||||
|
||||
- run:
|
||||
name: Create iOS template project
|
||||
command: |
|
||||
REPO_ROOT=$(pwd)
|
||||
PACKAGE=$(cat build/react-native-package-version)
|
||||
PATH_TO_PACKAGE="$REPO_ROOT/build/$PACKAGE"
|
||||
node ./scripts/set-rn-template-version.js "file:$PATH_TO_PACKAGE"
|
||||
mkdir -p ~/tmp
|
||||
cd ~/tmp
|
||||
node "$REPO_ROOT/cli.js" init "$PROJECT_NAME" --template "$REPO_ROOT"
|
||||
|
||||
- run:
|
||||
name: Build template project
|
||||
command: |
|
||||
xcodebuild build \
|
||||
-workspace ~/tmp/$PROJECT_NAME/ios/$PROJECT_NAME.xcworkspace \
|
||||
-scheme $PROJECT_NAME \
|
||||
-sdk iphonesimulator
|
||||
|
||||
# -------------------------
|
||||
# JOBS: Windows
|
||||
# -------------------------
|
||||
test_windows:
|
||||
executor:
|
||||
name: win/default
|
||||
parameters:
|
||||
run_disabled_tests:
|
||||
type: boolean
|
||||
default: false
|
||||
environment:
|
||||
- ANDROID_HOME: "C:\\Android\\android-sdk"
|
||||
- ANDROID_NDK: "C:\\Android\\android-sdk\\ndk\\20.1.5948944"
|
||||
- ANDROID_BUILD_VERSION: 31
|
||||
- ANDROID_TOOLS_VERSION: 31.0.0
|
||||
- GRADLE_OPTS: -Dorg.gradle.daemon=false
|
||||
steps:
|
||||
- checkout
|
||||
|
||||
- run:
|
||||
name: Install Node
|
||||
# Note: Version set separately for non-Windows builds, see above.
|
||||
command: |
|
||||
nvm install 16
|
||||
nvm use 16
|
||||
|
||||
# Setup Dependencies
|
||||
- run:
|
||||
name: Install Yarn
|
||||
command: choco install yarn
|
||||
|
||||
- run:
|
||||
name: Display Environment info
|
||||
command: npx envinfo@latest
|
||||
|
||||
- restore_cache:
|
||||
keys:
|
||||
- v1-win-yarn-cache-{{ arch }}-{{ checksum "yarn.lock" }}
|
||||
- run:
|
||||
name: "Yarn: Install Dependencies"
|
||||
command: yarn install --frozen-lockfile --non-interactive
|
||||
- save_cache:
|
||||
key: v1-win-yarn-cache-{{ arch }}-{{ checksum "yarn.lock" }}
|
||||
paths:
|
||||
- C:\Users\circleci\AppData\Local\Yarn
|
||||
|
||||
# Try to install the SDK up to 3 times, since network flakiness can cause install failures
|
||||
# Using a timeout of 9 mins, as circle ci will timeout if there is no output for 10 mins
|
||||
- run:
|
||||
name: Install Android SDK Tools
|
||||
command: choco install android-sdk --timeout 540; if (!$?) { choco install android-sdk --timeout 540 --force --forcedependencies}; if (!$?) { choco install android-sdk --force --forcedependencies}
|
||||
|
||||
- run:
|
||||
name: Setup Android SDKs
|
||||
command: |
|
||||
sdkmanager --licenses
|
||||
sdkmanager "system-images;android-21;google_apis;armeabi-v7a"
|
||||
sdkmanager "platforms;android-%ANDROID_BUILD_VERSION%"
|
||||
sdkmanager "build-tools;%ANDROID_TOOLS_VERSION%"
|
||||
sdkmanager "add-ons;addon-google_apis-google-23"
|
||||
sdkmanager "extras;android;m2repository"
|
||||
|
||||
# -------------------------
|
||||
# Run Tests
|
||||
- run:
|
||||
name: "Flow: Check Android"
|
||||
command: yarn flow-check-android
|
||||
- run:
|
||||
name: "Flow: Check iOS"
|
||||
command: yarn flow-check-ios
|
||||
- run:
|
||||
name: "Run Tests: JavaScript Tests"
|
||||
command: yarn test
|
||||
|
||||
# Optionally, run disabled tests
|
||||
- when:
|
||||
condition: << parameters.run_disabled_tests >>
|
||||
steps:
|
||||
- run: echo "Failing tests may be moved here temporarily."
|
||||
- run:
|
||||
name: Android Build
|
||||
command: ./gradlew.bat packages:rn-tester:android:app:assembleRelease
|
||||
|
||||
# -------------------------
|
||||
# JOBS: Coverage
|
||||
# -------------------------
|
||||
# Collect JavaScript test coverage
|
||||
js_coverage:
|
||||
executor: nodelts
|
||||
environment:
|
||||
- CI_BRANCH: $CIRCLE_BRANCH
|
||||
- CI_PULL_REQUEST: $CIRCLE_PULL_REQUEST
|
||||
- CI_BUILD_NUMBER: $CIRCLE_BUILD_NUM
|
||||
- CI_BUILD_URL: $CIRCLE_BUILD_URL
|
||||
steps:
|
||||
- checkout
|
||||
- setup_artifacts
|
||||
- run_yarn
|
||||
- run:
|
||||
name: Collect test coverage information
|
||||
command: |
|
||||
scripts/circleci/exec_swallow_error.sh yarn test --coverage --maxWorkers=2
|
||||
if [[ -e ./coverage/lcov.info ]]; then
|
||||
cat ./coverage/lcov.info | scripts/circleci/exec_swallow_error.sh ./node_modules/.bin/coveralls
|
||||
fi
|
||||
- store_artifacts:
|
||||
path: ~/react-native/coverage/
|
||||
|
||||
# -------------------------
|
||||
# JOBS: Releases
|
||||
# -------------------------
|
||||
prepare_package_for_release:
|
||||
parameters:
|
||||
version:
|
||||
type: string
|
||||
latest:
|
||||
type: boolean
|
||||
default: false
|
||||
executor: reactnativeios
|
||||
steps:
|
||||
- checkout
|
||||
- run_yarn
|
||||
- add_ssh_keys:
|
||||
fingerprints:
|
||||
- "1f:c7:61:c4:e2:ff:77:e3:cc:ca:a7:34:c2:79:e3:3c"
|
||||
- run:
|
||||
name: "Set new react-native version and commit changes"
|
||||
command: |
|
||||
node ./scripts/prepare-package-for-release.js -v << parameters.version >> -l << parameters.latest >>
|
||||
|
||||
build_npm_package:
|
||||
parameters:
|
||||
publish_npm_args:
|
||||
type: string
|
||||
default: --dry-run
|
||||
executor: reactnativeandroid
|
||||
steps:
|
||||
- run:
|
||||
name: Add github.com to SSH known hosts
|
||||
command: |
|
||||
mkdir -p ~/.ssh
|
||||
echo '|1|If6MU203eXTaaWL678YEfWkVMrw=|kqLeIAyTy8pzpj8x8Ae4Fr8Mtlc= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==' >> ~/.ssh/known_hosts
|
||||
- checkout
|
||||
- run_yarn
|
||||
- install_buck_tooling
|
||||
- download_buck_dependencies
|
||||
- download_gradle_dependencies
|
||||
# Only tagged releases and nightlies should be able to publish to npm
|
||||
- when:
|
||||
condition:
|
||||
or:
|
||||
- equal: [ --release, << parameters.publish_npm_args >> ]
|
||||
- equal: [ --nightly, << parameters.publish_npm_args >> ]
|
||||
steps:
|
||||
- run: echo "//registry.npmjs.org/:_authToken=${CIRCLE_NPM_TOKEN}" > ~/.npmrc
|
||||
- run: |
|
||||
git config --global user.email "react-native-bot@users.noreply.github.com"
|
||||
git config --global user.name "npm Deployment Script"
|
||||
echo "machine github.com login react-native-bot password $GITHUB_TOKEN" > ~/.netrc
|
||||
- run: node ./scripts/publish-npm.js << parameters.publish_npm_args >>
|
||||
- when:
|
||||
condition:
|
||||
equal: [ --dry-run, << parameters.publish_npm_args >> ]
|
||||
steps:
|
||||
- run:
|
||||
name: Build release package as a job artifact
|
||||
command: |
|
||||
mkdir -p build
|
||||
FILENAME=$(npm pack)
|
||||
mv $FILENAME build/
|
||||
echo $FILENAME > build/react-native-package-version
|
||||
- store_artifacts:
|
||||
path: ~/react-native/build/
|
||||
destination: build
|
||||
- persist_to_workspace:
|
||||
root: .
|
||||
paths:
|
||||
- build/*
|
||||
|
||||
- when:
|
||||
condition:
|
||||
matches: { pattern: '^pull\/.*$', value: << pipeline.git.branch >> }
|
||||
steps:
|
||||
- install_github_bot_deps
|
||||
- run:
|
||||
name: Post link to PR build artifacts (pull-bot)
|
||||
command: GITHUB_TOKEN="$PUBLIC_PULLBOT_GITHUB_TOKEN_A""$PUBLIC_PULLBOT_GITHUB_TOKEN_B" scripts/circleci/post-artifacts-link.sh || true
|
||||
|
||||
- when:
|
||||
condition:
|
||||
equal: [ --release, << parameters.publish_npm_args >> ]
|
||||
steps:
|
||||
- run:
|
||||
name: Update rn-diff-purge to generate upgrade-support diff
|
||||
command: |
|
||||
curl -X POST https://api.github.com/repos/react-native-community/rn-diff-purge/dispatches \
|
||||
-H "Accept: application/vnd.github.v3+json" \
|
||||
-H "Authorization: Bearer $REACT_NATIVE_BOT_GITHUB_TOKEN" \
|
||||
-d "{\"event_type\": \"publish\", \"client_payload\": { \"version\": \"${CIRCLE_TAG:1}\" }}"
|
||||
|
||||
# -------------------------
|
||||
# JOBS: Nightly
|
||||
# -------------------------
|
||||
nightly_job:
|
||||
machine:
|
||||
image: ubuntu-2004:202010-01
|
||||
steps:
|
||||
- run:
|
||||
name: Nightly
|
||||
command: |
|
||||
echo "Nightly build run"
|
||||
|
||||
|
||||
# -------------------------
|
||||
# PIPELINE PARAMETERS
|
||||
# -------------------------
|
||||
parameters:
|
||||
run_package_release_workflow_only:
|
||||
default: false
|
||||
type: boolean
|
||||
|
||||
release_latest:
|
||||
default: false
|
||||
type: boolean
|
||||
|
||||
release_version:
|
||||
default: "9999"
|
||||
type: string
|
||||
|
||||
# -------------------------
|
||||
# WORK FLOWS
|
||||
#
|
||||
# When creating a new workflow, make sure to include condition `unless: << pipeline.parameters.run_package_release_workflow_only >>`
|
||||
# It's setup this way so we can trigger a release via a POST
|
||||
# See limitations: https://support.circleci.com/hc/en-us/articles/360050351292-How-to-trigger-a-workflow-via-CircleCI-API-v2
|
||||
# -------------------------
|
||||
workflows:
|
||||
version: 2
|
||||
|
||||
tests:
|
||||
unless: << pipeline.parameters.run_package_release_workflow_only >>
|
||||
jobs:
|
||||
- build_npm_package:
|
||||
# Build a release package on every untagged commit, but do not publish to npm.
|
||||
publish_npm_args: --dry-run
|
||||
- test_js:
|
||||
run_disabled_tests: false
|
||||
filters:
|
||||
branches:
|
||||
ignore: gh-pages
|
||||
- test_android:
|
||||
run_disabled_tests: false
|
||||
filters:
|
||||
branches:
|
||||
ignore: gh-pages
|
||||
- test_android_template:
|
||||
requires:
|
||||
- build_npm_package
|
||||
filters:
|
||||
branches:
|
||||
ignore: gh-pages
|
||||
- test_ios_template:
|
||||
requires:
|
||||
- build_npm_package
|
||||
filters:
|
||||
branches:
|
||||
ignore: gh-pages
|
||||
- test_ios:
|
||||
name: test_ios_unit_jsc
|
||||
run_unit_tests: true
|
||||
filters:
|
||||
branches:
|
||||
ignore: gh-pages
|
||||
# DISABLED: USE_FRAMEWORKS=1 not supported by Flipper
|
||||
# - test_ios:
|
||||
# name: test_ios_unit_frameworks_jsc
|
||||
# use_frameworks: true
|
||||
# run_unit_tests: true
|
||||
- test_ios:
|
||||
name: test_ios_unit_hermes
|
||||
use_hermes: true
|
||||
run_unit_tests: true
|
||||
filters:
|
||||
branches:
|
||||
ignore: gh-pages
|
||||
# DISABLED: USE_FRAMEWORKS=1 not supported by Flipper
|
||||
# - test_ios:
|
||||
# name: test_ios_unit_frameworks_hermes
|
||||
# use_hermes: true
|
||||
# use_frameworks: true
|
||||
# run_unit_tests: true
|
||||
- test_js:
|
||||
name: test_js_prev_lts
|
||||
executor: nodeprevlts
|
||||
filters:
|
||||
branches:
|
||||
ignore: gh-pages
|
||||
- test_windows:
|
||||
filters:
|
||||
branches:
|
||||
ignore: gh-pages
|
||||
run_disabled_tests: false
|
||||
|
||||
# This workflow should only be triggered by release script
|
||||
package_release:
|
||||
when: << pipeline.parameters.run_package_release_workflow_only >>
|
||||
jobs:
|
||||
# This job will trigger publish_release workflow
|
||||
- prepare_package_for_release:
|
||||
name: prepare_package_for_release
|
||||
version: << pipeline.parameters.release_version >>
|
||||
latest : << pipeline.parameters.release_latest >>
|
||||
|
||||
publish_release:
|
||||
unless: << pipeline.parameters.run_package_release_workflow_only >>
|
||||
jobs:
|
||||
# This job will trigger when a version tag is pushed (by package_release)
|
||||
- build_npm_package:
|
||||
name: build_and_publish_npm_package
|
||||
context: react-native-bot
|
||||
publish_npm_args: --release
|
||||
# CircleCI filters are OR-ed, with all branches triggering by default and tags excluded by default
|
||||
# CircleCI env-vars are only set with the branch OR tag that triggered the job, not both.
|
||||
# In this case, CIRCLE_BRANCH is unset, but CIRCLE_TAG is set
|
||||
filters:
|
||||
# Both of the following conditions must be included!
|
||||
# Ignore any commit on any branch by default.
|
||||
branches:
|
||||
ignore: /.*/
|
||||
# Only act on version tags.
|
||||
tags:
|
||||
only: /v[0-9]+(\.[0-9]+)*(\-rc(\.[0-9]+)?)?/
|
||||
|
||||
analysis:
|
||||
unless: << pipeline.parameters.run_package_release_workflow_only >>
|
||||
jobs:
|
||||
# Run lints on every commit other than those to the gh-pages branch
|
||||
- analyze_code:
|
||||
filters:
|
||||
branches:
|
||||
ignore: gh-pages
|
||||
|
||||
# Run code checks on PRs from forks
|
||||
- analyze_pr:
|
||||
filters:
|
||||
branches:
|
||||
only: /^pull\/.*$/
|
||||
|
||||
# Gather coverage
|
||||
- js_coverage:
|
||||
filters:
|
||||
branches:
|
||||
ignore: gh-pages
|
||||
|
||||
nightly:
|
||||
unless: << pipeline.parameters.run_package_release_workflow_only >>
|
||||
triggers:
|
||||
- schedule:
|
||||
cron: "0 20 * * *"
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- main
|
||||
jobs:
|
||||
- nightly_job
|
||||
|
||||
- build_npm_package:
|
||||
publish_npm_args: --nightly
|
||||
@@ -1,91 +0,0 @@
|
||||
---
|
||||
AccessModifierOffset: -1
|
||||
AlignAfterOpenBracket: AlwaysBreak
|
||||
AlignConsecutiveAssignments: false
|
||||
AlignConsecutiveDeclarations: false
|
||||
AlignEscapedNewlinesLeft: true
|
||||
AlignOperands: false
|
||||
AlignTrailingComments: false
|
||||
AllowAllParametersOfDeclarationOnNextLine: false
|
||||
AllowShortBlocksOnASingleLine: false
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: Empty
|
||||
AllowShortIfStatementsOnASingleLine: false
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
AlwaysBreakAfterReturnType: None
|
||||
AlwaysBreakBeforeMultilineStrings: true
|
||||
AlwaysBreakTemplateDeclarations: true
|
||||
BinPackArguments: false
|
||||
BinPackParameters: false
|
||||
BraceWrapping:
|
||||
AfterClass: false
|
||||
AfterControlStatement: false
|
||||
AfterEnum: false
|
||||
AfterFunction: false
|
||||
AfterNamespace: false
|
||||
AfterObjCDeclaration: false
|
||||
AfterStruct: false
|
||||
AfterUnion: false
|
||||
BeforeCatch: false
|
||||
BeforeElse: false
|
||||
IndentBraces: false
|
||||
BreakBeforeBinaryOperators: None
|
||||
BreakBeforeBraces: Attach
|
||||
BreakBeforeTernaryOperators: true
|
||||
BreakConstructorInitializersBeforeComma: false
|
||||
BreakAfterJavaFieldAnnotations: false
|
||||
BreakStringLiterals: false
|
||||
ColumnLimit: 80
|
||||
CommentPragmas: '^ IWYU pragma:'
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
||||
ConstructorInitializerIndentWidth: 4
|
||||
ContinuationIndentWidth: 4
|
||||
Cpp11BracedListStyle: true
|
||||
DerivePointerAlignment: false
|
||||
DisableFormat: false
|
||||
ForEachMacros: [ FOR_EACH_RANGE, FOR_EACH, ]
|
||||
IncludeCategories:
|
||||
- Regex: '^<.*\.h(pp)?>'
|
||||
Priority: 1
|
||||
- Regex: '^<.*'
|
||||
Priority: 2
|
||||
- Regex: '.*'
|
||||
Priority: 3
|
||||
IndentCaseLabels: true
|
||||
IndentWidth: 2
|
||||
IndentWrappedFunctionNames: false
|
||||
KeepEmptyLinesAtTheStartOfBlocks: false
|
||||
MacroBlockBegin: ''
|
||||
MacroBlockEnd: ''
|
||||
MaxEmptyLinesToKeep: 1
|
||||
NamespaceIndentation: None
|
||||
ObjCBlockIndentWidth: 2
|
||||
ObjCSpaceAfterProperty: true
|
||||
ObjCSpaceBeforeProtocolList: true
|
||||
PenaltyBreakBeforeFirstCallParameter: 1
|
||||
PenaltyBreakComment: 300
|
||||
PenaltyBreakFirstLessLess: 120
|
||||
PenaltyBreakString: 1000
|
||||
PenaltyExcessCharacter: 1000000
|
||||
PenaltyReturnTypeOnItsOwnLine: 200
|
||||
PointerAlignment: Right
|
||||
ReflowComments: true
|
||||
SortIncludes: true
|
||||
SpaceAfterCStyleCast: false
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesBeforeTrailingComments: 1
|
||||
SpacesInAngles: false
|
||||
SpacesInContainerLiterals: true
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInParentheses: false
|
||||
SpacesInSquareBrackets: false
|
||||
Standard: Cpp11
|
||||
TabWidth: 8
|
||||
UseTab: Never
|
||||
---
|
||||
Language: ObjC
|
||||
ColumnLimit: 120
|
||||
BreakBeforeBraces: WebKit
|
||||
...
|
||||
@@ -1,20 +0,0 @@
|
||||
# EditorConfig is awesome: https://EditorConfig.org
|
||||
|
||||
# top-most EditorConfig file
|
||||
root = true
|
||||
|
||||
# Unix-style newlines with a newline ending every file
|
||||
[*]
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[*.gradle]
|
||||
indent_size = 4
|
||||
|
||||
[*.kts]
|
||||
indent_size = 4
|
||||
|
||||
[BUCK]
|
||||
indent_size = 4
|
||||
@@ -1,10 +1,5 @@
|
||||
**/main.js
|
||||
# node_modules ignored by default
|
||||
|
||||
**/staticBundle.js
|
||||
bots/node_modules
|
||||
docs/generatedComponentApiDocs.js
|
||||
flow/
|
||||
Libraries/Renderer/*
|
||||
**/main.js
|
||||
Libraries/vendor/**/*
|
||||
node_modules/
|
||||
packages/*/node_modules
|
||||
packages/react-native-codegen/lib
|
||||
|
||||
@@ -1,60 +1,218 @@
|
||||
{
|
||||
"root": true,
|
||||
"parser": "babel-eslint",
|
||||
|
||||
"extends": [
|
||||
"./packages/eslint-config-react-native-community/index.js"
|
||||
],
|
||||
"ecmaFeatures": {
|
||||
"jsx": true
|
||||
},
|
||||
|
||||
"env": {
|
||||
"es6": true,
|
||||
"jasmine": true,
|
||||
},
|
||||
|
||||
"plugins": [
|
||||
"@react-native/eslint-plugin-specs"
|
||||
"react"
|
||||
],
|
||||
|
||||
"overrides": [
|
||||
{
|
||||
"files": [
|
||||
"Libraries/**/*.js",
|
||||
],
|
||||
"rules": {
|
||||
"@react-native-community/no-haste-imports": 2,
|
||||
"@react-native-community/error-subclass-name": 2,
|
||||
"@react-native-community/platform-colors": 2,
|
||||
"@react-native/specs/react-native-modules": 2
|
||||
}
|
||||
},
|
||||
{
|
||||
"files": [
|
||||
"flow-typed/**/*.js",
|
||||
],
|
||||
"rules": {
|
||||
quotes: 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"files": [
|
||||
"**/__fixtures__/**/*.js",
|
||||
"**/__mocks__/**/*.js",
|
||||
"**/__tests__/**/*.js",
|
||||
"jest/**/*.js",
|
||||
"packages/rn-tester/**/*.js",
|
||||
],
|
||||
"globals": {
|
||||
// Expose some Jest globals for test helpers
|
||||
"afterAll": true,
|
||||
"afterEach": true,
|
||||
"beforeAll": true,
|
||||
"beforeEach": true,
|
||||
"expect": true,
|
||||
"jest": true,
|
||||
},
|
||||
},
|
||||
{
|
||||
"files": [
|
||||
"**/__tests__/**/*-test.js",
|
||||
],
|
||||
"env": {
|
||||
"jasmine": true,
|
||||
"jest": true
|
||||
}
|
||||
}
|
||||
]
|
||||
// Map from global var to bool specifying if it can be redefined
|
||||
"globals": {
|
||||
"__DEV__": true,
|
||||
"__dirname": false,
|
||||
"__fbBatchedBridgeConfig": false,
|
||||
"cancelAnimationFrame": false,
|
||||
"clearImmediate": true,
|
||||
"clearInterval": false,
|
||||
"clearTimeout": false,
|
||||
"console": false,
|
||||
"document": false,
|
||||
"escape": false,
|
||||
"exports": false,
|
||||
"fetch": false,
|
||||
"global": false,
|
||||
"jest": false,
|
||||
"Map": true,
|
||||
"module": false,
|
||||
"navigator": false,
|
||||
"process": false,
|
||||
"Promise": true,
|
||||
"requestAnimationFrame": true,
|
||||
"require": false,
|
||||
"Set": true,
|
||||
"setImmediate": true,
|
||||
"setInterval": false,
|
||||
"setTimeout": false,
|
||||
"window": false,
|
||||
"XMLHttpRequest": false,
|
||||
"pit": false
|
||||
},
|
||||
|
||||
"rules": {
|
||||
"comma-dangle": 0, // disallow trailing commas in object literals
|
||||
"no-cond-assign": 1, // disallow assignment in conditional expressions
|
||||
"no-console": 0, // disallow use of console (off by default in the node environment)
|
||||
"no-constant-condition": 0, // disallow use of constant expressions in conditions
|
||||
"no-control-regex": 1, // disallow control characters in regular expressions
|
||||
"no-debugger": 1, // disallow use of debugger
|
||||
"no-dupe-keys": 1, // disallow duplicate keys when creating object literals
|
||||
"no-empty": 0, // disallow empty statements
|
||||
"no-ex-assign": 1, // disallow assigning to the exception in a catch block
|
||||
"no-extra-boolean-cast": 1, // disallow double-negation boolean casts in a boolean context
|
||||
"no-extra-parens": 0, // disallow unnecessary parentheses (off by default)
|
||||
"no-extra-semi": 1, // disallow unnecessary semicolons
|
||||
"no-func-assign": 1, // disallow overwriting functions written as function declarations
|
||||
"no-inner-declarations": 0, // disallow function or variable declarations in nested blocks
|
||||
"no-invalid-regexp": 1, // disallow invalid regular expression strings in the RegExp constructor
|
||||
"no-negated-in-lhs": 1, // disallow negation of the left operand of an in expression
|
||||
"no-obj-calls": 1, // disallow the use of object properties of the global object (Math and JSON) as functions
|
||||
"no-regex-spaces": 1, // disallow multiple spaces in a regular expression literal
|
||||
"no-reserved-keys": 0, // disallow reserved words being used as object literal keys (off by default)
|
||||
"no-sparse-arrays": 1, // disallow sparse arrays
|
||||
"no-unreachable": 1, // disallow unreachable statements after a return, throw, continue, or break statement
|
||||
"use-isnan": 1, // disallow comparisons with the value NaN
|
||||
"valid-jsdoc": 0, // Ensure JSDoc comments are valid (off by default)
|
||||
"valid-typeof": 1, // Ensure that the results of typeof are compared against a valid string
|
||||
|
||||
// Best Practices
|
||||
// These are rules designed to prevent you from making mistakes. They either prescribe a better way of doing something or help you avoid footguns.
|
||||
|
||||
"block-scoped-var": 0, // treat var statements as if they were block scoped (off by default)
|
||||
"complexity": 0, // specify the maximum cyclomatic complexity allowed in a program (off by default)
|
||||
"consistent-return": 0, // require return statements to either always or never specify values
|
||||
"curly": 1, // specify curly brace conventions for all control statements
|
||||
"default-case": 0, // require default case in switch statements (off by default)
|
||||
"dot-notation": 1, // encourages use of dot notation whenever possible
|
||||
"eqeqeq": 1, // require the use of === and !==
|
||||
"guard-for-in": 0, // make sure for-in loops have an if statement (off by default)
|
||||
"no-alert": 1, // disallow the use of alert, confirm, and prompt
|
||||
"no-caller": 1, // disallow use of arguments.caller or arguments.callee
|
||||
"no-div-regex": 1, // disallow division operators explicitly at beginning of regular expression (off by default)
|
||||
"no-else-return": 0, // disallow else after a return in an if (off by default)
|
||||
"no-empty-label": 1, // disallow use of labels for anything other then loops and switches
|
||||
"no-eq-null": 0, // disallow comparisons to null without a type-checking operator (off by default)
|
||||
"no-eval": 1, // disallow use of eval()
|
||||
"no-extend-native": 1, // disallow adding to native types
|
||||
"no-extra-bind": 1, // disallow unnecessary function binding
|
||||
"no-fallthrough": 1, // disallow fallthrough of case statements
|
||||
"no-floating-decimal": 1, // disallow the use of leading or trailing decimal points in numeric literals (off by default)
|
||||
"no-implied-eval": 1, // disallow use of eval()-like methods
|
||||
"no-labels": 1, // disallow use of labeled statements
|
||||
"no-iterator": 1, // disallow usage of __iterator__ property
|
||||
"no-lone-blocks": 1, // disallow unnecessary nested blocks
|
||||
"no-loop-func": 0, // disallow creation of functions within loops
|
||||
"no-multi-str": 0, // disallow use of multiline strings
|
||||
"no-native-reassign": 0, // disallow reassignments of native objects
|
||||
"no-new": 1, // disallow use of new operator when not part of the assignment or comparison
|
||||
"no-new-func": 1, // disallow use of new operator for Function object
|
||||
"no-new-wrappers": 1, // disallows creating new instances of String,Number, and Boolean
|
||||
"no-octal": 1, // disallow use of octal literals
|
||||
"no-octal-escape": 1, // disallow use of octal escape sequences in string literals, such as var foo = "Copyright \251";
|
||||
"no-proto": 1, // disallow usage of __proto__ property
|
||||
"no-redeclare": 0, // disallow declaring the same variable more then once
|
||||
"no-return-assign": 1, // disallow use of assignment in return statement
|
||||
"no-script-url": 1, // disallow use of javascript: urls.
|
||||
"no-self-compare": 1, // disallow comparisons where both sides are exactly the same (off by default)
|
||||
"no-sequences": 1, // disallow use of comma operator
|
||||
"no-unused-expressions": 0, // disallow usage of expressions in statement position
|
||||
"no-void": 1, // disallow use of void operator (off by default)
|
||||
"no-warning-comments": 0, // disallow usage of configurable warning terms in comments": 1, // e.g. TODO or FIXME (off by default)
|
||||
"no-with": 1, // disallow use of the with statement
|
||||
"radix": 1, // require use of the second argument for parseInt() (off by default)
|
||||
"semi-spacing": 1, // require a space after a semi-colon
|
||||
"vars-on-top": 0, // requires to declare all vars on top of their containing scope (off by default)
|
||||
"wrap-iife": 0, // require immediate function invocation to be wrapped in parentheses (off by default)
|
||||
"yoda": 1, // require or disallow Yoda conditions
|
||||
|
||||
// Strict Mode
|
||||
// These rules relate to using strict mode.
|
||||
|
||||
"strict": [2, "global"], // require or disallow the "use strict" pragma in the global scope (off by default in the node environment)
|
||||
|
||||
// Variables
|
||||
// These rules have to do with variable declarations.
|
||||
|
||||
"no-catch-shadow": 1, // disallow the catch clause parameter name being the same as a variable in the outer scope (off by default in the node environment)
|
||||
"no-delete-var": 1, // disallow deletion of variables
|
||||
"no-label-var": 1, // disallow labels that share a name with a variable
|
||||
"no-shadow": 1, // disallow declaration of variables already declared in the outer scope
|
||||
"no-shadow-restricted-names": 1, // disallow shadowing of names such as arguments
|
||||
"no-undef": 2, // disallow use of undeclared variables unless mentioned in a /*global */ block
|
||||
"no-undefined": 0, // disallow use of undefined variable (off by default)
|
||||
"no-undef-init": 1, // disallow use of undefined when initializing variables
|
||||
"no-unused-vars": [1, {"vars": "all", "args": "none"}], // disallow declaration of variables that are not used in the code
|
||||
"no-use-before-define": 0, // disallow use of variables before they are defined
|
||||
|
||||
// Node.js
|
||||
// These rules are specific to JavaScript running on Node.js.
|
||||
|
||||
"handle-callback-err": 1, // enforces error handling in callbacks (off by default) (on by default in the node environment)
|
||||
"no-mixed-requires": 1, // disallow mixing regular variable and require declarations (off by default) (on by default in the node environment)
|
||||
"no-new-require": 1, // disallow use of new operator with the require function (off by default) (on by default in the node environment)
|
||||
"no-path-concat": 1, // disallow string concatenation with __dirname and __filename (off by default) (on by default in the node environment)
|
||||
"no-process-exit": 0, // disallow process.exit() (on by default in the node environment)
|
||||
"no-restricted-modules": 1, // restrict usage of specified node modules (off by default)
|
||||
"no-sync": 0, // disallow use of synchronous methods (off by default)
|
||||
|
||||
// Stylistic Issues
|
||||
// These rules are purely matters of style and are quite subjective.
|
||||
|
||||
"key-spacing": 0,
|
||||
"comma-spacing": 0,
|
||||
"no-multi-spaces": 0,
|
||||
"brace-style": 0, // enforce one true brace style (off by default)
|
||||
"camelcase": 0, // require camel case names
|
||||
"consistent-this": [1, "self"], // enforces consistent naming when capturing the current execution context (off by default)
|
||||
"eol-last": 1, // enforce newline at the end of file, with no multiple empty lines
|
||||
"func-names": 0, // require function expressions to have a name (off by default)
|
||||
"func-style": 0, // enforces use of function declarations or expressions (off by default)
|
||||
"new-cap": 0, // require a capital letter for constructors
|
||||
"new-parens": 1, // disallow the omission of parentheses when invoking a constructor with no arguments
|
||||
"no-nested-ternary": 0, // disallow nested ternary expressions (off by default)
|
||||
"no-array-constructor": 1, // disallow use of the Array constructor
|
||||
"no-lonely-if": 0, // disallow if as the only statement in an else block (off by default)
|
||||
"no-new-object": 1, // disallow use of the Object constructor
|
||||
"no-spaced-func": 1, // disallow space between function identifier and application
|
||||
"no-ternary": 0, // disallow the use of ternary operators (off by default)
|
||||
"no-trailing-spaces": 1, // disallow trailing whitespace at the end of lines
|
||||
"no-underscore-dangle": 0, // disallow dangling underscores in identifiers
|
||||
"no-mixed-spaces-and-tabs": 1, // disallow mixed spaces and tabs for indentation
|
||||
"quotes": [1, "single", "avoid-escape"], // specify whether double or single quotes should be used
|
||||
"quote-props": 0, // require quotes around object literal property names (off by default)
|
||||
"semi": 1, // require or disallow use of semicolons instead of ASI
|
||||
"sort-vars": 0, // sort variables within the same declaration block (off by default)
|
||||
"space-after-keywords": 1, // require a space after certain keywords (off by default)
|
||||
"space-in-brackets": 0, // require or disallow spaces inside brackets (off by default)
|
||||
"space-in-parens": 0, // require or disallow spaces inside parentheses (off by default)
|
||||
"space-infix-ops": 1, // require spaces around operators
|
||||
"space-return-throw-case": 1, // require a space after return, throw, and case
|
||||
"space-unary-ops": [1, { "words": true, "nonwords": false }], // require or disallow spaces before/after unary operators (words on by default, nonwords off by default)
|
||||
"max-nested-callbacks": 0, // specify the maximum depth callbacks can be nested (off by default)
|
||||
"one-var": 0, // allow just one var statement per function (off by default)
|
||||
"wrap-regex": 0, // require regex literals to be wrapped in parentheses (off by default)
|
||||
|
||||
// Legacy
|
||||
// The following rules are included for compatibility with JSHint and JSLint. While the names of the rules may not match up with the JSHint/JSLint counterpart, the functionality is the same.
|
||||
|
||||
"max-depth": 0, // specify the maximum depth that blocks can be nested (off by default)
|
||||
"max-len": 0, // specify the maximum length of a line in your program (off by default)
|
||||
"max-params": 0, // limits the number of parameters that can be used in the function declaration. (off by default)
|
||||
"max-statements": 0, // specify the maximum number of statement allowed in a function (off by default)
|
||||
"no-bitwise": 1, // disallow use of bitwise operators (off by default)
|
||||
"no-plusplus": 0, // disallow use of unary operators, ++ and -- (off by default)
|
||||
|
||||
"react/display-name": 0,
|
||||
"react/jsx-boolean-value": 0,
|
||||
"react/jsx-quotes": [1, "double", "avoid-escape"],
|
||||
"react/jsx-no-undef": 1,
|
||||
"react/jsx-sort-props": 0,
|
||||
"react/jsx-uses-react": 0,
|
||||
"react/jsx-uses-vars": 1,
|
||||
"react/no-did-mount-set-state": [1, "allow-in-func"],
|
||||
"react/no-did-update-set-state": [1, "allow-in-func"],
|
||||
"react/no-multi-comp": 0,
|
||||
"react/no-unknown-property": 0,
|
||||
"react/prop-types": 0,
|
||||
"react/react-in-jsx-scope": 0,
|
||||
"react/self-closing-comp": 1,
|
||||
"react/wrap-multilines": 0
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,75 +1,51 @@
|
||||
[ignore]
|
||||
; We fork some components by platform
|
||||
.*/*[.]android.js
|
||||
|
||||
; Ignore templates for 'react-native init'
|
||||
<PROJECT_ROOT>/template/.*
|
||||
# We fork some components by platform.
|
||||
.*/*.web.js
|
||||
.*/*.android.js
|
||||
|
||||
; Ignore the Dangerfile
|
||||
<PROJECT_ROOT>/bots/dangerfile.js
|
||||
# Some modules have their own node_modules with overlap
|
||||
.*/node_modules/node-haste/.*
|
||||
|
||||
; Ignore "BUCK" generated dirs
|
||||
<PROJECT_ROOT>/\.buckd/
|
||||
# Ignore react-tools where there are overlaps, but don't ignore anything that
|
||||
# react-native relies on
|
||||
.*/node_modules/react-tools/src/React.js
|
||||
.*/node_modules/react-tools/src/renderers/shared/event/EventPropagators.js
|
||||
.*/node_modules/react-tools/src/renderers/shared/event/eventPlugins/ResponderEventPlugin.js
|
||||
.*/node_modules/react-tools/src/shared/vendor/core/ExecutionEnvironment.js
|
||||
|
||||
; Flow doesn't support platforms
|
||||
.*/Libraries/Utilities/LoadingView.js
|
||||
# Ignore commoner tests
|
||||
.*/node_modules/commoner/test/.*
|
||||
|
||||
.*/node_modules/resolve/test/resolver/malformed_package_json/package\.json$
|
||||
# See https://github.com/facebook/flow/issues/442
|
||||
.*/react-tools/node_modules/commoner/lib/reader.js
|
||||
|
||||
[untyped]
|
||||
.*/node_modules/@react-native-community/cli/.*/.*
|
||||
# Ignore jest
|
||||
.*/node_modules/jest-cli/.*
|
||||
|
||||
# Ignore Website
|
||||
.*/website/.*
|
||||
|
||||
[include]
|
||||
|
||||
[declarations]
|
||||
.*/node_modules/.*
|
||||
|
||||
[libs]
|
||||
interface.js
|
||||
flow/
|
||||
Libraries/react-native/react-native-interface.js
|
||||
|
||||
[options]
|
||||
emoji=true
|
||||
|
||||
exact_by_default=true
|
||||
|
||||
format.bracket_spacing=false
|
||||
|
||||
module.file_ext=.js
|
||||
module.file_ext=.json
|
||||
module.file_ext=.ios.js
|
||||
module.system=haste
|
||||
|
||||
munge_underscores=true
|
||||
|
||||
module.name_mapper='^react-native$' -> '<PROJECT_ROOT>/index.js'
|
||||
module.name_mapper='^react-native/\(.*\)$' -> '<PROJECT_ROOT>/\1'
|
||||
module.name_mapper='^@?[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> '<PROJECT_ROOT>/Libraries/Image/RelativeImageStub'
|
||||
module.name_mapper='^image![a-zA-Z0-9$_-]+$' -> 'GlobalImageStub'
|
||||
module.name_mapper='^[./a-zA-Z0-9$_-]+\.png$' -> 'RelativeImageStub'
|
||||
|
||||
suppress_type=$FlowIssue
|
||||
suppress_type=$FlowFixMe
|
||||
suppress_type=$FlowFixMeProps
|
||||
suppress_type=$FlowFixMeState
|
||||
suppress_type=$FlowFixMeEmpty
|
||||
suppress_type=$FixMe
|
||||
|
||||
[lints]
|
||||
sketchy-null-number=warn
|
||||
sketchy-null-mixed=warn
|
||||
sketchy-number=warn
|
||||
untyped-type-import=warn
|
||||
nonstrict-import=warn
|
||||
deprecated-type=error
|
||||
unsafe-getters-setters=warn
|
||||
unnecessary-invariant=warn
|
||||
signature-verification-failure=warn
|
||||
|
||||
[strict]
|
||||
deprecated-type
|
||||
nonstrict-import
|
||||
sketchy-null
|
||||
unclear-type
|
||||
unsafe-getters-setters
|
||||
untyped-import
|
||||
untyped-type-import
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(1[0-7]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(1[0-7]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)? #[0-9]+
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy
|
||||
|
||||
[version]
|
||||
^0.170.0
|
||||
0.17.0
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
[ignore]
|
||||
; We fork some components by platform
|
||||
.*/*[.]ios.js
|
||||
|
||||
; Ignore templates for 'react-native init'
|
||||
<PROJECT_ROOT>/template/.*
|
||||
|
||||
; Ignore the Dangerfile
|
||||
<PROJECT_ROOT>/bots/dangerfile.js
|
||||
|
||||
; Ignore "BUCK" generated dirs
|
||||
<PROJECT_ROOT>/\.buckd/
|
||||
|
||||
; Flow doesn't support platforms
|
||||
.*/Libraries/Utilities/LoadingView.js
|
||||
|
||||
.*/node_modules/resolve/test/resolver/malformed_package_json/package\.json$
|
||||
|
||||
[untyped]
|
||||
.*/node_modules/@react-native-community/cli/.*/.*
|
||||
|
||||
[include]
|
||||
|
||||
[declarations]
|
||||
.*/node_modules/.*
|
||||
|
||||
[libs]
|
||||
interface.js
|
||||
flow/
|
||||
|
||||
[options]
|
||||
emoji=true
|
||||
|
||||
exact_by_default=true
|
||||
|
||||
format.bracket_spacing=false
|
||||
|
||||
module.file_ext=.js
|
||||
module.file_ext=.json
|
||||
module.file_ext=.android.js
|
||||
|
||||
munge_underscores=true
|
||||
|
||||
module.name_mapper='^react-native$' -> '<PROJECT_ROOT>/index.js'
|
||||
module.name_mapper='^react-native/\(.*\)$' -> '<PROJECT_ROOT>/\1'
|
||||
module.name_mapper='^@?[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> '<PROJECT_ROOT>/Libraries/Image/RelativeImageStub'
|
||||
|
||||
suppress_type=$FlowIssue
|
||||
suppress_type=$FlowFixMe
|
||||
suppress_type=$FlowFixMeProps
|
||||
suppress_type=$FlowFixMeState
|
||||
suppress_type=$FlowFixMeEmpty
|
||||
|
||||
[lints]
|
||||
sketchy-null-number=warn
|
||||
sketchy-null-mixed=warn
|
||||
sketchy-number=warn
|
||||
untyped-type-import=warn
|
||||
nonstrict-import=warn
|
||||
deprecated-type=error
|
||||
unsafe-getters-setters=warn
|
||||
unnecessary-invariant=warn
|
||||
signature-verification-failure=warn
|
||||
|
||||
[strict]
|
||||
deprecated-type
|
||||
nonstrict-import
|
||||
sketchy-null
|
||||
unclear-type
|
||||
unsafe-getters-setters
|
||||
untyped-import
|
||||
untyped-type-import
|
||||
|
||||
[version]
|
||||
^0.170.0
|
||||
@@ -0,0 +1,6 @@
|
||||
# Force LF line endings for Bash scripts. On Windows the rest of the source
|
||||
# files will typically have CR+LF endings (Git default on Windows), but Bash
|
||||
# scripts need to have LF endings to work (under Cygwin), thus override to force
|
||||
# that.
|
||||
gradlew text eol=lf
|
||||
*.sh text eol=lf
|
||||
@@ -1,40 +0,0 @@
|
||||
# See https://help.github.com/en/articles/about-code-owners
|
||||
# to learn more about code owners.
|
||||
# Order is important; the last matching pattern takes the most
|
||||
# precedence. You may specify either a GitHub username, or an
|
||||
# email address if you prefer, as the code owner.
|
||||
|
||||
# Any Markdown file anywhere in the repository
|
||||
**/*.md @hramos @cpojer
|
||||
|
||||
# GitHub Settings, Bots
|
||||
/.github/ @hramos
|
||||
/bots @hramos
|
||||
|
||||
# Continuous Integration
|
||||
/.circleci/ @hramos
|
||||
/.circleci/Dockerfiles @gengjiawen
|
||||
/.appveyor/ @gengjiawen
|
||||
|
||||
# Internals
|
||||
React/Base/* @shergin
|
||||
React/Views/* @shergin
|
||||
React/Modules/* @shergin
|
||||
React/CxxBridge/* @mhorowitz
|
||||
|
||||
# Components and APIs
|
||||
ReactAndroid/src/main/java/com/facebook/react/animated/* @janicduplessis
|
||||
Libraries/Animated/* @janicduplessis
|
||||
Libraries/NativeAnimation/* @janicduplessis
|
||||
Libraries/Image/* @shergin
|
||||
Libraries/Text/* @shergin
|
||||
|
||||
# Modifications to package.json typically require
|
||||
# additional effort from a Facebook employee to land
|
||||
/package.json @hramos @cpojer
|
||||
|
||||
# These should not be modified through a GitHub PR
|
||||
LICENSE* @hramos @cpojer @yungsters
|
||||
|
||||
# The eslint-config-react-native-community package requires manual publishing after merging
|
||||
/packages/eslint-config-react-native-community/* @matt-oakes
|
||||
@@ -1,4 +0,0 @@
|
||||
✋ To keep the backlog clean and actionable, issues will be
|
||||
🚫 closed if they do not follow one of the issue templates:
|
||||
👉 https://github.com/facebook/react-native/issues/new/choose
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
name: 🐛 Bug Report
|
||||
description: Report a reproducible bug or regression in React Native.
|
||||
labels: ["Needs: Triage :mag:"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Please provide all the information requested. Issues that do not follow this format are likely to stall.
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: Description
|
||||
description: Please provide a clear and concise description of what the bug is. Include screenshots if needed. Please test using the latest React Native release to make sure your issue has not already been fixed - https://reactnative.dev/docs/upgrading.html
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: version
|
||||
attributes:
|
||||
label: Version
|
||||
description: What react-native version does this appear on?
|
||||
placeholder: ex. 0.66.0
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: react-native-info
|
||||
attributes:
|
||||
label: Output of `npx react-native info`
|
||||
description: Run `npx react-native info` in your terminal, copy and paste the results here.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: reproduction
|
||||
attributes:
|
||||
label: Steps to reproduce
|
||||
description: Provide a detailed list of steps that reproduce the issue.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: extra
|
||||
attributes:
|
||||
label: Snack, code example, screenshot, or link to a repository
|
||||
description: |
|
||||
Please provide a Snack (https://snack.expo.io/), a link to a repository on GitHub, or provide a minimal code example that reproduces the problem.
|
||||
You may provide a screenshot of the application if you think it is relevant to your bug report.
|
||||
Here are some tips for providing a minimal example: https://stackoverflow.com/help/mcve
|
||||
validations:
|
||||
required: false
|
||||
@@ -1,11 +0,0 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: 📃 Documentation Issue
|
||||
url: https://github.com/facebook/react-native-website/issues
|
||||
about: Please report documentation issues in the React Native website repository.
|
||||
- name: 🤔 Questions and Help
|
||||
url: https://reactnative.dev/help
|
||||
about: Looking for help with your app? Please refer to the React Native community's support resources.
|
||||
- name: 🚀 Discussions and Proposals
|
||||
url: https://github.com/react-native-community/discussions-and-proposals
|
||||
about: Discuss the future of React Native in the React Native community's discussions and proposals repository.
|
||||
@@ -1,46 +0,0 @@
|
||||
name: Upgrade - Build Regression
|
||||
description: If you are upgrading to a new React Native version (stable or pre-release) and encounter a build regression.
|
||||
labels: ["Needs: Triage :mag:", "Type: Upgrade Issue"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Please use this form to file an issue if you have upgarded or are upgrading to [latest stable release](https://github.com/facebook/react-native/releases/latest) and have experienced a regression (something that used to work in previous version).
|
||||
- type: input
|
||||
id: new-version
|
||||
attributes:
|
||||
label: New Version
|
||||
description: This is the version you are attempting to upgrade to.
|
||||
placeholder: ex. 0.66.1
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: old-version
|
||||
attributes:
|
||||
label: Old Version
|
||||
description: This is the version you were on where the behavior was working.
|
||||
placeholder: ex. 0.65.1
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: target
|
||||
attributes:
|
||||
label: Build Target(s)
|
||||
description: What target(s) are encountering this issue?
|
||||
placeholder: iOS simulator in release flavor
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: react-native-info
|
||||
attributes:
|
||||
label: Output of `react-native info`
|
||||
description: Run `react-native info` in your terminal, copy and paste the results here.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: reproduction
|
||||
attributes:
|
||||
label: Issue and Reproduction Steps
|
||||
description: Please describe the issue and list out commands run to reproduce.
|
||||
validations:
|
||||
required: true
|
||||
@@ -1,17 +0,0 @@
|
||||
<!-- Thanks for submitting a pull request! We appreciate you spending the time to work on these changes. Please provide enough information so that others can review your pull request. The three fields below are mandatory. -->
|
||||
|
||||
## Summary
|
||||
|
||||
<!-- Explain the **motivation** for making this change. What existing problem does the pull request solve? -->
|
||||
|
||||
## Changelog
|
||||
|
||||
<!-- Help reviewers and the release process by writing your own changelog entry. For an example, see:
|
||||
https://github.com/facebook/react-native/wiki/Changelog
|
||||
-->
|
||||
|
||||
[CATEGORY] [TYPE] - Message
|
||||
|
||||
## Test Plan
|
||||
|
||||
<!-- Demonstrate the code is solid. Example: The exact commands you ran and their output, screenshots / videos if the pull request changes the user interface. -->
|
||||
@@ -1,35 +0,0 @@
|
||||
Thanks for using React Native! If you need help with your React Native app, the right place to go depends on the type of help that you need.
|
||||
|
||||
|
||||
## 🤔 I have a question or need help with my React Native app.
|
||||
|
||||
If you have a coding question related to React Native, it might be better suited for Stack Overflow. It's a great place to browse through [frequent questions about using React Native](https://stackoverflow.com/questions/tagged/react-native?sort=frequent&pageSize=15), as well as [ask for help with specific questions](https://stackoverflow.com/questions/tagged/react-native).
|
||||
|
||||
[Reactiflux](https://www.reactiflux.com/) is an active community of React and React Native developers. If you are looking for immediate assistance or have a general question about React Native, the #react-native channel is a good place to start.
|
||||
|
||||
|
||||
## 📃 I found something that seems wrong in the documentation.
|
||||
|
||||
The React Native website is hosted on a [separate repository](https://github.com/facebook/react-native-website). If you want to report something that is wrong or missing from the documentation, [please open a new issue there](https://github.com/facebook/react-native-website/issues).
|
||||
|
||||
|
||||
## 🐛 I found a bug in React Native.
|
||||
|
||||
If you want to report a reproducible bug or regression in the React Native library, you can [create a new issue](https://github.com/facebook/react-native/issues/new?labels=Type%3A+Bug+Report&template=bug_report.md). It's a good idea to look through [open issues](https://github.com/facebook/react-native/issues) before doing so, as someone else may have reported a similar issue.
|
||||
|
||||
|
||||
## 🚀 I want to discuss the future of React Native.
|
||||
|
||||
If you'd like to discuss topics related to the future of React Native, please check out the [React Native Community Discussions and Proposals](https://github.com/react-native-community/discussions-and-proposals) repository.
|
||||
|
||||
|
||||
## 💬 I want to talk to other React Native developers.
|
||||
|
||||
If you want to participate in casual discussions about the use of React Native, consider participating in one of the following forums:
|
||||
|
||||
- [Reactiflux Discord Server](https://www.reactiflux.com)
|
||||
- [Spectrum Chat](https://spectrum.chat/react-native)
|
||||
- [React Native Community Facebook Group](https://www.facebook.com/groups/react.native.community)
|
||||
|
||||
|
||||
> For a full list of community resources, check out [React Native's Community page](https://reactnative.dev/help).
|
||||
@@ -1,52 +0,0 @@
|
||||
# Configuration for Respond To Issue Based on Label https://github.com/marketplace/actions/respond-to-issue-based-on-label
|
||||
|
||||
"Type: Invalid":
|
||||
close: true
|
||||
"Type: Question":
|
||||
comment: >
|
||||
We are using GitHub issues exclusively to track bugs in React Native. GitHub may not be the ideal place to ask a question, but you can try asking over on [Stack Overflow](http://stackoverflow.com/questions/tagged/react-native), or on [Reactiflux](https://www.reactiflux.com/).
|
||||
close: true
|
||||
"Type: Docs":
|
||||
comment: >
|
||||
Please report documentation issues in the [`react-native-website`](https://github.com/facebook/react-native-website/issues) repository.
|
||||
close: true
|
||||
"Resolution: For Stack Overflow":
|
||||
comment: >
|
||||
We are using GitHub issues exclusively to track bugs in the core React Native library. Please try asking over on [Stack Overflow](http://stackoverflow.com/questions/tagged/react-native) as it is better suited for this type of question.
|
||||
close: true
|
||||
"Needs: Issue Template":
|
||||
comment: >
|
||||
<table><tbody><tr><th width="50">:warning:</th><th width="100%">
|
||||
Missing Required Fields
|
||||
</th></tr><tr><td>:information_source:</td><td>
|
||||
It looks like your issue may be missing some necessary information. GitHub provides an example template whenever a <a href="https://github.com/facebook/react-native/issues/new?template=bug_report.md">new issue is created</a>. Could you go back and make sure to fill out the template? You may edit this issue, or close it and open a new one.
|
||||
</td></tr></tbody></table>
|
||||
labels:
|
||||
- "Needs: Author Feedback"
|
||||
"Needs: Environment Info":
|
||||
comment: >
|
||||
<table><tbody><tr><th width="50">:warning:</th><th width="100%">
|
||||
Missing Environment Information
|
||||
</th></tr><tr><td>:information_source:</td><td>
|
||||
Your issue may be missing information about your development environment. You can obtain the missing information by running <code>react-native info</code> in a console.
|
||||
</td></tr></tbody></table>
|
||||
labels:
|
||||
- "Needs: Author Feedback"
|
||||
"Needs: Verify on Latest Version":
|
||||
comment: >
|
||||
<table><tbody><tr><th width="50">:warning:</th><th width="100%">
|
||||
Using Old Version
|
||||
</th></tr><tr><td>:information_source:</td><td>
|
||||
It looks like you are using an older version of React Native. Please <a href="https://reactnative.dev/docs/upgrading">upgrade</a> to the latest version, and verify if the issue persists. If it does not, please let us know so we can close out this issue. This helps us ensure we are looking at issues that still exist in the current release.
|
||||
</td></tr></tbody></table>
|
||||
labels:
|
||||
- "Needs: Author Feedback"
|
||||
"Needs: Repro":
|
||||
comment: >
|
||||
<table><tbody><tr><th width="50">:warning:</th><th width="100%">
|
||||
Missing Reproducible Example
|
||||
</th></tr><tr><td>:information_source:</td><td>
|
||||
It looks like your issue is missing a reproducible example. Please provide a <a href="https://snack.expo.io">Snack</a> or a repository that demonstrates the issue you are reporting in a <a href="https://stackoverflow.com/help/minimal-reproducible-example">minimal, complete, and reproducible</a> manner.
|
||||
</td></tr></tbody></table>
|
||||
labels:
|
||||
- "Needs: Author Feedback"
|
||||
@@ -1,16 +0,0 @@
|
||||
name: Apply version label to issue
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [opened, edited]
|
||||
|
||||
jobs:
|
||||
add-version-label-issue:
|
||||
runs-on: ubuntu-latest
|
||||
continue-on-error: true
|
||||
|
||||
steps:
|
||||
- uses: react-native-community/actions-apply-version-label@v0.0.3
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
required-label: "Type: Upgrade Issue"
|
||||
@@ -1,21 +0,0 @@
|
||||
name: Issue Needs Attention
|
||||
# This workflow is triggered on issue comments.
|
||||
on:
|
||||
issue_comment:
|
||||
types: created
|
||||
|
||||
jobs:
|
||||
applyNeedsAttentionLabel:
|
||||
name: Apply Needs Attention Label
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Apply Needs Attention Label
|
||||
uses: hramos/needs-attention@v1
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
response-required-label: "Needs: Author Feedback"
|
||||
needs-attention-label: "Needs: Attention"
|
||||
id: needs-attention
|
||||
- name: Result
|
||||
run: echo '${{ steps.needs-attention.outputs.result }}'
|
||||
@@ -1,16 +0,0 @@
|
||||
name: On Issue Labeled
|
||||
# This workflow is triggered when a label is added to an issue.
|
||||
on:
|
||||
issues:
|
||||
types: labeled
|
||||
|
||||
jobs:
|
||||
respondToIssueBasedOnLabel:
|
||||
name: Respond to Issue Based on Label
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Respond to Issue Based on Label
|
||||
uses: hramos/respond-to-issue-based-on-label@v2
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -1,19 +0,0 @@
|
||||
name: Mark stale issues and pull requests
|
||||
on:
|
||||
schedule:
|
||||
- cron: "30 1 * * *"
|
||||
jobs:
|
||||
stale:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
steps:
|
||||
- uses: actions/stale@v4
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
days-before-stale: 365
|
||||
stale-issue-message: 'This issue is stale because it has been open 365 days with no activity. Remove stale label or comment or this will be closed in 7 days.'
|
||||
stale-pr-message: 'This PR is stale because it has been open 365 days with no activity. Remove stale label or comment or this will be closed in 7 days.'
|
||||
close-issue-message: 'This issue was closed because it has been stalled for 7 days with no activity.'
|
||||
close-pr-message: 'This PR was closed because it has been stalled for 7 days with no activity.'
|
||||
@@ -1,19 +0,0 @@
|
||||
name: Test Docker Android Image
|
||||
# This workflow is triggered on commits to main and pull requests.
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request:
|
||||
types: [ synchronize ]
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
test-docker-android:
|
||||
name: Test Docker
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Build Docker image with Android test app
|
||||
run: npm run docker-build-android
|
||||
@@ -21,100 +21,19 @@ DerivedData
|
||||
*.xcuserstate
|
||||
project.xcworkspace
|
||||
|
||||
# Gradle
|
||||
/build/
|
||||
/packages/react-native-gradle-plugin/build/
|
||||
/packages/rn-tester/android/app/.cxx/
|
||||
/packages/rn-tester/android/app/build/
|
||||
/packages/rn-tester/android/app/gradle/
|
||||
/packages/rn-tester/android/app/gradlew
|
||||
/packages/rn-tester/android/app/gradlew.bat
|
||||
/ReactAndroid/build/
|
||||
/ReactAndroid/.cxx/
|
||||
/ReactAndroid/gradle/
|
||||
/ReactAndroid/gradlew
|
||||
/ReactAndroid/gradlew.bat
|
||||
/template/android/app/build/
|
||||
/template/android/build/
|
||||
|
||||
# Buck
|
||||
.buckd
|
||||
buck-out
|
||||
/.lsp.buckd
|
||||
/.lsp-buck-out
|
||||
/ReactAndroid/src/main/jni/prebuilt/lib/
|
||||
/ReactAndroid/src/main/gen
|
||||
|
||||
# Android Studio
|
||||
.project
|
||||
.settings
|
||||
.classpath
|
||||
|
||||
# Watchman
|
||||
.watchmanconfig
|
||||
# Xcode, Gradle
|
||||
build/
|
||||
|
||||
# Android
|
||||
.idea
|
||||
.gradle
|
||||
local.properties
|
||||
*.iml
|
||||
/android/
|
||||
|
||||
# Node
|
||||
node_modules
|
||||
*.log
|
||||
.nvm
|
||||
/bots/node_modules/
|
||||
package-lock.json
|
||||
|
||||
# OS X
|
||||
.DS_Store
|
||||
|
||||
# Test generated files
|
||||
/ReactAndroid/src/androidTest/assets/AndroidTestBundle.js
|
||||
*.js.meta
|
||||
|
||||
/coverage
|
||||
/third-party
|
||||
|
||||
# Root dir shouldn't have Xcode project
|
||||
/*.xcodeproj
|
||||
|
||||
# ReactCommon subdir shouldn't have Xcode project
|
||||
/ReactCommon/**/*.xcodeproj
|
||||
/packages/rn-tester/build
|
||||
/packages/rn-tester/android/app/build/*
|
||||
|
||||
# Libs that shouldn't have Xcode project
|
||||
/Libraries/FBLazyVector/**/*.xcodeproj
|
||||
/Libraries/RCTRequired/**/*.xcodeproj
|
||||
/React/CoreModules/**/*.xcodeproj
|
||||
/React/FBReactNativeSpec/**/*.xcodeproj
|
||||
/packages/react-native-codegen/**/*.xcodeproj
|
||||
|
||||
# Ruby Gems (Bundler)
|
||||
/vendor
|
||||
/template/vendor
|
||||
|
||||
# iOS / CocoaPods
|
||||
/template/ios/build/
|
||||
/template/ios/Pods/
|
||||
/template/ios/Podfile.lock
|
||||
/packages/rn-tester/Gemfile.lock
|
||||
|
||||
# Ignore RNTester specific Pods, but keep the __offline_mirrors__ here.
|
||||
/packages/rn-tester/Pods/*
|
||||
!/packages/rn-tester/Pods/__offline_mirrors__
|
||||
|
||||
# react-native-codegen
|
||||
/React/FBReactNativeSpec/FBReactNativeSpec
|
||||
/packages/react-native-codegen/lib
|
||||
/ReactCommon/react/renderer/components/rncore/
|
||||
/packages/rn-tester/NativeModuleExample/ScreenshotManagerSpec*
|
||||
|
||||
# Visual studio
|
||||
.vscode
|
||||
.vs
|
||||
|
||||
# Android memory profiler files
|
||||
*.hprof
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"arrowParens": "avoid",
|
||||
"bracketSameLine": true,
|
||||
"bracketSpacing": false,
|
||||
"requirePragma": true,
|
||||
"singleQuote": true,
|
||||
"trailingComma": "all"
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
2.7.4
|
||||
@@ -0,0 +1,85 @@
|
||||
language: objective-c
|
||||
|
||||
osx_image: xcode7
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- node_modules
|
||||
- .nvm
|
||||
|
||||
install:
|
||||
- brew reinstall nvm
|
||||
- mkdir -p .nvm
|
||||
- export NVM_DIR="$PWD/.nvm"
|
||||
- source $(brew --prefix nvm)/nvm.sh
|
||||
- nvm install 4
|
||||
- rm -Rf "${TMPDIR}/jest_preprocess_cache"
|
||||
- npm config set spin=false
|
||||
- npm install -g flow-bin@`node -p "require('fs').readFileSync('.flowconfig', 'utf8').split('[version]')[1].trim()"`
|
||||
- npm install
|
||||
|
||||
script:
|
||||
- |
|
||||
if [ "$TEST_TYPE" = objc ]
|
||||
then
|
||||
|
||||
./scripts/objc-test.sh
|
||||
|
||||
elif [ "$TEST_TYPE" = js ]
|
||||
then
|
||||
|
||||
flow check && npm test -- '\/Libraries\/'
|
||||
|
||||
elif [ "$TEST_TYPE" = packager ]
|
||||
then
|
||||
|
||||
npm test -- '\/packager\/'
|
||||
|
||||
elif [ "$TEST_TYPE" = cli ]
|
||||
then
|
||||
|
||||
npm test -- '\/(local|private|react-native)-cli\/'
|
||||
|
||||
elif [ "$TEST_TYPE" = build_website ]
|
||||
then
|
||||
|
||||
cd website
|
||||
$(which npm) install
|
||||
./setup.sh
|
||||
if [ "$TRAVIS_PULL_REQUEST" = false ] && [ "$TRAVIS_BRANCH" = master ]; then
|
||||
# Automatically publish the website
|
||||
echo "machine github.com login reactjs-bot password $GITHUB_TOKEN" >~/.netrc
|
||||
./publish.sh
|
||||
else
|
||||
# Make sure the website builds without error
|
||||
node server/generate.js
|
||||
fi
|
||||
|
||||
elif [ "$TEST_TYPE" = e2e ]
|
||||
then
|
||||
./scripts/e2e-test.sh
|
||||
else
|
||||
echo "Unknown test type: $TEST_TYPE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
env:
|
||||
matrix:
|
||||
- TEST_TYPE=objc
|
||||
- TEST_TYPE=js
|
||||
- TEST_TYPE=packager
|
||||
- TEST_TYPE=cli
|
||||
- TEST_TYPE=build_website
|
||||
- TEST_TYPE=e2e
|
||||
global:
|
||||
# $GITHUB_TOKEN
|
||||
- secure: "HlmG8M2DmBUSBh6KH1yVIe/8gR4iibg4WfcHq1x/xYQxGbvleq7NOo04V6eFHnl9cvZCu+PKH0841WLnGR7c4BBf47GVu/o16nXzggPumHKy++lDzxFPlJ1faMDfjg/5vjbAxRUe7D3y98hQSeGHH4tedc8LvTaFLVu7iiGqvjU="
|
||||
# $APPETIZE_TOKEN
|
||||
- secure: "egsvVSpszTzrNd6bN62DsVAzMiSZI/OHgdizfPryqvqWBf655ztE6XFQSEFNpuIAzSKDDF25ioT8iPfVsbC1iK6HDWHfmqYxML0L+OoU0gi+hV2oKUBFZDZ1fwSnFoWuBdNdMDpLlUxvJp6N1WyfNOB2dxuZUt8eTt48Hi3+Hpc="
|
||||
# $S3_TOKEN
|
||||
- secure: "lY8JZPA0A7zT7L5KF9BBg34XYWIeR/RJiEvE7l7oVr88KnEPtyd//79eHhhVKnUnav7zsk5QJwkcX0MxKTp/dp4G0Am+zOX+sfA8kQrJ+2/+FzFW7AEsW/kHByfaIEIly9DQvUFt4I4oMm8nQZysJLahDgNWglyI3RTuJp//hcY="
|
||||
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- /^.*-stable$/
|
||||
@@ -1,77 +0,0 @@
|
||||
# Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as
|
||||
contributors and maintainers pledge to make participation in our project and
|
||||
our community a harassment-free experience for everyone, regardless of age, body
|
||||
size, disability, ethnicity, sex characteristics, gender identity and expression,
|
||||
level of experience, education, socio-economic status, nationality, personal
|
||||
appearance, race, religion, or sexual identity and orientation.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment
|
||||
include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or
|
||||
advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic
|
||||
address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable
|
||||
behavior and are expected to take appropriate and fair corrective action in
|
||||
response to any instances of unacceptable behavior.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or
|
||||
reject comments, commits, code, wiki edits, issues, and other contributions
|
||||
that are not aligned to this Code of Conduct, or to ban temporarily or
|
||||
permanently any contributor for other behaviors that they deem inappropriate,
|
||||
threatening, offensive, or harmful.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies within all project spaces, and it also applies when
|
||||
an individual is representing the project or its community in public spaces.
|
||||
Examples of representing a project or community include using an official
|
||||
project e-mail address, posting via an official social media account, or acting
|
||||
as an appointed representative at an online or offline event. Representation of
|
||||
a project may be further defined and clarified by project maintainers.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported by contacting the project team at <opensource-conduct@fb.com>. All
|
||||
complaints will be reviewed and investigated and will result in a response that
|
||||
is deemed necessary and appropriate to the circumstances. The project team is
|
||||
obligated to maintain confidentiality with regard to the reporter of an incident.
|
||||
Further details of specific enforcement policies may be posted separately.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good
|
||||
faith may face temporary or permanent repercussions as determined by other
|
||||
members of the project's leadership.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.1,
|
||||
available at https://www.contributor-covenant.org/version/2/1/code_of_conduct/
|
||||
|
||||
[homepage]: https://www.contributor-covenant.org
|
||||
|
||||
For answers to common questions about this code of conduct, see
|
||||
https://www.contributor-covenant.org/faq
|
||||
|
||||
@@ -1,113 +1,84 @@
|
||||
# Contributing to React Native
|
||||
|
||||
Thank you for your interest in contributing to React Native! From commenting on and triaging issues, to reviewing and sending Pull Requests, all contributions are welcome. We aim to build a vibrant and inclusive [ecosystem of partners, core contributors, and community](ECOSYSTEM.md) that goes beyond the main React Native GitHub repository.
|
||||
React Native is one of Facebook's first open source projects that is both under very active development and is also being used to ship code to everybody on [facebook.com](https://facebook.com). We're still working out the kinks to make contributing to this project as easy and transparent as possible, but we're not quite there yet. Hopefully this document makes the process for contributing clear and preempts some questions you may have.
|
||||
|
||||
The [Open Source Guides](https://opensource.guide/) website has a collection of resources for individuals, communities, and companies who want to learn how to run and contribute to an open source project. Contributors and people new to open source alike will find the following guides especially useful:
|
||||
## Our Development Process
|
||||
|
||||
* [How to Contribute to Open Source](https://opensource.guide/how-to-contribute/)
|
||||
* [Building Welcoming Communities](https://opensource.guide/building-community/)
|
||||
Some of the core team will be working directly on GitHub. These changes will be public from the beginning. Other changesets will come via a bridge with Facebook's internal source control. This is a necessity as it allows engineers at Facebook outside of the core team to move fast and contribute from an environment they are comfortable in.
|
||||
|
||||
### `master` is unsafe
|
||||
|
||||
### [Code of Conduct](https://github.com/facebook/react-native/blob/HEAD/CODE_OF_CONDUCT.md)
|
||||
We will do our best to keep `master` in good shape, with tests passing at all times. But in order to move fast, we will make API changes that your application might not be compatible with. We will do our best to communicate these changes and version appropriately so you can lock into a specific version if need be.
|
||||
|
||||
As a reminder, all contributors are expected to adhere to the [Code of Conduct](https://github.com/facebook/react-native/blob/HEAD/CODE_OF_CONDUCT.md).
|
||||
### Pull Requests
|
||||
|
||||
## Ways to Contribute
|
||||
The core team will be monitoring for pull requests. When we get one, we'll run some Facebook-specific integration tests on it first. From here, we'll need to get another person to sign off on the changes and then merge the pull request. For API changes we may need to fix internal uses, which could cause some delay. We'll do our best to provide updates and feedback throughout the process.
|
||||
|
||||
If you are eager to start contributing code right away, we have a list of [good first issues](https://github.com/facebook/react-native/labels/good%20first%20issue) that contain bugs which have a relatively limited scope. As you gain more experience and demonstrate a commitment to evolving React Native, you may be granted issue management permissions in the repository.
|
||||
*Before* submitting a pull request, please make sure the following is done…
|
||||
|
||||
There are other ways you can contribute without writing a single line of code. Here are a few things you can do to help out:
|
||||
1. Fork the repo and create your branch from `master`.
|
||||
2. If you've added code that should be tested, add tests!
|
||||
3. If you've changed APIs, update the documentation.
|
||||
4. Ensure tests pass on Travis.
|
||||
5. Make sure your code lints (`node linter.js <files touched>`).
|
||||
6. Squash your commits (`git rebase -i`).
|
||||
7. If you haven't already, complete the CLA.
|
||||
|
||||
1. **Replying and handling open issues.** We get a lot of issues every day, and some of them may lack necessary information. You can help out by guiding people through the process of filling out the issue template, asking for clarifying information, or pointing them to existing issues that match their description of the problem. We cover more about this process in the [Issue Triage wiki](https://github.com/facebook/react-native/wiki/Triaging-GitHub-Issues).
|
||||
2. **Reviewing pull requests for the docs.** Reviewing [documentation updates](https://github.com/facebook/react-native-website/pulls) can be as simple as checking for spelling and grammar. If you encounter situations that can be explained better in the docs, click **Edit** at the top of most docs pages to get started with your own contribution.
|
||||
3. **Help people write test plans.** Some pull requests sent to the main repository may lack a proper test plan. These help reviewers understand how the change was tested, and can speed up the time it takes for a contribution to be accepted.
|
||||
### Contributor License Agreement (CLA)
|
||||
|
||||
Each of these tasks is highly impactful, and maintainers will greatly appreciate your help.
|
||||
In order to accept your pull request, we need you to submit a CLA. You only need to do this once, so if you've done this for another Facebook open source project, you're good to go. If you are submitting a pull request for the first time, just let us know that you have completed the CLA and we can cross-check with your GitHub username.
|
||||
|
||||
### Our Development Process
|
||||
[Complete your CLA here](https://code.facebook.com/cla)
|
||||
|
||||
We use GitHub issues and pull requests to keep track of bug reports and contributions from the community. All changes from engineers at Facebook will sync to [GitHub](https://github.com/facebook/react-native) through a bridge with Facebook's internal source control. Changes from the community are handled through GitHub pull requests. Once a change made on GitHub is approved, it will first be imported into Facebook's internal source control and tested against Facebook's codebase. Once merged at Facebook, the change will eventually sync back to GitHub as a single commit once it has passed Facebook's internal tests.
|
||||
## Bugs
|
||||
|
||||
You can learn more about the contribution process in the following documents:
|
||||
### Where to Find Known Issues
|
||||
|
||||
* [Issues](https://github.com/facebook/react-native/wiki/Triaging-GitHub-Issues)
|
||||
* [Pull Requests](https://github.com/facebook/react-native/wiki/Managing-Pull-Requests)
|
||||
We are using GitHub Issues for our public bugs. We keep a close eye on this and try to make it clear when we have an internal fix in progress. Before filing a new task, try to make sure your problem doesn't already exist.
|
||||
|
||||
We also have a thriving community of contributors who would be happy to help you get set up. You can reach out to us through [@ReactNative](http://twitter.com/reactnative) (the React Native team) and [@ReactNativeComm](http://twitter.com/reactnativecomm) (the React Native Community organization).
|
||||
### Reporting New Issues
|
||||
|
||||
### Repositories
|
||||
|
||||
The main repository, <https://github.com/facebook/react-native>, contains the React Native framework itself and it is here where we keep track of bug reports and manage pull requests.
|
||||
|
||||
There are a few other repositories you might want to familiarize yourself with:
|
||||
|
||||
* **React Native website** which contains the source code for the website, including the documentation, located at <https://github.com/facebook/react-native-website>
|
||||
* **Releases** Conversations for new releases are happening [in this discussion repo](https://github.com/reactwg/react-native-releases/discussions).
|
||||
* **Changelog** The changelog can be found [here](https://github.com/facebook/react-native/blob/main/CHANGELOG.md).
|
||||
* **Discussions** about the future of React Native take place in the <https://github.com/react-native-community/discussions-and-proposals> repository.
|
||||
* **High-quality plugins** for React Native can be found throughout the [React Native Community GitHub Organization](http://github.com/react-native-community/).
|
||||
|
||||
Browsing through these repositories should provide some insight into how the React Native open source project is managed.
|
||||
|
||||
## GitHub Issues
|
||||
|
||||
We use GitHub issues to track bugs exclusively. We have documented our issue handling processes in the [Issues wiki](https://github.com/facebook/react-native/wiki/Triaging-GitHub-Issues).
|
||||
The best way to get your bug fixed is to provide a reduced test case. Please provide either a public repository with a runnable example or a [React Native Playground](https://rnplay.org/) snippet.
|
||||
|
||||
### Security Bugs
|
||||
|
||||
Facebook has a [bounty program](https://www.facebook.com/whitehat/) for the safe disclosure of security bugs. In those cases, please go through the process outlined on that page and do not file a public issue.
|
||||
Facebook has a [bounty program](https://www.facebook.com/whitehat/) for the safe disclosure of security bugs. With that in mind, please do not file public issues; go through the process outlined on that page.
|
||||
|
||||
## Helping with Documentation
|
||||
## How to Get in Touch
|
||||
|
||||
The React Native documentation is hosted as part of the React Native website repository at https://github.com/facebook/react-native-website. The website itself is located at <https://reactnative.dev/> and it is built using [Docusaurus](https://docusaurus.io/). If there's anything you'd like to change in the docs, you can get started by clicking on the "Edit" button located on the upper right of most pages in the website.
|
||||
* [Facebook group](https://www.facebook.com/groups/react.native.community/)
|
||||
* Reactiflux — [#react-native](http://join.reactiflux.com/)
|
||||
|
||||
If you are adding new functionality or introducing a change in behavior, we will ask you to update the documentation to reflect your changes.
|
||||
## Style Guide
|
||||
|
||||
### Contributing to the Blog
|
||||
### Code
|
||||
|
||||
The React Native blog is generated [from the Markdown sources for the blog](https://github.com/facebook/react-native-website/tree/HEAD/website/blog).
|
||||
#### General
|
||||
|
||||
Please open an issue in the https://github.com/facebook/react-native-website repository or tag us on [@ReactNative on Twitter](http://twitter.com/reactnative) and get the go-ahead from a maintainer before writing an article intended for the React Native blog. In most cases, you might want to share your article on your own blog or writing medium instead. It's worth asking, though, in case we find your article is a good fit for the blog.
|
||||
* Add trailing commas,
|
||||
* 2 spaces for indentation (no tabs)
|
||||
* "Attractive"
|
||||
|
||||
We recommend referring to the [CONTRIBUTING](https://github.com/facebook/react-native-website/blob/HEAD/CONTRIBUTING.md) document for the `react-native-website` repository to learn more about contributing to the website in general.
|
||||
#### JavaScript
|
||||
|
||||
## Contributing Code
|
||||
* Use semicolons;
|
||||
* `'use strict';`
|
||||
* Prefer `'` over `"`
|
||||
* Do not use the optional parameters of `setTimeout` and `setInterval`
|
||||
* 80 character line length
|
||||
|
||||
Code-level contributions to React Native generally come in the form of [pull requests](https://help.github.com/en/articles/about-pull-requests). These are done by forking the repo and making changes locally. Directly in the repo, there is the [`rn-tester` app](/packages/rn-tester) that you can install on your device (or simulators) and use to test the changes you're making to React Native sources.
|
||||
#### Objective-C
|
||||
|
||||
The process of proposing a change to React Native can be summarized as follows:
|
||||
* Space after `@property` declarations
|
||||
* Brackets on *every* `if`, on the *same* line
|
||||
* `- method`, `@interface`, and `@implementation` brackets on the following line
|
||||
* *Try* to keep it around 80 characters line length (sometimes it's just not possible...)
|
||||
* `*` operator goes with the variable name (e.g. `NSObject *variableName;`)
|
||||
|
||||
1. Fork the React Native repository and create your branch from `main`.
|
||||
2. Make the desired changes to React Native sources. Use the `packages/rn-tester` app to test them out.
|
||||
3. If you've added code that should be tested, add tests.
|
||||
4. If you've changed APIs, update the documentation, which lives in [another repo](https://github.com/facebook/react-native-website/).
|
||||
5. Ensure the test suite passes, either locally or on CI once you opened a pull request.
|
||||
6. Make sure your code lints (for example via `yarn lint --fix`).
|
||||
7. Push the changes to your fork.
|
||||
8. Create a pull request to the React Native repository.
|
||||
9. Review and address comments on your pull request.
|
||||
1. A bot may comment with suggestions. Generally we ask you to resolve these first before a maintainer will review your code.
|
||||
2. If changes are requested and addressed, please [request review](https://docs.github.com/en/github/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/requesting-a-pull-request-review) to notify reviewers to take another look.
|
||||
10. If you haven't already, please complete the [Contributor License Agreement](https://github.com/facebook/react-native/wiki/Contributor-License-Agreement) ("CLA"). **[Complete your CLA here.](https://code.facebook.com/cla)**
|
||||
### Documentation
|
||||
|
||||
If all goes well, your pull request will be merged. If it is not merged, maintainers will do their best to explain the reason why.
|
||||
* Do not wrap lines at 80 characters - configure your editor to soft-wrap when editing documentation.
|
||||
|
||||
### Step-by-step Guide
|
||||
## License
|
||||
|
||||
Whenever you are ready to contribute code, check out our [step-by-step guide to sending your first pull request](https://github.com/facebook/react-native/wiki/How-to-Open-a-Pull-Request), or read the [How to Contribute Code](https://github.com/facebook/react-native/wiki/How-to-Contribute-Code) wiki for more details.
|
||||
|
||||
### Tests
|
||||
|
||||
Tests help us prevent regressions from being introduced to the codebase. The GitHub repository is continuously tested using Circle and Appveyor, the results of which are available through the Checks functionality on [commits](https://github.com/facebook/react-native/commits/HEAD) and pull requests. You can learn more about running and writing tests in the [Tests wiki](http://github.com/facebook/react-native/wiki/Tests).
|
||||
|
||||
## Community Contributions
|
||||
|
||||
Contributions to React Native are not limited to GitHub. You can help others by sharing your experience using React Native, whether that is through blog posts, presenting talks at conferences, or simply sharing your thoughts on Twitter and tagging @ReactNative.
|
||||
|
||||
## Where to Get Help
|
||||
|
||||
As you work on React Native, it is natural that sooner or later you may require help. In addition to the resources listed in [SUPPORT](.github/SUPPORT.md), people interested in contributing may take advantage of the following:
|
||||
|
||||
* **Twitter**. The React Native team at Facebook has its own account at [@reactnative](https://twitter.com/reactnative), and the React Native Community uses [@reactnativecomm](https://twitter.com/reactnativecomm). If you feel stuck, or need help contributing, please do not hesitate to reach out.
|
||||
* **Proposals Repository**. If you are considering working on a feature large in scope, consider [creating a proposal first](https://github.com/react-native-community/discussions-and-proposals). The community can help you figure out the right approach, and we'd be happy to help.
|
||||
* **React Native Community Discord**. While we try to hold most discussions in public, sometimes it can be beneficial to have conversations in real time with other contributors. People who have demonstrated a commitment to moving React Native forward through sustained contributions to the project may eventually be invited to join the React Native Community Discord.
|
||||
By contributing to React Native, you agree that your contributions will be licensed under its BSD license.
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
# The React Native Ecosystem
|
||||
|
||||
We aim to build a vibrant and inclusive ecosystem of partners, core contributors, and community that goes beyond the main React Native GitHub repository. This document explains the roles and responsibilities of various stakeholders and provides guidelines for the community organization. The structure outlined in this document has been in place for a while but hadn't been written down before.
|
||||
|
||||
There are three types of stakeholders:
|
||||
|
||||
* **Partners:** Companies that are significantly invested in React Native and have been for years.
|
||||
* **Core Contributors:** Individual people who contribute to the React Native project.
|
||||
* **Community Contributors:** Individuals who support projects in the [react-native-community](https://github.com/react-native-community) organization.
|
||||
|
||||
## Partners
|
||||
|
||||
Partners are companies that are significantly invested in React Native and have been for years. Informed by their use of React Native, they push for improvements of the core and/or the ecosystem around it. Partners think of React Native as a product: they understand the trade offs that the project makes as well as future plans and goals. Together we shape the vision for React Native to make it the best way to build applications.
|
||||
|
||||
React Native's current set of partners include Callstack, Expo, Facebook, Infinite Red, Microsoft and Software Mansion. Many engineers from these companies are core contributors, and their partner responsibilities also include:
|
||||
|
||||
* **[Callstack](https://callstack.com/):** Manages releases, maintains the [React Native CLI](https://github.com/react-native-community/react-native-cli) and organizes [React Native EU](https://react-native.eu/)
|
||||
* **[Expo](https://expo.io/):** Builds [expo](https://github.com/expo/expo) on top of React Native to simplify app development
|
||||
* **[Facebook](https://opensource.facebook.com):** Oversees the React Native product and maintains the [React Native core repo](https://reactnative.dev/)
|
||||
* **[Infinite Red](https://infinite.red/):** Maintains the [ignite cli/boilerplate](https://github.com/infinitered/ignite), organizes [Chain React Conf](https://cr.infinite.red/)
|
||||
* **[Microsoft](http://aka.ms/reactnative):** Develops [React Native Windows](https://github.com/Microsoft/react-native-windows) and [React Native macOS](https://github.com/microsoft/react-native-macos) for building apps that target Windows and macOS
|
||||
* **[Software Mansion](https://swmansion.com/):** Maintain core infrastructure including JSC, Animated, and other popular third-party plugins.
|
||||
|
||||
In terms of open source work, pull requests from partners are commonly prioritized. When you are contributing to React Native, you'll most likely meet somebody who works at one of the partner companies and who is a core contributor:
|
||||
|
||||
## Core Contributors
|
||||
|
||||
Core contributors are individuals who contribute to the React Native project. A core contributor is somebody who displayed a lasting commitment to the evolution and maintenance of React Native. The work done by core contributors includes responsibilities mentioned in the “Partners” section above, and concretely means that they:
|
||||
|
||||
* Consistently contribute high quality changes, fixes and improvements
|
||||
* Actively review changes and provide quality feedback to contributors
|
||||
* Manage the release process of React Native by maintaining release branches, communicating changes to users and publishing releases
|
||||
* Love to help out other users with issues on GitHub
|
||||
* Mentor and encourage first time contributors
|
||||
* Identify React Native community members who could be effective core contributors
|
||||
* Help build an inclusive community with people from all backgrounds
|
||||
* Are great at communicating with other contributors and the community in general
|
||||
|
||||
These are behaviors we have observed in our existing core contributors. They aren't strict rules but rather outline their usual responsibilities. We do not expect every core contributor to do all of the above things all the time. Most importantly, we want to create a supportive and friendly environment that fosters collaboration. Above all else, **we are always polite and friendly.**
|
||||
|
||||
Core contributor status is attained after consistently contributing and taking on the responsibilities outlined above and granted by other core contributors. Similarly, after a long period of inactivity, a core contributor may be removed.
|
||||
|
||||
We aim to make contributing to React Native as easy and transparent as possible. All important topics are handled through a [discussion or RFC process on GitHub](https://github.com/react-native-community/discussions-and-proposals). We are always looking for active, enthusiastic members of the React Native community to become core contributors.
|
||||
|
||||
## Community Contributors
|
||||
|
||||
Community contributors are individuals who support projects in the [react-native-community](https://github.com/react-native-community) organization. This organization exists as an incubator for high quality components that extend the capabilities of React Native with functionality that many but not all applications require. Facebook engineers will provide guidance to help build a vibrant community of people and components that make React Native better.
|
||||
|
||||
This structure has multiple benefits:
|
||||
|
||||
* Keep the core of React Native small, which improves performance and reduces the surface area
|
||||
* Provide visibility to projects through shared representation, for example on the React Native website or on Twitter
|
||||
* Ensure a consistent and high standard for code, documentation, user experience, stability and contributions for third-party components
|
||||
* Upgrade the most important components right away when we make breaking changes and move the ecosystem forward at a fast pace
|
||||
* Find new maintainers for projects that are important but were abandoned by previous owners
|
||||
|
||||
Additionally, some companies may choose to sponsor the development of one or many of the packages that are part of the community organization. They will commit to maintain projects, triage issues, fix bugs and develop features. In turn, they will be able to gain visibility for their work, for example through a mention of active maintainers in the README of individual projects after a consistent period of contributions. Such a mention may be removed if maintainers abandon the project.
|
||||
|
||||
If you are working on a popular component and would like to move it to the React Native community, please create an issue on the [discussions-and-proposals repository](https://github.com/react-native-community/discussions-and-proposals).
|
||||
@@ -0,0 +1,405 @@
|
||||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 46;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; };
|
||||
13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB11A68108700A75B9A /* LaunchScreen.xib */; };
|
||||
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
|
||||
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
|
||||
1461632D1AC3E23900C2F5AD /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1461632C1AC3E22900C2F5AD /* libReact.a */; };
|
||||
5F82F1781B85785200FAE87E /* libRCTWebSocket.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5F82F1771B85784500FAE87E /* libRCTWebSocket.a */; };
|
||||
832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 832341B51AAA6A8300B99B32 /* libRCTText.a */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
1461632B1AC3E22900C2F5AD /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 146163271AC3E22900C2F5AD /* React.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 83CBBA2E1A601D0E00E9B192;
|
||||
remoteInfo = React;
|
||||
};
|
||||
5F82F1761B85784500FAE87E /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 5F82F1721B85784500FAE87E /* RCTWebSocket.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 3C86DF461ADF2C930047B81A;
|
||||
remoteInfo = RCTWebSocket;
|
||||
};
|
||||
832341B41AAA6A8300B99B32 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 58B5119B1A9E6C1200147676;
|
||||
remoteInfo = RCTText;
|
||||
};
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
13B07F961A680F5B00A75B9A /* 2048.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = 2048.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = 2048/AppDelegate.h; sourceTree = "<group>"; };
|
||||
13B07FB01A68108700A75B9A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = 2048/AppDelegate.m; sourceTree = "<group>"; };
|
||||
13B07FB21A68108700A75B9A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = "<group>"; };
|
||||
13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = 2048/Images.xcassets; sourceTree = "<group>"; };
|
||||
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = 2048/Info.plist; sourceTree = "<group>"; };
|
||||
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = 2048/main.m; sourceTree = "<group>"; };
|
||||
146163271AC3E22900C2F5AD /* React.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = React.xcodeproj; path = ../../React/React.xcodeproj; sourceTree = "<group>"; };
|
||||
5F82F1721B85784500FAE87E /* RCTWebSocket.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTWebSocket.xcodeproj; path = ../../Libraries/WebSocket/RCTWebSocket.xcodeproj; sourceTree = "<group>"; };
|
||||
832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = ../../Libraries/Text/RCTText.xcodeproj; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
13B07F8C1A680F5B00A75B9A /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
5F82F1781B85785200FAE87E /* libRCTWebSocket.a in Frameworks */,
|
||||
1461632D1AC3E23900C2F5AD /* libReact.a in Frameworks */,
|
||||
832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
13B07FAE1A68108700A75B9A /* 2048 */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
13B07FAF1A68108700A75B9A /* AppDelegate.h */,
|
||||
13B07FB01A68108700A75B9A /* AppDelegate.m */,
|
||||
13B07FB51A68108700A75B9A /* Images.xcassets */,
|
||||
13B07FB61A68108700A75B9A /* Info.plist */,
|
||||
13B07FB11A68108700A75B9A /* LaunchScreen.xib */,
|
||||
13B07FB71A68108700A75B9A /* main.m */,
|
||||
);
|
||||
name = 2048;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
146163281AC3E22900C2F5AD /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
1461632C1AC3E22900C2F5AD /* libReact.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
5F82F1731B85784500FAE87E /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
5F82F1771B85784500FAE87E /* libRCTWebSocket.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
832341AE1AAA6A7D00B99B32 /* Libraries */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
5F82F1721B85784500FAE87E /* RCTWebSocket.xcodeproj */,
|
||||
146163271AC3E22900C2F5AD /* React.xcodeproj */,
|
||||
832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */,
|
||||
);
|
||||
name = Libraries;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
832341B11AAA6A8300B99B32 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
832341B51AAA6A8300B99B32 /* libRCTText.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
83CBB9F61A601CBA00E9B192 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
13B07FAE1A68108700A75B9A /* 2048 */,
|
||||
832341AE1AAA6A7D00B99B32 /* Libraries */,
|
||||
83CBBA001A601CBA00E9B192 /* Products */,
|
||||
);
|
||||
indentWidth = 2;
|
||||
sourceTree = "<group>";
|
||||
tabWidth = 2;
|
||||
};
|
||||
83CBBA001A601CBA00E9B192 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
13B07F961A680F5B00A75B9A /* 2048.app */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
13B07F861A680F5B00A75B9A /* 2048 */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "2048" */;
|
||||
buildPhases = (
|
||||
13B07F871A680F5B00A75B9A /* Sources */,
|
||||
13B07F8C1A680F5B00A75B9A /* Frameworks */,
|
||||
13B07F8E1A680F5B00A75B9A /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = 2048;
|
||||
productName = "Hello World";
|
||||
productReference = 13B07F961A680F5B00A75B9A /* 2048.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
83CBB9F71A601CBA00E9B192 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 0700;
|
||||
ORGANIZATIONNAME = Facebook;
|
||||
};
|
||||
buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "2048" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
Base,
|
||||
);
|
||||
mainGroup = 83CBB9F61A601CBA00E9B192;
|
||||
productRefGroup = 83CBBA001A601CBA00E9B192 /* Products */;
|
||||
projectDirPath = "";
|
||||
projectReferences = (
|
||||
{
|
||||
ProductGroup = 832341B11AAA6A8300B99B32 /* Products */;
|
||||
ProjectRef = 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = 5F82F1731B85784500FAE87E /* Products */;
|
||||
ProjectRef = 5F82F1721B85784500FAE87E /* RCTWebSocket.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = 146163281AC3E22900C2F5AD /* Products */;
|
||||
ProjectRef = 146163271AC3E22900C2F5AD /* React.xcodeproj */;
|
||||
},
|
||||
);
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
13B07F861A680F5B00A75B9A /* 2048 */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXReferenceProxy section */
|
||||
1461632C1AC3E22900C2F5AD /* libReact.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libReact.a;
|
||||
remoteRef = 1461632B1AC3E22900C2F5AD /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
5F82F1771B85784500FAE87E /* libRCTWebSocket.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libRCTWebSocket.a;
|
||||
remoteRef = 5F82F1761B85784500FAE87E /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
832341B51AAA6A8300B99B32 /* libRCTText.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libRCTText.a;
|
||||
remoteRef = 832341B41AAA6A8300B99B32 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
/* End PBXReferenceProxy section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
13B07F8E1A680F5B00A75B9A /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */,
|
||||
13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
13B07F871A680F5B00A75B9A /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */,
|
||||
13B07FC11A68108700A75B9A /* main.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXVariantGroup section */
|
||||
13B07FB11A68108700A75B9A /* LaunchScreen.xib */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
13B07FB21A68108700A75B9A /* Base */,
|
||||
);
|
||||
name = LaunchScreen.xib;
|
||||
path = 2048;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXVariantGroup section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
13B07F941A680F5B00A75B9A /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||
"$(SRCROOT)/../../React/**",
|
||||
);
|
||||
INFOPLIST_FILE = "$(SRCROOT)/2048/Info.plist";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
LIBRARY_SEARCH_PATHS = "$(inherited)";
|
||||
OTHER_LDFLAGS = "-ObjC";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.facebook.$(PRODUCT_NAME:rfc1034identifier)";
|
||||
PRODUCT_NAME = 2048;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
13B07F951A680F5B00A75B9A /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||
"$(SRCROOT)/../../React/**",
|
||||
);
|
||||
INFOPLIST_FILE = "$(SRCROOT)/2048/Info.plist";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
LIBRARY_SEARCH_PATHS = "$(inherited)";
|
||||
OTHER_LDFLAGS = "-ObjC";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.facebook.$(PRODUCT_NAME:rfc1034identifier)";
|
||||
PRODUCT_NAME = 2048;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
83CBBA201A601CBA00E9B192 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||
"$(SRCROOT)/../../React/**",
|
||||
);
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = iphoneos;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
83CBBA211A601CBA00E9B192 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
COPY_PHASE_STRIP = YES;
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||
"$(SRCROOT)/../../React/**",
|
||||
);
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
SDKROOT = iphoneos;
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "2048" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
13B07F941A680F5B00A75B9A /* Debug */,
|
||||
13B07F951A680F5B00A75B9A /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "2048" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
83CBBA201A601CBA00E9B192 /* Debug */,
|
||||
83CBBA211A601CBA00E9B192 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = 83CBB9F71A601CBA00E9B192 /* Project object */;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface AppDelegate : UIResponder <UIApplicationDelegate>
|
||||
|
||||
@property (nonatomic, strong) UIWindow *window;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,66 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#import "AppDelegate.h"
|
||||
|
||||
#import "RCTRootView.h"
|
||||
|
||||
@implementation AppDelegate
|
||||
|
||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
||||
{
|
||||
NSURL *jsCodeLocation;
|
||||
|
||||
/**
|
||||
* Loading JavaScript code - uncomment the one you want.
|
||||
*
|
||||
* OPTION 1
|
||||
* Load from development server. Start the server from the repository root:
|
||||
*
|
||||
* $ npm start
|
||||
*
|
||||
* To run on device, change `localhost` to the IP address of your computer
|
||||
* (you can get this by typing `ifconfig` into the terminal and selecting the
|
||||
* `inet` value under `en0:`) and make sure your computer and iOS device are
|
||||
* on the same Wi-Fi network.
|
||||
*/
|
||||
|
||||
jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/Examples/2048/Game2048.bundle?platform=ios&dev=true"];
|
||||
|
||||
/**
|
||||
* OPTION 2
|
||||
* Load from pre-bundled file on disk. To re-generate the static bundle, `cd`
|
||||
* to your Xcode project folder in the terminal, and run
|
||||
*
|
||||
* $ curl 'http://localhost:8081/Examples/2048/Game2048.bundle?platform=ios' -o main.jsbundle
|
||||
*
|
||||
* then add the `main.jsbundle` file to your project and uncomment this line:
|
||||
*/
|
||||
|
||||
// jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
|
||||
|
||||
RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
|
||||
moduleName:@"Game2048"
|
||||
initialProperties:nil
|
||||
launchOptions:launchOptions];
|
||||
|
||||
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
|
||||
UIViewController *rootViewController = [[UIViewController alloc] init];
|
||||
rootViewController.view = rootView;
|
||||
self.window.rootViewController = rootViewController;
|
||||
[self.window makeKeyAndVisible];
|
||||
return YES;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="6254" systemVersion="14C109" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6247"/>
|
||||
<capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<view contentMode="scaleToFill" id="iN0-l3-epB">
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="480"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text=" Copyright (c) 2015 Facebook. All rights reserved." textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="9" translatesAutoresizingMaskIntoConstraints="NO" id="8ie-xW-0ye">
|
||||
<rect key="frame" x="20" y="439" width="441" height="21"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="2048" textAlignment="center" lineBreakMode="middleTruncation" baselineAdjustment="alignBaselines" minimumFontSize="18" translatesAutoresizingMaskIntoConstraints="NO" id="kId-c2-rCX">
|
||||
<rect key="frame" x="20" y="140" width="441" height="43"/>
|
||||
<fontDescription key="fontDescription" type="boldSystem" pointSize="36"/>
|
||||
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
|
||||
<constraints>
|
||||
<constraint firstItem="kId-c2-rCX" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="bottom" multiplier="1/3" constant="1" id="5cJ-9S-tgC"/>
|
||||
<constraint firstAttribute="centerX" secondItem="kId-c2-rCX" secondAttribute="centerX" id="Koa-jz-hwk"/>
|
||||
<constraint firstAttribute="bottom" secondItem="8ie-xW-0ye" secondAttribute="bottom" constant="20" id="Kzo-t9-V3l"/>
|
||||
<constraint firstItem="8ie-xW-0ye" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="MfP-vx-nX0"/>
|
||||
<constraint firstAttribute="centerX" secondItem="8ie-xW-0ye" secondAttribute="centerX" id="ZEH-qu-HZ9"/>
|
||||
<constraint firstItem="kId-c2-rCX" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="fvb-Df-36g"/>
|
||||
</constraints>
|
||||
<nil key="simulatedStatusBarMetrics"/>
|
||||
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
|
||||
<point key="canvasLocation" x="548" y="455"/>
|
||||
</view>
|
||||
</objects>
|
||||
</document>
|
||||
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "29x29",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "29x29",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "40x40",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "40x40",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "60x60",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "60x60",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<dict>
|
||||
<key>NSAllowsArbitraryLoads</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>LaunchScreen</string>
|
||||
<key>UIRequiredDeviceCapabilities</key>
|
||||
<array>
|
||||
<string>armv7</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import "AppDelegate.h"
|
||||
|
||||
int main(int argc, char * argv[]) {
|
||||
@autoreleasepool {
|
||||
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,321 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* @providesModule Game2048
|
||||
* @flow
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var React = require('react-native');
|
||||
var {
|
||||
AppRegistry,
|
||||
StyleSheet,
|
||||
Text,
|
||||
View,
|
||||
} = React;
|
||||
|
||||
var Animated = require('Animated');
|
||||
var GameBoard = require('GameBoard');
|
||||
var TouchableBounce = require('TouchableBounce');
|
||||
|
||||
var BOARD_PADDING = 3;
|
||||
var CELL_MARGIN = 4;
|
||||
var CELL_SIZE = 60;
|
||||
|
||||
class Cell extends React.Component {
|
||||
render() {
|
||||
return <View style={styles.cell} />;
|
||||
}
|
||||
}
|
||||
|
||||
class Board extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<View style={styles.board}>
|
||||
<View style={styles.row}><Cell/><Cell/><Cell/><Cell/></View>
|
||||
<View style={styles.row}><Cell/><Cell/><Cell/><Cell/></View>
|
||||
<View style={styles.row}><Cell/><Cell/><Cell/><Cell/></View>
|
||||
<View style={styles.row}><Cell/><Cell/><Cell/><Cell/></View>
|
||||
{this.props.children}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class Tile extends React.Component {
|
||||
static _getPosition(index): number {
|
||||
return BOARD_PADDING + (index * (CELL_SIZE + CELL_MARGIN * 2) + CELL_MARGIN);
|
||||
}
|
||||
|
||||
constructor(props: {}) {
|
||||
super(props);
|
||||
|
||||
var tile = this.props.tile;
|
||||
|
||||
this.state = {
|
||||
opacity: new Animated.Value(0),
|
||||
top: new Animated.Value(Tile._getPosition(tile.toRow())),
|
||||
left: new Animated.Value(Tile._getPosition(tile.toColumn())),
|
||||
};
|
||||
}
|
||||
|
||||
calculateOffset(): {top: number; left: number; opacity: number} {
|
||||
var tile = this.props.tile;
|
||||
|
||||
var offset = {
|
||||
top: this.state.top,
|
||||
left: this.state.left,
|
||||
opacity: this.state.opacity,
|
||||
};
|
||||
|
||||
if (tile.isNew()) {
|
||||
Animated.timing(this.state.opacity, {
|
||||
duration: 100,
|
||||
toValue: 1,
|
||||
}).start();
|
||||
} else {
|
||||
Animated.parallel([
|
||||
Animated.timing(offset.top, {
|
||||
duration: 100,
|
||||
toValue: Tile._getPosition(tile.toRow()),
|
||||
}),
|
||||
Animated.timing(offset.left, {
|
||||
duration: 100,
|
||||
toValue: Tile._getPosition(tile.toColumn()),
|
||||
}),
|
||||
]).start();
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
||||
render() {
|
||||
var tile = this.props.tile;
|
||||
|
||||
var tileStyles = [
|
||||
styles.tile,
|
||||
styles['tile' + tile.value],
|
||||
this.calculateOffset(),
|
||||
];
|
||||
|
||||
var textStyles = [
|
||||
styles.value,
|
||||
tile.value > 4 && styles.whiteText,
|
||||
tile.value > 100 && styles.threeDigits,
|
||||
tile.value > 1000 && styles.fourDigits,
|
||||
];
|
||||
|
||||
return (
|
||||
<Animated.View style={tileStyles}>
|
||||
<Text style={textStyles}>{tile.value}</Text>
|
||||
</Animated.View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class GameEndOverlay extends React.Component {
|
||||
render() {
|
||||
var board = this.props.board;
|
||||
|
||||
if (!board.hasWon() && !board.hasLost()) {
|
||||
return <View/>;
|
||||
}
|
||||
|
||||
var message = board.hasWon() ?
|
||||
'Good Job!' : 'Game Over';
|
||||
|
||||
return (
|
||||
<View style={styles.overlay}>
|
||||
<Text style={styles.overlayMessage}>{message}</Text>
|
||||
<TouchableBounce onPress={this.props.onRestart} style={styles.tryAgain}>
|
||||
<Text style={styles.tryAgainText}>Try Again?</Text>
|
||||
</TouchableBounce>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class Game2048 extends React.Component {
|
||||
startX: number;
|
||||
startY: number;
|
||||
|
||||
constructor(props: {}) {
|
||||
super(props);
|
||||
this.state = {
|
||||
board: new GameBoard(),
|
||||
};
|
||||
this.startX = 0;
|
||||
this.startY = 0;
|
||||
}
|
||||
|
||||
restartGame() {
|
||||
this.setState({board: new GameBoard()});
|
||||
}
|
||||
|
||||
handleTouchStart(event: Object) {
|
||||
if (this.state.board.hasWon()) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.startX = event.nativeEvent.pageX;
|
||||
this.startY = event.nativeEvent.pageY;
|
||||
}
|
||||
|
||||
handleTouchEnd(event: Object) {
|
||||
if (this.state.board.hasWon()) {
|
||||
return;
|
||||
}
|
||||
|
||||
var deltaX = event.nativeEvent.pageX - this.startX;
|
||||
var deltaY = event.nativeEvent.pageY - this.startY;
|
||||
|
||||
var direction = -1;
|
||||
if (Math.abs(deltaX) > 3 * Math.abs(deltaY) && Math.abs(deltaX) > 30) {
|
||||
direction = deltaX > 0 ? 2 : 0;
|
||||
} else if (Math.abs(deltaY) > 3 * Math.abs(deltaX) && Math.abs(deltaY) > 30) {
|
||||
direction = deltaY > 0 ? 3 : 1;
|
||||
}
|
||||
|
||||
if (direction !== -1) {
|
||||
this.setState({board: this.state.board.move(direction)});
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
var tiles = this.state.board.tiles
|
||||
.filter((tile) => tile.value)
|
||||
.map((tile) => <Tile ref={tile.id} key={tile.id} tile={tile} />);
|
||||
|
||||
return (
|
||||
<View
|
||||
style={styles.container}
|
||||
onTouchStart={(event) => this.handleTouchStart(event)}
|
||||
onTouchEnd={(event) => this.handleTouchEnd(event)}>
|
||||
<Board>
|
||||
{tiles}
|
||||
</Board>
|
||||
<GameEndOverlay board={this.state.board} onRestart={() => this.restartGame()} />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
},
|
||||
board: {
|
||||
padding: BOARD_PADDING,
|
||||
backgroundColor: '#bbaaaa',
|
||||
borderRadius: 5,
|
||||
},
|
||||
overlay: {
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
backgroundColor: 'rgba(221, 221, 221, 0.5)',
|
||||
flex: 1,
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
},
|
||||
overlayMessage: {
|
||||
fontSize: 40,
|
||||
marginBottom: 20,
|
||||
},
|
||||
tryAgain: {
|
||||
backgroundColor: '#887766',
|
||||
padding: 20,
|
||||
borderRadius: 5,
|
||||
},
|
||||
tryAgainText: {
|
||||
color: '#ffffff',
|
||||
fontSize: 20,
|
||||
fontWeight: '500',
|
||||
},
|
||||
cell: {
|
||||
width: CELL_SIZE,
|
||||
height: CELL_SIZE,
|
||||
borderRadius: 5,
|
||||
backgroundColor: '#ddccbb',
|
||||
margin: CELL_MARGIN,
|
||||
},
|
||||
row: {
|
||||
flexDirection: 'row',
|
||||
},
|
||||
tile: {
|
||||
position: 'absolute',
|
||||
width: CELL_SIZE,
|
||||
height: CELL_SIZE,
|
||||
backgroundColor: '#ddccbb',
|
||||
borderRadius: 5,
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
},
|
||||
value: {
|
||||
fontSize: 24,
|
||||
color: '#776666',
|
||||
fontFamily: 'Verdana',
|
||||
fontWeight: '500',
|
||||
},
|
||||
tile2: {
|
||||
backgroundColor: '#eeeeee',
|
||||
},
|
||||
tile4: {
|
||||
backgroundColor: '#eeeecc',
|
||||
},
|
||||
tile8: {
|
||||
backgroundColor: '#ffbb88',
|
||||
},
|
||||
tile16: {
|
||||
backgroundColor: '#ff9966',
|
||||
},
|
||||
tile32: {
|
||||
backgroundColor: '#ff7755',
|
||||
},
|
||||
tile64: {
|
||||
backgroundColor: '#ff5533',
|
||||
},
|
||||
tile128: {
|
||||
backgroundColor: '#eecc77',
|
||||
},
|
||||
tile256: {
|
||||
backgroundColor: '#eecc66',
|
||||
},
|
||||
tile512: {
|
||||
backgroundColor: '#eecc55',
|
||||
},
|
||||
tile1024: {
|
||||
backgroundColor: '#eecc33',
|
||||
},
|
||||
tile2048: {
|
||||
backgroundColor: '#eecc22',
|
||||
},
|
||||
whiteText: {
|
||||
color: '#ffffff',
|
||||
},
|
||||
threeDigits: {
|
||||
fontSize: 20,
|
||||
},
|
||||
fourDigits: {
|
||||
fontSize: 18,
|
||||
},
|
||||
});
|
||||
|
||||
AppRegistry.registerComponent('Game2048', () => Game2048);
|
||||
|
||||
module.exports = Game2048;
|
||||
@@ -0,0 +1,201 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* @providesModule GameBoard
|
||||
* @flow
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
// NB: Taken straight from: https://github.com/IvanVergiliev/2048-react/blob/master/src/board.js
|
||||
// with no modificiation except to format it for CommonJS and fix lint/flow errors
|
||||
|
||||
var rotateLeft = function (matrix) {
|
||||
var rows = matrix.length;
|
||||
var columns = matrix[0].length;
|
||||
var res = [];
|
||||
for (var row = 0; row < rows; ++row) {
|
||||
res.push([]);
|
||||
for (var column = 0; column < columns; ++column) {
|
||||
res[row][column] = matrix[column][columns - row - 1];
|
||||
}
|
||||
}
|
||||
return res;
|
||||
};
|
||||
|
||||
var Tile = function (value?: number, row?: number, column?: number) {
|
||||
this.value = value || 0;
|
||||
this.row = row || -1;
|
||||
|
||||
this.column = column || -1;
|
||||
this.oldRow = -1;
|
||||
this.oldColumn = -1;
|
||||
this.markForDeletion = false;
|
||||
this.mergedInto = null;
|
||||
this.id = Tile.id++;
|
||||
};
|
||||
|
||||
Tile.id = 0;
|
||||
|
||||
Tile.prototype.moveTo = function (row, column) {
|
||||
this.oldRow = this.row;
|
||||
this.oldColumn = this.column;
|
||||
this.row = row;
|
||||
this.column = column;
|
||||
};
|
||||
|
||||
Tile.prototype.isNew = function () {
|
||||
return this.oldRow === -1 && !this.mergedInto;
|
||||
};
|
||||
|
||||
Tile.prototype.hasMoved = function () {
|
||||
return (this.fromRow() !== -1 && (this.fromRow() !== this.toRow() || this.fromColumn() !== this.toColumn())) ||
|
||||
this.mergedInto;
|
||||
};
|
||||
|
||||
Tile.prototype.fromRow = function () {
|
||||
return this.mergedInto ? this.row : this.oldRow;
|
||||
};
|
||||
|
||||
Tile.prototype.fromColumn = function () {
|
||||
return this.mergedInto ? this.column : this.oldColumn;
|
||||
};
|
||||
|
||||
Tile.prototype.toRow = function () {
|
||||
return this.mergedInto ? this.mergedInto.row : this.row;
|
||||
};
|
||||
|
||||
Tile.prototype.toColumn = function () {
|
||||
return this.mergedInto ? this.mergedInto.column : this.column;
|
||||
};
|
||||
|
||||
var Board = function () {
|
||||
this.tiles = [];
|
||||
this.cells = [];
|
||||
for (var i = 0; i < Board.size; ++i) {
|
||||
this.cells[i] = [this.addTile(), this.addTile(), this.addTile(), this.addTile()];
|
||||
}
|
||||
this.addRandomTile();
|
||||
this.setPositions();
|
||||
this.won = false;
|
||||
};
|
||||
|
||||
Board.prototype.addTile = function () {
|
||||
var res = new Tile();
|
||||
Tile.apply(res, arguments);
|
||||
this.tiles.push(res);
|
||||
return res;
|
||||
};
|
||||
|
||||
Board.size = 4;
|
||||
|
||||
Board.prototype.moveLeft = function () {
|
||||
var hasChanged = false;
|
||||
for (var row = 0; row < Board.size; ++row) {
|
||||
var currentRow = this.cells[row].filter(function (tile) { return tile.value !== 0; });
|
||||
var resultRow = [];
|
||||
for (var target = 0; target < Board.size; ++target) {
|
||||
var targetTile = currentRow.length ? currentRow.shift() : this.addTile();
|
||||
if (currentRow.length > 0 && currentRow[0].value === targetTile.value) {
|
||||
var tile1 = targetTile;
|
||||
targetTile = this.addTile(targetTile.value);
|
||||
tile1.mergedInto = targetTile;
|
||||
var tile2 = currentRow.shift();
|
||||
tile2.mergedInto = targetTile;
|
||||
targetTile.value += tile2.value;
|
||||
}
|
||||
resultRow[target] = targetTile;
|
||||
this.won = this.won || (targetTile.value === 2048);
|
||||
hasChanged = hasChanged || (targetTile.value !== this.cells[row][target].value);
|
||||
}
|
||||
this.cells[row] = resultRow;
|
||||
}
|
||||
return hasChanged;
|
||||
};
|
||||
|
||||
Board.prototype.setPositions = function () {
|
||||
this.cells.forEach(function (row, rowIndex) {
|
||||
row.forEach(function (tile, columnIndex) {
|
||||
tile.oldRow = tile.row;
|
||||
tile.oldColumn = tile.column;
|
||||
tile.row = rowIndex;
|
||||
tile.column = columnIndex;
|
||||
tile.markForDeletion = false;
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
Board.fourProbability = 0.1;
|
||||
|
||||
Board.prototype.addRandomTile = function () {
|
||||
var emptyCells = [];
|
||||
for (var r = 0; r < Board.size; ++r) {
|
||||
for (var c = 0; c < Board.size; ++c) {
|
||||
if (this.cells[r][c].value === 0) {
|
||||
emptyCells.push({r: r, c: c});
|
||||
}
|
||||
}
|
||||
}
|
||||
var index = Math.floor(Math.random() * emptyCells.length);
|
||||
var cell = emptyCells[index];
|
||||
var newValue = Math.random() < Board.fourProbability ? 4 : 2;
|
||||
this.cells[cell.r][cell.c] = this.addTile(newValue);
|
||||
};
|
||||
|
||||
Board.prototype.move = function (direction) {
|
||||
// 0 -> left, 1 -> up, 2 -> right, 3 -> down
|
||||
this.clearOldTiles();
|
||||
for (var i = 0; i < direction; ++i) {
|
||||
this.cells = rotateLeft(this.cells);
|
||||
}
|
||||
var hasChanged = this.moveLeft();
|
||||
for (var i = direction; i < 4; ++i) {
|
||||
this.cells = rotateLeft(this.cells);
|
||||
}
|
||||
if (hasChanged) {
|
||||
this.addRandomTile();
|
||||
}
|
||||
this.setPositions();
|
||||
return this;
|
||||
};
|
||||
|
||||
Board.prototype.clearOldTiles = function () {
|
||||
this.tiles = this.tiles.filter(function (tile) { return tile.markForDeletion === false; });
|
||||
this.tiles.forEach(function (tile) { tile.markForDeletion = true; });
|
||||
};
|
||||
|
||||
Board.prototype.hasWon = function () {
|
||||
return this.won;
|
||||
};
|
||||
|
||||
Board.deltaX = [-1, 0, 1, 0];
|
||||
Board.deltaY = [0, -1, 0, 1];
|
||||
|
||||
Board.prototype.hasLost = function () {
|
||||
var canMove = false;
|
||||
for (var row = 0; row < Board.size; ++row) {
|
||||
for (var column = 0; column < Board.size; ++column) {
|
||||
canMove = canMove || (this.cells[row][column].value === 0);
|
||||
for (var dir = 0; dir < 4; ++dir) {
|
||||
var newRow = row + Board.deltaX[dir];
|
||||
var newColumn = column + Board.deltaY[dir];
|
||||
if (newRow < 0 || newRow >= Board.size || newColumn < 0 || newColumn >= Board.size) {
|
||||
continue;
|
||||
}
|
||||
canMove = canMove || (this.cells[row][column].value === this.cells[newRow][newColumn].value);
|
||||
}
|
||||
}
|
||||
}
|
||||
return !canMove;
|
||||
};
|
||||
|
||||
module.exports = Board;
|
||||
@@ -0,0 +1,108 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* @flow
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var React = require('react-native');
|
||||
var {
|
||||
Image,
|
||||
PixelRatio,
|
||||
Platform,
|
||||
StyleSheet,
|
||||
Text,
|
||||
TouchableHighlight,
|
||||
TouchableNativeFeedback,
|
||||
View
|
||||
} = React;
|
||||
|
||||
var getStyleFromScore = require('./getStyleFromScore');
|
||||
var getImageSource = require('./getImageSource');
|
||||
var getTextFromScore = require('./getTextFromScore');
|
||||
|
||||
var MovieCell = React.createClass({
|
||||
render: function() {
|
||||
var criticsScore = this.props.movie.ratings.critics_score;
|
||||
var TouchableElement = TouchableHighlight;
|
||||
if (Platform.OS === 'android') {
|
||||
TouchableElement = TouchableNativeFeedback;
|
||||
}
|
||||
return (
|
||||
<View>
|
||||
<TouchableElement
|
||||
onPress={this.props.onSelect}
|
||||
onShowUnderlay={this.props.onHighlight}
|
||||
onHideUnderlay={this.props.onUnhighlight}>
|
||||
<View style={styles.row}>
|
||||
{/* $FlowIssue #7363964 - There's a bug in Flow where you cannot
|
||||
* omit a property or set it to undefined if it's inside a shape,
|
||||
* even if it isn't required */}
|
||||
<Image
|
||||
source={getImageSource(this.props.movie, 'det')}
|
||||
style={styles.cellImage}
|
||||
/>
|
||||
<View style={styles.textContainer}>
|
||||
<Text style={styles.movieTitle} numberOfLines={2}>
|
||||
{this.props.movie.title}
|
||||
</Text>
|
||||
<Text style={styles.movieYear} numberOfLines={1}>
|
||||
{this.props.movie.year}
|
||||
{' '}•{' '}
|
||||
<Text style={getStyleFromScore(criticsScore)}>
|
||||
Critics {getTextFromScore(criticsScore)}
|
||||
</Text>
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
</TouchableElement>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
textContainer: {
|
||||
flex: 1,
|
||||
},
|
||||
movieTitle: {
|
||||
flex: 1,
|
||||
fontSize: 16,
|
||||
fontWeight: '500',
|
||||
marginBottom: 2,
|
||||
},
|
||||
movieYear: {
|
||||
color: '#999999',
|
||||
fontSize: 12,
|
||||
},
|
||||
row: {
|
||||
alignItems: 'center',
|
||||
backgroundColor: 'white',
|
||||
flexDirection: 'row',
|
||||
padding: 5,
|
||||
},
|
||||
cellImage: {
|
||||
backgroundColor: '#dddddd',
|
||||
height: 93,
|
||||
marginRight: 10,
|
||||
width: 60,
|
||||
},
|
||||
cellBorder: {
|
||||
backgroundColor: 'rgba(0, 0, 0, 0.1)',
|
||||
// Trick to get the thinest line the device can display
|
||||
height: 1 / PixelRatio.get(),
|
||||
marginLeft: 4,
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = MovieCell;
|
||||
@@ -0,0 +1,167 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* @flow
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var React = require('react-native');
|
||||
var {
|
||||
Image,
|
||||
PixelRatio,
|
||||
ScrollView,
|
||||
StyleSheet,
|
||||
Text,
|
||||
View,
|
||||
} = React;
|
||||
|
||||
var getImageSource = require('./getImageSource');
|
||||
var getStyleFromScore = require('./getStyleFromScore');
|
||||
var getTextFromScore = require('./getTextFromScore');
|
||||
|
||||
var MovieScreen = React.createClass({
|
||||
render: function() {
|
||||
return (
|
||||
<ScrollView contentContainerStyle={styles.contentContainer}>
|
||||
<View style={styles.mainSection}>
|
||||
{/* $FlowIssue #7363964 - There's a bug in Flow where you cannot
|
||||
* omit a property or set it to undefined if it's inside a shape,
|
||||
* even if it isn't required */}
|
||||
<Image
|
||||
source={getImageSource(this.props.movie, 'det')}
|
||||
style={styles.detailsImage}
|
||||
/>
|
||||
<View style={styles.rightPane}>
|
||||
<Text style={styles.movieTitle}>{this.props.movie.title}</Text>
|
||||
<Text>{this.props.movie.year}</Text>
|
||||
<View style={styles.mpaaWrapper}>
|
||||
<Text style={styles.mpaaText}>
|
||||
{this.props.movie.mpaa_rating}
|
||||
</Text>
|
||||
</View>
|
||||
<Ratings ratings={this.props.movie.ratings} />
|
||||
</View>
|
||||
</View>
|
||||
<View style={styles.separator} />
|
||||
<Text>
|
||||
{this.props.movie.synopsis}
|
||||
</Text>
|
||||
<View style={styles.separator} />
|
||||
<Cast actors={this.props.movie.abridged_cast} />
|
||||
</ScrollView>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
var Ratings = React.createClass({
|
||||
render: function() {
|
||||
var criticsScore = this.props.ratings.critics_score;
|
||||
var audienceScore = this.props.ratings.audience_score;
|
||||
|
||||
return (
|
||||
<View>
|
||||
<View style={styles.rating}>
|
||||
<Text style={styles.ratingTitle}>Critics:</Text>
|
||||
<Text style={[styles.ratingValue, getStyleFromScore(criticsScore)]}>
|
||||
{getTextFromScore(criticsScore)}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={styles.rating}>
|
||||
<Text style={styles.ratingTitle}>Audience:</Text>
|
||||
<Text style={[styles.ratingValue, getStyleFromScore(audienceScore)]}>
|
||||
{getTextFromScore(audienceScore)}
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
var Cast = React.createClass({
|
||||
render: function() {
|
||||
if (!this.props.actors) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<View>
|
||||
<Text style={styles.castTitle}>Actors</Text>
|
||||
{this.props.actors.map(actor =>
|
||||
<Text key={actor.name} style={styles.castActor}>
|
||||
• {actor.name}
|
||||
</Text>
|
||||
)}
|
||||
</View>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
contentContainer: {
|
||||
padding: 10,
|
||||
},
|
||||
rightPane: {
|
||||
justifyContent: 'space-between',
|
||||
flex: 1,
|
||||
},
|
||||
movieTitle: {
|
||||
flex: 1,
|
||||
fontSize: 16,
|
||||
fontWeight: '500',
|
||||
},
|
||||
rating: {
|
||||
marginTop: 10,
|
||||
},
|
||||
ratingTitle: {
|
||||
fontSize: 14,
|
||||
},
|
||||
ratingValue: {
|
||||
fontSize: 28,
|
||||
fontWeight: '500',
|
||||
},
|
||||
mpaaWrapper: {
|
||||
alignSelf: 'flex-start',
|
||||
borderColor: 'black',
|
||||
borderWidth: 1,
|
||||
paddingHorizontal: 3,
|
||||
marginVertical: 5,
|
||||
},
|
||||
mpaaText: {
|
||||
fontFamily: 'Palatino',
|
||||
fontSize: 13,
|
||||
fontWeight: '500',
|
||||
},
|
||||
mainSection: {
|
||||
flexDirection: 'row',
|
||||
},
|
||||
detailsImage: {
|
||||
width: 134,
|
||||
height: 200,
|
||||
backgroundColor: '#eaeaea',
|
||||
marginRight: 10,
|
||||
},
|
||||
separator: {
|
||||
backgroundColor: 'rgba(0, 0, 0, 0.1)',
|
||||
height: 1 / PixelRatio.get(),
|
||||
marginVertical: 10,
|
||||
},
|
||||
castTitle: {
|
||||
fontWeight: '500',
|
||||
marginBottom: 3,
|
||||
},
|
||||
castActor: {
|
||||
marginLeft: 2,
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = MovieScreen;
|
||||
@@ -0,0 +1,497 @@
|
||||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 46;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
1341801E1AA91750003F314A /* libRCTNetwork.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1341801B1AA91740003F314A /* libRCTNetwork.a */; };
|
||||
13442C061AA90EA00037E5B0 /* libRCTImage.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 13442C051AA90E7D0037E5B0 /* libRCTImage.a */; };
|
||||
13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; };
|
||||
13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB11A68108700A75B9A /* LaunchScreen.xib */; };
|
||||
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
|
||||
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
|
||||
140D9B661AC36C42004F25EE /* libRCTLinking.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 14312D241AC3654D00CDC950 /* libRCTLinking.a */; };
|
||||
14A2D4421AC3E43800CC738A /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 14A2D4411AC3E41A00CC738A /* libReact.a */; };
|
||||
58C5726B1AA6239E00CDF9C8 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 58C5725B1AA6236500CDF9C8 /* libRCTText.a */; };
|
||||
67C95F201B0E64A30040BCE2 /* libRCTWebSocket.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 67C95F1E1B0E647A0040BCE2 /* libRCTWebSocket.a */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
1341801A1AA91740003F314A /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 134180151AA91740003F314A /* RCTNetwork.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 58B511DB1A9E6C8500147676;
|
||||
remoteInfo = RCTNetwork;
|
||||
};
|
||||
13442C041AA90E7D0037E5B0 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 13442C001AA90E7D0037E5B0 /* RCTImage.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 58B5115D1A9E6B3D00147676;
|
||||
remoteInfo = RCTImage;
|
||||
};
|
||||
14312D231AC3654D00CDC950 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 14312D1E1AC3654D00CDC950 /* RCTLinking.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 134814201AA4EA6300B7C361;
|
||||
remoteInfo = RCTLinking;
|
||||
};
|
||||
14A2D4401AC3E41A00CC738A /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 14A2D43C1AC3E41A00CC738A /* React.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 83CBBA2E1A601D0E00E9B192;
|
||||
remoteInfo = React;
|
||||
};
|
||||
58C5725A1AA6236500CDF9C8 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 587650F61A9EB120008B8F17 /* RCTText.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 58B5119B1A9E6C1200147676;
|
||||
remoteInfo = RCTText;
|
||||
};
|
||||
67C95F1D1B0E647A0040BCE2 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 67C95F151B0E647A0040BCE2 /* RCTWebSocket.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 3C86DF461ADF2C930047B81A;
|
||||
remoteInfo = RCTWebSocket;
|
||||
};
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
134180151AA91740003F314A /* RCTNetwork.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTNetwork.xcodeproj; path = ../../Libraries/Network/RCTNetwork.xcodeproj; sourceTree = "<group>"; };
|
||||
13442C001AA90E7D0037E5B0 /* RCTImage.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTImage.xcodeproj; path = ../../Libraries/Image/RCTImage.xcodeproj; sourceTree = "<group>"; };
|
||||
13B07F961A680F5B00A75B9A /* Movies.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Movies.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = Movies/AppDelegate.h; sourceTree = "<group>"; };
|
||||
13B07FB01A68108700A75B9A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = Movies/AppDelegate.m; sourceTree = "<group>"; };
|
||||
13B07FB21A68108700A75B9A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = "<group>"; };
|
||||
13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = Movies/Images.xcassets; sourceTree = "<group>"; };
|
||||
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = Movies/Info.plist; sourceTree = "<group>"; };
|
||||
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = Movies/main.m; sourceTree = "<group>"; };
|
||||
14312D1E1AC3654D00CDC950 /* RCTLinking.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTLinking.xcodeproj; path = ../../Libraries/LinkingIOS/RCTLinking.xcodeproj; sourceTree = "<group>"; };
|
||||
14A2D43C1AC3E41A00CC738A /* React.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = React.xcodeproj; path = ../../React/React.xcodeproj; sourceTree = "<group>"; };
|
||||
587650F61A9EB120008B8F17 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = ../../Libraries/Text/RCTText.xcodeproj; sourceTree = SOURCE_ROOT; };
|
||||
67C95F151B0E647A0040BCE2 /* RCTWebSocket.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTWebSocket.xcodeproj; path = ../../Libraries/WebSocket/RCTWebSocket.xcodeproj; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
13B07F8C1A680F5B00A75B9A /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
67C95F201B0E64A30040BCE2 /* libRCTWebSocket.a in Frameworks */,
|
||||
14A2D4421AC3E43800CC738A /* libReact.a in Frameworks */,
|
||||
140D9B661AC36C42004F25EE /* libRCTLinking.a in Frameworks */,
|
||||
1341801E1AA91750003F314A /* libRCTNetwork.a in Frameworks */,
|
||||
13442C061AA90EA00037E5B0 /* libRCTImage.a in Frameworks */,
|
||||
58C5726B1AA6239E00CDF9C8 /* libRCTText.a in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
134180161AA91740003F314A /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
1341801B1AA91740003F314A /* libRCTNetwork.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
13442C011AA90E7D0037E5B0 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
13442C051AA90E7D0037E5B0 /* libRCTImage.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
13B07FAE1A68108700A75B9A /* Movies */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
13B07FAF1A68108700A75B9A /* AppDelegate.h */,
|
||||
13B07FB01A68108700A75B9A /* AppDelegate.m */,
|
||||
13B07FB51A68108700A75B9A /* Images.xcassets */,
|
||||
13B07FB61A68108700A75B9A /* Info.plist */,
|
||||
13B07FB11A68108700A75B9A /* LaunchScreen.xib */,
|
||||
13B07FB71A68108700A75B9A /* main.m */,
|
||||
);
|
||||
name = Movies;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
14312D1F1AC3654D00CDC950 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
14312D241AC3654D00CDC950 /* libRCTLinking.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
14A2D43D1AC3E41A00CC738A /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
14A2D4411AC3E41A00CC738A /* libReact.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
58C571FC1AA6124500CDF9C8 /* Libraries */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
67C95F151B0E647A0040BCE2 /* RCTWebSocket.xcodeproj */,
|
||||
14A2D43C1AC3E41A00CC738A /* React.xcodeproj */,
|
||||
14312D1E1AC3654D00CDC950 /* RCTLinking.xcodeproj */,
|
||||
134180151AA91740003F314A /* RCTNetwork.xcodeproj */,
|
||||
13442C001AA90E7D0037E5B0 /* RCTImage.xcodeproj */,
|
||||
587650F61A9EB120008B8F17 /* RCTText.xcodeproj */,
|
||||
);
|
||||
name = Libraries;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
58C572571AA6236500CDF9C8 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
58C5725B1AA6236500CDF9C8 /* libRCTText.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
67C95F161B0E647A0040BCE2 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
67C95F1E1B0E647A0040BCE2 /* libRCTWebSocket.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
83CBB9F61A601CBA00E9B192 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
13B07FAE1A68108700A75B9A /* Movies */,
|
||||
58C571FC1AA6124500CDF9C8 /* Libraries */,
|
||||
83CBBA001A601CBA00E9B192 /* Products */,
|
||||
);
|
||||
indentWidth = 2;
|
||||
sourceTree = "<group>";
|
||||
tabWidth = 2;
|
||||
};
|
||||
83CBBA001A601CBA00E9B192 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
13B07F961A680F5B00A75B9A /* Movies.app */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
13B07F861A680F5B00A75B9A /* Movies */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "Movies" */;
|
||||
buildPhases = (
|
||||
13B07F871A680F5B00A75B9A /* Sources */,
|
||||
13B07F8C1A680F5B00A75B9A /* Frameworks */,
|
||||
13B07F8E1A680F5B00A75B9A /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = Movies;
|
||||
productName = "Hello World";
|
||||
productReference = 13B07F961A680F5B00A75B9A /* Movies.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
83CBB9F71A601CBA00E9B192 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 0700;
|
||||
ORGANIZATIONNAME = Facebook;
|
||||
};
|
||||
buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "Movies" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
Base,
|
||||
);
|
||||
mainGroup = 83CBB9F61A601CBA00E9B192;
|
||||
productRefGroup = 83CBBA001A601CBA00E9B192 /* Products */;
|
||||
projectDirPath = "";
|
||||
projectReferences = (
|
||||
{
|
||||
ProductGroup = 13442C011AA90E7D0037E5B0 /* Products */;
|
||||
ProjectRef = 13442C001AA90E7D0037E5B0 /* RCTImage.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = 14312D1F1AC3654D00CDC950 /* Products */;
|
||||
ProjectRef = 14312D1E1AC3654D00CDC950 /* RCTLinking.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = 134180161AA91740003F314A /* Products */;
|
||||
ProjectRef = 134180151AA91740003F314A /* RCTNetwork.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = 58C572571AA6236500CDF9C8 /* Products */;
|
||||
ProjectRef = 587650F61A9EB120008B8F17 /* RCTText.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = 67C95F161B0E647A0040BCE2 /* Products */;
|
||||
ProjectRef = 67C95F151B0E647A0040BCE2 /* RCTWebSocket.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = 14A2D43D1AC3E41A00CC738A /* Products */;
|
||||
ProjectRef = 14A2D43C1AC3E41A00CC738A /* React.xcodeproj */;
|
||||
},
|
||||
);
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
13B07F861A680F5B00A75B9A /* Movies */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXReferenceProxy section */
|
||||
1341801B1AA91740003F314A /* libRCTNetwork.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libRCTNetwork.a;
|
||||
remoteRef = 1341801A1AA91740003F314A /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
13442C051AA90E7D0037E5B0 /* libRCTImage.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libRCTImage.a;
|
||||
remoteRef = 13442C041AA90E7D0037E5B0 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
14312D241AC3654D00CDC950 /* libRCTLinking.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libRCTLinking.a;
|
||||
remoteRef = 14312D231AC3654D00CDC950 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
14A2D4411AC3E41A00CC738A /* libReact.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libReact.a;
|
||||
remoteRef = 14A2D4401AC3E41A00CC738A /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
58C5725B1AA6236500CDF9C8 /* libRCTText.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libRCTText.a;
|
||||
remoteRef = 58C5725A1AA6236500CDF9C8 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
67C95F1E1B0E647A0040BCE2 /* libRCTWebSocket.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libRCTWebSocket.a;
|
||||
remoteRef = 67C95F1D1B0E647A0040BCE2 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
/* End PBXReferenceProxy section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
13B07F8E1A680F5B00A75B9A /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */,
|
||||
13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
13B07F871A680F5B00A75B9A /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */,
|
||||
13B07FC11A68108700A75B9A /* main.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXVariantGroup section */
|
||||
13B07FB11A68108700A75B9A /* LaunchScreen.xib */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
13B07FB21A68108700A75B9A /* Base */,
|
||||
);
|
||||
name = LaunchScreen.xib;
|
||||
path = Movies;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXVariantGroup section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
13B07F941A680F5B00A75B9A /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||
"$(SRCROOT)/../../React/**",
|
||||
);
|
||||
INFOPLIST_FILE = "$(SRCROOT)/Movies/Info.plist";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
LIBRARY_SEARCH_PATHS = "$(inherited)";
|
||||
OTHER_LDFLAGS = "-ObjC";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.facebook.$(PRODUCT_NAME:rfc1034identifier)";
|
||||
PRODUCT_NAME = Movies;
|
||||
USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/../../Libraries/**";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
13B07F951A680F5B00A75B9A /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||
"$(SRCROOT)/../../React/**",
|
||||
);
|
||||
INFOPLIST_FILE = "$(SRCROOT)/Movies/Info.plist";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
LIBRARY_SEARCH_PATHS = "$(inherited)";
|
||||
OTHER_LDFLAGS = "-ObjC";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.facebook.$(PRODUCT_NAME:rfc1034identifier)";
|
||||
PRODUCT_NAME = Movies;
|
||||
USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/../../Libraries/**";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
83CBBA201A601CBA00E9B192 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||
"$(SRCROOT)/../../React/**",
|
||||
);
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = iphoneos;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
83CBBA211A601CBA00E9B192 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
COPY_PHASE_STRIP = YES;
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||
"$(SRCROOT)/../../React/**",
|
||||
);
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
SDKROOT = iphoneos;
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "Movies" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
13B07F941A680F5B00A75B9A /* Debug */,
|
||||
13B07F951A680F5B00A75B9A /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "Movies" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
83CBBA201A601CBA00E9B192 /* Debug */,
|
||||
83CBBA211A601CBA00E9B192 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = 83CBB9F71A601CBA00E9B192 /* Project object */;
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0700"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
|
||||
BuildableName = "Movies.app"
|
||||
BlueprintName = "Movies"
|
||||
ReferencedContainer = "container:Movies.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
buildConfiguration = "Debug">
|
||||
<Testables>
|
||||
</Testables>
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
|
||||
BuildableName = "Movies.app"
|
||||
BlueprintName = "Movies"
|
||||
ReferencedContainer = "container:Movies.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
buildConfiguration = "Debug"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
|
||||
BuildableName = "Movies.app"
|
||||
BlueprintName = "Movies"
|
||||
ReferencedContainer = "container:Movies.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
buildConfiguration = "Release"
|
||||
debugDocumentVersioning = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
|
||||
BuildableName = "Movies.app"
|
||||
BlueprintName = "Movies"
|
||||
ReferencedContainer = "container:Movies.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
||||
@@ -0,0 +1,22 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface AppDelegate : UIResponder <UIApplicationDelegate>
|
||||
|
||||
@property (nonatomic, strong) UIWindow *window;
|
||||
|
||||
@end
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#import "AppDelegate.h"
|
||||
|
||||
#import "RCTLinkingManager.h"
|
||||
#import "RCTRootView.h"
|
||||
|
||||
@implementation AppDelegate
|
||||
|
||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
||||
{
|
||||
NSURL *jsCodeLocation;
|
||||
|
||||
/**
|
||||
* Loading JavaScript code - uncomment the one you want.
|
||||
*
|
||||
* OPTION 1
|
||||
* Load from development server. Start the server from the repository root:
|
||||
*
|
||||
* $ npm start
|
||||
*
|
||||
* To run on device, change `localhost` to the IP address of your computer
|
||||
* (you can get this by typing `ifconfig` into the terminal and selecting the
|
||||
* `inet` value under `en0:`) and make sure your computer and iOS device are
|
||||
* on the same Wi-Fi network.
|
||||
*/
|
||||
|
||||
jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/Examples/Movies/MoviesApp.ios.bundle?platform=ios&dev=true"];
|
||||
|
||||
/**
|
||||
* OPTION 2
|
||||
* Load from pre-bundled file on disk. To re-generate the static bundle, `cd`
|
||||
* to your Xcode project folder in the terminal, and run
|
||||
*
|
||||
* $ curl 'http://localhost:8081/Examples/Movies/MoviesApp.ios.bundle?platform=ios&dev=true' -o main.jsbundle
|
||||
*
|
||||
* then add the `main.jsbundle` file to your project and uncomment this line:
|
||||
*/
|
||||
|
||||
// jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
|
||||
|
||||
RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
|
||||
moduleName:@"MoviesApp"
|
||||
initialProperties:nil
|
||||
launchOptions:launchOptions];
|
||||
|
||||
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
|
||||
UIViewController *rootViewController = [[UIViewController alloc] init];
|
||||
rootViewController.view = rootView;
|
||||
self.window.rootViewController = rootViewController;
|
||||
[self.window makeKeyAndVisible];
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)application:(UIApplication *)application
|
||||
openURL:(NSURL *)url
|
||||
sourceApplication:(NSString *)sourceApplication
|
||||
annotation:(id)annotation
|
||||
{
|
||||
return [RCTLinkingManager application:application
|
||||
openURL:url
|
||||
sourceApplication:sourceApplication
|
||||
annotation:annotation];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="6254" systemVersion="14B25" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6247"/>
|
||||
<capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<view contentMode="scaleToFill" id="iN0-l3-epB">
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="480"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text=" Copyright (c) 2015 Facebook. All rights reserved." textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="9" translatesAutoresizingMaskIntoConstraints="NO" id="8ie-xW-0ye">
|
||||
<rect key="frame" x="20" y="439" width="441" height="21"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Movies" textAlignment="center" lineBreakMode="middleTruncation" baselineAdjustment="alignBaselines" minimumFontSize="18" translatesAutoresizingMaskIntoConstraints="NO" id="kId-c2-rCX">
|
||||
<rect key="frame" x="20" y="140" width="441" height="43"/>
|
||||
<fontDescription key="fontDescription" type="boldSystem" pointSize="36"/>
|
||||
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
|
||||
<constraints>
|
||||
<constraint firstItem="kId-c2-rCX" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="bottom" multiplier="1/3" constant="1" id="5cJ-9S-tgC"/>
|
||||
<constraint firstAttribute="centerX" secondItem="kId-c2-rCX" secondAttribute="centerX" id="Koa-jz-hwk"/>
|
||||
<constraint firstAttribute="bottom" secondItem="8ie-xW-0ye" secondAttribute="bottom" constant="20" id="Kzo-t9-V3l"/>
|
||||
<constraint firstItem="8ie-xW-0ye" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="MfP-vx-nX0"/>
|
||||
<constraint firstAttribute="centerX" secondItem="8ie-xW-0ye" secondAttribute="centerX" id="ZEH-qu-HZ9"/>
|
||||
<constraint firstItem="kId-c2-rCX" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="fvb-Df-36g"/>
|
||||
</constraints>
|
||||
<nil key="simulatedStatusBarMetrics"/>
|
||||
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
|
||||
<point key="canvasLocation" x="548" y="455"/>
|
||||
</view>
|
||||
</objects>
|
||||
</document>
|
||||
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "29x29",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "29x29",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "40x40",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "40x40",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "60x60",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "60x60",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleURLTypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
<key>CFBundleURLSchemes</key>
|
||||
<array>
|
||||
<string>movies</string>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<dict>
|
||||
<key>NSAllowsArbitraryLoads</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>LaunchScreen</string>
|
||||
<key>UIRequiredDeviceCapabilities</key>
|
||||
<array>
|
||||
<string>armv7</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,22 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "AppDelegate.h"
|
||||
|
||||
int main(int argc, char * argv[]) {
|
||||
@autoreleasepool {
|
||||
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* @providesModule MoviesApp
|
||||
* @flow
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var React = require('react-native');
|
||||
var {
|
||||
AppRegistry,
|
||||
BackAndroid,
|
||||
Navigator,
|
||||
StyleSheet,
|
||||
ToolbarAndroid,
|
||||
View,
|
||||
} = React;
|
||||
|
||||
var MovieScreen = require('./MovieScreen');
|
||||
var SearchScreen = require('./SearchScreen');
|
||||
|
||||
var _navigator;
|
||||
BackAndroid.addEventListener('hardwareBackPress', () => {
|
||||
if (_navigator && _navigator.getCurrentRoutes().length > 1) {
|
||||
_navigator.pop();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
var RouteMapper = function(route, navigationOperations, onComponentRef) {
|
||||
_navigator = navigationOperations;
|
||||
if (route.name === 'search') {
|
||||
return (
|
||||
<SearchScreen navigator={navigationOperations} />
|
||||
);
|
||||
} else if (route.name === 'movie') {
|
||||
return (
|
||||
<View style={{flex: 1}}>
|
||||
<ToolbarAndroid
|
||||
actions={[]}
|
||||
navIcon={require('image!android_back_white')}
|
||||
onIconClicked={navigationOperations.pop}
|
||||
style={styles.toolbar}
|
||||
titleColor="white"
|
||||
title={route.movie.title} />
|
||||
<MovieScreen
|
||||
style={{flex: 1}}
|
||||
navigator={navigationOperations}
|
||||
movie={route.movie}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
var MoviesApp = React.createClass({
|
||||
render: function() {
|
||||
var initialRoute = {name: 'search'};
|
||||
return (
|
||||
<Navigator
|
||||
style={styles.container}
|
||||
initialRoute={initialRoute}
|
||||
configureScene={() => Navigator.SceneConfigs.FadeAndroid}
|
||||
renderScene={RouteMapper}
|
||||
/>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: 'white',
|
||||
},
|
||||
toolbar: {
|
||||
backgroundColor: '#a9a9a9',
|
||||
height: 56,
|
||||
},
|
||||
});
|
||||
|
||||
AppRegistry.registerComponent('MoviesApp', () => MoviesApp);
|
||||
|
||||
module.exports = MoviesApp;
|
||||
@@ -0,0 +1,51 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* @providesModule MoviesApp
|
||||
* @flow
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var React = require('react-native');
|
||||
var {
|
||||
AppRegistry,
|
||||
NavigatorIOS,
|
||||
StyleSheet,
|
||||
} = React;
|
||||
|
||||
var SearchScreen = require('./SearchScreen');
|
||||
|
||||
var MoviesApp = React.createClass({
|
||||
render: function() {
|
||||
return (
|
||||
<NavigatorIOS
|
||||
style={styles.container}
|
||||
initialRoute={{
|
||||
title: 'Movies',
|
||||
component: SearchScreen,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: 'white',
|
||||
},
|
||||
});
|
||||
|
||||
AppRegistry.registerComponent('MoviesApp', () => MoviesApp);
|
||||
|
||||
module.exports = MoviesApp;
|
||||
@@ -0,0 +1,41 @@
|
||||
# Movies app
|
||||
|
||||
The Movies app is a demonstration of basic concepts, such as fetching data, rendering a list of data including images, and navigating between different screens.
|
||||
|
||||
## Running this app
|
||||
|
||||
Before running the app, make sure you ran:
|
||||
|
||||
cd react-native
|
||||
npm install
|
||||
|
||||
### Running on iOS
|
||||
|
||||
Mac OS and Xcode are required.
|
||||
|
||||
- Open `Examples/Movies/Movies.xcodeproj` in Xcode
|
||||
- Hit the Run button
|
||||
|
||||
See [Running on device](https://facebook.github.io/react-native/docs/running-on-device-ios.html) if you want to use a physical device.
|
||||
|
||||
### Running on Android
|
||||
|
||||
You'll need to have all the [prerequisites](https://github.com/facebook/react-native/tree/master/ReactAndroid#prerequisites) (SDK, NDK) for Building React Native installed.
|
||||
|
||||
Start an Android emulator ([Genymotion](https://www.genymotion.com) is recommended).
|
||||
|
||||
cd react-native
|
||||
./gradlew :Examples:Movies:android:app:installDebug
|
||||
./packager/packager.sh
|
||||
|
||||
_Note: Building for the first time can take a while._
|
||||
|
||||
Open the Movies app in your emulator.
|
||||
|
||||
See [Running on Device](https://facebook.github.io/react-native/docs/running-on-device-android.html) in case you want to use a physical device.
|
||||
|
||||
## Built from source
|
||||
|
||||
Building the app on both iOS and Android means building the React Native framework from source. This way you're running the latest native and JS code the way you see it in your clone of the github repo.
|
||||
|
||||
This is different from apps created using `react-native init` which have a dependency on a specific version of React Native JS and native code, declared in a `package.json` file (and `build.gradle` for Android apps).
|
||||
@@ -0,0 +1,104 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* @providesModule SearchBar
|
||||
* @flow
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var React = require('react-native');
|
||||
var {
|
||||
Image,
|
||||
Platform,
|
||||
ProgressBarAndroid,
|
||||
TextInput,
|
||||
StyleSheet,
|
||||
TouchableNativeFeedback,
|
||||
View,
|
||||
} = React;
|
||||
|
||||
var IS_RIPPLE_EFFECT_SUPPORTED = Platform.Version >= 21;
|
||||
|
||||
var SearchBar = React.createClass({
|
||||
render: function() {
|
||||
var loadingView;
|
||||
if (this.props.isLoading) {
|
||||
loadingView = (
|
||||
<ProgressBarAndroid
|
||||
styleAttr="Large"
|
||||
style={styles.spinner}
|
||||
/>
|
||||
);
|
||||
} else {
|
||||
loadingView = <View style={styles.spinner} />;
|
||||
}
|
||||
var background = IS_RIPPLE_EFFECT_SUPPORTED ?
|
||||
TouchableNativeFeedback.SelectableBackgroundBorderless() :
|
||||
TouchableNativeFeedback.SelectableBackground();
|
||||
return (
|
||||
<View style={styles.searchBar}>
|
||||
<TouchableNativeFeedback
|
||||
background={background}
|
||||
onPress={() => this.refs.input && this.refs.input.focus()}>
|
||||
<View>
|
||||
<Image
|
||||
source={require('image!android_search_white')}
|
||||
style={styles.icon}
|
||||
/>
|
||||
</View>
|
||||
</TouchableNativeFeedback>
|
||||
<TextInput
|
||||
ref="input"
|
||||
autoCapitalize="none"
|
||||
autoCorrect={false}
|
||||
autoFocus={true}
|
||||
onChange={this.props.onSearchChange}
|
||||
placeholder="Search a movie..."
|
||||
placeholderTextColor="rgba(255, 255, 255, 0.5)"
|
||||
onFocus={this.props.onFocus}
|
||||
style={styles.searchBarInput}
|
||||
/>
|
||||
{loadingView}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
searchBar: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
backgroundColor: '#a9a9a9',
|
||||
height: 56,
|
||||
},
|
||||
searchBarInput: {
|
||||
flex: 1,
|
||||
fontSize: 20,
|
||||
fontWeight: 'bold',
|
||||
color: 'white',
|
||||
height: 50,
|
||||
padding: 0,
|
||||
backgroundColor: 'transparent'
|
||||
},
|
||||
spinner: {
|
||||
width: 30,
|
||||
height: 30,
|
||||
},
|
||||
icon: {
|
||||
width: 24,
|
||||
height: 24,
|
||||
marginHorizontal: 8,
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = SearchBar;
|
||||
@@ -0,0 +1,66 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* @providesModule SearchBar
|
||||
* @flow
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var React = require('react-native');
|
||||
var {
|
||||
ActivityIndicatorIOS,
|
||||
TextInput,
|
||||
StyleSheet,
|
||||
View,
|
||||
} = React;
|
||||
|
||||
var SearchBar = React.createClass({
|
||||
render: function() {
|
||||
return (
|
||||
<View style={styles.searchBar}>
|
||||
<TextInput
|
||||
autoCapitalize="none"
|
||||
autoCorrect={false}
|
||||
onChange={this.props.onSearchChange}
|
||||
placeholder="Search a movie..."
|
||||
onFocus={this.props.onFocus}
|
||||
style={styles.searchBarInput}
|
||||
/>
|
||||
<ActivityIndicatorIOS
|
||||
animating={this.props.isLoading}
|
||||
style={styles.spinner}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
searchBar: {
|
||||
marginTop: 64,
|
||||
padding: 3,
|
||||
paddingLeft: 8,
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
},
|
||||
searchBarInput: {
|
||||
fontSize: 15,
|
||||
flex: 1,
|
||||
height: 30,
|
||||
},
|
||||
spinner: {
|
||||
width: 30,
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = SearchBar;
|
||||
@@ -0,0 +1,376 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* @flow
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var React = require('react-native');
|
||||
var {
|
||||
ActivityIndicatorIOS,
|
||||
ListView,
|
||||
Platform,
|
||||
ProgressBarAndroid,
|
||||
StyleSheet,
|
||||
Text,
|
||||
View,
|
||||
} = React;
|
||||
var TimerMixin = require('react-timer-mixin');
|
||||
|
||||
var invariant = require('invariant');
|
||||
var dismissKeyboard = require('dismissKeyboard');
|
||||
|
||||
var MovieCell = require('./MovieCell');
|
||||
var MovieScreen = require('./MovieScreen');
|
||||
var SearchBar = require('SearchBar');
|
||||
|
||||
/**
|
||||
* This is for demo purposes only, and rate limited.
|
||||
* In case you want to use the Rotten Tomatoes' API on a real app you should
|
||||
* create an account at http://developer.rottentomatoes.com/
|
||||
*/
|
||||
var API_URL = 'http://api.rottentomatoes.com/api/public/v1.0/';
|
||||
var API_KEYS = [
|
||||
'7waqfqbprs7pajbz28mqf6vz',
|
||||
// 'y4vwv8m33hed9ety83jmv52f', Fallback api_key
|
||||
];
|
||||
|
||||
// Results should be cached keyed by the query
|
||||
// with values of null meaning "being fetched"
|
||||
// and anything besides null and undefined
|
||||
// as the result of a valid query
|
||||
var resultsCache = {
|
||||
dataForQuery: {},
|
||||
nextPageNumberForQuery: {},
|
||||
totalForQuery: {},
|
||||
};
|
||||
|
||||
var LOADING = {};
|
||||
|
||||
var SearchScreen = React.createClass({
|
||||
mixins: [TimerMixin],
|
||||
|
||||
timeoutID: (null: any),
|
||||
|
||||
getInitialState: function() {
|
||||
return {
|
||||
isLoading: false,
|
||||
isLoadingTail: false,
|
||||
dataSource: new ListView.DataSource({
|
||||
rowHasChanged: (row1, row2) => row1 !== row2,
|
||||
}),
|
||||
filter: '',
|
||||
queryNumber: 0,
|
||||
};
|
||||
},
|
||||
|
||||
componentDidMount: function() {
|
||||
this.searchMovies('');
|
||||
},
|
||||
|
||||
_urlForQueryAndPage: function(query: string, pageNumber: number): string {
|
||||
var apiKey = API_KEYS[this.state.queryNumber % API_KEYS.length];
|
||||
if (query) {
|
||||
return (
|
||||
API_URL + 'movies.json?apikey=' + apiKey + '&q=' +
|
||||
encodeURIComponent(query) + '&page_limit=20&page=' + pageNumber
|
||||
);
|
||||
} else {
|
||||
// With no query, load latest movies
|
||||
return (
|
||||
API_URL + 'lists/movies/in_theaters.json?apikey=' + apiKey +
|
||||
'&page_limit=20&page=' + pageNumber
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
searchMovies: function(query: string) {
|
||||
this.timeoutID = null;
|
||||
|
||||
this.setState({filter: query});
|
||||
|
||||
var cachedResultsForQuery = resultsCache.dataForQuery[query];
|
||||
if (cachedResultsForQuery) {
|
||||
if (!LOADING[query]) {
|
||||
this.setState({
|
||||
dataSource: this.getDataSource(cachedResultsForQuery),
|
||||
isLoading: false
|
||||
});
|
||||
} else {
|
||||
this.setState({isLoading: true});
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
LOADING[query] = true;
|
||||
resultsCache.dataForQuery[query] = null;
|
||||
this.setState({
|
||||
isLoading: true,
|
||||
queryNumber: this.state.queryNumber + 1,
|
||||
isLoadingTail: false,
|
||||
});
|
||||
|
||||
fetch(this._urlForQueryAndPage(query, 1))
|
||||
.then((response) => response.json())
|
||||
.catch((error) => {
|
||||
LOADING[query] = false;
|
||||
resultsCache.dataForQuery[query] = undefined;
|
||||
|
||||
this.setState({
|
||||
dataSource: this.getDataSource([]),
|
||||
isLoading: false,
|
||||
});
|
||||
})
|
||||
.then((responseData) => {
|
||||
LOADING[query] = false;
|
||||
resultsCache.totalForQuery[query] = responseData.total;
|
||||
resultsCache.dataForQuery[query] = responseData.movies;
|
||||
resultsCache.nextPageNumberForQuery[query] = 2;
|
||||
|
||||
if (this.state.filter !== query) {
|
||||
// do not update state if the query is stale
|
||||
return;
|
||||
}
|
||||
|
||||
this.setState({
|
||||
isLoading: false,
|
||||
dataSource: this.getDataSource(responseData.movies),
|
||||
});
|
||||
})
|
||||
.done();
|
||||
},
|
||||
|
||||
hasMore: function(): boolean {
|
||||
var query = this.state.filter;
|
||||
if (!resultsCache.dataForQuery[query]) {
|
||||
return true;
|
||||
}
|
||||
return (
|
||||
resultsCache.totalForQuery[query] !==
|
||||
resultsCache.dataForQuery[query].length
|
||||
);
|
||||
},
|
||||
|
||||
onEndReached: function() {
|
||||
var query = this.state.filter;
|
||||
if (!this.hasMore() || this.state.isLoadingTail) {
|
||||
// We're already fetching or have all the elements so noop
|
||||
return;
|
||||
}
|
||||
|
||||
if (LOADING[query]) {
|
||||
return;
|
||||
}
|
||||
|
||||
LOADING[query] = true;
|
||||
this.setState({
|
||||
queryNumber: this.state.queryNumber + 1,
|
||||
isLoadingTail: true,
|
||||
});
|
||||
|
||||
var page = resultsCache.nextPageNumberForQuery[query];
|
||||
invariant(page != null, 'Next page number for "%s" is missing', query);
|
||||
fetch(this._urlForQueryAndPage(query, page))
|
||||
.then((response) => response.json())
|
||||
.catch((error) => {
|
||||
console.error(error);
|
||||
LOADING[query] = false;
|
||||
this.setState({
|
||||
isLoadingTail: false,
|
||||
});
|
||||
})
|
||||
.then((responseData) => {
|
||||
var moviesForQuery = resultsCache.dataForQuery[query].slice();
|
||||
|
||||
LOADING[query] = false;
|
||||
// We reached the end of the list before the expected number of results
|
||||
if (!responseData.movies) {
|
||||
resultsCache.totalForQuery[query] = moviesForQuery.length;
|
||||
} else {
|
||||
for (var i in responseData.movies) {
|
||||
moviesForQuery.push(responseData.movies[i]);
|
||||
}
|
||||
resultsCache.dataForQuery[query] = moviesForQuery;
|
||||
resultsCache.nextPageNumberForQuery[query] += 1;
|
||||
}
|
||||
|
||||
if (this.state.filter !== query) {
|
||||
// do not update state if the query is stale
|
||||
return;
|
||||
}
|
||||
|
||||
this.setState({
|
||||
isLoadingTail: false,
|
||||
dataSource: this.getDataSource(resultsCache.dataForQuery[query]),
|
||||
});
|
||||
})
|
||||
.done();
|
||||
},
|
||||
|
||||
getDataSource: function(movies: Array<any>): ListView.DataSource {
|
||||
return this.state.dataSource.cloneWithRows(movies);
|
||||
},
|
||||
|
||||
selectMovie: function(movie: Object) {
|
||||
if (Platform.OS === 'ios') {
|
||||
this.props.navigator.push({
|
||||
title: movie.title,
|
||||
component: MovieScreen,
|
||||
passProps: {movie},
|
||||
});
|
||||
} else {
|
||||
dismissKeyboard();
|
||||
this.props.navigator.push({
|
||||
title: movie.title,
|
||||
name: 'movie',
|
||||
movie: movie,
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
onSearchChange: function(event: Object) {
|
||||
var filter = event.nativeEvent.text.toLowerCase();
|
||||
|
||||
this.clearTimeout(this.timeoutID);
|
||||
this.timeoutID = this.setTimeout(() => this.searchMovies(filter), 100);
|
||||
},
|
||||
|
||||
renderFooter: function() {
|
||||
if (!this.hasMore() || !this.state.isLoadingTail) {
|
||||
return <View style={styles.scrollSpinner} />;
|
||||
}
|
||||
if (Platform.OS === 'ios') {
|
||||
return <ActivityIndicatorIOS style={styles.scrollSpinner} />;
|
||||
} else {
|
||||
return (
|
||||
<View style={{alignItems: 'center'}}>
|
||||
<ProgressBarAndroid styleAttr="Large"/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
renderSeparator: function(
|
||||
sectionID: number | string,
|
||||
rowID: number | string,
|
||||
adjacentRowHighlighted: boolean
|
||||
) {
|
||||
var style = styles.rowSeparator;
|
||||
if (adjacentRowHighlighted) {
|
||||
style = [style, styles.rowSeparatorHide];
|
||||
}
|
||||
return (
|
||||
<View key={'SEP_' + sectionID + '_' + rowID} style={style}/>
|
||||
);
|
||||
},
|
||||
|
||||
renderRow: function(
|
||||
movie: Object,
|
||||
sectionID: number | string,
|
||||
rowID: number | string,
|
||||
highlightRowFunc: (sectionID: ?number | string, rowID: ?number | string) => void,
|
||||
) {
|
||||
return (
|
||||
<MovieCell
|
||||
key={movie.id}
|
||||
onSelect={() => this.selectMovie(movie)}
|
||||
onHighlight={() => highlightRowFunc(sectionID, rowID)}
|
||||
onUnhighlight={() => highlightRowFunc(null, null)}
|
||||
movie={movie}
|
||||
/>
|
||||
);
|
||||
},
|
||||
|
||||
render: function() {
|
||||
var content = this.state.dataSource.getRowCount() === 0 ?
|
||||
<NoMovies
|
||||
filter={this.state.filter}
|
||||
isLoading={this.state.isLoading}
|
||||
/> :
|
||||
<ListView
|
||||
ref="listview"
|
||||
renderSeparator={this.renderSeparator}
|
||||
dataSource={this.state.dataSource}
|
||||
renderFooter={this.renderFooter}
|
||||
renderRow={this.renderRow}
|
||||
onEndReached={this.onEndReached}
|
||||
automaticallyAdjustContentInsets={false}
|
||||
keyboardDismissMode="on-drag"
|
||||
keyboardShouldPersistTaps={true}
|
||||
showsVerticalScrollIndicator={false}
|
||||
/>;
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<SearchBar
|
||||
onSearchChange={this.onSearchChange}
|
||||
isLoading={this.state.isLoading}
|
||||
onFocus={() =>
|
||||
this.refs.listview && this.refs.listview.getScrollResponder().scrollTo(0, 0)}
|
||||
/>
|
||||
<View style={styles.separator} />
|
||||
{content}
|
||||
</View>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
var NoMovies = React.createClass({
|
||||
render: function() {
|
||||
var text = '';
|
||||
if (this.props.filter) {
|
||||
text = `No results for "${this.props.filter}"`;
|
||||
} else if (!this.props.isLoading) {
|
||||
// If we're looking at the latest movies, aren't currently loading, and
|
||||
// still have no results, show a message
|
||||
text = 'No movies found';
|
||||
}
|
||||
|
||||
return (
|
||||
<View style={[styles.container, styles.centerText]}>
|
||||
<Text style={styles.noMoviesText}>{text}</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: 'white',
|
||||
},
|
||||
centerText: {
|
||||
alignItems: 'center',
|
||||
},
|
||||
noMoviesText: {
|
||||
marginTop: 80,
|
||||
color: '#888888',
|
||||
},
|
||||
separator: {
|
||||
height: 1,
|
||||
backgroundColor: '#eeeeee',
|
||||
},
|
||||
scrollSpinner: {
|
||||
marginVertical: 20,
|
||||
},
|
||||
rowSeparator: {
|
||||
backgroundColor: 'rgba(0, 0, 0, 0.1)',
|
||||
height: 1,
|
||||
marginLeft: 4,
|
||||
},
|
||||
rowSeparatorHide: {
|
||||
opacity: 0.0,
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = SearchScreen;
|
||||
@@ -0,0 +1,36 @@
|
||||
/**
|
||||
* Copyright 2004-present Facebook. All Rights Reserved.
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
jest.dontMock('../getImageSource');
|
||||
|
||||
var getImageSource = require('../getImageSource');
|
||||
|
||||
describe('getImageSource', () => {
|
||||
it('returns null for invalid input', () => {
|
||||
expect(getImageSource().uri).toBe(null);
|
||||
});
|
||||
|
||||
it('returns a movie thumbnail', () => {
|
||||
var uri = 'https://facebook.com';
|
||||
var source = {
|
||||
posters: {
|
||||
thumbnail: uri,
|
||||
},
|
||||
};
|
||||
expect(getImageSource(source).uri).toBe(uri);
|
||||
});
|
||||
|
||||
it('returns a movie thumbnail with kind', () => {
|
||||
var uri = 'https://facebook.com?tmb';
|
||||
var source = {
|
||||
posters: {
|
||||
thumbnail: uri,
|
||||
},
|
||||
};
|
||||
expect(getImageSource(source, 'kind').uri).toBe(
|
||||
'https://facebook.com?kind'
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,31 @@
|
||||
apply plugin: 'com.android.application'
|
||||
|
||||
android {
|
||||
compileSdkVersion 23
|
||||
buildToolsVersion "23.0.1"
|
||||
|
||||
defaultConfig {
|
||||
applicationId "com.facebook.react.movies"
|
||||
minSdkVersion 16
|
||||
targetSdkVersion 22
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
ndk {
|
||||
abiFilters "armeabi-v7a", "x86"
|
||||
}
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile fileTree(dir: 'libs', include: ['*.jar'])
|
||||
compile 'com.android.support:appcompat-v7:23.0.1'
|
||||
|
||||
// Build React Native from source
|
||||
compile project(':ReactAndroid')
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
android.useDeprecatedNdk=true
|
||||
@@ -0,0 +1,17 @@
|
||||
# Add project specific ProGuard rules here.
|
||||
# By default, the flags in this file are appended to flags specified
|
||||
# in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt
|
||||
# You can edit the include path and order by changing the proguardFiles
|
||||
# directive in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# Add any project specific keep options here:
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
@@ -0,0 +1,21 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.facebook.react.movies">
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:label="@string/app_name"
|
||||
android:icon="@drawable/rotten_tomatoes_icon"
|
||||
android:theme="@style/AppTheme">
|
||||
<activity
|
||||
android:name=".MoviesActivity">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
@@ -0,0 +1,89 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.facebook.react.movies;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.view.KeyEvent;
|
||||
|
||||
import com.facebook.react.LifecycleState;
|
||||
import com.facebook.react.ReactInstanceManager;
|
||||
import com.facebook.react.ReactRootView;
|
||||
import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;
|
||||
import com.facebook.react.shell.MainReactPackage;
|
||||
|
||||
public class MoviesActivity extends Activity implements DefaultHardwareBackBtnHandler {
|
||||
|
||||
private ReactInstanceManager mReactInstanceManager;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_main);
|
||||
|
||||
mReactInstanceManager = ReactInstanceManager.builder()
|
||||
.setApplication(getApplication())
|
||||
.setBundleAssetName("MoviesApp.android.bundle")
|
||||
.setJSMainModuleName("Examples/Movies/MoviesApp.android")
|
||||
.addPackage(new MainReactPackage())
|
||||
.setUseDeveloperSupport(true)
|
||||
.setInitialLifecycleState(LifecycleState.RESUMED)
|
||||
.build();
|
||||
|
||||
((ReactRootView) findViewById(R.id.react_root_view))
|
||||
.startReactApplication(mReactInstanceManager, "MoviesApp", null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onKeyUp(int keyCode, KeyEvent event) {
|
||||
if (keyCode == KeyEvent.KEYCODE_MENU && mReactInstanceManager != null) {
|
||||
mReactInstanceManager.showDevOptionsDialog();
|
||||
return true;
|
||||
}
|
||||
return super.onKeyUp(keyCode, event);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
|
||||
if (mReactInstanceManager != null) {
|
||||
mReactInstanceManager.onPause();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
|
||||
if (mReactInstanceManager != null) {
|
||||
mReactInstanceManager.onResume(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
if (mReactInstanceManager != null) {
|
||||
mReactInstanceManager.onBackPressed();
|
||||
} else {
|
||||
super.onBackPressed();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invokeDefaultOnBackPressed() {
|
||||
super.onBackPressed();
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 237 B |
|
After Width: | Height: | Size: 575 B |
|
After Width: | Height: | Size: 190 B |
|
After Width: | Height: | Size: 337 B |
|
After Width: | Height: | Size: 266 B |
|
After Width: | Height: | Size: 581 B |
|
After Width: | Height: | Size: 337 B |
|
After Width: | Height: | Size: 930 B |
|
After Width: | Height: | Size: 57 KiB |
@@ -0,0 +1,12 @@
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".MoviesApp">
|
||||
|
||||
<com.facebook.react.ReactRootView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:id="@+id/react_root_view"/>
|
||||
|
||||
</RelativeLayout>
|
||||
@@ -0,0 +1,3 @@
|
||||
<resources>
|
||||
<string name="app_name">MoviesApp</string>
|
||||
</resources>
|
||||
@@ -0,0 +1,8 @@
|
||||
<resources>
|
||||
|
||||
<!-- Base application theme. -->
|
||||
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
|
||||
<!-- Customize your theme here. -->
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* @flow
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
function getImageSource(movie: Object, kind: ?string): {uri: ?string} {
|
||||
var uri = movie && movie.posters ? movie.posters.thumbnail : null;
|
||||
if (uri && kind) {
|
||||
uri = uri.replace('tmb', kind);
|
||||
}
|
||||
return { uri };
|
||||
}
|
||||
|
||||
module.exports = getImageSource;
|
||||
@@ -0,0 +1,48 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* @flow
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var React = require('react-native');
|
||||
var {
|
||||
StyleSheet,
|
||||
} = React;
|
||||
|
||||
var MAX_VALUE = 200;
|
||||
|
||||
import type { StyleObj } from 'StyleSheetTypes';
|
||||
|
||||
function getStyleFromScore(score: number): StyleObj {
|
||||
if (score < 0) {
|
||||
return styles.noScore;
|
||||
}
|
||||
|
||||
var normalizedScore = Math.round((score / 100) * MAX_VALUE);
|
||||
return {
|
||||
color: 'rgb(' +
|
||||
(MAX_VALUE - normalizedScore) + ', ' +
|
||||
normalizedScore + ', ' +
|
||||
0 +
|
||||
')'
|
||||
};
|
||||
}
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
noScore: {
|
||||
color: '#999999',
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = getStyleFromScore;
|
||||
@@ -0,0 +1,22 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* @flow
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
function getTextFromScore(score: number): string {
|
||||
return score > 0 ? score + '%' : 'N/A';
|
||||
}
|
||||
|
||||
module.exports = getTextFromScore;
|
||||
@@ -0,0 +1,465 @@
|
||||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 46;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
1341803E1AA91802003F314A /* libRCTImage.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1341803D1AA917ED003F314A /* libRCTImage.a */; };
|
||||
13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; };
|
||||
13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB11A68108700A75B9A /* LaunchScreen.xib */; };
|
||||
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
|
||||
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
|
||||
144C5F691AC3E5E300B004E7 /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 144C5F681AC3E5D800B004E7 /* libReact.a */; };
|
||||
58C572511AA6229D00CDF9C8 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 58C5724D1AA6224400CDF9C8 /* libRCTText.a */; };
|
||||
5FF8942E1B85571A007731BE /* libRCTWebSocket.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5FF8942D1B8556F8007731BE /* libRCTWebSocket.a */; };
|
||||
832044981B492C2500E297FC /* libRCTSettings.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 832044951B492C1E00E297FC /* libRCTSettings.a */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
1341803C1AA917ED003F314A /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 134180381AA917ED003F314A /* RCTImage.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 58B5115D1A9E6B3D00147676;
|
||||
remoteInfo = RCTImage;
|
||||
};
|
||||
144C5F671AC3E5D800B004E7 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 144C5F631AC3E5D800B004E7 /* React.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 83CBBA2E1A601D0E00E9B192;
|
||||
remoteInfo = React;
|
||||
};
|
||||
58C5724C1AA6224400CDF9C8 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 587650DA1A9EB0DB008B8F17 /* RCTText.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 58B5119B1A9E6C1200147676;
|
||||
remoteInfo = RCTText;
|
||||
};
|
||||
5FF8942C1B8556F8007731BE /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 5FF894281B8556F8007731BE /* RCTWebSocket.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 3C86DF461ADF2C930047B81A;
|
||||
remoteInfo = RCTWebSocket;
|
||||
};
|
||||
832044941B492C1E00E297FC /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 8320448F1B492C1E00E297FC /* RCTSettings.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 134814201AA4EA6300B7C361;
|
||||
remoteInfo = RCTSettings;
|
||||
};
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
134180381AA917ED003F314A /* RCTImage.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTImage.xcodeproj; path = ../../Libraries/Image/RCTImage.xcodeproj; sourceTree = "<group>"; };
|
||||
13B07F961A680F5B00A75B9A /* TicTacToe.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TicTacToe.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = TicTacToe/AppDelegate.h; sourceTree = "<group>"; };
|
||||
13B07FB01A68108700A75B9A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = TicTacToe/AppDelegate.m; sourceTree = "<group>"; };
|
||||
13B07FB21A68108700A75B9A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = "<group>"; };
|
||||
13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = TicTacToe/Images.xcassets; sourceTree = "<group>"; };
|
||||
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = TicTacToe/Info.plist; sourceTree = "<group>"; };
|
||||
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = TicTacToe/main.m; sourceTree = "<group>"; };
|
||||
144C5F631AC3E5D800B004E7 /* React.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = React.xcodeproj; path = ../../React/React.xcodeproj; sourceTree = "<group>"; };
|
||||
587650DA1A9EB0DB008B8F17 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = ../../Libraries/Text/RCTText.xcodeproj; sourceTree = "<group>"; };
|
||||
5FF894281B8556F8007731BE /* RCTWebSocket.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTWebSocket.xcodeproj; path = ../../Libraries/WebSocket/RCTWebSocket.xcodeproj; sourceTree = "<group>"; };
|
||||
8320448F1B492C1E00E297FC /* RCTSettings.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTSettings.xcodeproj; path = ../../Libraries/Settings/RCTSettings.xcodeproj; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
13B07F8C1A680F5B00A75B9A /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
5FF8942E1B85571A007731BE /* libRCTWebSocket.a in Frameworks */,
|
||||
144C5F691AC3E5E300B004E7 /* libReact.a in Frameworks */,
|
||||
1341803E1AA91802003F314A /* libRCTImage.a in Frameworks */,
|
||||
58C572511AA6229D00CDF9C8 /* libRCTText.a in Frameworks */,
|
||||
832044981B492C2500E297FC /* libRCTSettings.a in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
134180391AA917ED003F314A /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
1341803D1AA917ED003F314A /* libRCTImage.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
13B07FAE1A68108700A75B9A /* TicTacToe */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
13B07FAF1A68108700A75B9A /* AppDelegate.h */,
|
||||
13B07FB01A68108700A75B9A /* AppDelegate.m */,
|
||||
13B07FB51A68108700A75B9A /* Images.xcassets */,
|
||||
13B07FB61A68108700A75B9A /* Info.plist */,
|
||||
13B07FB11A68108700A75B9A /* LaunchScreen.xib */,
|
||||
13B07FB71A68108700A75B9A /* main.m */,
|
||||
);
|
||||
name = TicTacToe;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
144C5F641AC3E5D800B004E7 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
144C5F681AC3E5D800B004E7 /* libReact.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
58C572071AA6126D00CDF9C8 /* Libraries */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
5FF894281B8556F8007731BE /* RCTWebSocket.xcodeproj */,
|
||||
144C5F631AC3E5D800B004E7 /* React.xcodeproj */,
|
||||
134180381AA917ED003F314A /* RCTImage.xcodeproj */,
|
||||
8320448F1B492C1E00E297FC /* RCTSettings.xcodeproj */,
|
||||
587650DA1A9EB0DB008B8F17 /* RCTText.xcodeproj */,
|
||||
);
|
||||
name = Libraries;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
58C572481AA6224300CDF9C8 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
58C5724D1AA6224400CDF9C8 /* libRCTText.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
5FF894291B8556F8007731BE /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
5FF8942D1B8556F8007731BE /* libRCTWebSocket.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
832044901B492C1E00E297FC /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
832044951B492C1E00E297FC /* libRCTSettings.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
83CBB9F61A601CBA00E9B192 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
13B07FAE1A68108700A75B9A /* TicTacToe */,
|
||||
58C572071AA6126D00CDF9C8 /* Libraries */,
|
||||
83CBBA001A601CBA00E9B192 /* Products */,
|
||||
);
|
||||
indentWidth = 2;
|
||||
sourceTree = "<group>";
|
||||
tabWidth = 2;
|
||||
};
|
||||
83CBBA001A601CBA00E9B192 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
13B07F961A680F5B00A75B9A /* TicTacToe.app */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
13B07F861A680F5B00A75B9A /* TicTacToe */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "TicTacToe" */;
|
||||
buildPhases = (
|
||||
13B07F871A680F5B00A75B9A /* Sources */,
|
||||
13B07F8C1A680F5B00A75B9A /* Frameworks */,
|
||||
13B07F8E1A680F5B00A75B9A /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = TicTacToe;
|
||||
productName = "Hello World";
|
||||
productReference = 13B07F961A680F5B00A75B9A /* TicTacToe.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
83CBB9F71A601CBA00E9B192 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 0700;
|
||||
ORGANIZATIONNAME = Facebook;
|
||||
};
|
||||
buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "TicTacToe" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
Base,
|
||||
);
|
||||
mainGroup = 83CBB9F61A601CBA00E9B192;
|
||||
productRefGroup = 83CBBA001A601CBA00E9B192 /* Products */;
|
||||
projectDirPath = "";
|
||||
projectReferences = (
|
||||
{
|
||||
ProductGroup = 134180391AA917ED003F314A /* Products */;
|
||||
ProjectRef = 134180381AA917ED003F314A /* RCTImage.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = 832044901B492C1E00E297FC /* Products */;
|
||||
ProjectRef = 8320448F1B492C1E00E297FC /* RCTSettings.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = 58C572481AA6224300CDF9C8 /* Products */;
|
||||
ProjectRef = 587650DA1A9EB0DB008B8F17 /* RCTText.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = 5FF894291B8556F8007731BE /* Products */;
|
||||
ProjectRef = 5FF894281B8556F8007731BE /* RCTWebSocket.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = 144C5F641AC3E5D800B004E7 /* Products */;
|
||||
ProjectRef = 144C5F631AC3E5D800B004E7 /* React.xcodeproj */;
|
||||
},
|
||||
);
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
13B07F861A680F5B00A75B9A /* TicTacToe */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXReferenceProxy section */
|
||||
1341803D1AA917ED003F314A /* libRCTImage.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libRCTImage.a;
|
||||
remoteRef = 1341803C1AA917ED003F314A /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
144C5F681AC3E5D800B004E7 /* libReact.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libReact.a;
|
||||
remoteRef = 144C5F671AC3E5D800B004E7 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
58C5724D1AA6224400CDF9C8 /* libRCTText.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libRCTText.a;
|
||||
remoteRef = 58C5724C1AA6224400CDF9C8 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
5FF8942D1B8556F8007731BE /* libRCTWebSocket.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libRCTWebSocket.a;
|
||||
remoteRef = 5FF8942C1B8556F8007731BE /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
832044951B492C1E00E297FC /* libRCTSettings.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libRCTSettings.a;
|
||||
remoteRef = 832044941B492C1E00E297FC /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
/* End PBXReferenceProxy section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
13B07F8E1A680F5B00A75B9A /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */,
|
||||
13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
13B07F871A680F5B00A75B9A /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */,
|
||||
13B07FC11A68108700A75B9A /* main.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXVariantGroup section */
|
||||
13B07FB11A68108700A75B9A /* LaunchScreen.xib */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
13B07FB21A68108700A75B9A /* Base */,
|
||||
);
|
||||
name = LaunchScreen.xib;
|
||||
path = TicTacToe;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXVariantGroup section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
13B07F941A680F5B00A75B9A /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||
"$(SRCROOT)/../../React/**",
|
||||
);
|
||||
INFOPLIST_FILE = "$(SRCROOT)/TicTacToe/Info.plist";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
LIBRARY_SEARCH_PATHS = "$(inherited)";
|
||||
OTHER_LDFLAGS = "-ObjC";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.facebook.$(PRODUCT_NAME:rfc1034identifier)";
|
||||
PRODUCT_NAME = TicTacToe;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
13B07F951A680F5B00A75B9A /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||
"$(SRCROOT)/../../React/**",
|
||||
);
|
||||
INFOPLIST_FILE = "$(SRCROOT)/TicTacToe/Info.plist";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
LIBRARY_SEARCH_PATHS = "$(inherited)";
|
||||
OTHER_LDFLAGS = "-ObjC";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.facebook.$(PRODUCT_NAME:rfc1034identifier)";
|
||||
PRODUCT_NAME = TicTacToe;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
83CBBA201A601CBA00E9B192 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||
"$(SRCROOT)/../../React/**",
|
||||
);
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = iphoneos;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
83CBBA211A601CBA00E9B192 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
COPY_PHASE_STRIP = YES;
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||
"$(SRCROOT)/../../React/**",
|
||||
);
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
SDKROOT = iphoneos;
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "TicTacToe" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
13B07F941A680F5B00A75B9A /* Debug */,
|
||||
13B07F951A680F5B00A75B9A /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "TicTacToe" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
83CBBA201A601CBA00E9B192 /* Debug */,
|
||||
83CBBA211A601CBA00E9B192 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = 83CBB9F71A601CBA00E9B192 /* Project object */;
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0700"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
|
||||
BuildableName = "TicTacToe.app"
|
||||
BlueprintName = "TicTacToe"
|
||||
ReferencedContainer = "container:TicTacToe.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
buildConfiguration = "Debug">
|
||||
<Testables>
|
||||
</Testables>
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
|
||||
BuildableName = "TicTacToe.app"
|
||||
BlueprintName = "TicTacToe"
|
||||
ReferencedContainer = "container:TicTacToe.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
buildConfiguration = "Debug"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
|
||||
BuildableName = "TicTacToe.app"
|
||||
BlueprintName = "TicTacToe"
|
||||
ReferencedContainer = "container:TicTacToe.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
buildConfiguration = "Release"
|
||||
debugDocumentVersioning = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
|
||||
BuildableName = "TicTacToe.app"
|
||||
BlueprintName = "TicTacToe"
|
||||
ReferencedContainer = "container:TicTacToe.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
||||
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface AppDelegate : UIResponder <UIApplicationDelegate>
|
||||
|
||||
@property (nonatomic, strong) UIWindow *window;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,66 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#import "AppDelegate.h"
|
||||
|
||||
#import "RCTRootView.h"
|
||||
|
||||
@implementation AppDelegate
|
||||
|
||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
||||
{
|
||||
NSURL *jsCodeLocation;
|
||||
|
||||
/**
|
||||
* Loading JavaScript code - uncomment the one you want.
|
||||
*
|
||||
* OPTION 1
|
||||
* Load from development server. Start the server from the repository root:
|
||||
*
|
||||
* $ npm start
|
||||
*
|
||||
* To run on device, change `localhost` to the IP address of your computer
|
||||
* (you can get this by typing `ifconfig` into the terminal and selecting the
|
||||
* `inet` value under `en0:`) and make sure your computer and iOS device are
|
||||
* on the same Wi-Fi network.
|
||||
*/
|
||||
|
||||
jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/Examples/TicTacToe/TicTacToeApp.bundle?platform=ios&dev=true"];
|
||||
|
||||
/**
|
||||
* OPTION 2
|
||||
* Load from pre-bundled file on disk. To re-generate the static bundle, `cd`
|
||||
* to your Xcode project folder in the terminal, and run
|
||||
*
|
||||
* $ curl 'http://localhost:8081/Examples/TicTacToe/TicTacToeApp.bundle?platform=ios' -o main.jsbundle
|
||||
*
|
||||
* then add the `main.jsbundle` file to your project and uncomment this line:
|
||||
*/
|
||||
|
||||
// jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
|
||||
|
||||
RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
|
||||
moduleName:@"TicTacToeApp"
|
||||
initialProperties:nil
|
||||
launchOptions:launchOptions];
|
||||
|
||||
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
|
||||
UIViewController *rootViewController = [[UIViewController alloc] init];
|
||||
rootViewController.view = rootView;
|
||||
self.window.rootViewController = rootViewController;
|
||||
[self.window makeKeyAndVisible];
|
||||
return YES;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="6254" systemVersion="14B25" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6247"/>
|
||||
<capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<view contentMode="scaleToFill" id="iN0-l3-epB">
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="480"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text=" Copyright (c) 2015 Facebook. All rights reserved." textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="9" translatesAutoresizingMaskIntoConstraints="NO" id="8ie-xW-0ye">
|
||||
<rect key="frame" x="20" y="439" width="441" height="21"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="TicTacToe" textAlignment="center" lineBreakMode="middleTruncation" baselineAdjustment="alignBaselines" minimumFontSize="18" translatesAutoresizingMaskIntoConstraints="NO" id="kId-c2-rCX">
|
||||
<rect key="frame" x="20" y="140" width="441" height="43"/>
|
||||
<fontDescription key="fontDescription" type="boldSystem" pointSize="36"/>
|
||||
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
|
||||
<constraints>
|
||||
<constraint firstItem="kId-c2-rCX" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="bottom" multiplier="1/3" constant="1" id="5cJ-9S-tgC"/>
|
||||
<constraint firstAttribute="centerX" secondItem="kId-c2-rCX" secondAttribute="centerX" id="Koa-jz-hwk"/>
|
||||
<constraint firstAttribute="bottom" secondItem="8ie-xW-0ye" secondAttribute="bottom" constant="20" id="Kzo-t9-V3l"/>
|
||||
<constraint firstItem="8ie-xW-0ye" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="MfP-vx-nX0"/>
|
||||
<constraint firstAttribute="centerX" secondItem="8ie-xW-0ye" secondAttribute="centerX" id="ZEH-qu-HZ9"/>
|
||||
<constraint firstItem="kId-c2-rCX" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="fvb-Df-36g"/>
|
||||
</constraints>
|
||||
<nil key="simulatedStatusBarMetrics"/>
|
||||
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
|
||||
<point key="canvasLocation" x="548" y="455"/>
|
||||
</view>
|
||||
</objects>
|
||||
</document>
|
||||
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "29x29",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "29x29",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "40x40",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "40x40",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "60x60",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "60x60",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>LaunchScreen</string>
|
||||
<key>UIRequiredDeviceCapabilities</key>
|
||||
<array>
|
||||
<string>armv7</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||
<false/>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<dict>
|
||||
<!--See http://ste.vn/2015/06/10/configuring-app-transport-security-ios-9-osx-10-11/-->
|
||||
<key>NSAllowsArbitraryLoads</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,22 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "AppDelegate.h"
|
||||
|
||||
int main(int argc, char * argv[]) {
|
||||
@autoreleasepool {
|
||||
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,322 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* @providesModule TicTacToeApp
|
||||
* @flow
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var React = require('react-native');
|
||||
var {
|
||||
AppRegistry,
|
||||
StyleSheet,
|
||||
Text,
|
||||
TouchableHighlight,
|
||||
View,
|
||||
} = React;
|
||||
|
||||
class Board {
|
||||
grid: Array<Array<number>>;
|
||||
turn: number;
|
||||
|
||||
constructor() {
|
||||
var size = 3;
|
||||
var grid = Array(size);
|
||||
for (var i = 0; i < size; i++) {
|
||||
var row = Array(size);
|
||||
for (var j = 0; j < size; j++) {
|
||||
row[j] = 0;
|
||||
}
|
||||
grid[i] = row;
|
||||
}
|
||||
this.grid = grid;
|
||||
|
||||
this.turn = 1;
|
||||
}
|
||||
|
||||
mark(row: number, col: number, player: number): Board {
|
||||
this.grid[row][col] = player;
|
||||
return this;
|
||||
}
|
||||
|
||||
hasMark(row: number, col: number): boolean {
|
||||
return this.grid[row][col] !== 0;
|
||||
}
|
||||
|
||||
winner(): ?number {
|
||||
for (var i = 0; i < 3; i++) {
|
||||
if (this.grid[i][0] !== 0 && this.grid[i][0] === this.grid[i][1] &&
|
||||
this.grid[i][0] === this.grid[i][2]) {
|
||||
return this.grid[i][0];
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < 3; i++) {
|
||||
if (this.grid[0][i] !== 0 && this.grid[0][i] === this.grid[1][i] &&
|
||||
this.grid[0][i] === this.grid[2][i]) {
|
||||
return this.grid[0][i];
|
||||
}
|
||||
}
|
||||
|
||||
if (this.grid[0][0] !== 0 && this.grid[0][0] === this.grid[1][1] &&
|
||||
this.grid[0][0] === this.grid[2][2]) {
|
||||
return this.grid[0][0];
|
||||
}
|
||||
|
||||
if (this.grid[0][2] !== 0 && this.grid[0][2] === this.grid[1][1] &&
|
||||
this.grid[0][2] === this.grid[2][0]) {
|
||||
return this.grid[0][2];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
tie(): boolean {
|
||||
for (var i = 0; i < 3; i++) {
|
||||
for (var j = 0; j < 3; j++) {
|
||||
if (this.grid[i][j] === 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return this.winner() === null;
|
||||
}
|
||||
}
|
||||
|
||||
var Cell = React.createClass({
|
||||
cellStyle() {
|
||||
switch (this.props.player) {
|
||||
case 1:
|
||||
return styles.cellX;
|
||||
case 2:
|
||||
return styles.cellO;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
textStyle() {
|
||||
switch (this.props.player) {
|
||||
case 1:
|
||||
return styles.cellTextX;
|
||||
case 2:
|
||||
return styles.cellTextO;
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
},
|
||||
|
||||
textContents() {
|
||||
switch (this.props.player) {
|
||||
case 1:
|
||||
return 'X';
|
||||
case 2:
|
||||
return 'O';
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
},
|
||||
|
||||
render() {
|
||||
return (
|
||||
<TouchableHighlight
|
||||
onPress={this.props.onPress}
|
||||
underlayColor="transparent"
|
||||
activeOpacity={0.5}>
|
||||
<View style={[styles.cell, this.cellStyle()]}>
|
||||
<Text style={[styles.cellText, this.textStyle()]}>
|
||||
{this.textContents()}
|
||||
</Text>
|
||||
</View>
|
||||
</TouchableHighlight>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var GameEndOverlay = React.createClass({
|
||||
render() {
|
||||
var board = this.props.board;
|
||||
|
||||
var tie = board.tie();
|
||||
var winner = board.winner();
|
||||
if (!winner && !tie) {
|
||||
return <View />;
|
||||
}
|
||||
|
||||
var message;
|
||||
if (tie) {
|
||||
message = 'It\'s a tie!';
|
||||
} else {
|
||||
message = (winner === 1 ? 'X' : 'O') + ' wins!';
|
||||
}
|
||||
|
||||
return (
|
||||
<View style={styles.overlay}>
|
||||
<Text style={styles.overlayMessage}>{message}</Text>
|
||||
<TouchableHighlight
|
||||
onPress={this.props.onRestart}
|
||||
underlayColor="transparent"
|
||||
activeOpacity={0.5}>
|
||||
<View style={styles.newGame}>
|
||||
<Text style={styles.newGameText}>New Game</Text>
|
||||
</View>
|
||||
</TouchableHighlight>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var TicTacToeApp = React.createClass({
|
||||
getInitialState() {
|
||||
return { board: new Board(), player: 1 };
|
||||
},
|
||||
|
||||
restartGame() {
|
||||
this.setState(this.getInitialState());
|
||||
},
|
||||
|
||||
nextPlayer(): number {
|
||||
return this.state.player === 1 ? 2 : 1;
|
||||
},
|
||||
|
||||
handleCellPress(row: number, col: number) {
|
||||
if (this.state.board.hasMark(row, col)) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.setState({
|
||||
board: this.state.board.mark(row, col, this.state.player),
|
||||
player: this.nextPlayer(),
|
||||
});
|
||||
},
|
||||
|
||||
render() {
|
||||
var rows = this.state.board.grid.map((cells, row) =>
|
||||
<View key={'row' + row} style={styles.row}>
|
||||
{cells.map((player, col) =>
|
||||
<Cell
|
||||
key={'cell' + col}
|
||||
player={player}
|
||||
onPress={this.handleCellPress.bind(this, row, col)}
|
||||
/>
|
||||
)}
|
||||
</View>
|
||||
);
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<Text style={styles.title}>EXTREME T3</Text>
|
||||
<View style={styles.board}>
|
||||
{rows}
|
||||
</View>
|
||||
<GameEndOverlay
|
||||
board={this.state.board}
|
||||
onRestart={this.restartGame}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
backgroundColor: 'white'
|
||||
},
|
||||
title: {
|
||||
fontFamily: 'Chalkduster',
|
||||
fontSize: 39,
|
||||
marginBottom: 20,
|
||||
},
|
||||
board: {
|
||||
padding: 5,
|
||||
backgroundColor: '#47525d',
|
||||
borderRadius: 10,
|
||||
},
|
||||
row: {
|
||||
flexDirection: 'row',
|
||||
},
|
||||
|
||||
// CELL
|
||||
|
||||
cell: {
|
||||
width: 80,
|
||||
height: 80,
|
||||
borderRadius: 5,
|
||||
backgroundColor: '#7b8994',
|
||||
margin: 5,
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
},
|
||||
cellX: {
|
||||
backgroundColor: '#72d0eb',
|
||||
},
|
||||
cellO: {
|
||||
backgroundColor: '#7ebd26',
|
||||
},
|
||||
|
||||
// CELL TEXT
|
||||
|
||||
cellText: {
|
||||
borderRadius: 5,
|
||||
fontSize: 50,
|
||||
fontFamily: 'AvenirNext-Bold',
|
||||
},
|
||||
cellTextX: {
|
||||
color: '#19a9e5',
|
||||
},
|
||||
cellTextO: {
|
||||
color: '#b9dc2f',
|
||||
},
|
||||
|
||||
// GAME OVER
|
||||
|
||||
overlay: {
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
backgroundColor: 'rgba(221, 221, 221, 0.5)',
|
||||
flex: 1,
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
},
|
||||
overlayMessage: {
|
||||
fontSize: 40,
|
||||
marginBottom: 20,
|
||||
marginLeft: 20,
|
||||
marginRight: 20,
|
||||
fontFamily: 'AvenirNext-DemiBold',
|
||||
textAlign: 'center',
|
||||
},
|
||||
newGame: {
|
||||
backgroundColor: '#887766',
|
||||
padding: 20,
|
||||
borderRadius: 5,
|
||||
},
|
||||
newGameText: {
|
||||
color: 'white',
|
||||
fontSize: 20,
|
||||
fontFamily: 'AvenirNext-DemiBold',
|
||||
},
|
||||
});
|
||||
|
||||
AppRegistry.registerComponent('TicTacToeApp', () => TicTacToeApp);
|
||||
|
||||
module.exports = TicTacToeApp;
|
||||
@@ -0,0 +1,213 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var React = require('react-native');
|
||||
var {
|
||||
StyleSheet,
|
||||
Text,
|
||||
View,
|
||||
ToastAndroid,
|
||||
TouchableWithoutFeedback,
|
||||
} = React;
|
||||
|
||||
var UIExplorerBlock = require('./UIExplorerBlock');
|
||||
var UIExplorerPage = require('./UIExplorerPage');
|
||||
|
||||
var importantForAccessibilityValues = ['auto', 'yes', 'no', 'no-hide-descendants'];
|
||||
|
||||
var AccessibilityAndroidExample = React.createClass({
|
||||
|
||||
statics: {
|
||||
title: 'Accessibility',
|
||||
description: 'Examples of using Accessibility API.',
|
||||
},
|
||||
|
||||
getInitialState: function() {
|
||||
return {
|
||||
count: 0,
|
||||
backgroundImportantForAcc: 0,
|
||||
forgroundImportantForAcc: 0,
|
||||
};
|
||||
},
|
||||
|
||||
_addOne: function() {
|
||||
this.setState({
|
||||
count: ++this.state.count,
|
||||
});
|
||||
},
|
||||
|
||||
_changeBackgroundImportantForAcc: function() {
|
||||
this.setState({
|
||||
backgroundImportantForAcc: (this.state.backgroundImportantForAcc + 1) % 4,
|
||||
});
|
||||
},
|
||||
|
||||
_changeForgroundImportantForAcc: function() {
|
||||
this.setState({
|
||||
forgroundImportantForAcc: (this.state.forgroundImportantForAcc + 1) % 4,
|
||||
});
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return (
|
||||
<UIExplorerPage title={'Accessibility'}>
|
||||
|
||||
<UIExplorerBlock title="Nonaccessible view with TextViews">
|
||||
<View>
|
||||
<Text style={{color: 'green',}}>
|
||||
This is
|
||||
</Text>
|
||||
<Text style={{color: 'blue'}}>
|
||||
nontouchable normal view.
|
||||
</Text>
|
||||
</View>
|
||||
</UIExplorerBlock>
|
||||
|
||||
<UIExplorerBlock title="Accessible view with TextViews wihout label">
|
||||
<View accessible={true}>
|
||||
<Text style={{color: 'green',}}>
|
||||
This is
|
||||
</Text>
|
||||
<Text style={{color: 'blue'}}>
|
||||
nontouchable accessible view without label.
|
||||
</Text>
|
||||
</View>
|
||||
</UIExplorerBlock>
|
||||
|
||||
<UIExplorerBlock title="Accessible view with TextViews with label">
|
||||
<View accessible={true}
|
||||
accessibilityLabel="I have label, so I read it instead of embedded text.">
|
||||
<Text style={{color: 'green',}}>
|
||||
This is
|
||||
</Text>
|
||||
<Text style={{color: 'blue'}}>
|
||||
nontouchable accessible view with label.
|
||||
</Text>
|
||||
</View>
|
||||
</UIExplorerBlock>
|
||||
|
||||
<UIExplorerBlock title="Touchable with component type = button">
|
||||
<TouchableWithoutFeedback
|
||||
onPress={() => ToastAndroid.show('Toasts work by default', ToastAndroid.SHORT)}
|
||||
accessibilityComponentType="button">
|
||||
<View style={styles.embedded}>
|
||||
<Text>Click me</Text>
|
||||
<Text>Or not</Text>
|
||||
</View>
|
||||
</TouchableWithoutFeedback>
|
||||
</UIExplorerBlock>
|
||||
|
||||
<UIExplorerBlock title="LiveRegion">
|
||||
<TouchableWithoutFeedback onPress={this._addOne}>
|
||||
<View style={styles.embedded}>
|
||||
<Text>Click me</Text>
|
||||
</View>
|
||||
</TouchableWithoutFeedback>
|
||||
<Text accessibilityLiveRegion="polite">
|
||||
Clicked {this.state.count} times
|
||||
</Text>
|
||||
</UIExplorerBlock>
|
||||
|
||||
<UIExplorerBlock title="Overlapping views and importantForAccessibility property">
|
||||
<View style={styles.container}>
|
||||
<View
|
||||
style={{
|
||||
position: 'absolute',
|
||||
left: 10,
|
||||
top: 10,
|
||||
right: 10,
|
||||
height: 100,
|
||||
backgroundColor: 'green'}}
|
||||
accessible={true}
|
||||
accessibilityLabel="First layout"
|
||||
importantForAccessibility={
|
||||
importantForAccessibilityValues[this.state.backgroundImportantForAcc]}>
|
||||
<View accessible={true}>
|
||||
<Text style={{fontSize: 25}}>
|
||||
Hello
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
<View
|
||||
style={{
|
||||
position: 'absolute',
|
||||
left: 10,
|
||||
top: 25,
|
||||
right: 10,
|
||||
height: 110,
|
||||
backgroundColor: 'yellow', opacity: 0.5}}
|
||||
accessible={true}
|
||||
accessibilityLabel="Second layout"
|
||||
importantForAccessibility={
|
||||
importantForAccessibilityValues[this.state.forgroundImportantForAcc]}>
|
||||
<View accessible={true}>
|
||||
<Text style={{fontSize: 20}}>
|
||||
world
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
<TouchableWithoutFeedback onPress={this._changeBackgroundImportantForAcc}>
|
||||
<View style={styles.embedded}>
|
||||
<Text>
|
||||
Change importantForAccessibility for background layout.
|
||||
</Text>
|
||||
</View>
|
||||
</TouchableWithoutFeedback>
|
||||
<View accessible={true}>
|
||||
<Text>
|
||||
Background layout importantForAccessibility
|
||||
</Text>
|
||||
<Text>
|
||||
{importantForAccessibilityValues[this.state.backgroundImportantForAcc]}
|
||||
</Text>
|
||||
</View>
|
||||
<TouchableWithoutFeedback onPress={this._changeForgroundImportantForAcc}>
|
||||
<View style={styles.embedded}>
|
||||
<Text>
|
||||
Change importantForAccessibility for forground layout.
|
||||
</Text>
|
||||
</View>
|
||||
</TouchableWithoutFeedback>
|
||||
<View accessible={true}>
|
||||
<Text>
|
||||
Forground layout importantForAccessibility
|
||||
</Text>
|
||||
<Text>
|
||||
{importantForAccessibilityValues[this.state.forgroundImportantForAcc]}
|
||||
</Text>
|
||||
</View>
|
||||
</UIExplorerBlock>
|
||||
|
||||
</UIExplorerPage>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
embedded: {
|
||||
backgroundColor: 'yellow',
|
||||
padding:10,
|
||||
},
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: 'white',
|
||||
padding: 10,
|
||||
height:150,
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = AccessibilityAndroidExample;
|
||||
@@ -0,0 +1,65 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* @flow
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var React = require('react-native');
|
||||
var {
|
||||
Text,
|
||||
View,
|
||||
} = React;
|
||||
|
||||
var AccessibilityIOSExample = React.createClass({
|
||||
render() {
|
||||
return (
|
||||
<View>
|
||||
<View
|
||||
onAccessibilityTap={() => alert('onAccessibilityTap success')}
|
||||
accessible={true}>
|
||||
<Text>
|
||||
Accessibility normal tap example
|
||||
</Text>
|
||||
</View>
|
||||
<View onMagicTap={() => alert('onMagicTap success')}
|
||||
accessible={true}>
|
||||
<Text>
|
||||
Accessibility magic tap example
|
||||
</Text>
|
||||
</View>
|
||||
<View accessibilityLabel="Some announcement"
|
||||
accessible={true}>
|
||||
<Text>
|
||||
Accessibility label example
|
||||
</Text>
|
||||
</View>
|
||||
<View accessibilityTraits={['button', 'selected']}
|
||||
accessible={true}>
|
||||
<Text>
|
||||
Accessibility traits example
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
exports.title = 'AccessibilityIOS';
|
||||
exports.description = 'Interface to show iOS\' accessibility samples';
|
||||
exports.examples = [
|
||||
{
|
||||
title: 'Accessibility elements',
|
||||
render(): ReactElement { return <AccessibilityIOSExample />; }
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1,125 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* @flow
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var React = require('react-native');
|
||||
var {
|
||||
ActionSheetIOS,
|
||||
StyleSheet,
|
||||
Text,
|
||||
View,
|
||||
} = React;
|
||||
|
||||
var BUTTONS = [
|
||||
'Option 0',
|
||||
'Option 1',
|
||||
'Option 2',
|
||||
'Destruct',
|
||||
'Cancel',
|
||||
];
|
||||
var DESTRUCTIVE_INDEX = 3;
|
||||
var CANCEL_INDEX = 4;
|
||||
|
||||
var ActionSheetExample = React.createClass({
|
||||
getInitialState() {
|
||||
return {
|
||||
clicked: 'none',
|
||||
};
|
||||
},
|
||||
|
||||
render() {
|
||||
return (
|
||||
<View>
|
||||
<Text onPress={this.showActionSheet} style={style.button}>
|
||||
Click to show the ActionSheet
|
||||
</Text>
|
||||
<Text>
|
||||
Clicked button: {this.state.clicked}
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
},
|
||||
|
||||
showActionSheet() {
|
||||
ActionSheetIOS.showActionSheetWithOptions({
|
||||
options: BUTTONS,
|
||||
cancelButtonIndex: CANCEL_INDEX,
|
||||
destructiveButtonIndex: DESTRUCTIVE_INDEX,
|
||||
},
|
||||
(buttonIndex) => {
|
||||
this.setState({ clicked: BUTTONS[buttonIndex] });
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
var ShareActionSheetExample = React.createClass({
|
||||
getInitialState() {
|
||||
return {
|
||||
text: ''
|
||||
};
|
||||
},
|
||||
|
||||
render() {
|
||||
return (
|
||||
<View>
|
||||
<Text onPress={this.showShareActionSheet} style={style.button}>
|
||||
Click to show the Share ActionSheet
|
||||
</Text>
|
||||
<Text>
|
||||
{this.state.text}
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
},
|
||||
|
||||
showShareActionSheet() {
|
||||
ActionSheetIOS.showShareActionSheetWithOptions({
|
||||
url: 'https://code.facebook.com',
|
||||
},
|
||||
(error) => {
|
||||
console.error(error);
|
||||
},
|
||||
(success, method) => {
|
||||
var text;
|
||||
if (success) {
|
||||
text = `Shared via ${method}`;
|
||||
} else {
|
||||
text = 'You didn\'t share';
|
||||
}
|
||||
this.setState({text});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
var style = StyleSheet.create({
|
||||
button: {
|
||||
marginBottom: 10,
|
||||
fontWeight: '500',
|
||||
}
|
||||
});
|
||||
|
||||
exports.title = 'ActionSheetIOS';
|
||||
exports.description = 'Interface to show iOS\' action sheets';
|
||||
exports.examples = [
|
||||
{
|
||||
title: 'Show Action Sheet',
|
||||
render(): ReactElement { return <ActionSheetExample />; }
|
||||
},
|
||||
{
|
||||
title: 'Show Share Action Sheet',
|
||||
render(): ReactElement { return <ShareActionSheetExample />; }
|
||||
}
|
||||
];
|
||||
@@ -0,0 +1,162 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* @flow
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var React = require('react-native');
|
||||
var {
|
||||
ActivityIndicatorIOS,
|
||||
StyleSheet,
|
||||
View,
|
||||
} = React;
|
||||
var TimerMixin = require('react-timer-mixin');
|
||||
|
||||
var ToggleAnimatingActivityIndicator = React.createClass({
|
||||
mixins: [TimerMixin],
|
||||
|
||||
getInitialState: function() {
|
||||
return {
|
||||
animating: true,
|
||||
};
|
||||
},
|
||||
|
||||
setToggleTimeout: function() {
|
||||
this.setTimeout(
|
||||
() => {
|
||||
this.setState({animating: !this.state.animating});
|
||||
this.setToggleTimeout();
|
||||
},
|
||||
1200
|
||||
);
|
||||
},
|
||||
|
||||
componentDidMount: function() {
|
||||
this.setToggleTimeout();
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return (
|
||||
<ActivityIndicatorIOS
|
||||
animating={this.state.animating}
|
||||
style={[styles.centering, {height: 80}]}
|
||||
size="large"
|
||||
/>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
exports.displayName = (undefined: ?string);
|
||||
exports.framework = 'React';
|
||||
exports.title = '<ActivityIndicatorIOS>';
|
||||
exports.description = 'Animated loading indicators.';
|
||||
|
||||
exports.examples = [
|
||||
{
|
||||
title: 'Default (small, white)',
|
||||
render: function() {
|
||||
return (
|
||||
<ActivityIndicatorIOS
|
||||
style={[styles.centering, styles.gray, {height: 40}]}
|
||||
color="white"
|
||||
/>
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Gray',
|
||||
render: function() {
|
||||
return (
|
||||
<View>
|
||||
<ActivityIndicatorIOS
|
||||
style={[styles.centering, {height: 40}]}
|
||||
/>
|
||||
<ActivityIndicatorIOS
|
||||
style={[styles.centering, {backgroundColor: '#eeeeee', height: 40}]}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Custom colors',
|
||||
render: function() {
|
||||
return (
|
||||
<View style={styles.horizontal}>
|
||||
<ActivityIndicatorIOS color="#0000ff" />
|
||||
<ActivityIndicatorIOS color="#aa00aa" />
|
||||
<ActivityIndicatorIOS color="#aa3300" />
|
||||
<ActivityIndicatorIOS color="#00aa00" />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Large',
|
||||
render: function() {
|
||||
return (
|
||||
<ActivityIndicatorIOS
|
||||
style={[styles.centering, styles.gray, {height: 80}]}
|
||||
color="white"
|
||||
size="large"
|
||||
/>
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Large, custom colors',
|
||||
render: function() {
|
||||
return (
|
||||
<View style={styles.horizontal}>
|
||||
<ActivityIndicatorIOS
|
||||
size="large"
|
||||
color="#0000ff"
|
||||
/>
|
||||
<ActivityIndicatorIOS
|
||||
size="large"
|
||||
color="#aa00aa"
|
||||
/>
|
||||
<ActivityIndicatorIOS
|
||||
size="large"
|
||||
color="#aa3300"
|
||||
/>
|
||||
<ActivityIndicatorIOS
|
||||
size="large"
|
||||
color="#00aa00"
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Start/stop',
|
||||
render: function(): ReactElement {
|
||||
return <ToggleAnimatingActivityIndicator />;
|
||||
}
|
||||
},
|
||||
];
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
centering: {
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
gray: {
|
||||
backgroundColor: '#cccccc',
|
||||
},
|
||||
horizontal: {
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-around',
|
||||
},
|
||||
});
|
||||