Compare commits

..
Author SHA1 Message Date
Brent Vatne a767c7b5f3 Bump to 0.8.0 2015-07-24 15:16:45 -07:00
James Ide c6cf3d9405 0.8.0-rc.2
- Suppressed TextInput.props warning
- Reverted layout-only UIView removal
- Reverted scroll view sticky header fix related to UIView removal
2015-07-17 13:39:06 -07:00
Spencer Ahrens 8ef7a50af4 Reverted ca9d1b3bf5a6f46ec29babe8685634690ff9a2bc to unbreak groups 2015-07-17 13:34:08 -07:00
Spencer Ahrens 2858a10d08 revert [React Native] Fix scroll view sticky headers 2015-07-17 13:15:59 -07:00
Spencer Ahrens d4af948261 [ReactNative] Fix crash in ListView 2015-07-15 19:03:21 -07:00
James Ide 95608dac9b [ListView] Operate on the true scroll responder instead of the scroll component
Summary:
When composing scroll views, `this.refs[SCROLLVIEW_REF]` may refer to another higher-order scroll component instead of a ScrollView. This can cause issues if you expect to need it to be a ScrollView backed by an RCTScrollView.

The solution is to call `getScrollResponder()` - as long as all higher-order scroll components implement this method, it will make its way down to the true ScrollView, which is what ListView wants here.

Closes https://github.com/facebook/react-native/pull/1927
Github Author: James Ide <ide@jameside.com>
2015-07-15 19:03:13 -07:00
Matt Revell b59f173863 Issues/#1689 text input warning
Summary:
This should close issue 1689. Using Object.assign to pass Flow checks.
Closes https://github.com/facebook/react-native/pull/1956
Github Author: Matt Revell <mattrevell82@me.com>
2015-07-15 13:50:36 -07:00
James Ide e5358b5a9b Update version numbers in package.json and React.podspec to 0.8.0-rc 2015-07-10 13:30:39 -07:00
Evan Solomon 12cae9a724 Bump babel-core version to enforce params option name change 2015-07-10 13:29:31 -07:00
Evan Solomon 0cb1312370 Rename babel's es6.parameters.rest option to es6.parameters
The old name was deprecated and spits out a bunch of annoying log
messages now.

See https://github.com/babel/babel/commit/c0fd4c1f9e0b18231f585c4fa793e4cb0e01aed1
2015-07-10 13:29:22 -07:00
2478 changed files with 39533 additions and 191441 deletions
-10
View File
@@ -1,10 +0,0 @@
[android]
target = Google Inc.:Google APIs:23
[maven_repositories]
central = https://repo1.maven.org/maven2
[alias]
movies = //Examples/Movies/android/app:app
uiexplorer = //Examples/UIExplorer/android/app:app
-1
View File
@@ -1 +0,0 @@
-Xmx512m -XX:+HeapDumpOnOutOfMemoryError
-11
View File
@@ -1,11 +0,0 @@
# EditorConfig is awesome: http://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
+19 -35
View File
@@ -19,7 +19,6 @@
"__DEV__": true,
"__dirname": false,
"__fbBatchedBridgeConfig": false,
"alert": false,
"cancelAnimationFrame": false,
"clearImmediate": true,
"clearInterval": false,
@@ -27,11 +26,8 @@
"console": false,
"document": false,
"escape": false,
"Event": false,
"EventTarget": false,
"exports": false,
"fetch": false,
"FormData": false,
"global": false,
"jest": false,
"Map": true,
@@ -47,29 +43,7 @@
"setTimeout": false,
"window": false,
"XMLHttpRequest": false,
"pit": false,
// Flow global types.
"ReactComponent": false,
"ReactClass": false,
"ReactElement": false,
"ReactPropsCheckType": false,
"ReactPropsChainableTypeChecker": false,
"ReactPropTypes": false,
"SyntheticEvent": false,
"$Either": false,
"$All": false,
"$Tuple": false,
"$Supertype": false,
"$Subtype": false,
"$Shape": false,
"$Diff": false,
"$Keys": false,
"$Enum": false,
"$Exports": false,
"$FlowIssue": false,
"$FlowFixMe": false,
"$FixMe": false
"pit": false
},
"rules": {
@@ -81,6 +55,7 @@
"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-empty-class": 1, // disallow the use of empty character classes in regular expressions
"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)
@@ -107,12 +82,13 @@
"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, "allow-null"], // require the use of === and !==
"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
@@ -147,6 +123,13 @@
"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.
"global-strict": [2, "always"], // require or disallow the "use strict" pragma in the global scope (off by default in the node environment)
"no-extra-strict": 1, // disallow unnecessary use of "use strict"; when already in strict mode
"strict": 0, // require that all functions are run in strict mode
// Variables
// These rules have to do with variable declarations.
@@ -176,8 +159,6 @@
// These rules are purely matters of style and are quite subjective.
"key-spacing": 0,
"keyword-spacing": 1, // enforce spacing before and after keywords
"jsx-quotes": [1, "prefer-double"],
"comma-spacing": 0,
"no-multi-spaces": 0,
"brace-style": 0, // enforce one true brace style (off by default)
@@ -193,17 +174,21 @@
"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-space-before-semi": 1, // disallow space before semicolon
"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-wrap-func": 1, // disallow wrapping of non-IIFE statements in parens
"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)
@@ -221,19 +206,18 @@
"react/display-name": 0,
"react/jsx-boolean-value": 0,
"react/jsx-no-duplicate-props": 2,
"react/jsx-quotes": [1, "double", "avoid-escape"],
"react/jsx-no-undef": 1,
"react/jsx-sort-props": 0,
"react/jsx-uses-react": 1,
"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-string-refs": 1,
"react/no-unknown-property": 0,
"react/prop-types": 0,
"react/react-in-jsx-scope": 1,
"react/react-in-jsx-scope": 0,
"react/self-closing-comp": 1,
"react/wrap-multilines": 0,
"react/wrap-multilines": 0
}
}
+11 -61
View File
@@ -7,26 +7,13 @@
# Some modules have their own node_modules with overlap
.*/node_modules/node-haste/.*
# Ugh
.*/node_modules/babel.*
.*/node_modules/babylon.*
.*/node_modules/invariant.*
# Ignore react and fbjs where there are overlaps, but don't ignore
# anything that react-native relies on
.*/node_modules/fbjs/lib/Map.js
.*/node_modules/fbjs/lib/ErrorUtils.js
# Flow has a built-in definition for the 'react' module which we prefer to use
# over the currently-untyped source
.*/node_modules/react/react.js
.*/node_modules/react/lib/React.js
.*/node_modules/react/lib/ReactDOM.js
.*/__mocks__/.*
.*/__tests__/.*
.*/commoner/test/source/widget/share.js
# Ignore react-tools where there are overlaps, but don't ignore anything that
# react-native relies on
.*/node_modules/react-tools/src/vendor/core/ExecutionEnvironment.js
.*/node_modules/react-tools/src/browser/eventPlugins/ResponderEventPlugin.js
.*/node_modules/react-tools/src/browser/ui/React.js
.*/node_modules/react-tools/src/core/ReactInstanceHandles.js
.*/node_modules/react-tools/src/event/EventPropagators.js
# Ignore commoner tests
.*/node_modules/commoner/test/.*
@@ -40,59 +27,22 @@
# Ignore Website
.*/website/.*
# Ignore generators
.*/local-cli/generator.*
# Ignore BUCK generated folders
.*\.buckd/
# Ignore RNPM
.*/local-cli/rnpm/.*
.*/node_modules/is-my-json-valid/test/.*\.json
.*/node_modules/iconv-lite/encodings/tables/.*\.json
.*/node_modules/y18n/test/.*\.json
.*/node_modules/spdx-license-ids/spdx-license-ids.json
.*/node_modules/spdx-exceptions/index.json
.*/node_modules/resolve/test/subdirs/node_modules/a/b/c/x.json
.*/node_modules/resolve/lib/core.json
.*/node_modules/jsonparse/samplejson/.*\.json
.*/node_modules/json5/test/.*\.json
.*/node_modules/ua-parser-js/test/.*\.json
.*/node_modules/builtin-modules/builtin-modules.json
.*/node_modules/binary-extensions/binary-extensions.json
.*/node_modules/url-regex/tlds.json
.*/node_modules/joi/.*\.json
.*/node_modules/isemail/.*\.json
.*/node_modules/tr46/.*\.json
[include]
[libs]
Libraries/react-native/react-native-interface.js
flow/
Examples/UIExplorer/ImageMocks.js
[options]
module.system=haste
esproposal.class_static_fields=enable
esproposal.class_instance_fields=enable
experimental.strict_type_args=true
munge_underscores=true
module.name_mapper='^image![a-zA-Z0-9$_-]+$' -> 'GlobalImageStub'
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\)$' -> 'RelativeImageStub'
suppress_type=$FlowIssue
suppress_type=$FlowFixMe
suppress_type=$FixMe
suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(2[0-6]\\|1[0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)
suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(2[0-6]\\|1[0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)?:? #[0-9]+
suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(1[0-3]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)
suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(1[0-3]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)? #[0-9]+
suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy
[version]
^0.26.0
0.13.1
-6
View File
@@ -1,6 +0,0 @@
# 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
+3 -26
View File
@@ -4,6 +4,7 @@
!**/*.xcworkspacedata
!**/*.xcsettings
!**/*.xcscheme
build/
*.pbxuser
!default.pbxuser
*.mode1v3
@@ -21,34 +22,10 @@ DerivedData
*.xcuserstate
project.xcworkspace
# Gradle
/build/
/Examples/**/android/app/build/
/Examples/**/android/app/gradle/
/Examples/**/android/app/gradlew
/Examples/**/android/app/gradlew.bat
/ReactAndroid/build/
# Buck
.buckd
buck-out
/ReactAndroid/src/main/jni/prebuilt/lib/armeabi-v7a/
/ReactAndroid/src/main/jni/prebuilt/lib/x86/
# Android
.idea
.gradle
local.properties
*.iml
/android/
# OS X
.DS_Store
# Node
node_modules
*.log
.nvm
# OS X
.DS_Store
# Test generated files
/ReactAndroid/src/androidTest/assets/AndroidTestBundle.js
-2
View File
@@ -1,2 +0,0 @@
# rnpm
/local-cli/rnpm
+52 -21
View File
@@ -1,39 +1,70 @@
language: objective-c
osx_image: xcode7.3
osx_image: beta-xcode6.3
cache:
directories:
- node_modules
- .nvm
before_install:
- brew update
install:
- mkdir -p /Users/travis/build/facebook/.nvm
- export NVM_DIR="/Users/travis/build/facebook/.nvm"
- brew install nvm
- brew reinstall flow xctool nvm
- mkdir -p .nvm
- cp $(brew --prefix nvm)/nvm-exec .nvm/
- export NVM_DIR=.nvm
- source $(brew --prefix nvm)/nvm.sh
# testing with npm@2 for diversity, Circle tests with npm@3
- nvm install 4.4.3
- rm -Rf "${TMPDIR}/jest_preprocess_cache"
- nvm install iojs-v2
- npm config set spin=false
- npm config set progress=false
- npm install
script:
- if [[ "$TEST_TYPE" = objc ]]; then travis_retry ./scripts/objc-test.sh; fi
- if [[ "$TEST_TYPE" = e2e-objc ]]; then node ./scripts/run-ci-e2e-tests.js --ios --js --retries 3; fi
- if [[ "$TEST_TYPE" = js ]]; then npm run flow check; fi
- if [[ "$TEST_TYPE" = js ]]; then npm test -- --maxWorkers=1; fi
- |
nvm use iojs-v2
if [ "$TEST_TYPE" = objc ]
then
./scripts/objc-test.sh
elif [ "$TEST_TYPE" = js ]
then
flow check && npm test
elif [ "$TEST_TYPE" = build_website ]
then
cd website
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=e2e-objc
- TEST_TYPE=objc
- TEST_TYPE=js
- TEST_TYPE=build_website
- TEST_TYPE=e2e
global:
- secure: "HlmG8M2DmBUSBh6KH1yVIe/8gR4iibg4WfcHq1x/xYQxGbvleq7NOo04V6eFHnl9cvZCu+PKH0841WLnGR7c4BBf47GVu/o16nXzggPumHKy++lDzxFPlJ1faMDfjg/5vjbAxRUe7D3y98hQSeGHH4tedc8LvTaFLVu7iiGqvjU="
branches:
only:
- master
- /^.*-stable$/
notifications:
email:
recipients:
- bestander@gmail.com
on_failure: change
on_success: change
+6 -46
View File
@@ -17,36 +17,11 @@ The core team will be monitoring for pull requests. When we get one, we'll run s
*Before* submitting a pull request, please make sure the following is done…
1. Fork the repo and create your branch from `master`.
2. **Describe your test plan in your commit.** If you've added code that should be tested, add tests!
2. If you've added code that should be tested, add tests!
3. If you've changed APIs, update the documentation.
4. If you've updated the docs, verify the website locally and submit screenshots if applicable
```
$ cd website
$ npm install && npm start
go to: http://localhost:8079/react-native/index.html
```
5. Add the copyright notice to the top of any new files you've added.
6. Ensure tests pass on Travis and Circle CI.
7. Make sure your code lints (`node linter.js <files touched>`).
8. Squash your commits (`git rebase -i`).
9. If you haven't already, sign the [CLA](https://code.facebook.com/cla).
#### Copyright Notice for files
Copy and paste this to the top of your new file(s):
```JS
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
```
If you've added a new module, add a `@providesModule <moduleName>` at the end of the comment. This will allow the haste package manager to find it.
4. Ensure tests pass on Travis.
5. Make sure your code lints (`node linter.js <files touched>`).
6. If you haven't already, complete the CLA.
### Contributor License Agreement (CLA)
@@ -58,7 +33,7 @@ In order to accept your pull request, we need you to submit a CLA. You only need
### Where to Find Known Issues
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 will be using GitHub Issues for our public bugs. We will 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.
### Reporting New Issues
@@ -70,8 +45,8 @@ Facebook has a [bounty program](https://www.facebook.com/whitehat/) for the safe
## How to Get in Touch
* IRC - [#reactnative on freenode](http://webchat.freenode.net/?channels=reactnative)
* [Facebook group](https://www.facebook.com/groups/react.native.community/)
* Reactiflux — [#react-native](http://join.reactiflux.com/)
## Style Guide
@@ -79,7 +54,6 @@ Facebook has a [bounty program](https://www.facebook.com/whitehat/) for the safe
#### General
* **Most important: Look around.** Match the style you see used in the rest of the project. This includes formatting, naming things in code, naming things in documentation.
* Add trailing commas,
* 2 spaces for indentation (no tabs)
* "Attractive"
@@ -92,14 +66,6 @@ Facebook has a [bounty program](https://www.facebook.com/whitehat/) for the safe
* Do not use the optional parameters of `setTimeout` and `setInterval`
* 80 character line length
#### JSX
* Prefer `'` over `"` for string literal props
* When wrapping opening tags over multiple lines, place one prop per line
* `{}` of props should hug their values (no spaces)
* Place the closing `>` of opening tags on the same line as the last prop
* Place the closing `/>` of self-closing tags on their own line and left-align them with the opening `<`
#### Objective-C
* Space after `@property` declarations
@@ -108,12 +74,6 @@ Facebook has a [bounty program](https://www.facebook.com/whitehat/) for the safe
* *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;`)
#### Java
* If a method call spans multiple lines closing bracket is on the same line as the last argument.
* If a method header doesn't fit on one line each argument goes on a separate line.
* 100 character line length
### Documentation
* Do not wrap lines at 80 characters - configure your editor to soft-wrap when editing documentation.
-5
View File
@@ -1,5 +0,0 @@
{
"rules": {
"no-alert": 0
}
}
+25 -25
View File
@@ -12,7 +12,7 @@
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 */; };
58C1E40E1ACF54E9006D1A47 /* libRCTAnimationExperimental.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 58C1E40B1ACF54B4006D1A47 /* libRCTAnimationExperimental.a */; };
832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 832341B51AAA6A8300B99B32 /* libRCTText.a */; };
/* End PBXBuildFile section */
@@ -24,12 +24,12 @@
remoteGlobalIDString = 83CBBA2E1A601D0E00E9B192;
remoteInfo = React;
};
5F82F1761B85784500FAE87E /* PBXContainerItemProxy */ = {
58C1E40A1ACF54B4006D1A47 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 5F82F1721B85784500FAE87E /* RCTWebSocket.xcodeproj */;
containerPortal = 13ACB66C1AC2113500FF4204 /* RCTAnimationExperimental.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 3C86DF461ADF2C930047B81A;
remoteInfo = RCTWebSocket;
remoteGlobalIDString = 134814201AA4EA6300B7C361;
remoteInfo = RCTAnimationExperimental;
};
832341B41AAA6A8300B99B32 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
@@ -41,6 +41,7 @@
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
13ACB66C1AC2113500FF4204 /* RCTAnimationExperimental.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTAnimationExperimental.xcodeproj; path = ../../Libraries/Animation/RCTAnimationExperimental.xcodeproj; sourceTree = "<group>"; };
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>"; };
@@ -49,7 +50,6 @@
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 */
@@ -58,8 +58,8 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
5F82F1781B85785200FAE87E /* libRCTWebSocket.a in Frameworks */,
1461632D1AC3E23900C2F5AD /* libReact.a in Frameworks */,
58C1E40E1ACF54E9006D1A47 /* libRCTAnimationExperimental.a in Frameworks */,
832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -88,10 +88,10 @@
name = Products;
sourceTree = "<group>";
};
5F82F1731B85784500FAE87E /* Products */ = {
58C1E4071ACF54B4006D1A47 /* Products */ = {
isa = PBXGroup;
children = (
5F82F1771B85784500FAE87E /* libRCTWebSocket.a */,
58C1E40B1ACF54B4006D1A47 /* libRCTAnimationExperimental.a */,
);
name = Products;
sourceTree = "<group>";
@@ -99,9 +99,9 @@
832341AE1AAA6A7D00B99B32 /* Libraries */ = {
isa = PBXGroup;
children = (
5F82F1721B85784500FAE87E /* RCTWebSocket.xcodeproj */,
146163271AC3E22900C2F5AD /* React.xcodeproj */,
832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */,
13ACB66C1AC2113500FF4204 /* RCTAnimationExperimental.xcodeproj */,
);
name = Libraries;
sourceTree = "<group>";
@@ -175,12 +175,12 @@
projectDirPath = "";
projectReferences = (
{
ProductGroup = 832341B11AAA6A8300B99B32 /* Products */;
ProjectRef = 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */;
ProductGroup = 58C1E4071ACF54B4006D1A47 /* Products */;
ProjectRef = 13ACB66C1AC2113500FF4204 /* RCTAnimationExperimental.xcodeproj */;
},
{
ProductGroup = 5F82F1731B85784500FAE87E /* Products */;
ProjectRef = 5F82F1721B85784500FAE87E /* RCTWebSocket.xcodeproj */;
ProductGroup = 832341B11AAA6A8300B99B32 /* Products */;
ProjectRef = 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */;
},
{
ProductGroup = 146163281AC3E22900C2F5AD /* Products */;
@@ -202,11 +202,11 @@
remoteRef = 1461632B1AC3E22900C2F5AD /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
5F82F1771B85784500FAE87E /* libRCTWebSocket.a */ = {
58C1E40B1ACF54B4006D1A47 /* libRCTAnimationExperimental.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = libRCTWebSocket.a;
remoteRef = 5F82F1761B85784500FAE87E /* PBXContainerItemProxy */;
path = libRCTAnimationExperimental.a;
remoteRef = 58C1E40A1ACF54B4006D1A47 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
832341B51AAA6A8300B99B32 /* libRCTText.a */ = {
@@ -266,11 +266,11 @@
);
INFOPLIST_FILE = "$(SRCROOT)/2048/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LIBRARY_SEARCH_PATHS = "$(inherited)";
OTHER_LDFLAGS = (
"-ObjC",
"-lc++",
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"/Users/sahrens/src/fbobjc-hg/Libraries/FBReactKit/js/react-native-github/Libraries/Animation/build/Debug-iphoneos",
);
OTHER_LDFLAGS = "-ObjC";
PRODUCT_BUNDLE_IDENTIFIER = "com.facebook.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = 2048;
};
@@ -287,11 +287,11 @@
);
INFOPLIST_FILE = "$(SRCROOT)/2048/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LIBRARY_SEARCH_PATHS = "$(inherited)";
OTHER_LDFLAGS = (
"-ObjC",
"-lc++",
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"/Users/sahrens/src/fbobjc-hg/Libraries/FBReactKit/js/react-native-github/Libraries/Animation/build/Debug-iphoneos",
);
OTHER_LDFLAGS = "-ObjC";
PRODUCT_BUNDLE_IDENTIFIER = "com.facebook.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = 2048;
};
+3 -4
View File
@@ -36,14 +36,14 @@
* on the same Wi-Fi network.
*/
jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/Examples/2048/Game2048.bundle?platform=ios&dev=true"];
jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/Examples/2048/Game2048.includeRequire.runModule.bundle"];
/**
* 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
* $ curl 'http://localhost:8081/Examples/2048/Game2048.includeRequire.runModule.bundle' -o main.jsbundle
*
* then add the `main.jsbundle` file to your project and uncomment this line:
*/
@@ -52,11 +52,10 @@
RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
moduleName:@"Game2048"
initialProperties:nil
launchOptions:launchOptions];
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
UIViewController *rootViewController = [UIViewController new];
UIViewController *rootViewController = [[UIViewController alloc] init];
rootViewController.view = rootView;
self.window.rootViewController = rootViewController;
[self.window makeKeyAndVisible];
+45 -47
View File
@@ -16,16 +16,15 @@
*/
'use strict';
var React = require('react');
var ReactNative = require('react-native');
var React = require('react-native');
var {
AppRegistry,
StyleSheet,
Text,
View,
} = ReactNative;
} = React;
var Animated = require('Animated');
var AnimationExperimental = require('AnimationExperimental');
var GameBoard = require('GameBoard');
var TouchableBounce = require('TouchableBounce');
@@ -54,60 +53,58 @@ class Board extends React.Component {
}
class Tile extends React.Component {
state: any;
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 pos = (i) => {
return BOARD_PADDING + (i * (CELL_SIZE + CELL_MARGIN * 2) + CELL_MARGIN);
};
var animationPosition = (i) => {
return pos(i) + (CELL_SIZE / 2);
};
var offset = {
top: this.state.top,
left: this.state.left,
opacity: this.state.opacity,
top: pos(tile.toRow()),
left: pos(tile.toColumn()),
opacity: 1,
};
if (tile.isNew()) {
Animated.timing(this.state.opacity, {
duration: 100,
toValue: 1,
}).start();
offset.opacity = 0;
} 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();
var point = {
x: animationPosition(tile.toColumn()),
y: animationPosition(tile.toRow()),
};
AnimationExperimental.startAnimation({
node: this.refs['this'],
duration: 100,
easing: 'easeInOutQuad',
property: 'position',
toValue: point,
});
}
return offset;
}
componentDidMount() {
AnimationExperimental.startAnimation({
node: this.refs['this'],
duration: 100,
easing: 'easeInOutQuad',
property: 'opacity',
toValue: 1,
});
}
render() {
var tile = this.props.tile;
var tileStyles = [
styles.tile,
styles['tile' + tile.value],
this.calculateOffset(),
this.calculateOffset()
];
var textStyles = [
@@ -118,9 +115,9 @@ class Tile extends React.Component {
];
return (
<Animated.View style={tileStyles}>
<View ref="this" style={tileStyles}>
<Text style={textStyles}>{tile.value}</Text>
</Animated.View>
</View>
);
}
}
@@ -139,8 +136,10 @@ class GameEndOverlay extends React.Component {
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 onPress={this.props.onRestart}>
<View style={styles.tryAgain}>
<Text style={styles.tryAgainText}>Try Again?</Text>
</View>
</TouchableBounce>
</View>
);
@@ -150,7 +149,6 @@ class GameEndOverlay extends React.Component {
class Game2048 extends React.Component {
startX: number;
startY: number;
state: any;
constructor(props: {}) {
super(props);
@@ -241,7 +239,7 @@ var styles = StyleSheet.create({
marginBottom: 20,
},
tryAgain: {
backgroundColor: '#887761',
backgroundColor: '#887766',
padding: 20,
borderRadius: 5,
},
@@ -283,7 +281,7 @@ var styles = StyleSheet.create({
backgroundColor: '#eeeecc',
},
tile8: {
backgroundColor: '#ffbb87',
backgroundColor: '#ffbb88',
},
tile16: {
backgroundColor: '#ff9966',
+1 -1
View File
@@ -17,7 +17,7 @@
'use strict';
// NB: Taken straight from: https://github.com/IvanVergiliev/2048-react/blob/master/src/board.js
// with no modification except to format it for CommonJS and fix lint/flow errors
// with no modificiation except to format it for CommonJS and fix lint/flow errors
var rotateLeft = function (matrix) {
var rows = matrix.length;
+10 -12
View File
@@ -15,17 +15,15 @@
*/
'use strict';
var React = require('react');
var ReactNative = require('react-native');
var React = require('react-native');
var {
Image,
Platform,
PixelRatio,
StyleSheet,
Text,
TouchableHighlight,
TouchableNativeFeedback,
View
} = ReactNative;
} = React;
var getStyleFromScore = require('./getStyleFromScore');
var getImageSource = require('./getImageSource');
@@ -34,17 +32,16 @@ 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
<TouchableHighlight
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}
@@ -62,7 +59,7 @@ var MovieCell = React.createClass({
</Text>
</View>
</View>
</TouchableElement>
</TouchableHighlight>
</View>
);
}
@@ -96,7 +93,8 @@ var styles = StyleSheet.create({
},
cellBorder: {
backgroundColor: 'rgba(0, 0, 0, 0.1)',
height: StyleSheet.hairlineWidth,
// Trick to get the thinest line the device can display
height: 1 / PixelRatio.get(),
marginLeft: 4,
},
});
+7 -4
View File
@@ -15,15 +15,15 @@
*/
'use strict';
var React = require('react');
var ReactNative = require('react-native');
var React = require('react-native');
var {
Image,
PixelRatio,
ScrollView,
StyleSheet,
Text,
View,
} = ReactNative;
} = React;
var getImageSource = require('./getImageSource');
var getStyleFromScore = require('./getStyleFromScore');
@@ -34,6 +34,9 @@ var MovieScreen = React.createClass({
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}
@@ -149,7 +152,7 @@ var styles = StyleSheet.create({
},
separator: {
backgroundColor: 'rgba(0, 0, 0, 0.1)',
height: StyleSheet.hairlineWidth,
height: 1 / PixelRatio.get(),
marginVertical: 10,
},
castTitle: {
@@ -216,7 +216,7 @@
83CBB9F71A601CBA00E9B192 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0700;
LastUpgradeCheck = 0610;
ORGANIZATIONNAME = Facebook;
};
buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "Movies" */;
@@ -357,11 +357,7 @@
INFOPLIST_FILE = "$(SRCROOT)/Movies/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LIBRARY_SEARCH_PATHS = "$(inherited)";
OTHER_LDFLAGS = (
"-ObjC",
"-lc++",
);
PRODUCT_BUNDLE_IDENTIFIER = "com.facebook.$(PRODUCT_NAME:rfc1034identifier)";
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = Movies;
USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/../../Libraries/**";
};
@@ -379,11 +375,7 @@
INFOPLIST_FILE = "$(SRCROOT)/Movies/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LIBRARY_SEARCH_PATHS = "$(inherited)";
OTHER_LDFLAGS = (
"-ObjC",
"-lc++",
);
PRODUCT_BUNDLE_IDENTIFIER = "com.facebook.$(PRODUCT_NAME:rfc1034identifier)";
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = Movies;
USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/../../Libraries/**";
};
@@ -409,7 +401,6 @@
"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;
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0700"
LastUpgradeVersion = "0610"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@@ -38,8 +38,6 @@
ReferencedContainer = "container:Movies.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
@@ -49,10 +47,8 @@
buildConfiguration = "Debug"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableProductRunnable>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
@@ -70,8 +66,7 @@
useCustomWorkingDirectory = "NO"
buildConfiguration = "Release"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableProductRunnable>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
+3 -4
View File
@@ -37,14 +37,14 @@
* on the same Wi-Fi network.
*/
jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/Examples/Movies/MoviesApp.ios.bundle?platform=ios&dev=true"];
jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/Examples/Movies/MoviesApp.includeRequire.runModule.bundle"];
/**
* 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
* $ curl 'http://localhost:8081/Examples/Movies/MoviesApp.includeRequire.runModule.bundle' -o main.jsbundle
*
* then add the `main.jsbundle` file to your project and uncomment this line:
*/
@@ -53,11 +53,10 @@
RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
moduleName:@"MoviesApp"
initialProperties:nil
launchOptions:launchOptions];
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
UIViewController *rootViewController = [UIViewController new];
UIViewController *rootViewController = [[UIViewController alloc] init];
rootViewController.view = rootView;
self.window.rootViewController = rootViewController;
[self.window makeKeyAndVisible];
+7 -6
View File
@@ -7,7 +7,7 @@
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<string>com.facebook.$(PRODUCT_NAME:rfc1034identifier)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
@@ -33,11 +33,6 @@
<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>
@@ -52,5 +47,11 @@
</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>
-95
View File
@@ -1,95 +0,0 @@
/**
* 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');
var ReactNative = require('react-native');
var {
AppRegistry,
BackAndroid,
Navigator,
StyleSheet,
ToolbarAndroid,
View,
} = ReactNative;
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;
@@ -16,13 +16,12 @@
*/
'use strict';
var React = require('react');
var ReactNative = require('react-native');
var React = require('react-native');
var {
AppRegistry,
NavigatorIOS,
StyleSheet,
} = ReactNative;
} = React;
var SearchScreen = require('./SearchScreen');
-57
View File
@@ -1,57 +0,0 @@
# 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:
git clone https://github.com/facebook/react-native.git
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.
### Running with Buck
Follow the same setup as running with gradle.
Install Buck from [here](https://buckbuild.com/setup/install.html).
Run the following commands from the react-native folder:
./gradlew :ReactAndroid:packageReactNdkLibsForBuck
buck fetch movies
buck install -r movies
./packager/packager.sh
_Note: The native libs are still built using gradle. Full build with buck is coming soon(tm)._
## 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).
-105
View File
@@ -1,105 +0,0 @@
/**
* 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');
var ReactNative = require('react-native');
var {
Image,
Platform,
ProgressBarAndroid,
TextInput,
StyleSheet,
TouchableNativeFeedback,
View,
} = ReactNative;
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;
-67
View File
@@ -1,67 +0,0 @@
/**
* 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');
var ReactNative = require('react-native');
var {
ActivityIndicatorIOS,
TextInput,
StyleSheet,
View,
} = ReactNative;
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;
+49 -36
View File
@@ -15,25 +15,21 @@
*/
'use strict';
var React = require('react');
var ReactNative = require('react-native');
var React = require('react-native');
var {
ActivityIndicatorIOS,
ListView,
Platform,
ProgressBarAndroid,
StyleSheet,
Text,
TextInput,
View,
} = ReactNative;
} = React;
var TimerMixin = require('react-timer-mixin');
var invariant = require('fbjs/lib/invariant');
var dismissKeyboard = require('dismissKeyboard');
var invariant = require('invariant');
var MovieCell = require('./MovieCell');
var MovieScreen = require('./MovieScreen');
var SearchBar = require('SearchBar');
/**
* This is for demo purposes only, and rate limited.
@@ -223,20 +219,11 @@ var SearchScreen = React.createClass({
},
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,
});
}
this.props.navigator.push({
title: movie.title,
component: MovieScreen,
passProps: {movie},
});
},
onSearchChange: function(event: Object) {
@@ -250,15 +237,7 @@ var SearchScreen = React.createClass({
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>
);
}
return <ActivityIndicatorIOS style={styles.scrollSpinner} />;
},
renderSeparator: function(
@@ -271,7 +250,7 @@ var SearchScreen = React.createClass({
style = [style, styles.rowSeparatorHide];
}
return (
<View key={'SEP_' + sectionID + '_' + rowID} style={style}/>
<View key={"SEP_" + sectionID + "_" + rowID} style={style}/>
);
},
@@ -283,7 +262,6 @@ var SearchScreen = React.createClass({
) {
return (
<MovieCell
key={movie.id}
onSelect={() => this.selectMovie(movie)}
onHighlight={() => highlightRowFunc(sectionID, rowID)}
onUnhighlight={() => highlightRowFunc(null, null)}
@@ -316,8 +294,7 @@ var SearchScreen = React.createClass({
<SearchBar
onSearchChange={this.onSearchChange}
isLoading={this.state.isLoading}
onFocus={() =>
this.refs.listview && this.refs.listview.getScrollResponder().scrollTo({ x: 0, y: 0 })}
onFocus={() => this.refs.listview.getScrollResponder().scrollTo(0, 0)}
/>
<View style={styles.separator} />
{content}
@@ -330,7 +307,7 @@ var NoMovies = React.createClass({
render: function() {
var text = '';
if (this.props.filter) {
text = `No results for "${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
@@ -345,6 +322,27 @@ var NoMovies = React.createClass({
}
});
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({
container: {
flex: 1,
@@ -357,10 +355,25 @@ var styles = StyleSheet.create({
marginTop: 80,
color: '#888888',
},
searchBar: {
marginTop: 64,
padding: 3,
paddingLeft: 8,
flexDirection: 'row',
alignItems: 'center',
},
searchBarInput: {
fontSize: 15,
flex: 1,
height: 30,
},
separator: {
height: 1,
backgroundColor: '#eeeeee',
},
spinner: {
width: 30,
},
scrollSpinner: {
marginVertical: 20,
},
@@ -3,7 +3,7 @@
*/
'use strict';
jest.unmock('../getImageSource');
jest.dontMock('../getImageSource');
var getImageSource = require('../getImageSource');
-31
View File
@@ -1,31 +0,0 @@
include_defs('//ReactAndroid/DEFS')
android_binary(
name = 'app',
manifest = 'src/main/AndroidManifest.xml',
keystore = '//keystores:debug',
deps = [
':movies-lib',
],
)
android_library(
name = 'movies-lib',
srcs = glob(['src/main/java/**/*.java']),
deps = [
':res',
react_native_dep('third-party/java/jsr-305:jsr-305'),
react_native_target('java/com/facebook/react/modules/core:core'),
react_native_target('java/com/facebook/react/shell:shell'),
react_native_target('java/com/facebook/react:react'),
react_native_target('jni/prebuilt:android-jsc'),
# .so files are prebuilt by Gradle with `./gradlew :ReactAndroid:packageReactNdkLibsForBuck`
react_native_target('jni/prebuilt:reactnative-libs'),
],
)
android_resource(
name = 'res',
res = 'src/main/res',
package = 'com.facebook.react.movies',
)
-31
View File
@@ -1,31 +0,0 @@
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')
}
@@ -1 +0,0 @@
android.useDeprecatedNdk=true
-17
View File
@@ -1,17 +0,0 @@
# 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 *;
#}
@@ -1,29 +0,0 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.facebook.react.movies"
android:versionCode="1"
android:versionName="1.0">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<uses-sdk
android:minSdkVersion="16"
android:targetSdkVersion="22" />
<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>
@@ -1,52 +0,0 @@
/**
* 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 com.facebook.react.ReactActivity;
import com.facebook.react.ReactPackage;
import com.facebook.react.shell.MainReactPackage;
import java.util.Arrays;
import java.util.List;
import javax.annotation.Nullable;
public class MoviesActivity extends ReactActivity {
@Override
protected String getMainComponentName() {
return "MoviesApp";
}
@Override
protected @Nullable String getBundleAssetName() {
return "MoviesApp.android.bundle";
};
@Override
protected String getJSMainModuleName() {
return "Examples/Movies/MoviesApp.android";
}
@Override
protected boolean getUseDeveloperSupport() {
return true;
}
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage()
);
}
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 237 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 575 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 190 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 337 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 266 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 581 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 337 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 930 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 57 KiB

@@ -1,12 +0,0 @@
<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>
@@ -1,3 +0,0 @@
<resources>
<string name="app_name">MoviesApp</string>
</resources>
@@ -1,8 +0,0 @@
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
</style>
</resources>
+3 -5
View File
@@ -15,16 +15,14 @@
*/
'use strict';
var ReactNative = require('react-native');
var React = require('react-native');
var {
StyleSheet,
} = ReactNative;
} = React;
var MAX_VALUE = 200;
import type { StyleObj } from 'StyleSheetTypes';
function getStyleFromScore(score: number): StyleObj {
function getStyleFromScore(score: number): {color: string} {
if (score < 0) {
return styles.noScore;
}
+27
View File
@@ -0,0 +1,27 @@
# OSX
#
.DS_Store
# Xcode
#
build/
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata
*.xccheckout
*.moved-aside
DerivedData
*.hmap
*.ipa
*.xcuserstate
# node.js
#
node_modules/
npm-debug.log
@@ -7,12 +7,13 @@
objects = {
/* Begin PBXBuildFile section */
008F07F31AC5B25A0029DE68 /* main.jsbundle in Resources */ = {isa = PBXBuildFile; fileRef = 008F07F21AC5B25A0029DE68 /* main.jsbundle */; };
00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */; };
00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */; };
00C302E81ABCBA2D00DB3ED1 /* libRCTImage.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302C01ABCB91800DB3ED1 /* libRCTImage.a */; };
00C302E91ABCBA2D00DB3ED1 /* libRCTNetwork.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302DC1ABCB9D200DB3ED1 /* libRCTNetwork.a */; };
00C302EA1ABCBA2D00DB3ED1 /* libRCTVibration.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302E41ABCB9EE00DB3ED1 /* libRCTVibration.a */; };
00E356F31AD99517003FC87E /* BasicTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* BasicTests.m */; };
00E356F31AD99517003FC87E /* SampleAppTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* SampleAppTests.m */; };
133E29F31AD74F7200F7D852 /* libRCTLinking.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 78C398B91ACF4ADC00677621 /* libRCTLinking.a */; };
139105C61AF99C1200B5F7CC /* libRCTSettings.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 139105C11AF99BAD00B5F7CC /* libRCTSettings.a */; };
139FDEF61B0652A700C62182 /* libRCTWebSocket.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 139FDEF41B06529B00C62182 /* libRCTWebSocket.a */; };
@@ -65,7 +66,7 @@
containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 13B07F861A680F5B00A75B9A;
remoteInfo = Basic;
remoteInfo = SampleApp;
};
139105C01AF99BAD00B5F7CC /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
@@ -105,27 +106,27 @@
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
008F07F21AC5B25A0029DE68 /* main.jsbundle */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = main.jsbundle; sourceTree = "<group>"; };
00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTActionSheet.xcodeproj; path = "../node_modules/react-native/Libraries/ActionSheetIOS/RCTActionSheet.xcodeproj"; sourceTree = "<group>"; };
00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTGeolocation.xcodeproj; path = "../node_modules/react-native/Libraries/Geolocation/RCTGeolocation.xcodeproj"; sourceTree = "<group>"; };
00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTImage.xcodeproj; path = "../node_modules/react-native/Libraries/Image/RCTImage.xcodeproj"; sourceTree = "<group>"; };
00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTNetwork.xcodeproj; path = "../node_modules/react-native/Libraries/Network/RCTNetwork.xcodeproj"; sourceTree = "<group>"; };
00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTVibration.xcodeproj; path = "../node_modules/react-native/Libraries/Vibration/RCTVibration.xcodeproj"; sourceTree = "<group>"; };
00E356EE1AD99517003FC87E /* BasicTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = BasicTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
008F07F21AC5B25A0029DE68 /* main.jsbundle */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = main.jsbundle; path = iOS/main.jsbundle; sourceTree = "<group>"; };
00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTActionSheet.xcodeproj; path = ../../Libraries/ActionSheetIOS/RCTActionSheet.xcodeproj; sourceTree = "<group>"; };
00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTGeolocation.xcodeproj; path = ../../Libraries/Geolocation/RCTGeolocation.xcodeproj; sourceTree = "<group>"; };
00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTImage.xcodeproj; path = ../../Libraries/Image/RCTImage.xcodeproj; sourceTree = "<group>"; };
00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTNetwork.xcodeproj; path = ../../Libraries/Network/RCTNetwork.xcodeproj; sourceTree = "<group>"; };
00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTVibration.xcodeproj; path = ../../Libraries/Vibration/RCTVibration.xcodeproj; sourceTree = "<group>"; };
00E356EE1AD99517003FC87E /* SampleAppTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SampleAppTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
00E356F11AD99517003FC87E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
00E356F21AD99517003FC87E /* BasicTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BasicTests.m; sourceTree = "<group>"; };
139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTSettings.xcodeproj; path = "../node_modules/react-native/Libraries/Settings/RCTSettings.xcodeproj"; sourceTree = "<group>"; };
139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTWebSocket.xcodeproj; path = "../node_modules/react-native/Libraries/WebSocket/RCTWebSocket.xcodeproj"; sourceTree = "<group>"; };
13B07F961A680F5B00A75B9A /* Basic.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Basic.app; sourceTree = BUILT_PRODUCTS_DIR; };
13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = Basic/AppDelegate.h; sourceTree = "<group>"; };
13B07FB01A68108700A75B9A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = Basic/AppDelegate.m; sourceTree = "<group>"; };
00E356F21AD99517003FC87E /* SampleAppTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SampleAppTests.m; sourceTree = "<group>"; };
139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTSettings.xcodeproj; path = ../../Libraries/Settings/RCTSettings.xcodeproj; sourceTree = "<group>"; };
139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTWebSocket.xcodeproj; path = ../../Libraries/WebSocket/RCTWebSocket.xcodeproj; sourceTree = "<group>"; };
13B07F961A680F5B00A75B9A /* SampleApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SampleApp.app; sourceTree = BUILT_PRODUCTS_DIR; };
13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = iOS/AppDelegate.h; sourceTree = "<group>"; };
13B07FB01A68108700A75B9A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = iOS/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 = Basic/Images.xcassets; sourceTree = "<group>"; };
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = Basic/Info.plist; sourceTree = "<group>"; };
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = Basic/main.m; sourceTree = "<group>"; };
146833FF1AC3E56700842450 /* React.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = React.xcodeproj; path = "../node_modules/react-native/React/React.xcodeproj"; sourceTree = "<group>"; };
78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTLinking.xcodeproj; path = "../node_modules/react-native/Libraries/LinkingIOS/RCTLinking.xcodeproj"; sourceTree = "<group>"; };
832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = "../node_modules/react-native/Libraries/Text/RCTText.xcodeproj"; sourceTree = "<group>"; };
13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = iOS/Images.xcassets; sourceTree = "<group>"; };
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = iOS/Info.plist; sourceTree = "<group>"; };
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = iOS/main.m; sourceTree = "<group>"; };
146833FF1AC3E56700842450 /* React.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = React.xcodeproj; path = ../../React/React.xcodeproj; sourceTree = "<group>"; };
78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTLinking.xcodeproj; path = ../../Libraries/LinkingIOS/RCTLinking.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 */
@@ -196,13 +197,13 @@
name = Products;
sourceTree = "<group>";
};
00E356EF1AD99517003FC87E /* BasicTests */ = {
00E356EF1AD99517003FC87E /* SampleAppTests */ = {
isa = PBXGroup;
children = (
00E356F21AD99517003FC87E /* BasicTests.m */,
00E356F21AD99517003FC87E /* SampleAppTests.m */,
00E356F01AD99517003FC87E /* Supporting Files */,
);
path = BasicTests;
path = SampleAppTests;
sourceTree = "<group>";
};
00E356F01AD99517003FC87E /* Supporting Files */ = {
@@ -229,7 +230,7 @@
name = Products;
sourceTree = "<group>";
};
13B07FAE1A68108700A75B9A /* Basic */ = {
13B07FAE1A68108700A75B9A /* SampleApp */ = {
isa = PBXGroup;
children = (
008F07F21AC5B25A0029DE68 /* main.jsbundle */,
@@ -240,7 +241,7 @@
13B07FB11A68108700A75B9A /* LaunchScreen.xib */,
13B07FB71A68108700A75B9A /* main.m */,
);
name = Basic;
name = SampleApp;
sourceTree = "<group>";
};
146834001AC3E56700842450 /* Products */ = {
@@ -287,10 +288,9 @@
83CBB9F61A601CBA00E9B192 = {
isa = PBXGroup;
children = (
AD9196DA1CABA83E000E8D91 /* NestedGroup */,
13B07FAE1A68108700A75B9A /* Basic */,
13B07FAE1A68108700A75B9A /* SampleApp */,
832341AE1AAA6A7D00B99B32 /* Libraries */,
00E356EF1AD99517003FC87E /* BasicTests */,
00E356EF1AD99517003FC87E /* SampleAppTests */,
83CBBA001A601CBA00E9B192 /* Products */,
);
indentWidth = 2;
@@ -300,33 +300,18 @@
83CBBA001A601CBA00E9B192 /* Products */ = {
isa = PBXGroup;
children = (
13B07F961A680F5B00A75B9A /* Basic.app */,
00E356EE1AD99517003FC87E /* BasicTests.xctest */,
13B07F961A680F5B00A75B9A /* SampleApp.app */,
00E356EE1AD99517003FC87E /* SampleAppTests.xctest */,
);
name = Products;
sourceTree = "<group>";
};
AD9196DA1CABA83E000E8D91 /* NestedGroup */ = {
isa = PBXGroup;
children = (
AD9196DB1CABA844000E8D91 /* Libraries */,
);
name = NestedGroup;
sourceTree = "<group>";
};
AD9196DB1CABA844000E8D91 /* Libraries */ = {
isa = PBXGroup;
children = (
);
name = Libraries;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
00E356ED1AD99517003FC87E /* BasicTests */ = {
00E356ED1AD99517003FC87E /* SampleAppTests */ = {
isa = PBXNativeTarget;
buildConfigurationList = 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "BasicTests" */;
buildConfigurationList = 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "SampleAppTests" */;
buildPhases = (
00E356EA1AD99517003FC87E /* Sources */,
00E356EB1AD99517003FC87E /* Frameworks */,
@@ -337,27 +322,26 @@
dependencies = (
00E356F51AD99517003FC87E /* PBXTargetDependency */,
);
name = BasicTests;
productName = BasicTests;
productReference = 00E356EE1AD99517003FC87E /* BasicTests.xctest */;
name = SampleAppTests;
productName = SampleAppTests;
productReference = 00E356EE1AD99517003FC87E /* SampleAppTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
13B07F861A680F5B00A75B9A /* Basic */ = {
13B07F861A680F5B00A75B9A /* SampleApp */ = {
isa = PBXNativeTarget;
buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "Basic" */;
buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "SampleApp" */;
buildPhases = (
13B07F871A680F5B00A75B9A /* Sources */,
13B07F8C1A680F5B00A75B9A /* Frameworks */,
13B07F8E1A680F5B00A75B9A /* Resources */,
00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */,
);
buildRules = (
);
dependencies = (
);
name = Basic;
name = SampleApp;
productName = "Hello World";
productReference = 13B07F961A680F5B00A75B9A /* Basic.app */;
productReference = 13B07F961A680F5B00A75B9A /* SampleApp.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
@@ -375,7 +359,7 @@
};
};
};
buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "a" */;
buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "SampleApp" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
@@ -430,8 +414,8 @@
);
projectRoot = "";
targets = (
13B07F861A680F5B00A75B9A /* Basic */,
00E356ED1AD99517003FC87E /* BasicTests */,
13B07F861A680F5B00A75B9A /* SampleApp */,
00E356ED1AD99517003FC87E /* SampleAppTests */,
);
};
/* End PBXProject section */
@@ -521,6 +505,7 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
008F07F31AC5B25A0029DE68 /* main.jsbundle in Resources */,
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */,
13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */,
);
@@ -528,29 +513,12 @@
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Bundle React Native code and images";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "../node_modules/react-native/packager/react-native-xcode.sh";
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
00E356EA1AD99517003FC87E /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
00E356F31AD99517003FC87E /* BasicTests.m in Sources */,
00E356F31AD99517003FC87E /* SampleAppTests.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -568,7 +536,7 @@
/* Begin PBXTargetDependency section */
00E356F51AD99517003FC87E /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 13B07F861A680F5B00A75B9A /* Basic */;
target = 13B07F861A680F5B00A75B9A /* SampleApp */;
targetProxy = 00E356F41AD99517003FC87E /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
@@ -580,7 +548,7 @@
13B07FB21A68108700A75B9A /* Base */,
);
name = LaunchScreen.xib;
path = Basic;
path = iOS;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
@@ -598,11 +566,11 @@
"DEBUG=1",
"$(inherited)",
);
INFOPLIST_FILE = BasicTests/Info.plist;
INFOPLIST_FILE = SampleAppTests/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 8.2;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_NAME = "$(TARGET_NAME)";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Basic.app/Basic";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SampleApp.app/SampleApp";
};
name = Debug;
};
@@ -615,11 +583,11 @@
"$(SDKROOT)/Developer/Library/Frameworks",
"$(inherited)",
);
INFOPLIST_FILE = BasicTests/Info.plist;
INFOPLIST_FILE = SampleAppTests/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 8.2;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_NAME = "$(TARGET_NAME)";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Basic.app/Basic";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SampleApp.app/SampleApp";
};
name = Release;
};
@@ -627,16 +595,15 @@
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
DEAD_CODE_STRIPPING = NO;
HEADER_SEARCH_PATHS = (
"$(inherited)",
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
"$(SRCROOT)/../node_modules/react-native/React/**",
"$(SRCROOT)/../../React/**",
);
INFOPLIST_FILE = "Basic/Info.plist";
INFOPLIST_FILE = "iOS/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = Basic;
PRODUCT_NAME = SampleApp;
};
name = Debug;
};
@@ -647,12 +614,12 @@
HEADER_SEARCH_PATHS = (
"$(inherited)",
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
"$(SRCROOT)/../node_modules/react-native/React/**",
"$(SRCROOT)/../../React/**",
);
INFOPLIST_FILE = "Basic/Info.plist";
INFOPLIST_FILE = "iOS/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = Basic;
PRODUCT_NAME = SampleApp;
};
name = Release;
};
@@ -693,7 +660,7 @@
HEADER_SEARCH_PATHS = (
"$(inherited)",
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
"$(SRCROOT)/../node_modules/react-native/React/**",
"$(SRCROOT)/../../React/**",
);
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
MTL_ENABLE_DEBUG_INFO = YES;
@@ -733,7 +700,7 @@
HEADER_SEARCH_PATHS = (
"$(inherited)",
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
"$(SRCROOT)/../node_modules/react-native/React/**",
"$(SRCROOT)/../../React/**",
);
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
MTL_ENABLE_DEBUG_INFO = NO;
@@ -745,7 +712,7 @@
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "BasicTests" */ = {
00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "SampleAppTests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
00E356F61AD99517003FC87E /* Debug */,
@@ -754,7 +721,7 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "Basic" */ = {
13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "SampleApp" */ = {
isa = XCConfigurationList;
buildConfigurations = (
13B07F941A680F5B00A75B9A /* Debug */,
@@ -763,7 +730,7 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "a" */ = {
83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "SampleApp" */ = {
isa = XCConfigurationList;
buildConfigurations = (
83CBBA201A601CBA00E9B192 /* Debug */,
@@ -15,9 +15,9 @@
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
BuildableName = "<%= name %>.app"
BlueprintName = "<%= name %>"
ReferencedContainer = "container:<%= name %>.xcodeproj">
BuildableName = "SampleApp.app"
BlueprintName = "SampleApp"
ReferencedContainer = "container:SampleApp.xcodeproj">
</BuildableReference>
</BuildActionEntry>
<BuildActionEntry
@@ -29,9 +29,9 @@
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "00E356ED1AD99517003FC87E"
BuildableName = "<%= name %>Tests.xctest"
BlueprintName = "<%= name %>Tests"
ReferencedContainer = "container:<%= name %>.xcodeproj">
BuildableName = "SampleAppTests.xctest"
BlueprintName = "SampleAppTests"
ReferencedContainer = "container:SampleApp.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
@@ -47,9 +47,9 @@
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "00E356ED1AD99517003FC87E"
BuildableName = "<%= name %>Tests.xctest"
BlueprintName = "<%= name %>Tests"
ReferencedContainer = "container:<%= name %>.xcodeproj">
BuildableName = "SampleAppTests.xctest"
BlueprintName = "SampleAppTests"
ReferencedContainer = "container:SampleApp.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
@@ -57,9 +57,9 @@
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
BuildableName = "<%= name %>.app"
BlueprintName = "<%= name %>"
ReferencedContainer = "container:<%= name %>.xcodeproj">
BuildableName = "SampleApp.app"
BlueprintName = "SampleApp"
ReferencedContainer = "container:SampleApp.xcodeproj">
</BuildableReference>
</MacroExpansion>
</TestAction>
@@ -77,9 +77,9 @@
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
BuildableName = "<%= name %>.app"
BlueprintName = "<%= name %>"
ReferencedContainer = "container:<%= name %>.xcodeproj">
BuildableName = "SampleApp.app"
BlueprintName = "SampleApp"
ReferencedContainer = "container:SampleApp.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
@@ -96,9 +96,9 @@
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
BuildableName = "<%= name %>.app"
BlueprintName = "<%= name %>"
ReferencedContainer = "container:<%= name %>.xcodeproj">
BuildableName = "SampleApp.app"
BlueprintName = "SampleApp"
ReferencedContainer = "container:SampleApp.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
@@ -10,17 +10,19 @@
#import <UIKit/UIKit.h>
#import <XCTest/XCTest.h>
#import "RCTLog.h"
#import "RCTAssert.h"
#import "RCTRedBox.h"
#import "RCTRootView.h"
#define TIMEOUT_SECONDS 600
#define TIMEOUT_SECONDS 240
#define TEXT_TO_LOOK_FOR @"Welcome to React Native!"
@interface <%= name %>Tests : XCTestCase
@interface SampleAppTests : XCTestCase
@end
@implementation <%= name %>Tests
@implementation SampleAppTests
- (BOOL)findSubviewInView:(UIView *)view matching:(BOOL(^)(UIView *view))test
{
@@ -35,23 +37,18 @@
return NO;
}
- (void)testRendersWelcomeScreen
{
- (void)testRendersWelcomeScreen {
UIViewController *vc = [[[[UIApplication sharedApplication] delegate] window] rootViewController];
NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS];
BOOL foundElement = NO;
__block NSString *redboxError = nil;
RCTSetLogFunction(^(RCTLogLevel level, RCTLogSource source, NSString *fileName, NSNumber *lineNumber, NSString *message) {
if (level >= RCTLogLevelError) {
redboxError = message;
}
});
NSString *redboxError = nil;
while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) {
[[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
[[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
redboxError = [[RCTRedBox sharedInstance] currentErrorMessage];
foundElement = [self findSubviewInView:vc.view matching:^BOOL(UIView *view) {
if ([view.accessibilityLabel isEqualToString:TEXT_TO_LOOK_FOR]) {
return YES;
@@ -60,8 +57,6 @@
}];
}
RCTSetLogFunction(RCTDefaultLogFunction);
XCTAssertNil(redboxError, @"RedBox error: %@", redboxError);
XCTAssertTrue(foundElement, @"Couldn't find element with text '%@' in %d seconds", TEXT_TO_LOOK_FOR, TIMEOUT_SECONDS);
}
+44
View File
@@ -0,0 +1,44 @@
[ignore]
# We fork some components by platform.
.*/*.web.js
.*/*.android.js
# Some modules have their own node_modules with overlap
.*/node_modules/node-haste/.*
# Ignore react-tools where there are overlaps, but don't ignore anything that
# react-native relies on
.*/node_modules/react-tools/src/vendor/core/ExecutionEnvironment.js
.*/node_modules/react-tools/src/browser/eventPlugins/ResponderEventPlugin.js
.*/node_modules/react-tools/src/browser/ui/React.js
.*/node_modules/react-tools/src/core/ReactInstanceHandles.js
.*/node_modules/react-tools/src/event/EventPropagators.js
# Ignore commoner tests
.*/node_modules/commoner/test/.*
# See https://github.com/facebook/flow/issues/442
.*/react-tools/node_modules/commoner/lib/reader.js
# Ignore jest
.*/react-native/node_modules/jest-cli/.*
[include]
[libs]
node_modules/react-native/Libraries/react-native/react-native-interface.js
[options]
module.system=haste
suppress_type=$FlowIssue
suppress_type=$FlowFixMe
suppress_type=$FixMe
suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(1[0-3]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)
suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(1[0-3]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)? #[0-9]+
suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy
[version]
0.13.1
@@ -22,20 +22,7 @@ DerivedData
*.xcuserstate
project.xcworkspace
# Android/IJ
#
*.iml
.idea
.gradle
local.properties
# node.js
#
node_modules/
npm-debug.log
# BUCK
buck-out/
\.buckd/
android/app/libs
android/keystores/debug.keystore
@@ -31,26 +31,26 @@
* on the same Wi-Fi network.
*/
jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/index.ios.bundle?platform=ios&dev=true"];
jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/Examples/SampleApp/index.ios.bundle"];
/**
* OPTION 2
* Load from pre-bundled file on disk. The static bundle is automatically
* generated by the "Bundle React Native code and images" build step when
* running the project on an actual device or running the project on the
* simulator in the "Release" build configuration.
* Load from pre-bundled file on disk. To re-generate the static bundle
* from the root of your project directory, run
*
* $ react-native bundle --minify
*
* see http://facebook.github.io/react-native/docs/runningondevice.html
*/
// jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
moduleName:@"<%= name %>"
initialProperties:nil
moduleName:@"SampleApp"
launchOptions:launchOptions];
rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1];
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
UIViewController *rootViewController = [UIViewController new];
UIViewController *rootViewController = [[UIViewController alloc] init];
rootViewController.view = rootView;
self.window.rootViewController = rootViewController;
[self.window makeKeyAndVisible];
@@ -18,7 +18,7 @@
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="<%= name %>" textAlignment="center" lineBreakMode="middleTruncation" baselineAdjustment="alignBaselines" minimumFontSize="18" translatesAutoresizingMaskIntoConstraints="NO" id="kId-c2-rCX">
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="SampleApp" 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"/>
@@ -38,17 +38,11 @@
<false/>
<key>NSLocationWhenInUseUsageDescription</key>
<string></string>
<key>NSAppTransportSecurity</key>
<!--See http://ste.vn/2015/06/10/configuring-app-transport-security-ios-9-osx-10-11/ -->
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>localhost</key>
<dict>
<key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
<true/>
</dict>
</dict>
</dict>
<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>
+8
View File
@@ -0,0 +1,8 @@
// Offline JS
// To re-generate the offline bundle, run this from the root of your project:
//
// $ react-native bundle --minify
//
// See http://facebook.github.io/react-native/docs/runningondevice.html for more details.
throw new Error('Offline JS file is empty. See iOS/main.jsbundle for instructions');
@@ -1,19 +1,19 @@
/**
* Sample React Native App
* https://github.com/facebook/react-native
* @flow
*/
'use strict';
import React, { Component } from 'react';
import {
var React = require('react-native');
var {
AppRegistry,
StyleSheet,
Text,
View
} from 'react-native';
View,
} = React;
class <%= name %> extends Component {
render() {
var SampleApp = React.createClass({
render: function() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>
@@ -29,9 +29,9 @@ class <%= name %> extends Component {
</View>
);
}
}
});
const styles = StyleSheet.create({
var styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
@@ -50,4 +50,4 @@ const styles = StyleSheet.create({
},
});
AppRegistry.registerComponent('<%= name %>', () => <%= name %>);
AppRegistry.registerComponent('SampleApp', () => SampleApp);
@@ -14,7 +14,6 @@
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 */
@@ -40,13 +39,6 @@
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 */;
@@ -67,7 +59,6 @@
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 */
@@ -76,7 +67,6 @@
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 */,
@@ -119,7 +109,6 @@
58C572071AA6126D00CDF9C8 /* Libraries */ = {
isa = PBXGroup;
children = (
5FF894281B8556F8007731BE /* RCTWebSocket.xcodeproj */,
144C5F631AC3E5D800B004E7 /* React.xcodeproj */,
134180381AA917ED003F314A /* RCTImage.xcodeproj */,
8320448F1B492C1E00E297FC /* RCTSettings.xcodeproj */,
@@ -136,14 +125,6 @@
name = Products;
sourceTree = "<group>";
};
5FF894291B8556F8007731BE /* Products */ = {
isa = PBXGroup;
children = (
5FF8942D1B8556F8007731BE /* libRCTWebSocket.a */,
);
name = Products;
sourceTree = "<group>";
};
832044901B492C1E00E297FC /* Products */ = {
isa = PBXGroup;
children = (
@@ -224,10 +205,6 @@
ProductGroup = 58C572481AA6224300CDF9C8 /* Products */;
ProjectRef = 587650DA1A9EB0DB008B8F17 /* RCTText.xcodeproj */;
},
{
ProductGroup = 5FF894291B8556F8007731BE /* Products */;
ProjectRef = 5FF894281B8556F8007731BE /* RCTWebSocket.xcodeproj */;
},
{
ProductGroup = 144C5F641AC3E5D800B004E7 /* Products */;
ProjectRef = 144C5F631AC3E5D800B004E7 /* React.xcodeproj */;
@@ -262,13 +239,6 @@
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;
@@ -327,10 +297,7 @@
INFOPLIST_FILE = "$(SRCROOT)/TicTacToe/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LIBRARY_SEARCH_PATHS = "$(inherited)";
OTHER_LDFLAGS = (
"-ObjC",
"-lc++",
);
OTHER_LDFLAGS = "-ObjC";
PRODUCT_BUNDLE_IDENTIFIER = "com.facebook.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = TicTacToe;
};
@@ -348,10 +315,7 @@
INFOPLIST_FILE = "$(SRCROOT)/TicTacToe/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LIBRARY_SEARCH_PATHS = "$(inherited)";
OTHER_LDFLAGS = (
"-ObjC",
"-lc++",
);
OTHER_LDFLAGS = "-ObjC";
PRODUCT_BUNDLE_IDENTIFIER = "com.facebook.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = TicTacToe;
};
+3 -4
View File
@@ -36,14 +36,14 @@
* on the same Wi-Fi network.
*/
jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/Examples/TicTacToe/TicTacToeApp.bundle?platform=ios&dev=true"];
jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/Examples/TicTacToe/TicTacToeApp.includeRequire.runModule.bundle"];
/**
* 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
* $ curl 'http://localhost:8081/Examples/TicTacToe/TicTacToeApp.includeRequire.runModule.bundle' -o main.jsbundle
*
* then add the `main.jsbundle` file to your project and uncomment this line:
*/
@@ -52,11 +52,10 @@
RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
moduleName:@"TicTacToeApp"
initialProperties:nil
launchOptions:launchOptions];
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
UIViewController *rootViewController = [UIViewController new];
UIViewController *rootViewController = [[UIViewController alloc] init];
rootViewController.view = rootView;
self.window.rootViewController = rootViewController;
[self.window makeKeyAndVisible];
+5 -4
View File
@@ -16,15 +16,14 @@
*/
'use strict';
var React = require('react');
var ReactNative = require('react-native');
var React = require('react-native');
var {
AppRegistry,
StyleSheet,
Text,
TouchableHighlight,
View,
} = ReactNative;
} = React;
class Board {
grid: Array<Array<number>>;
@@ -90,6 +89,7 @@ class Board {
}
}
}
return this.winner() === null;
}
}
@@ -272,6 +272,7 @@ var styles = StyleSheet.create({
// CELL TEXT
cellText: {
borderRadius: 5,
fontSize: 50,
fontFamily: 'AvenirNext-Bold',
},
@@ -305,7 +306,7 @@ var styles = StyleSheet.create({
textAlign: 'center',
},
newGame: {
backgroundColor: '#887765',
backgroundColor: '#887766',
padding: 20,
borderRadius: 5,
},
@@ -1,214 +0,0 @@
/**
* 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');
var ReactNative = require('react-native');
var {
StyleSheet,
Text,
View,
ToastAndroid,
TouchableWithoutFeedback,
} = ReactNative;
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;
@@ -15,12 +15,11 @@
*/
'use strict';
var React = require('react');
var ReactNative = require('react-native');
var React = require('react-native');
var {
Text,
View,
} = ReactNative;
} = React;
var AccessibilityIOSExample = React.createClass({
render() {
@@ -45,7 +44,7 @@ var AccessibilityIOSExample = React.createClass({
Accessibility label example
</Text>
</View>
<View accessibilityTraits={['button', 'selected']}
<View accessibilityTraits={["button", "selected"]}
accessible={true}>
<Text>
Accessibility traits example
@@ -61,6 +60,6 @@ exports.description = 'Interface to show iOS\' accessibility samples';
exports.examples = [
{
title: 'Accessibility elements',
render(): ReactElement<any> { return <AccessibilityIOSExample />; }
render(): ReactElement { return <AccessibilityIOSExample />; }
},
];
+14 -114
View File
@@ -15,21 +15,19 @@
*/
'use strict';
var React = require('react');
var ReactNative = require('react-native');
var React = require('react-native');
var {
ActionSheetIOS,
StyleSheet,
Text,
UIManager,
View,
} = ReactNative;
} = React;
var BUTTONS = [
'Option 0',
'Option 1',
'Option 2',
'Delete',
'Button Index: 0',
'Button Index: 1',
'Button Index: 2',
'Destruct',
'Cancel',
];
var DESTRUCTIVE_INDEX = 3;
@@ -49,7 +47,7 @@ var ActionSheetExample = React.createClass({
Click to show the ActionSheet
</Text>
<Text>
Clicked button: {this.state.clicked}
Clicked button at index: "{this.state.clicked}"
</Text>
</View>
);
@@ -67,39 +65,6 @@ var ActionSheetExample = React.createClass({
}
});
var ActionSheetTintExample = 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,
tintColor: 'green',
},
(buttonIndex) => {
this.setState({ clicked: BUTTONS[buttonIndex] });
});
}
});
var ShareActionSheetExample = React.createClass({
getInitialState() {
return {
@@ -122,14 +87,11 @@ var ShareActionSheetExample = React.createClass({
showShareActionSheet() {
ActionSheetIOS.showShareActionSheetWithOptions({
url: this.props.url,
message: 'message to go with the shared url',
subject: 'a subject to go in the email heading',
excludedActivityTypes: [
'com.apple.UIKit.activity.PostToTwitter'
]
url: 'https://code.facebook.com',
},
(error) => {
console.error(error);
},
(error) => alert(error),
(success, method) => {
var text;
if (success) {
@@ -137,55 +99,11 @@ var ShareActionSheetExample = React.createClass({
} else {
text = 'You didn\'t share';
}
this.setState({text});
this.setState({text})
});
}
});
var ShareScreenshotExample = 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() {
// Take the snapshot (returns a temp file uri)
UIManager.takeSnapshot('window').then((uri) => {
// Share image data
ActionSheetIOS.showShareActionSheetWithOptions({
url: uri,
excludedActivityTypes: [
'com.apple.UIKit.activity.PostToTwitter'
]
},
(error) => alert(error),
(success, method) => {
var text;
if (success) {
text = `Shared via ${method}`;
} else {
text = 'You didn\'t share';
}
this.setState({text});
});
}).catch((error) => alert(error));
}
});
var style = StyleSheet.create({
button: {
marginBottom: 10,
@@ -198,28 +116,10 @@ exports.description = 'Interface to show iOS\' action sheets';
exports.examples = [
{
title: 'Show Action Sheet',
render(): ReactElement<any> { return <ActionSheetExample />; }
},
{
title: 'Show Action Sheet with tinted buttons',
render(): ReactElement<any> { return <ActionSheetTintExample />; }
render(): ReactElement { return <ActionSheetExample />; }
},
{
title: 'Show Share Action Sheet',
render(): ReactElement<any> {
return <ShareActionSheetExample url="https://code.facebook.com" />;
}
},
{
title: 'Share Local Image',
render(): ReactElement<any> {
return <ShareActionSheetExample url="bunny.png" />;
}
},
{
title: 'Share Screenshot',
render(): ReactElement<any> {
return <ShareScreenshotExample />;
}
render(): ReactElement { return <ShareActionSheetExample />; }
}
];
@@ -15,38 +15,40 @@
*/
'use strict';
const React = require('react');
const ReactNative = require('react-native');
const {
ActivityIndicator,
var React = require('react-native');
var {
ActivityIndicatorIOS,
StyleSheet,
View,
} = ReactNative;
const TimerMixin = require('react-timer-mixin');
} = React;
var TimerMixin = require('react-timer-mixin');
const ToggleAnimatingActivityIndicator = React.createClass({
var ToggleAnimatingActivityIndicator = React.createClass({
mixins: [TimerMixin],
getInitialState() {
getInitialState: function() {
return {
animating: true,
};
},
setToggleTimeout() {
this.setTimeout(() => {
this.setState({animating: !this.state.animating});
this.setToggleTimeout();
}, 2000);
setToggleTimeout: function() {
this.setTimeout(
() => {
this.setState({animating: !this.state.animating});
this.setToggleTimeout();
},
1200
);
},
componentDidMount() {
componentDidMount: function() {
this.setToggleTimeout();
},
render() {
render: function() {
return (
<ActivityIndicator
<ActivityIndicatorIOS
animating={this.state.animating}
style={[styles.centering, {height: 80}]}
size="large"
@@ -57,31 +59,31 @@ const ToggleAnimatingActivityIndicator = React.createClass({
exports.displayName = (undefined: ?string);
exports.framework = 'React';
exports.title = '<ActivityIndicator>';
exports.title = '<ActivityIndicatorIOS>';
exports.description = 'Animated loading indicators.';
exports.examples = [
{
title: 'Default (small, white)',
render() {
render: function() {
return (
<ActivityIndicator
style={[styles.centering, styles.gray]}
<ActivityIndicatorIOS
style={[styles.centering, styles.gray, {height: 40}]}
color="white"
/>
/>
);
}
},
{
title: 'Gray',
render() {
render: function() {
return (
<View>
<ActivityIndicator
style={[styles.centering]}
<ActivityIndicatorIOS
style={[styles.centering, {height: 40}]}
/>
<ActivityIndicator
style={[styles.centering, {backgroundColor: '#eeeeee'}]}
<ActivityIndicatorIOS
style={[styles.centering, {backgroundColor: '#eeeeee', height: 40}]}
/>
</View>
);
@@ -89,23 +91,23 @@ exports.examples = [
},
{
title: 'Custom colors',
render() {
render: function() {
return (
<View style={styles.horizontal}>
<ActivityIndicator color="#0000ff" />
<ActivityIndicator color="#aa00aa" />
<ActivityIndicator color="#aa3300" />
<ActivityIndicator color="#00aa00" />
<ActivityIndicatorIOS color="#0000ff" />
<ActivityIndicatorIOS color="#aa00aa" />
<ActivityIndicatorIOS color="#aa3300" />
<ActivityIndicatorIOS color="#00aa00" />
</View>
);
}
},
{
title: 'Large',
render() {
render: function() {
return (
<ActivityIndicator
style={[styles.centering, styles.gray]}
<ActivityIndicatorIOS
style={[styles.centering, styles.gray, {height: 80}]}
color="white"
size="large"
/>
@@ -114,22 +116,22 @@ exports.examples = [
},
{
title: 'Large, custom colors',
render() {
render: function() {
return (
<View style={styles.horizontal}>
<ActivityIndicator
<ActivityIndicatorIOS
size="large"
color="#0000ff"
/>
<ActivityIndicator
<ActivityIndicatorIOS
size="large"
color="#aa00aa"
/>
<ActivityIndicator
<ActivityIndicatorIOS
size="large"
color="#aa3300"
/>
<ActivityIndicator
<ActivityIndicatorIOS
size="large"
color="#00aa00"
/>
@@ -139,28 +141,16 @@ exports.examples = [
},
{
title: 'Start/stop',
render() {
render: function(): ReactElement {
return <ToggleAnimatingActivityIndicator />;
}
},
{
title: 'Custom size',
render() {
return (
<ActivityIndicator
style={[styles.centering, {transform: [{scale: 1.5}]}]}
size="large"
/>
);
}
},
];
const styles = StyleSheet.create({
var styles = StyleSheet.create({
centering: {
alignItems: 'center',
justifyContent: 'center',
padding: 8,
},
gray: {
backgroundColor: '#cccccc',
@@ -168,6 +158,5 @@ const styles = StyleSheet.create({
horizontal: {
flexDirection: 'row',
justifyContent: 'space-around',
padding: 8,
},
});
+3 -4
View File
@@ -15,14 +15,13 @@
*/
'use strict';
var React = require('react');
var ReactNative = require('react-native');
var React = require('react-native');
var {
AdSupportIOS,
StyleSheet,
Text,
View,
} = ReactNative;
} = React;
exports.framework = 'React';
exports.title = 'Advertising ID';
@@ -31,7 +30,7 @@ exports.description = 'Example of using the ad support API.';
exports.examples = [
{
title: 'Ad Support IOS',
render: function(): ReactElement<any> {
render: function(): ReactElement {
return <AdSupportIOSExample />;
},
}
-137
View File
@@ -1,137 +0,0 @@
/**
* 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');
var ReactNative = require('react-native');
var {
Alert,
StyleSheet,
Text,
TouchableHighlight,
View,
} = ReactNative;
var UIExplorerBlock = require('./UIExplorerBlock');
// corporate ipsum > lorem ipsum
var alertMessage = 'Credibly reintermediate next-generation potentialities after goal-oriented ' +
'catalysts for change. Dynamically revolutionize.';
/**
* Simple alert examples.
*/
var SimpleAlertExampleBlock = React.createClass({
render: function() {
return (
<View>
<TouchableHighlight style={styles.wrapper}
onPress={() => Alert.alert(
'Alert Title',
alertMessage,
)}>
<View style={styles.button}>
<Text>Alert with message and default button</Text>
</View>
</TouchableHighlight>
<TouchableHighlight style={styles.wrapper}
onPress={() => Alert.alert(
'Alert Title',
alertMessage,
[
{text: 'OK', onPress: () => console.log('OK Pressed!')},
]
)}>
<View style={styles.button}>
<Text>Alert with one button</Text>
</View>
</TouchableHighlight>
<TouchableHighlight style={styles.wrapper}
onPress={() => Alert.alert(
'Alert Title',
alertMessage,
[
{text: 'Cancel', onPress: () => console.log('Cancel Pressed!')},
{text: 'OK', onPress: () => console.log('OK Pressed!')},
]
)}>
<View style={styles.button}>
<Text>Alert with two buttons</Text>
</View>
</TouchableHighlight>
<TouchableHighlight style={styles.wrapper}
onPress={() => Alert.alert(
'Alert Title',
null,
[
{text: 'Foo', onPress: () => console.log('Foo Pressed!')},
{text: 'Bar', onPress: () => console.log('Bar Pressed!')},
{text: 'Baz', onPress: () => console.log('Baz Pressed!')},
]
)}>
<View style={styles.button}>
<Text>Alert with three buttons</Text>
</View>
</TouchableHighlight>
<TouchableHighlight style={styles.wrapper}
onPress={() => Alert.alert(
'Foo Title',
alertMessage,
'..............'.split('').map((dot, index) => ({
text: 'Button ' + index,
onPress: () => console.log('Pressed ' + index)
}))
)}>
<View style={styles.button}>
<Text>Alert with too many buttons</Text>
</View>
</TouchableHighlight>
</View>
);
},
});
var AlertExample = React.createClass({
statics: {
title: 'Alert',
description: 'Alerts display a concise and informative message ' +
'and prompt the user to make a decision.',
},
render: function() {
return (
<UIExplorerBlock title={'Alert'}>
<SimpleAlertExampleBlock />
</UIExplorerBlock>
);
}
});
var styles = StyleSheet.create({
wrapper: {
borderRadius: 5,
marginBottom: 5,
},
button: {
backgroundColor: '#eeeeee',
padding: 10,
},
});
module.exports = {
AlertExample,
SimpleAlertExampleBlock,
};
+84 -64
View File
@@ -15,97 +15,112 @@
*/
'use strict';
var React = require('react');
var ReactNative = require('react-native');
var React = require('react-native');
var {
StyleSheet,
View,
Text,
TouchableHighlight,
AlertIOS,
} = ReactNative;
var { SimpleAlertExampleBlock } = require('./AlertExample');
} = React;
exports.framework = 'React';
exports.title = 'AlertIOS';
exports.description = 'iOS alerts and action sheets';
exports.examples = [{
title: 'Alerts',
render() {
return <SimpleAlertExampleBlock />;
}
},
{
title: 'Prompt Options',
render(): ReactElement<any> {
return <PromptOptions />;
}
},
{
title: 'Prompt Types',
render() {
return (
<View>
<TouchableHighlight
style={styles.wrapper}
onPress={() => AlertIOS.prompt('Plain Text Entry')}>
<TouchableHighlight style={styles.wrapper}
onPress={() => AlertIOS.alert(
'Foo Title',
'My Alert Msg'
)}>
<View style={styles.button}>
<Text>
plain-text
</Text>
<Text>Alert with message and default button</Text>
</View>
</TouchableHighlight>
<TouchableHighlight
style={styles.wrapper}
onPress={() => AlertIOS.prompt('Secure Text', null, null, 'secure-text')}>
<TouchableHighlight style={styles.wrapper}
onPress={() => AlertIOS.alert(
null,
null,
[
{text: 'Button', onPress: () => console.log('Button Pressed!')},
]
)}>
<View style={styles.button}>
<Text>
secure-text
</Text>
<Text>Alert with only one button</Text>
</View>
</TouchableHighlight>
<TouchableHighlight
style={styles.wrapper}
onPress={() => AlertIOS.prompt('Login & Password', null, null, 'login-password')}>
<TouchableHighlight style={styles.wrapper}
onPress={() => AlertIOS.alert(
'Foo Title',
'My Alert Msg',
[
{text: 'Foo', onPress: () => console.log('Foo Pressed!')},
{text: 'Bar', onPress: () => console.log('Bar Pressed!')},
]
)}>
<View style={styles.button}>
<Text>
login-password
</Text>
<Text>Alert with two buttons</Text>
</View>
</TouchableHighlight>
<TouchableHighlight style={styles.wrapper}
onPress={() => AlertIOS.alert(
'Foo Title',
null,
[
{text: 'Foo', onPress: () => console.log('Foo Pressed!')},
{text: 'Bar', onPress: () => console.log('Bar Pressed!')},
{text: 'Baz', onPress: () => console.log('Baz Pressed!')},
]
)}>
<View style={styles.button}>
<Text>Alert with 3 buttons</Text>
</View>
</TouchableHighlight>
<TouchableHighlight style={styles.wrapper}
onPress={() => AlertIOS.alert(
'Foo Title',
'My Alert Msg',
'..............'.split('').map((dot, index) => ({
text: 'Button ' + index,
onPress: () => console.log('Pressed ' + index)
}))
)}>
<View style={styles.button}>
<Text>Alert with too many buttons</Text>
</View>
</TouchableHighlight>
</View>
);
}
},
{
title: 'Prompt',
render(): React.Component {
return <PromptExample />
}
}];
class PromptOptions extends React.Component {
state: any;
customButtons: Array<Object>;
class PromptExample extends React.Component {
constructor(props) {
super(props);
// $FlowFixMe this seems to be a Flow bug, `saveResponse` is defined below
this.saveResponse = this.saveResponse.bind(this);
this.customButtons = [{
text: 'Custom OK',
onPress: this.saveResponse
}, {
text: 'Custom Cancel',
style: 'cancel',
}];
this.promptResponse = this.promptResponse.bind(this);
this.state = {
promptValue: undefined,
};
this.title = 'Type a value';
this.defaultValue = 'Default value';
this.buttons = [{
text: 'Custom cancel',
}, {
text: 'Custom OK',
onPress: this.promptResponse
}];
}
render() {
@@ -117,7 +132,7 @@ class PromptOptions extends React.Component {
<TouchableHighlight
style={styles.wrapper}
onPress={() => AlertIOS.prompt('Type a value', null, this.saveResponse)}>
onPress={this.prompt.bind(this, this.title, this.promptResponse)}>
<View style={styles.button}>
<Text>
@@ -128,7 +143,7 @@ class PromptOptions extends React.Component {
<TouchableHighlight
style={styles.wrapper}
onPress={() => AlertIOS.prompt('Type a value', null, this.customButtons)}>
onPress={this.prompt.bind(this, this.title, this.buttons)}>
<View style={styles.button}>
<Text>
@@ -139,22 +154,22 @@ class PromptOptions extends React.Component {
<TouchableHighlight
style={styles.wrapper}
onPress={() => AlertIOS.prompt('Type a value', null, this.saveResponse, undefined, 'Default value')}>
onPress={this.prompt.bind(this, this.title, this.defaultValue, this.promptResponse)}>
<View style={styles.button}>
<Text>
prompt with title, callback & default value
prompt with title, default value & callback
</Text>
</View>
</TouchableHighlight>
<TouchableHighlight
style={styles.wrapper}
onPress={() => AlertIOS.prompt('Type a value', null, this.customButtons, 'login-password', 'admin@site.com')}>
onPress={this.prompt.bind(this, this.title, this.defaultValue, this.buttons)}>
<View style={styles.button}>
<Text>
prompt with title, custom buttons, login/password & default value
prompt with title, default value & custom buttons
</Text>
</View>
</TouchableHighlight>
@@ -162,8 +177,13 @@ class PromptOptions extends React.Component {
);
}
saveResponse(promptValue) {
this.setState({ promptValue: JSON.stringify(promptValue) });
prompt() {
// Flow's apply support is broken: #7035621
((AlertIOS.prompt: any).apply: any)(AlertIOS, arguments);
}
promptResponse(promptValue) {
this.setState({ promptValue });
}
}
-236
View File
@@ -1,236 +0,0 @@
/**
* 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');
var ReactNative = require('react-native');
var {
Animated,
Easing,
StyleSheet,
Text,
View,
} = ReactNative;
var UIExplorerButton = require('./UIExplorerButton');
exports.framework = 'React';
exports.title = 'Animated - Examples';
exports.description = 'Animated provides a powerful ' +
'and easy-to-use API for building modern, ' +
'interactive user experiences.';
exports.examples = [
{
title: 'FadeInView',
description: 'Uses a simple timing animation to ' +
'bring opacity from 0 to 1 when the component ' +
'mounts.',
render: function() {
class FadeInView extends React.Component {
state: any;
constructor(props) {
super(props);
this.state = {
fadeAnim: new Animated.Value(0), // opacity 0
};
}
componentDidMount() {
Animated.timing( // Uses easing functions
this.state.fadeAnim, // The value to drive
{
toValue: 1, // Target
duration: 2000, // Configuration
},
).start(); // Don't forget start!
}
render() {
return (
<Animated.View // Special animatable View
style={{
opacity: this.state.fadeAnim, // Binds
}}>
{this.props.children}
</Animated.View>
);
}
}
class FadeInExample extends React.Component {
state: any;
constructor(props) {
super(props);
this.state = {
show: true,
};
}
render() {
return (
<View>
<UIExplorerButton onPress={() => {
this.setState((state) => (
{show: !state.show}
));
}}>
Press to {this.state.show ?
'Hide' : 'Show'}
</UIExplorerButton>
{this.state.show && <FadeInView>
<View style={styles.content}>
<Text>FadeInView</Text>
</View>
</FadeInView>}
</View>
);
}
}
return <FadeInExample />;
},
},
{
title: 'Transform Bounce',
description: 'One `Animated.Value` is driven by a ' +
'spring with custom constants and mapped to an ' +
'ordered set of transforms. Each transform has ' +
'an interpolation to convert the value into the ' +
'right range and units.',
render: function() {
this.anim = this.anim || new Animated.Value(0);
return (
<View>
<UIExplorerButton onPress={() => {
Animated.spring(this.anim, {
toValue: 0, // Returns to the start
velocity: 3, // Velocity makes it move
tension: -10, // Slow
friction: 1, // Oscillate a lot
}).start(); }}>
Press to Fling it!
</UIExplorerButton>
<Animated.View
style={[styles.content, {
transform: [ // Array order matters
{scale: this.anim.interpolate({
inputRange: [0, 1],
outputRange: [1, 4],
})},
{translateX: this.anim.interpolate({
inputRange: [0, 1],
outputRange: [0, 500],
})},
{rotate: this.anim.interpolate({
inputRange: [0, 1],
outputRange: [
'0deg', '360deg' // 'deg' or 'rad'
],
})},
]}
]}>
<Text>Transforms!</Text>
</Animated.View>
</View>
);
},
},
{
title: 'Composite Animations with Easing',
description: 'Sequence, parallel, delay, and ' +
'stagger with different easing functions.',
render: function() {
this.anims = this.anims || [1,2,3].map(
() => new Animated.Value(0)
);
return (
<View>
<UIExplorerButton onPress={() => {
var timing = Animated.timing;
Animated.sequence([ // One after the other
timing(this.anims[0], {
toValue: 200,
easing: Easing.linear,
}),
Animated.delay(400), // Use with sequence
timing(this.anims[0], {
toValue: 0,
easing: Easing.elastic(2), // Springy
}),
Animated.delay(400),
Animated.stagger(200,
this.anims.map((anim) => timing(
anim, {toValue: 200}
)).concat(
this.anims.map((anim) => timing(
anim, {toValue: 0}
))),
),
Animated.delay(400),
Animated.parallel([
Easing.inOut(Easing.quad), // Symmetric
Easing.back(1.5), // Goes backwards first
Easing.ease // Default bezier
].map((easing, ii) => (
timing(this.anims[ii], {
toValue: 320, easing, duration: 3000,
})
))),
Animated.delay(400),
Animated.stagger(200,
this.anims.map((anim) => timing(anim, {
toValue: 0,
easing: Easing.bounce, // Like a ball
duration: 2000,
})),
),
]).start(); }}>
Press to Animate
</UIExplorerButton>
{['Composite', 'Easing', 'Animations!'].map(
(text, ii) => (
<Animated.View
key={text}
style={[styles.content, {
left: this.anims[ii]
}]}>
<Text>{text}</Text>
</Animated.View>
)
)}
</View>
);
},
},
{
title: 'Continuous Interactions',
description: 'Gesture events, chaining, 2D ' +
'values, interrupting and transitioning ' +
'animations, etc.',
render: () => (
<Text>Checkout the Gratuitous Animation App!</Text>
),
}
];
var styles = StyleSheet.create({
content: {
backgroundColor: 'deepskyblue',
borderWidth: 1,
borderColor: 'dodgerblue',
padding: 20,
margin: 20,
borderRadius: 10,
alignItems: 'center',
},
});
@@ -16,15 +16,14 @@
*/
'use strict';
var React = require('react');
var ReactNative = require('react-native');
var React = require('react-native');
var {
Animated,
LayoutAnimation,
PanResponder,
StyleSheet,
View,
} = ReactNative;
} = React;
var AnExSet = require('AnExSet');
@@ -33,21 +32,15 @@ var CIRCLE_MARGIN = 18;
var NUM_CIRCLES = 30;
class Circle extends React.Component {
state: any;
props: any;
longTimer: number;
_onLongPress: () => void;
_toggleIsActive: () => void;
constructor(props: Object): void {
super();
this._onLongPress = this._onLongPress.bind(this);
this._toggleIsActive = this._toggleIsActive.bind(this);
this.state = {
isActive: false,
pan: new Animated.ValueXY(), // Vectors reduce boilerplate. (step1: uncomment)
pop: new Animated.Value(0), // Initial value. (step2a: uncomment)
};
this.state = {isActive: false};
this.state.pan = new Animated.ValueXY(); // Vectors reduce boilerplate. (step1: uncomment)
this.state.pop = new Animated.Value(0); // Initial value. (step2a: uncomment)
}
_onLongPress(): void {
@@ -82,7 +75,7 @@ class Circle extends React.Component {
});
}
render(): ReactElement<any> {
render(): ReactElement {
if (this.state.panResponder) {
var handlers = this.state.panResponder.panHandlers;
var dragStyle = { // Used to position while dragging
@@ -161,13 +154,6 @@ class Circle extends React.Component {
}
class AnExApp extends React.Component {
state: any;
props: any;
static title = 'Animated - Gratuitous App';
static description = 'Bunch of Animations - tap a circle to ' +
'open a view with more animations, or longPress and drag to reorder circles.';
_onMove: (position: Point) => void;
constructor(props: any): void {
super(props);
@@ -183,7 +169,7 @@ class AnExApp extends React.Component {
this._onMove = this._onMove.bind(this);
}
render(): ReactElement<any> {
render(): ReactElement {
var circles = this.state.keys.map((key, idx) => {
if (key === this.state.activeKey) {
return <Circle key={key + 'd'} dummy={true} />;
@@ -278,9 +264,14 @@ function moveToClosest({activeKey, keys, restLayouts}, position) {
}
}
AnExApp.title = 'Animated - Gratuitous App';
AnExApp.description = 'Bunch of Animations - tap a circle to ' +
'open a view with more animations, or longPress and drag to reorder circles.';
var styles = StyleSheet.create({
container: {
flex: 1,
paddingTop: 64, // push content below nav bar
},
grid: {
flex: 1,
@@ -16,15 +16,14 @@
*/
'use strict';
var React = require('react');
var ReactNative = require('react-native');
var React = require('react-native');
var {
Animated,
Image,
PanResponder,
StyleSheet,
View,
} = ReactNative;
} = React;
var NUM_BOBBLES = 5;
var RAD_EACH = Math.PI / 2 / (NUM_BOBBLES - 2);
@@ -37,8 +36,6 @@ var BOBBLE_SPOTS = [...Array(NUM_BOBBLES)].map((_, i) => { // static positions
});
class AnExBobble extends React.Component {
state: any;
constructor(props: Object) {
super(props);
this.state = {};
@@ -89,7 +86,7 @@ class AnExBobble extends React.Component {
});
}
render(): ReactElement<any> {
render(): ReactElement {
return (
<View style={styles.bobbleContainer}>
{this.state.bobbles.map((_, i) => {
@@ -98,7 +95,6 @@ class AnExBobble extends React.Component {
return (
<Animated.Image
{...handlers}
key={i}
source={{uri: BOBBLE_IMGS[j]}}
style={[styles.circle, {
backgroundColor: randColor(), // re-renders are obvious
@@ -16,19 +16,16 @@
*/
'use strict';
var React = require('react');
var ReactNative = require('react-native');
var React = require('react-native');
var {
Animated,
Image,
PanResponder,
StyleSheet,
View,
} = ReactNative;
} = React;
class AnExChained extends React.Component {
state: any;
constructor(props: Object) {
super(props);
this.state = {
@@ -80,7 +77,6 @@ class AnExChained extends React.Component {
return (
<Animated.Image
{...handlers}
key={i}
source={{uri: CHAIN_IMGS[j]}}
style={[styles.sticker, {
transform: this.state.stickers[j].getTranslateTransform(), // simple conversion
@@ -12,12 +12,10 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* @providesModule AnExScroll
* @flow
*/
'use strict';
var React = require('react');
var ReactNative = require('react-native');
var React = require('react-native');
var {
Animated,
Image,
@@ -25,10 +23,15 @@ var {
StyleSheet,
Text,
View,
} = ReactNative;
} = React;
class AnExScroll extends React.Component {
state: any = { scrollX: new Animated.Value(0) };
constructor(props) {
super(props);
this.state = {
scrollX: new Animated.Value(0),
};
}
render() {
var width = this.props.panelWidth;
@@ -16,15 +16,14 @@
*/
'use strict';
var React = require('react');
var ReactNative = require('react-native');
var React = require('react-native');
var {
Animated,
PanResponder,
StyleSheet,
Text,
View,
} = ReactNative;
} = React;
var AnExBobble = require('./AnExBobble');
var AnExChained = require('./AnExChained');
@@ -32,8 +31,6 @@ var AnExScroll = require('./AnExScroll');
var AnExTilt = require('./AnExTilt');
class AnExSet extends React.Component {
state: any;
constructor(props: Object) {
super(props);
function randColor() {
@@ -45,7 +42,7 @@ class AnExSet extends React.Component {
openColor: randColor(),
};
}
render(): ReactElement<any> {
render(): ReactElement {
var backgroundColor = this.props.openVal ?
this.props.openVal.interpolate({
inputRange: [0, 1],
@@ -16,19 +16,16 @@
*/
'use strict';
var React = require('react');
var ReactNative = require('react-native');
var React = require('react-native');
var {
Animated,
Image,
PanResponder,
StyleSheet,
View,
} = ReactNative;
} = React;
class AnExTilt extends React.Component {
state: any;
constructor(props: Object) {
super(props);
this.state = {
@@ -90,7 +87,7 @@ class AnExTilt extends React.Component {
this._startBurnsZoom();
}
render(): ReactElement<any> {
render(): ReactElement {
return (
<Animated.View
{...this.state.tiltPanResponder.panHandlers}
@@ -1,11 +1,4 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* The examples provided by Facebook are for non-commercial testing and
* evaluation purposes only.
*
@@ -18,37 +11,36 @@
* 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 AppStateExample
* @providesModule AppStateIOSExample
* @flow
*/
'use strict';
const React = require('react');
const ReactNative = require('react-native');
const {
AppState,
var React = require('react-native');
var {
AppStateIOS,
Text,
View
} = ReactNative;
} = React;
var AppStateSubscription = React.createClass({
getInitialState() {
return {
appState: AppState.currentState,
appState: AppStateIOS.currentState,
previousAppStates: [],
memoryWarnings: 0,
};
},
componentDidMount: function() {
AppState.addEventListener('change', this._handleAppStateChange);
AppState.addEventListener('memoryWarning', this._handleMemoryWarning);
AppStateIOS.addEventListener('change', this._handleAppStateChange);
AppStateIOS.addEventListener('memoryWarning', this._handleMemoryWarning);
},
componentWillUnmount: function() {
AppState.removeEventListener('change', this._handleAppStateChange);
AppState.removeEventListener('memoryWarning', this._handleMemoryWarning);
AppStateIOS.removeEventListener('change', this._handleAppStateChange);
AppStateIOS.removeEventListener('memoryWarning', this._handleMemoryWarning);
},
_handleMemoryWarning: function() {
this.setState({memoryWarnings: this.state.memoryWarnings + 1});
this.setState({memoryWarnings: this.state.memoryWarnings + 1})
},
_handleAppStateChange: function(appState) {
var previousAppStates = this.state.previousAppStates.slice();
@@ -81,27 +73,26 @@ var AppStateSubscription = React.createClass({
}
});
exports.title = 'AppState';
exports.description = 'app background status';
exports.title = 'AppStateIOS';
exports.description = 'iOS app background status';
exports.examples = [
{
title: 'AppState.currentState',
title: 'AppStateIOS.currentState',
description: 'Can be null on app initialization',
render() { return <Text>{AppState.currentState}</Text>; }
render() { return <Text>{AppStateIOS.currentState}</Text>; }
},
{
title: 'Subscribed AppState:',
title: 'Subscribed AppStateIOS:',
description: 'This changes according to the current state, so you can only ever see it rendered as "active"',
render(): ReactElement<any> { return <AppStateSubscription showCurrentOnly={true} />; }
render(): ReactElement { return <AppStateSubscription showCurrentOnly={true} />; }
},
{
title: 'Previous states:',
render(): ReactElement<any> { return <AppStateSubscription showCurrentOnly={false} />; }
render(): ReactElement { return <AppStateSubscription showCurrentOnly={false} />; }
},
{
platform: 'ios',
title: 'Memory Warnings',
description: 'In the IOS simulator, hit Shift+Command+M to simulate a memory warning.',
render(): ReactElement<any> { return <AppStateSubscription showMemoryWarnings={true} />; }
description: "In the simulator, hit Shift+Command+M to simulate a memory warning.",
render(): ReactElement { return <AppStateSubscription showMemoryWarnings={true} />; }
},
];
@@ -1,99 +0,0 @@
/**
* 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');
var ReactNative = require('react-native');
var {
Image,
StyleSheet,
View,
ScrollView
} = ReactNative;
var AssetScaledImageExample = React.createClass({
getInitialState() {
return {
asset: this.props.asset
};
},
render() {
var image = this.state.asset.node.image;
return (
<ScrollView>
<View style={styles.row}>
<Image source={image} style={styles.imageWide}/>
</View>
<View style={styles.row}>
<Image source={image} style={styles.imageThumb}/>
<Image source={image} style={styles.imageThumb}/>
<Image source={image} style={styles.imageThumb}/>
</View>
<View style={styles.row}>
<Image source={image} style={styles.imageT1}/>
<Image source={image} style={styles.imageT2}/>
</View>
</ScrollView>
);
},
});
var styles = StyleSheet.create({
row: {
padding: 5,
flex: 1,
flexDirection: 'row',
alignSelf: 'center',
},
textColumn: {
flex: 1,
flexDirection: 'column',
},
imageWide: {
borderWidth: 1,
borderColor: 'black',
width: 320,
height: 240,
margin: 5,
},
imageThumb: {
borderWidth: 1,
borderColor: 'black',
width: 100,
height: 100,
margin: 5,
},
imageT1: {
borderWidth: 1,
borderColor: 'black',
width: 212,
height: 320,
margin: 5,
},
imageT2: {
borderWidth: 1,
borderColor: 'black',
width: 100,
height: 320,
margin: 5,
},
});
exports.title = '<AssetScaledImageExample>';
exports.description = 'Example component that displays the automatic scaling capabilities of the <Image /> tag';
module.exports = AssetScaledImageExample;
+25 -35
View File
@@ -15,14 +15,13 @@
*/
'use strict';
var React = require('react');
var ReactNative = require('react-native');
var React = require('react-native');
var {
AsyncStorage,
PickerIOS,
Text,
View
} = ReactNative;
} = React;
var PickerItemIOS = PickerIOS.Item;
var STORAGE_KEY = '@AsyncStorageExample:key';
@@ -30,23 +29,18 @@ var COLORS = ['red', 'orange', 'yellow', 'green', 'blue'];
var BasicStorageExample = React.createClass({
componentDidMount() {
this._loadInitialState().done();
AsyncStorage.getItem(STORAGE_KEY)
.then((value) => {
if (value !== null){
this.setState({selectedValue: value});
this._appendMessage('Recovered selection from disk: ' + value);
} else {
this._appendMessage('Initialized with no selection on disk.');
}
})
.catch((error) => this._appendMessage('AsyncStorage error: ' + error.message))
.done();
},
async _loadInitialState() {
try {
var value = await AsyncStorage.getItem(STORAGE_KEY);
if (value !== null){
this.setState({selectedValue: value});
this._appendMessage('Recovered selection from disk: ' + value);
} else {
this._appendMessage('Initialized with no selection on disk.');
}
} catch (error) {
this._appendMessage('AsyncStorage error: ' + error.message);
}
},
getInitialState() {
return {
selectedValue: COLORS[0],
@@ -81,28 +75,24 @@ var BasicStorageExample = React.createClass({
</Text>
<Text>{' '}</Text>
<Text>Messages:</Text>
{this.state.messages.map((m) => <Text key={m}>{m}</Text>)}
{this.state.messages.map((m) => <Text>{m}</Text>)}
</View>
);
},
async _onValueChange(selectedValue) {
_onValueChange(selectedValue) {
this.setState({selectedValue});
try {
await AsyncStorage.setItem(STORAGE_KEY, selectedValue);
this._appendMessage('Saved selection to disk: ' + selectedValue);
} catch (error) {
this._appendMessage('AsyncStorage error: ' + error.message);
}
AsyncStorage.setItem(STORAGE_KEY, selectedValue)
.then(() => this._appendMessage('Saved selection to disk: ' + selectedValue))
.catch((error) => this._appendMessage('AsyncStorage error: ' + error.message))
.done();
},
async _removeStorage() {
try {
await AsyncStorage.removeItem(STORAGE_KEY);
this._appendMessage('Selection removed from disk.');
} catch (error) {
this._appendMessage('AsyncStorage error: ' + error.message);
}
_removeStorage() {
AsyncStorage.removeItem(STORAGE_KEY)
.then(() => this._appendMessage('Selection removed from disk.'))
.catch((error) => { this._appendMessage('AsyncStorage error: ' + error.message) })
.done();
},
_appendMessage(message) {
@@ -115,6 +105,6 @@ exports.description = 'Asynchronous local disk storage.';
exports.examples = [
{
title: 'Basics - getItem, setItem, removeItem',
render(): ReactElement<any> { return <BasicStorageExample />; }
render(): ReactElement { return <BasicStorageExample />; }
},
];
+4 -79
View File
@@ -13,12 +13,11 @@
*/
'use strict';
var React = require('react');
var ReactNative = require('react-native');
var React = require('react-native');
var {
StyleSheet,
View
} = ReactNative;
} = React;
var styles = StyleSheet.create({
box: {
@@ -83,7 +82,7 @@ var styles = StyleSheet.create({
},
border7: {
borderWidth: 10,
borderColor: '#f007',
borderColor: 'rgba(255,0,0,0.5)',
borderRadius: 30,
overflow: 'hidden',
},
@@ -92,45 +91,10 @@ var styles = StyleSheet.create({
width: 100,
height: 100
},
border8: {
width: 60,
height: 60,
borderColor: 'black',
marginRight: 10,
backgroundColor: 'lightgrey',
},
border9: {
borderWidth: 10,
borderTopLeftRadius: 10,
borderBottomRightRadius: 20,
borderColor: 'black',
},
border10: {
borderWidth: 10,
backgroundColor: 'white',
borderTopLeftRadius: 10,
borderBottomRightRadius: 20,
borderColor: 'black',
elevation: 10,
},
border11: {
width: 0,
height: 0,
borderStyle: 'solid',
overflow: 'hidden',
borderTopWidth: 50,
borderRightWidth: 0,
borderBottomWidth: 50,
borderLeftWidth: 100,
borderTopColor: 'transparent',
borderRightColor: 'transparent',
borderBottomColor: 'transparent',
borderLeftColor: 'red',
},
});
exports.title = 'Border';
exports.description = 'Demonstrates some of the border styles available to Views.';
exports.description = 'View borders';
exports.examples = [
{
title: 'Equal-Width / Same-Color',
@@ -170,7 +134,6 @@ exports.examples = [
{
title: 'Custom Borders',
description: 'border*Width & border*Color',
platform: 'ios',
render() {
return <View style={[styles.box, styles.border5]} />;
}
@@ -178,7 +141,6 @@ exports.examples = [
{
title: 'Custom Borders',
description: 'border*Width & border*Color',
platform: 'ios',
render() {
return <View style={[styles.box, styles.border6]} />;
}
@@ -186,7 +148,6 @@ exports.examples = [
{
title: 'Custom Borders',
description: 'borderRadius & clipping',
platform: 'ios',
render() {
return (
<View style={[styles.box, styles.border7]}>
@@ -195,40 +156,4 @@ exports.examples = [
);
}
},
{
title: 'Single Borders',
description: 'top, left, bottom right',
render() {
return (
<View style={{flexDirection: 'row'}}>
<View style={[styles.box, styles.border8, {borderTopWidth: 5}]} />
<View style={[styles.box, styles.border8, {borderLeftWidth: 5}]} />
<View style={[styles.box, styles.border8, {borderBottomWidth: 5}]} />
<View style={[styles.box, styles.border8, {borderRightWidth: 5}]} />
</View>
);
}
},
{
title: 'Corner Radii',
description: 'borderTopLeftRadius & borderBottomRightRadius',
render() {
return <View style={[styles.box, styles.border9]} />;
}
},
{
title: 'Corner Radii / Elevation',
description: 'borderTopLeftRadius & borderBottomRightRadius & elevation',
platform: 'android',
render() {
return <View style={[styles.box, styles.border10]} />;
}
},
{
title: 'CSS Trick - Triangle',
description: 'create a triangle by manipulating border colors and widths',
render() {
return <View style={[styles.border11]} />;
}
},
];
-86
View File
@@ -1,86 +0,0 @@
/**
* 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');
var ReactNative = require('react-native');
var {
Image,
StyleSheet,
View
} = ReactNative;
var styles = StyleSheet.create({
box: {
width: 100,
height: 100,
borderWidth: 2,
},
shadow1: {
shadowOpacity: 0.5,
shadowRadius: 3,
shadowOffset: {width: 2, height: 2},
},
shadow2: {
shadowOpacity: 1.0,
shadowColor: 'red',
shadowRadius: 0,
shadowOffset: {width: 3, height: 3},
},
});
exports.title = 'Box Shadow';
exports.description = 'Demonstrates some of the shadow styles available to Views.';
exports.examples = [
{
title: 'Basic shadow',
description: 'shadowOpacity: 0.5, shadowOffset: {2, 2}',
render() {
return <View style={[styles.box, styles.shadow1]} />;
}
},
{
title: 'Colored shadow',
description: 'shadowColor: \'red\', shadowRadius: 0',
render() {
return <View style={[styles.box, styles.shadow2]} />;
}
},
{
title: 'Shaped shadow',
description: 'borderRadius: 50',
render() {
return <View style={[styles.box, styles.shadow1, {borderRadius: 50}]} />;
}
},
{
title: 'Image shadow',
description: 'Image shadows are derived exactly from the pixels.',
render() {
return <Image
source={require('./hawk.png')}
style={[styles.box, styles.shadow1, {borderWidth: 0, overflow: 'visible'}]}
/>;
}
},
{
title: 'Child shadow',
description: 'For views without an opaque background color, shadow will be derived from the subviews.',
render() {
return <View style={[styles.box, styles.shadow1, {backgroundColor: 'transparent'}]}>
<View style={[styles.box, {width: 80, height: 80, borderRadius: 40, margin: 8, backgroundColor: 'red'}]}/>
</View>;
}
},
];
@@ -15,26 +15,22 @@
*/
'use strict';
const React = require('react');
const ReactNative = require('react-native');
const {
var React = require('react-native');
var {
CameraRoll,
Image,
SliderIOS,
StyleSheet,
Switch,
SwitchIOS,
Text,
View,
TouchableOpacity
} = ReactNative;
} = React;
const CameraRollView = require('./CameraRollView');
var CameraRollView = require('./CameraRollView.ios');
const AssetScaledImageExampleView = require('./AssetScaledImageExample');
var CAMERA_ROLL_VIEW = 'camera_roll_view';
const CAMERA_ROLL_VIEW = 'camera_roll_view';
const CameraRollExample = React.createClass({
var CameraRollExample = React.createClass({
getInitialState() {
return {
@@ -47,7 +43,7 @@ const CameraRollExample = React.createClass({
render() {
return (
<View>
<Switch
<SwitchIOS
onValueChange={this._onSwitchChange}
value={this.state.bigImages} />
<Text>{(this.state.bigImages ? 'Big' : 'Small') + ' Images'}</Text>
@@ -58,7 +54,7 @@ const CameraRollExample = React.createClass({
<Text>{'Group Type: ' + this.state.groupTypes}</Text>
<CameraRollView
ref={CAMERA_ROLL_VIEW}
batchSize={20}
batchSize={5}
groupTypes={this.state.groupTypes}
renderImage={this._renderImage}
/>
@@ -66,44 +62,31 @@ const CameraRollExample = React.createClass({
);
},
loadAsset(asset){
if (this.props.navigator) {
this.props.navigator.push({
title: 'Camera Roll Image',
component: AssetScaledImageExampleView,
backButtonTitle: 'Back',
passProps: { asset: asset },
});
}
},
_renderImage(asset) {
const imageSize = this.state.bigImages ? 150 : 75;
const imageStyle = [styles.image, {width: imageSize, height: imageSize}];
const location = asset.node.location.longitude ?
var imageSize = this.state.bigImages ? 150 : 75;
var imageStyle = [styles.image, {width: imageSize, height: imageSize}];
var location = asset.node.location.longitude ?
JSON.stringify(asset.node.location) : 'Unknown location';
return (
<TouchableOpacity key={asset} onPress={ this.loadAsset.bind( this, asset ) }>
<View style={styles.row}>
<Image
source={asset.node.image}
style={imageStyle}
/>
<View style={styles.info}>
<Text style={styles.url}>{asset.node.image.uri}</Text>
<Text>{location}</Text>
<Text>{asset.node.group_name}</Text>
<Text>{new Date(asset.node.timestamp).toString()}</Text>
</View>
<View key={asset} style={styles.row}>
<Image
source={asset.node.image}
style={imageStyle}
/>
<View style={styles.info}>
<Text style={styles.url}>{asset.node.image.uri}</Text>
<Text>{location}</Text>
<Text>{asset.node.group_name}</Text>
<Text>{new Date(asset.node.timestamp).toString()}</Text>
</View>
</TouchableOpacity>
</View>
);
},
_onSliderChange(value) {
const options = CameraRoll.GroupTypesOptions;
const index = Math.floor(value * options.length * 0.99);
const groupTypes = options[index];
var options = CameraRoll.GroupTypesOptions;
var index = Math.floor(value * options.length * 0.99);
var groupTypes = options[index];
if (groupTypes !== this.state.groupTypes) {
this.setState({groupTypes: groupTypes});
}
@@ -115,7 +98,7 @@ const CameraRollExample = React.createClass({
}
});
const styles = StyleSheet.create({
var styles = StyleSheet.create({
row: {
flexDirection: 'row',
flex: 1,
@@ -132,11 +115,11 @@ const styles = StyleSheet.create({
},
});
exports.title = 'Camera Roll';
exports.title = '<CameraRollView>';
exports.description = 'Example component that uses CameraRoll to list user\'s photos';
exports.examples = [
{
title: 'Photos',
render(): ReactElement<any> { return <CameraRollExample />; }
render(): ReactElement { return <CameraRollExample />; }
}
];
@@ -16,17 +16,15 @@
*/
'use strict';
var React = require('react');
var ReactNative = require('react-native');
var React = require('react-native');
var {
ActivityIndicatorIOS,
CameraRoll,
Image,
ListView,
Platform,
StyleSheet,
View,
} = ReactNative;
} = React;
var groupByEveryN = require('groupByEveryN');
var logError = require('logError');
@@ -141,16 +139,11 @@ var CameraRollView = React.createClass({
groupTypes: this.props.groupTypes,
assetType: this.props.assetType,
};
if (Platform.OS === "android") {
// not supported in android
delete fetchParams.groupTypes;
}
if (this.state.lastCursor) {
fetchParams.after = this.state.lastCursor;
}
CameraRoll.getPhotos(fetchParams)
.then((data) => this._appendAssets(data), (e) => logError(e));
CameraRoll.getPhotos(fetchParams, this._appendAssets, logError);
},
/**
-66
View File
@@ -1,66 +0,0 @@
/**
* 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');
var ReactNative = require('react-native');
var {
Clipboard,
View,
Text,
} = ReactNative;
var ClipboardExample = React.createClass({
getInitialState() {
return {
content: 'Content will appear here'
};
},
async _setClipboardContent(){
Clipboard.setString('Hello World');
try {
var content = await Clipboard.getString();
this.setState({content});
} catch (e) {
this.setState({content:e.message});
}
},
render() {
return (
<View>
<Text onPress={this._setClipboardContent} style={{color: 'blue'}}>
Tap to put "Hello World" in the clipboard
</Text>
<Text style={{color: 'red', marginTop: 20}}>
{this.state.content}
</Text>
</View>
);
}
});
exports.title = 'Clipboard';
exports.description = 'Show Clipboard contents.';
exports.examples = [
{
title: 'Clipboard.setString() and getString()',
render() {
return <ClipboardExample/>;
}
}
];
@@ -1,118 +0,0 @@
/**
* 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');
var ReactNative = require('react-native');
var {
DatePickerAndroid,
StyleSheet,
Text,
TouchableWithoutFeedback,
} = ReactNative;
var UIExplorerBlock = require('./UIExplorerBlock');
var UIExplorerPage = require('./UIExplorerPage');
var DatePickerAndroidExample = React.createClass({
statics: {
title: 'DatePickerAndroid',
description: 'Standard Android date picker dialog',
},
getInitialState() {
return {
presetDate: new Date(2020, 4, 5),
allDate: new Date(2020, 4, 5),
simpleText: 'pick a date',
minText: 'pick a date, no earlier than today',
maxText: 'pick a date, no later than today',
presetText: 'pick a date, preset to 2020/5/5',
allText: 'pick a date between 2020/5/1 and 2020/5/10',
};
},
async showPicker(stateKey, options) {
try {
var newState = {};
const {action, year, month, day} = await DatePickerAndroid.open(options);
if (action === DatePickerAndroid.dismissedAction) {
newState[stateKey + 'Text'] = 'dismissed';
} else {
var date = new Date(year, month, day);
newState[stateKey + 'Text'] = date.toLocaleDateString();
newState[stateKey + 'Date'] = date;
}
this.setState(newState);
} catch ({code, message}) {
console.warn(`Error in example '${stateKey}': `, message);
}
},
render() {
return (
<UIExplorerPage title="DatePickerAndroid">
<UIExplorerBlock title="Simple date picker">
<TouchableWithoutFeedback
onPress={this.showPicker.bind(this, 'simple', {date: this.state.simpleDate})}>
<Text style={styles.text}>{this.state.simpleText}</Text>
</TouchableWithoutFeedback>
</UIExplorerBlock>
<UIExplorerBlock title="Date picker with pre-set date">
<TouchableWithoutFeedback
onPress={this.showPicker.bind(this, 'preset', {date: this.state.presetDate})}>
<Text style={styles.text}>{this.state.presetText}</Text>
</TouchableWithoutFeedback>
</UIExplorerBlock>
<UIExplorerBlock title="Date picker with minDate">
<TouchableWithoutFeedback
onPress={this.showPicker.bind(this, 'min', {
date: this.state.minDate,
minDate: new Date(),
})}>
<Text style={styles.text}>{this.state.minText}</Text>
</TouchableWithoutFeedback>
</UIExplorerBlock>
<UIExplorerBlock title="Date picker with maxDate">
<TouchableWithoutFeedback
onPress={this.showPicker.bind(this, 'max', {
date: this.state.maxDate,
maxDate: new Date(),
})}>
<Text style={styles.text}>{this.state.maxText}</Text>
</TouchableWithoutFeedback>
</UIExplorerBlock>
<UIExplorerBlock title="Date picker with all options">
<TouchableWithoutFeedback
onPress={this.showPicker.bind(this, 'all', {
date: this.state.allDate,
minDate: new Date(2020, 4, 1),
maxDate: new Date(2020, 4, 10),
})}>
<Text style={styles.text}>{this.state.allText}</Text>
</TouchableWithoutFeedback>
</UIExplorerBlock>
</UIExplorerPage>
);
},
});
var styles = StyleSheet.create({
text: {
color: 'black',
},
});
module.exports = DatePickerAndroidExample;
+3 -4
View File
@@ -15,15 +15,14 @@
*/
'use strict';
var React = require('react');
var ReactNative = require('react-native');
var React = require('react-native');
var {
DatePickerIOS,
StyleSheet,
Text,
TextInput,
View,
} = ReactNative;
} = React;
var DatePickerExample = React.createClass({
getDefaultProps: function () {
@@ -132,7 +131,7 @@ exports.description = 'Select dates and times using the native UIDatePicker.';
exports.examples = [
{
title: '<DatePickerIOS>',
render: function(): ReactElement<any> {
render: function(): ReactElement {
return <DatePickerExample />;
},
}];
+1 -3
View File
@@ -14,13 +14,11 @@
* @providesModule ExampleTypes
* @flow
*/
'use strict';
export type Example = {
title: string,
render: () => ?ReactElement<any>,
render: () => ?ReactElement<any, any, any>,
description?: string,
platform?: string;
};
export type ExampleModule = {
+7 -12
View File
@@ -17,13 +17,12 @@
'use strict';
var React = require('react');
var ReactNative = require('react-native');
var React = require('react-native');
var {
StyleSheet,
Text,
View,
} = ReactNative;
} = React;
exports.framework = 'React';
exports.title = 'Geolocation';
@@ -32,7 +31,7 @@ exports.description = 'Examples of using the Geolocation API.';
exports.examples = [
{
title: 'navigator.geolocation',
render: function(): ReactElement<any> {
render: function(): ReactElement {
return <GeolocationExample />;
},
}
@@ -50,15 +49,11 @@ var GeolocationExample = React.createClass({
componentDidMount: function() {
navigator.geolocation.getCurrentPosition(
(position) => {
var initialPosition = JSON.stringify(position);
this.setState({initialPosition});
},
(initialPosition) => this.setState({initialPosition}),
(error) => alert(error.message),
{enableHighAccuracy: true, timeout: 20000, maximumAge: 1000}
);
this.watchID = navigator.geolocation.watchPosition((position) => {
var lastPosition = JSON.stringify(position);
this.watchID = navigator.geolocation.watchPosition((lastPosition) => {
this.setState({lastPosition});
});
},
@@ -72,11 +67,11 @@ var GeolocationExample = React.createClass({
<View>
<Text>
<Text style={styles.title}>Initial position: </Text>
{this.state.initialPosition}
{JSON.stringify(this.state.initialPosition)}
</Text>
<Text>
<Text style={styles.title}>Current position: </Text>
{this.state.lastPosition}
{JSON.stringify(this.state.lastPosition)}
</Text>
</View>
);
+3 -5
View File
@@ -16,14 +16,13 @@
*/
'use strict';
var React = require('react');
var ReactNative = require('react-native');
var React = require('react-native');
var {
Image,
StyleSheet,
Text,
View,
} = ReactNative;
} = React;
var ImageCapInsetsExample = React.createClass({
render: function() {
@@ -36,7 +35,6 @@ var ImageCapInsetsExample = React.createClass({
<Image
source={require('image!story-background')}
style={styles.storyBackground}
resizeMode={Image.resizeMode.stretch}
capInsets={{left: 0, right: 0, bottom: 0, top: 0}}
/>
</View>
@@ -47,7 +45,6 @@ var ImageCapInsetsExample = React.createClass({
<Image
source={require('image!story-background')}
style={styles.storyBackground}
resizeMode={Image.resizeMode.stretch}
capInsets={{left: 15, right: 15, bottom: 15, top: 15}}
/>
</View>
@@ -69,6 +66,7 @@ var styles = StyleSheet.create({
width: 250,
height: 150,
borderWidth: 1,
resizeMode: Image.resizeMode.stretch,
},
text: {
fontSize: 13.5,
-326
View File
@@ -1,326 +0,0 @@
/**
* 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');
var ReactNative = require('react-native');
var {
CameraRoll,
Image,
ImageEditor,
NativeModules,
Platform,
ScrollView,
StyleSheet,
Text,
TouchableHighlight,
UIManager,
View,
} = ReactNative;
var PAGE_SIZE = 20;
type ImageOffset = {
x: number;
y: number;
};
type ImageSize = {
width: number;
height: number;
};
type ImageCropData = {
offset: ImageOffset;
size: ImageSize;
displaySize?: ?ImageSize;
resizeMode?: ?any;
};
class SquareImageCropper extends React.Component {
state: any;
_isMounted: boolean;
_transformData: ImageCropData;
constructor(props) {
super(props);
this._isMounted = true;
this.state = {
randomPhoto: null,
measuredSize: null,
croppedImageURI: null,
cropError: null,
};
this._fetchRandomPhoto();
}
async _fetchRandomPhoto() {
try {
const data = await CameraRoll.getPhotos({first: PAGE_SIZE});
if (!this._isMounted) {
return;
}
var edges = data.edges;
var edge = edges[Math.floor(Math.random() * edges.length)];
var randomPhoto = edge && edge.node && edge.node.image;
if (randomPhoto) {
this.setState({randomPhoto});
}
} catch (error) {
console.warn("Can't get a photo from camera roll", error);
}
}
componentWillUnmount() {
this._isMounted = false;
}
render() {
if (!this.state.measuredSize) {
return (
<View
style={styles.container}
onLayout={(event) => {
var measuredWidth = event.nativeEvent.layout.width;
if (!measuredWidth) {
return;
}
this.setState({
measuredSize: {width: measuredWidth, height: measuredWidth},
});
}}
/>
);
}
if (!this.state.croppedImageURI) {
return this._renderImageCropper();
}
return this._renderCroppedImage();
}
_renderImageCropper() {
if (!this.state.randomPhoto) {
return (
<View style={styles.container} />
);
}
var error = null;
if (this.state.cropError) {
error = (
<Text>{this.state.cropError.message}</Text>
);
}
return (
<View style={styles.container}>
<Text>Drag the image within the square to crop:</Text>
<ImageCropper
image={this.state.randomPhoto}
size={this.state.measuredSize}
style={[styles.imageCropper, this.state.measuredSize]}
onTransformDataChange={(data) => this._transformData = data}
/>
<TouchableHighlight
style={styles.cropButtonTouchable}
onPress={this._crop.bind(this)}>
<View style={styles.cropButton}>
<Text style={styles.cropButtonLabel}>
Crop
</Text>
</View>
</TouchableHighlight>
{error}
</View>
);
}
_renderCroppedImage() {
return (
<View style={styles.container}>
<Text>Here is the cropped image:</Text>
<Image
source={{uri: this.state.croppedImageURI}}
style={[styles.imageCropper, this.state.measuredSize]}
/>
<TouchableHighlight
style={styles.cropButtonTouchable}
onPress={this._reset.bind(this)}>
<View style={styles.cropButton}>
<Text style={styles.cropButtonLabel}>
Try again
</Text>
</View>
</TouchableHighlight>
</View>
);
}
_crop() {
ImageEditor.cropImage(
this.state.randomPhoto.uri,
this._transformData,
(croppedImageURI) => this.setState({croppedImageURI}),
(cropError) => this.setState({cropError})
);
}
_reset() {
this.setState({
randomPhoto: null,
croppedImageURI: null,
cropError: null,
});
this._fetchRandomPhoto();
}
}
class ImageCropper extends React.Component {
_contentOffset: ImageOffset;
_maximumZoomScale: number;
_minimumZoomScale: number;
_scaledImageSize: ImageSize;
_horizontal: boolean;
componentWillMount() {
// Scale an image to the minimum size that is large enough to completely
// fill the crop box.
var widthRatio = this.props.image.width / this.props.size.width;
var heightRatio = this.props.image.height / this.props.size.height;
this._horizontal = widthRatio > heightRatio;
if (this._horizontal) {
this._scaledImageSize = {
width: this.props.image.width / heightRatio,
height: this.props.size.height,
};
} else {
this._scaledImageSize = {
width: this.props.size.width,
height: this.props.image.height / widthRatio,
};
if (Platform.OS === 'android') {
// hack to work around Android ScrollView a) not supporting zoom, and
// b) not supporting vertical scrolling when nested inside another
// vertical ScrollView (which it is, when displayed inside UIExplorer)
this._scaledImageSize.width *= 2;
this._scaledImageSize.height *= 2;
this._horizontal = true;
}
}
this._contentOffset = {
x: (this._scaledImageSize.width - this.props.size.width) / 2,
y: (this._scaledImageSize.height - this.props.size.height) / 2,
};
this._maximumZoomScale = Math.min(
this.props.image.width / this._scaledImageSize.width,
this.props.image.height / this._scaledImageSize.height
);
this._minimumZoomScale = Math.max(
this.props.size.width / this._scaledImageSize.width,
this.props.size.height / this._scaledImageSize.height
);
this._updateTransformData(
this._contentOffset,
this._scaledImageSize,
this.props.size
);
}
_onScroll(event) {
this._updateTransformData(
event.nativeEvent.contentOffset,
event.nativeEvent.contentSize,
event.nativeEvent.layoutMeasurement
);
}
_updateTransformData(offset, scaledImageSize, croppedImageSize) {
var offsetRatioX = offset.x / scaledImageSize.width;
var offsetRatioY = offset.y / scaledImageSize.height;
var sizeRatioX = croppedImageSize.width / scaledImageSize.width;
var sizeRatioY = croppedImageSize.height / scaledImageSize.height;
var cropData: ImageCropData = {
offset: {
x: this.props.image.width * offsetRatioX,
y: this.props.image.height * offsetRatioY,
},
size: {
width: this.props.image.width * sizeRatioX,
height: this.props.image.height * sizeRatioY,
},
};
this.props.onTransformDataChange && this.props.onTransformDataChange(cropData);
}
render() {
return (
<ScrollView
alwaysBounceVertical={true}
automaticallyAdjustContentInsets={false}
contentOffset={this._contentOffset}
decelerationRate="fast"
horizontal={this._horizontal}
maximumZoomScale={this._maximumZoomScale}
minimumZoomScale={this._minimumZoomScale}
onMomentumScrollEnd={this._onScroll.bind(this)}
onScrollEndDrag={this._onScroll.bind(this)}
showsHorizontalScrollIndicator={false}
showsVerticalScrollIndicator={false}
style={this.props.style}
scrollEventThrottle={16}>
<Image source={this.props.image} style={this._scaledImageSize} />
</ScrollView>
);
}
}
exports.framework = 'React';
exports.title = 'ImageEditor';
exports.description = 'Cropping and scaling with ImageEditor';
exports.examples = [{
title: 'Image Cropping',
render() {
return <SquareImageCropper/>;
}
}];
var styles = StyleSheet.create({
container: {
flex: 1,
alignSelf: 'stretch',
},
imageCropper: {
alignSelf: 'center',
marginTop: 12,
},
cropButtonTouchable: {
alignSelf: 'center',
marginTop: 12,
},
cropButton: {
padding: 12,
backgroundColor: 'blue',
borderRadius: 4,
},
cropButtonLabel: {
color: 'white',
fontSize: 16,
fontWeight: '500',
},
});
+67 -328
View File
@@ -1,11 +1,4 @@
/**
* Copyright (c) 2013-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* The examples provided by Facebook are for non-commercial testing and
* evaluation purposes only.
*
@@ -22,139 +15,15 @@
*/
'use strict';
var React = require('react');
var ReactNative = require('react-native');
var React = require('react-native');
var {
Image,
Platform,
StyleSheet,
Text,
View,
ActivityIndicatorIOS
} = ReactNative;
var base64Icon = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEsAAABLCAQAAACSR7JhAAADtUlEQVR4Ac3YA2Bj6QLH0XPT1Fzbtm29tW3btm3bfLZtv7e2ObZnms7d8Uw098tuetPzrxv8wiISrtVudrG2JXQZ4VOv+qUfmqCGGl1mqLhoA52oZlb0mrjsnhKpgeUNEs91Z0pd1kvihA3ULGVHiQO2narKSHKkEMulm9VgUyE60s1aWoMQUbpZOWE+kaqs4eLEjdIlZTcFZB0ndc1+lhB1lZrIuk5P2aib1NBpZaL+JaOGIt0ls47SKzLC7CqrlGF6RZ09HGoNy1lYl2aRSWL5GuzqWU1KafRdoRp0iOQEiDzgZPnG6DbldcomadViflnl/cL93tOoVbsOLVM2jylvdWjXolWX1hmfZbGR/wjypDjFLSZIRov09BgYmtUqPQPlQrPapecLgTIy0jMgPKtTeob2zWtrGH3xvjUkPCtNg/tm1rjwrMa+mdUkPd3hWbH0jArPGiU9ufCsNNWFZ40wpwn+62/66R2RUtoso1OB34tnLOcy7YB1fUdc9e0q3yru8PGM773vXsuZ5YIZX+5xmHwHGVvlrGPN6ZSiP1smOsMMde40wKv2VmwPPVXNut4sVpUreZiLBHi0qln/VQeI/LTMYXpsJtFiclUN+5HVZazim+Ky+7sAvxWnvjXrJFneVtLWLyPJu9K3cXLWeOlbMTlrIelbMDlrLenrjEQOtIF+fuI9xRp9ZBFp6+b6WT8RrxEpdK64BuvHgDk+vUy+b5hYk6zfyfs051gRoNO1usU12WWRWL73/MMEy9pMi9qIrR4ZpV16Rrvduxazmy1FSvuFXRkqTnE7m2kdb5U8xGjLw/spRr1uTov4uOgQE+0N/DvFrG/Jt7i/FzwxbA9kDanhf2w+t4V97G8lrT7wc08aA2QNUkuTfW/KimT01wdlfK4yEw030VfT0RtZbzjeMprNq8m8tnSTASrTLti64oBNdpmMQm0eEwvfPwRbUBywG5TzjPCsdwk3IeAXjQblLCoXnDVeoAz6SfJNk5TTzytCNZk/POtTSV40NwOFWzw86wNJRpubpXsn60NJFlHeqlYRbslqZm2jnEZ3qcSKgm0kTli3zZVS7y/iivZTweYXJ26Y+RTbV1zh3hYkgyFGSTKPfRVbRqWWVReaxYeSLarYv1Qqsmh1s95S7G+eEWK0f3jYKTbV6bOwepjfhtafsvUsqrQvrGC8YhmnO9cSCk3yuY984F1vesdHYhWJ5FvASlacshUsajFt2mUM9pqzvKGcyNJW0arTKN1GGGzQlH0tXwLDgQTurS8eIQAAAABJRU5ErkJggg==';
} = React;
var ImageCapInsetsExample = require('./ImageCapInsetsExample');
const IMAGE_PREFETCH_URL = 'http://facebook.github.io/origami/public/images/blog-hero.jpg?r=1&t=' + Date.now();
var prefetchTask = Image.prefetch(IMAGE_PREFETCH_URL);
var NetworkImageCallbackExample = React.createClass({
getInitialState: function() {
return {
events: [],
startLoadPrefetched: false,
mountTime: new Date(),
};
},
componentWillMount() {
this.setState({mountTime: new Date()});
},
render: function() {
var { mountTime } = this.state;
return (
<View>
<Image
source={this.props.source}
style={[styles.base, {overflow: 'visible'}]}
onLoadStart={() => this._loadEventFired(`✔ onLoadStart (+${new Date() - mountTime}ms)`)}
onLoad={() => this._loadEventFired(`✔ onLoad (+${new Date() - mountTime}ms)`)}
onLoadEnd={() => {
this._loadEventFired(`✔ onLoadEnd (+${new Date() - mountTime}ms)`);
this.setState({startLoadPrefetched: true}, () => {
prefetchTask.then(() => {
this._loadEventFired(`✔ Prefetch OK (+${new Date() - mountTime}ms)`);
}, error => {
this._loadEventFired(`✘ Prefetch failed (+${new Date() - mountTime}ms)`);
});
});
}}
/>
{this.state.startLoadPrefetched ?
<Image
source={this.props.prefetchedSource}
style={[styles.base, {overflow: 'visible'}]}
onLoadStart={() => this._loadEventFired(`✔ (prefetched) onLoadStart (+${new Date() - mountTime}ms)`)}
onLoad={() => this._loadEventFired(`✔ (prefetched) onLoad (+${new Date() - mountTime}ms)`)}
onLoadEnd={() => this._loadEventFired(`✔ (prefetched) onLoadEnd (+${new Date() - mountTime}ms)`)}
/>
: null}
<Text style={{marginTop: 20}}>
{this.state.events.join('\n')}
</Text>
</View>
);
},
_loadEventFired(event) {
this.setState((state) => {
return state.events = [...state.events, event];
});
}
});
var NetworkImageExample = React.createClass({
getInitialState: function() {
return {
error: false,
loading: false,
progress: 0
};
},
render: function() {
var loader = this.state.loading ?
<View style={styles.progress}>
<Text>{this.state.progress}%</Text>
<ActivityIndicatorIOS style={{marginLeft:5}}/>
</View> : null;
return this.state.error ?
<Text>{this.state.error}</Text> :
<Image
source={this.props.source}
style={[styles.base, {overflow: 'visible'}]}
onLoadStart={(e) => this.setState({loading: true})}
onError={(e) => this.setState({error: e.nativeEvent.error, loading: false})}
onProgress={(e) => this.setState({progress: Math.round(100 * e.nativeEvent.loaded / e.nativeEvent.total)})}
onLoad={() => this.setState({loading: false, error: false})}>
{loader}
</Image>;
}
});
var ImageSizeExample = React.createClass({
getInitialState: function() {
return {
width: 0,
height: 0,
};
},
componentDidMount: function() {
Image.getSize(this.props.source.uri, (width, height) => {
this.setState({width, height});
});
},
render: function() {
return (
<View style={{flexDirection: 'row'}}>
<Image
style={{
width: 60,
height: 60,
backgroundColor: 'transparent',
marginRight: 10,
}}
source={this.props.source} />
<Text>
Actual dimensions:{'\n'}
Width: {this.state.width}, Height: {this.state.height}
</Text>
</View>
);
},
});
exports.displayName = (undefined: ?string);
exports.framework = 'React';
@@ -177,60 +46,19 @@ exports.examples = [
},
{
title: 'Plain Static Image',
description: 'Static assets should be placed in the source code tree, and ' +
'required in the same way as JavaScript modules.',
description: 'Static assets should be required by prefixing with `image!` ' +
'and are located in the app bundle.',
render: function() {
return (
<View style={styles.horizontal}>
<Image source={require('./uie_thumb_normal.png')} style={styles.icon} />
<Image source={require('./uie_thumb_selected.png')} style={styles.icon} />
<Image source={require('./uie_comment_normal.png')} style={styles.icon} />
<Image source={require('./uie_comment_highlighted.png')} style={styles.icon} />
<Image source={require('image!uie_thumb_normal')} style={styles.icon} />
<Image source={require('image!uie_thumb_selected')} style={styles.icon} />
<Image source={require('image!uie_comment_normal')} style={styles.icon} />
<Image source={require('image!uie_comment_highlighted')} style={styles.icon} />
</View>
);
},
},
{
title: 'Image Loading Events',
render: function() {
return (
<NetworkImageCallbackExample source={{uri: 'http://facebook.github.io/origami/public/images/blog-hero.jpg?r=1&t=' + Date.now()}}
prefetchedSource={{uri: IMAGE_PREFETCH_URL}}/>
);
},
},
{
title: 'Error Handler',
render: function() {
return (
<NetworkImageExample source={{uri: 'http://TYPO_ERROR_facebook.github.io/react/img/logo_og.png'}} />
);
},
platform: 'ios',
},
{
title: 'Image Download Progress',
render: function() {
return (
<NetworkImageExample source={{uri: 'http://facebook.github.io/origami/public/images/blog-hero.jpg?r=1'}}/>
);
},
platform: 'ios',
},
{
title: 'defaultSource',
description: 'Show a placeholder image when a network image is loading',
render: function() {
return (
<Image
defaultSource={require('./bunny.png')}
source={{uri: 'http://facebook.github.io/origami/public/images/birds.jpg'}}
style={styles.base}
/>
);
},
platform: 'ios',
},
{
title: 'Border Color',
render: function() {
@@ -271,12 +99,17 @@ exports.examples = [
return (
<View style={styles.horizontal}>
<Image
style={[styles.base, {borderRadius: 5}]}
source={fullImage}
style={[styles.base, styles.background, {borderRadius: 5}]}
source={smallImage}
/>
<Image
style={[styles.base, styles.leftMargin, {borderRadius: 19}]}
source={fullImage}
style={[
styles.base,
styles.background,
styles.leftMargin,
{borderRadius: 19}
]}
source={smallImage}
/>
</View>
);
@@ -361,46 +194,23 @@ exports.examples = [
'pixels to the tint color.',
render: function() {
return (
<View>
<View style={styles.horizontal}>
<Image
source={require('./uie_thumb_normal.png')}
style={[styles.icon, {borderRadius: 5, tintColor: '#5ac8fa' }]}
/>
<Image
source={require('./uie_thumb_normal.png')}
style={[styles.icon, styles.leftMargin, {borderRadius: 5, tintColor: '#4cd964' }]}
/>
<Image
source={require('./uie_thumb_normal.png')}
style={[styles.icon, styles.leftMargin, {borderRadius: 5, tintColor: '#ff2d55' }]}
/>
<Image
source={require('./uie_thumb_normal.png')}
style={[styles.icon, styles.leftMargin, {borderRadius: 5, tintColor: '#8e8e93' }]}
/>
</View>
<Text style={styles.sectionText}>
It also works with downloaded images:
</Text>
<View style={styles.horizontal}>
<Image
source={smallImage}
style={[styles.base, {borderRadius: 5, tintColor: '#5ac8fa' }]}
/>
<Image
source={smallImage}
style={[styles.base, styles.leftMargin, {borderRadius: 5, tintColor: '#4cd964' }]}
/>
<Image
source={smallImage}
style={[styles.base, styles.leftMargin, {borderRadius: 5, tintColor: '#ff2d55' }]}
/>
<Image
source={smallImage}
style={[styles.base, styles.leftMargin, {borderRadius: 5, tintColor: '#8e8e93' }]}
/>
</View>
<View style={styles.horizontal}>
<Image
source={require('image!uie_thumb_normal')}
style={[styles.icon, {tintColor: 'blue' }]}
/>
<Image
source={require('image!uie_thumb_normal')}
style={[styles.icon, styles.leftMargin, {tintColor: 'green' }]}
/>
<Image
source={require('image!uie_thumb_normal')}
style={[styles.icon, styles.leftMargin, {tintColor: 'red' }]}
/>
<Image
source={require('image!uie_thumb_normal')}
style={[styles.icon, styles.leftMargin, {tintColor: 'black' }]}
/>
</View>
);
},
@@ -411,87 +221,41 @@ exports.examples = [
'rendered within the frame.',
render: function() {
return (
<View>
{[smallImage, fullImage].map((image, index) => {
return (
<View key={index}>
<View style={styles.horizontal}>
<View>
<Text style={[styles.resizeModeText]}>
Contain
</Text>
<Image
style={styles.resizeMode}
resizeMode={Image.resizeMode.contain}
source={image}
/>
</View>
<View style={styles.leftMargin}>
<Text style={[styles.resizeModeText]}>
Cover
</Text>
<Image
style={styles.resizeMode}
resizeMode={Image.resizeMode.cover}
source={image}
/>
</View>
</View>
<View style={styles.horizontal}>
<View>
<Text style={[styles.resizeModeText]}>
Stretch
</Text>
<Image
style={styles.resizeMode}
resizeMode={Image.resizeMode.stretch}
source={image}
/>
</View>
{ Platform.OS === 'android' ?
<View style={styles.leftMargin}>
<Text style={[styles.resizeModeText]}>
Center
</Text>
<Image
style={styles.resizeMode}
resizeMode={Image.resizeMode.center}
source={image}
/>
</View>
: null }
</View>
</View>
);
})}
<View style={styles.horizontal}>
<View>
<Text style={[styles.resizeModeText]}>
Contain
</Text>
<Image
style={styles.resizeMode}
resizeMode={Image.resizeMode.contain}
source={fullImage}
/>
</View>
<View style={styles.leftMargin}>
<Text style={[styles.resizeModeText]}>
Cover
</Text>
<Image
style={styles.resizeMode}
resizeMode={Image.resizeMode.cover}
source={fullImage}
/>
</View>
<View style={styles.leftMargin}>
<Text style={[styles.resizeModeText]}>
Stretch
</Text>
<Image
style={styles.resizeMode}
resizeMode={Image.resizeMode.stretch}
source={fullImage}
/>
</View>
</View>
);
},
},
{
title: 'Animated GIF',
render: function() {
return (
<Image
style={styles.gif}
source={{uri: 'http://38.media.tumblr.com/9e9bd08c6e2d10561dd1fb4197df4c4e/tumblr_mfqekpMktw1rn90umo1_500.gif'}}
/>
);
},
platform: 'ios',
},
{
title: 'Base64 image',
render: function() {
return (
<Image
style={styles.base64}
source={{uri: base64Icon, scale: 3}}
/>
);
},
platform: 'ios',
},
{
title: 'Cap Insets',
description:
@@ -502,39 +266,23 @@ exports.examples = [
render: function() {
return <ImageCapInsetsExample />;
},
platform: 'ios',
},
{
title: 'Image Size',
render: function() {
return <ImageSizeExample source={fullImage} />;
},
},
];
var fullImage = {uri: 'http://facebook.github.io/react/img/logo_og.png'};
var smallImage = {uri: 'http://facebook.github.io/react/img/logo_small_2x.png'};
var smallImage = {uri: 'http://facebook.github.io/react/img/logo_small.png'};
var styles = StyleSheet.create({
base: {
width: 38,
height: 38,
},
progress: {
flex: 1,
alignItems: 'center',
flexDirection: 'row',
width: 100
},
leftMargin: {
marginLeft: 10,
},
background: {
backgroundColor: '#222222'
},
sectionText: {
marginVertical: 6,
},
nestedText: {
marginLeft: 12,
marginTop: 20,
@@ -557,14 +305,5 @@ var styles = StyleSheet.create({
},
horizontal: {
flexDirection: 'row',
},
gif: {
flex: 1,
height: 200,
},
base64: {
flex: 1,
height: 50,
resizeMode: 'contain',
},
}
});
+56
View File
@@ -0,0 +1,56 @@
/**
* 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';
declare module 'image!story-background' {
/* $FlowIssue #7387208 - There's a flow bug preventing this type from flowing
* into a proptype shape */
declare var uri: string;
declare var isStatic: boolean;
}
declare module 'image!uie_comment_highlighted' {
/* $FlowIssue #7387208 - There's a flow bug preventing this type from flowing
* into a proptype shape */
declare var uri: string;
declare var isStatic: boolean;
}
declare module 'image!uie_comment_normal' {
/* $FlowIssue #7387208 - There's a flow bug preventing this type from flowing
* into a proptype shape */
declare var uri: string;
declare var isStatic: boolean;
}
declare module 'image!uie_thumb_normal' {
/* $FlowIssue #7387208 - There's a flow bug preventing this type from flowing
* into a proptype shape */
declare var uri: string;
declare var isStatic: boolean;
}
declare module 'image!uie_thumb_selected' {
/* $FlowIssue #7387208 - There's a flow bug preventing this type from flowing
* into a proptype shape */
declare var uri: string;
declare var isStatic: boolean;
}
declare module 'image!NavBarButtonPlus' {
declare var uri: string;
declare var isStatic: boolean;
}
@@ -1,171 +0,0 @@
/**
* 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';
const React = require('react');
const ReactNative = require('react-native');
const {
LayoutAnimation,
StyleSheet,
Text,
View,
TouchableOpacity,
} = ReactNative;
const AddRemoveExample = React.createClass({
getInitialState() {
return {
views: [],
};
},
componentWillUpdate() {
LayoutAnimation.easeInEaseOut();
},
_onPressAddView() {
this.setState((state) => ({views: [...state.views, {}]}));
},
_onPressRemoveView() {
this.setState((state) => ({views: state.views.slice(0, -1)}));
},
render() {
const views = this.state.views.map((view, i) =>
<View key={i} style={styles.view}>
<Text>{i}</Text>
</View>
);
return (
<View style={styles.container}>
<TouchableOpacity onPress={this._onPressAddView}>
<View style={styles.button}>
<Text>Add view</Text>
</View>
</TouchableOpacity>
<TouchableOpacity onPress={this._onPressRemoveView}>
<View style={styles.button}>
<Text>Remove view</Text>
</View>
</TouchableOpacity>
<View style={styles.viewContainer}>
{views}
</View>
</View>
);
},
});
const GreenSquare = () =>
<View style={styles.greenSquare}>
<Text>Green square</Text>
</View>;
const BlueSquare = () =>
<View style={styles.blueSquare}>
<Text>Blue square</Text>
</View>;
const CrossFadeExample = React.createClass({
getInitialState() {
return {
toggled: false,
};
},
_onPressToggle() {
LayoutAnimation.easeInEaseOut();
this.setState((state) => ({toggled: !state.toggled}));
},
render() {
return (
<View style={styles.container}>
<TouchableOpacity onPress={this._onPressToggle}>
<View style={styles.button}>
<Text>Toggle</Text>
</View>
</TouchableOpacity>
<View style={styles.viewContainer}>
{
this.state.toggled ?
<GreenSquare /> :
<BlueSquare />
}
</View>
</View>
);
},
});
const styles = StyleSheet.create({
container: {
flex: 1,
},
button: {
borderRadius: 5,
backgroundColor: '#eeeeee',
padding: 10,
marginBottom: 10,
},
buttonText: {
fontSize: 16,
},
viewContainer: {
flex: 1,
flexDirection: 'row',
flexWrap: 'wrap',
},
view: {
height: 54,
width: 54,
backgroundColor: 'red',
margin: 8,
alignItems: 'center',
justifyContent: 'center',
},
greenSquare: {
width: 150,
height: 150,
backgroundColor: 'green',
alignItems: 'center',
justifyContent: 'center',
},
blueSquare: {
width: 150,
height: 150,
backgroundColor: 'blue',
alignItems: 'center',
justifyContent: 'center',
},
});
exports.title = 'Layout Animation';
exports.description = 'Layout animation';
exports.examples = [{
title: 'Add and remove views',
render(): ReactElement<any> {
return <AddRemoveExample />;
},
}, {
title: 'Cross fade views',
render(): ReactElement<any> {
return <CrossFadeExample />;
},
}];
+17 -31
View File
@@ -15,40 +15,28 @@
*/
'use strict';
var React = require('react');
var ReactNative = require('react-native');
var React = require('react-native');
var {
Image,
LayoutAnimation,
StyleSheet,
Text,
View,
} = ReactNative;
type Layout = {
x: number;
y: number;
width: number;
height: number;
};
} = React;
type LayoutEvent = {
nativeEvent: {
layout: Layout,
layout: {
x: number;
y: number;
width: number;
height: number;
};
};
};
type State = {
containerStyle?: { width: number },
extraText?: string,
imageLayout?: Layout,
textLayout?: Layout,
viewLayout?: Layout,
viewStyle: { margin: number },
};
var LayoutEventExample = React.createClass({
getInitialState(): State {
getInitialState: function() {
return {
viewStyle: {
margin: 20,
@@ -61,7 +49,8 @@ var LayoutEventExample = React.createClass({
() => {
console.log('layout animation done.');
this.addWrapText();
}
},
(error) => { throw new Error(JSON.stringify(error)); }
);
this.setState({
viewStyle: {
@@ -97,7 +86,8 @@ var LayoutEventExample = React.createClass({
return (
<View style={this.state.containerStyle}>
<Text>
layout events are called on mount and whenever layout is recalculated. Note that the layout event will typically be received <Text style={styles.italicText}>before</Text> the layout has updated on screen, especially when using layout animations.{' '}
onLayout events are called on mount and whenever layout is updated,
including after layout animations complete.{' '}
<Text style={styles.pressText} onPress={this.animateViewLayout}>
Press here to change layout.
</Text>
@@ -147,18 +137,14 @@ var styles = StyleSheet.create({
pressText: {
fontWeight: 'bold',
},
italicText: {
fontStyle: 'italic',
},
});
exports.title = 'Layout Events';
exports.description = 'Examples that show how Layout events can be used to ' +
'measure view size and position.';
exports.title = 'onLayout';
exports.description = 'Layout events can be used to measure view size and position.';
exports.examples = [
{
title: 'LayoutEventExample',
render: function(): ReactElement<any> {
title: 'onLayout',
render: function(): ReactElement {
return <LayoutEventExample />;
},
}];
+2 -3
View File
@@ -15,13 +15,12 @@
*/
'use strict';
var React = require('react');
var ReactNative = require('react-native');
var React = require('react-native');
var {
StyleSheet,
Text,
View,
} = ReactNative;
} = React;
var UIExplorerBlock = require('./UIExplorerBlock');
var UIExplorerPage = require('./UIExplorerPage');
-93
View File
@@ -1,93 +0,0 @@
/**
* 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');
var ReactNative = require('react-native');
var {
Linking,
StyleSheet,
Text,
TouchableOpacity,
View,
} = ReactNative;
var UIExplorerBlock = require('./UIExplorerBlock');
var OpenURLButton = React.createClass({
propTypes: {
url: React.PropTypes.string,
},
handleClick: function() {
Linking.canOpenURL(this.props.url).then(supported => {
if (supported) {
Linking.openURL(this.props.url);
} else {
console.log('Don\'t know how to open URI: ' + this.props.url);
}
});
},
render: function() {
return (
<TouchableOpacity
onPress={this.handleClick}>
<View style={styles.button}>
<Text style={styles.text}>Open {this.props.url}</Text>
</View>
</TouchableOpacity>
);
}
});
var IntentAndroidExample = React.createClass({
statics: {
title: 'Linking',
description: 'Shows how to use Linking to open URLs.',
},
render: function() {
return (
<UIExplorerBlock title="Open external URLs">
<OpenURLButton url={'https://www.facebook.com'} />
<OpenURLButton url={'http://www.facebook.com'} />
<OpenURLButton url={'http://facebook.com'} />
<OpenURLButton url={'fb://notifications'} />
<OpenURLButton url={'geo:37.484847,-122.148386'} />
<OpenURLButton url={'tel:9876543210'} />
</UIExplorerBlock>
);
},
});
var styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: 'white',
padding: 10,
paddingTop: 30,
},
button: {
padding: 10,
backgroundColor: '#3B5998',
marginBottom: 10,
},
text: {
color: 'white',
},
});
module.exports = IntentAndroidExample;

Some files were not shown because too many files have changed in this diff Show More