├── .watchmanconfig
├── .gitattributes
├── .babelrc
├── view
├── day12.js
├── img
│ ├── w2.png
│ ├── w3.png
│ ├── agrass.png
│ ├── day1.png
│ ├── day2.png
│ ├── day3.png
│ ├── sphere.jpg
│ ├── tumblr.png
│ ├── moments.mp4
│ ├── poincare.png
│ ├── tumblr-chat.png
│ ├── tumblr-link.png
│ ├── tumblr-text.png
│ ├── tumblrblur.png
│ ├── tumblr-audio.png
│ ├── tumblr-photo.png
│ └── tumblr-quote.png
├── dayTemplate.js
├── day29.js
├── day4.js
├── public
│ ├── demo2.html
│ ├── demo1.html
│ └── js
│ │ ├── sphere.js
│ │ └── poincare-disk.js
├── utils.js
├── day25.js
├── day19.js
├── day17.js
├── day27.js
├── day30.js
├── day5.js
├── day21.js
├── day23.js
├── day7.js
├── day15.js
├── day16.js
├── day22.js
├── day11.js
├── day10.js
├── day26.js
├── day6.js
├── day13.js
├── day28.js
├── day24.js
├── day20.js
├── day8.js
├── day14.js
└── day1.js
├── android
├── .gradle
│ └── 2.4
│ │ └── taskArtifacts
│ │ ├── cache.properties
│ │ ├── fileHashes.bin
│ │ ├── fileSnapshots.bin
│ │ ├── taskArtifacts.bin
│ │ ├── outputFileStates.bin
│ │ └── cache.properties.lock
├── app
│ ├── src
│ │ └── main
│ │ │ ├── res
│ │ │ ├── values
│ │ │ │ ├── strings.xml
│ │ │ │ └── styles.xml
│ │ │ ├── mipmap-hdpi
│ │ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-mdpi
│ │ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xhdpi
│ │ │ │ └── ic_launcher.png
│ │ │ └── mipmap-xxhdpi
│ │ │ │ └── ic_launcher.png
│ │ │ ├── assets
│ │ │ └── fonts
│ │ │ │ ├── Entypo.ttf
│ │ │ │ ├── Zocial.ttf
│ │ │ │ ├── Ionicons.ttf
│ │ │ │ ├── Octicons.ttf
│ │ │ │ ├── EvilIcons.ttf
│ │ │ │ ├── FontAwesome.ttf
│ │ │ │ ├── Foundation.ttf
│ │ │ │ └── MaterialIcons.ttf
│ │ │ ├── java
│ │ │ └── com
│ │ │ │ └── thirtydaysofreactnative
│ │ │ │ ├── MainActivity.java
│ │ │ │ └── MainApplication.java
│ │ │ └── AndroidManifest.xml
│ ├── BUCK
│ ├── proguard-rules.pro
│ └── build.gradle
├── gradle
│ └── wrapper
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
├── keystores
│ ├── debug.keystore.properties
│ └── BUCK
├── build.gradle
├── settings.gradle
├── gradle.properties
├── gradlew.bat
└── gradlew
├── ios
├── ThirtyDaysOfReactNative
│ ├── Images.xcassets
│ │ ├── Contents.json
│ │ ├── gl.imageset
│ │ │ ├── gl.png
│ │ │ └── Contents.json
│ │ ├── map.imageset
│ │ │ ├── map.png
│ │ │ └── Contents.json
│ │ ├── w2.imageset
│ │ │ ├── w2.png
│ │ │ └── Contents.json
│ │ ├── w3.imageset
│ │ │ ├── w3.png
│ │ │ └── Contents.json
│ │ ├── day1.imageset
│ │ │ ├── day1.png
│ │ │ └── Contents.json
│ │ ├── day2.imageset
│ │ │ ├── day2.png
│ │ │ └── Contents.json
│ │ ├── day3.imageset
│ │ │ ├── day3.png
│ │ │ └── Contents.json
│ │ ├── icon.imageset
│ │ │ ├── icon.png
│ │ │ └── Contents.json
│ │ ├── agrass.imageset
│ │ │ ├── agrass.png
│ │ │ └── Contents.json
│ │ ├── banner.imageset
│ │ │ ├── banner.png
│ │ │ └── Contents.json
│ │ ├── packed.imageset
│ │ │ ├── packed.png
│ │ │ └── Contents.json
│ │ ├── tumblr.imageset
│ │ │ ├── tumblr.png
│ │ │ └── Contents.json
│ │ ├── desktop.imageset
│ │ │ ├── desktop.png
│ │ │ └── Contents.json
│ │ ├── minion1.imageset
│ │ │ ├── minion1.png
│ │ │ └── Contents.json
│ │ ├── minion2.imageset
│ │ │ ├── minion2.png
│ │ │ └── Contents.json
│ │ ├── minion3.imageset
│ │ │ ├── minion3.png
│ │ │ └── Contents.json
│ │ ├── minion4.imageset
│ │ │ ├── minion4.png
│ │ │ └── Contents.json
│ │ ├── minion5.imageset
│ │ │ ├── minion5.png
│ │ │ └── Contents.json
│ │ ├── moreinfo.imageset
│ │ │ ├── moreinfo.png
│ │ │ └── Contents.json
│ │ ├── bannerBlur.imageset
│ │ │ ├── bannerBlur.png
│ │ │ └── Contents.json
│ │ ├── tumblrblur.imageset
│ │ │ ├── tumblrblur.png
│ │ │ └── Contents.json
│ │ ├── tumblr-chat.imageset
│ │ │ ├── tumblr-chat.png
│ │ │ └── Contents.json
│ │ ├── tumblr-link.imageset
│ │ │ ├── tumblr-link.png
│ │ │ └── Contents.json
│ │ ├── tumblr-text.imageset
│ │ │ ├── tumblr-text.png
│ │ │ └── Contents.json
│ │ ├── tumblr-audio.imageset
│ │ │ ├── tumblr-audio.png
│ │ │ └── Contents.json
│ │ ├── tumblr-photo.imageset
│ │ │ ├── tumblr-photo.png
│ │ │ └── Contents.json
│ │ ├── tumblr-quote.imageset
│ │ │ ├── tumblr-quote.png
│ │ │ └── Contents.json
│ │ ├── google.imageset
│ │ │ ├── googlelogo_color_272x92dp.png
│ │ │ └── Contents.json
│ │ └── AppIcon.appiconset
│ │ │ └── Contents.json
│ ├── AppDelegate.h
│ ├── main.m
│ ├── AppDelegate.m
│ ├── Info.plist
│ └── Base.lproj
│ │ └── LaunchScreen.xib
├── ThirtyDaysOfReactNativeTests
│ ├── Info.plist
│ └── ThirtyDaysOfReactNativeTests.m
└── ThirtyDaysOfReactNative.xcodeproj
│ └── xcshareddata
│ └── xcschemes
│ └── ThirtyDaysOfReactNative.xcscheme
├── package.json
├── .gitignore
├── .flowconfig
└── README.md
/.watchmanconfig:
--------------------------------------------------------------------------------
1 | {}
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | *.pbxproj -text
2 |
--------------------------------------------------------------------------------
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["react-native"]
3 | }
--------------------------------------------------------------------------------
/view/day12.js:
--------------------------------------------------------------------------------
1 | // create chart without library
--------------------------------------------------------------------------------
/android/.gradle/2.4/taskArtifacts/cache.properties:
--------------------------------------------------------------------------------
1 | #Wed Oct 05 20:01:44 MDT 2016
2 |
--------------------------------------------------------------------------------
/view/img/w2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangwei716/30-days-of-react-native/HEAD/view/img/w2.png
--------------------------------------------------------------------------------
/view/img/w3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangwei716/30-days-of-react-native/HEAD/view/img/w3.png
--------------------------------------------------------------------------------
/view/img/agrass.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangwei716/30-days-of-react-native/HEAD/view/img/agrass.png
--------------------------------------------------------------------------------
/view/img/day1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangwei716/30-days-of-react-native/HEAD/view/img/day1.png
--------------------------------------------------------------------------------
/view/img/day2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangwei716/30-days-of-react-native/HEAD/view/img/day2.png
--------------------------------------------------------------------------------
/view/img/day3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangwei716/30-days-of-react-native/HEAD/view/img/day3.png
--------------------------------------------------------------------------------
/view/img/sphere.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangwei716/30-days-of-react-native/HEAD/view/img/sphere.jpg
--------------------------------------------------------------------------------
/view/img/tumblr.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangwei716/30-days-of-react-native/HEAD/view/img/tumblr.png
--------------------------------------------------------------------------------
/view/img/moments.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangwei716/30-days-of-react-native/HEAD/view/img/moments.mp4
--------------------------------------------------------------------------------
/view/img/poincare.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangwei716/30-days-of-react-native/HEAD/view/img/poincare.png
--------------------------------------------------------------------------------
/view/img/tumblr-chat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangwei716/30-days-of-react-native/HEAD/view/img/tumblr-chat.png
--------------------------------------------------------------------------------
/view/img/tumblr-link.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangwei716/30-days-of-react-native/HEAD/view/img/tumblr-link.png
--------------------------------------------------------------------------------
/view/img/tumblr-text.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangwei716/30-days-of-react-native/HEAD/view/img/tumblr-text.png
--------------------------------------------------------------------------------
/view/img/tumblrblur.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangwei716/30-days-of-react-native/HEAD/view/img/tumblrblur.png
--------------------------------------------------------------------------------
/view/img/tumblr-audio.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangwei716/30-days-of-react-native/HEAD/view/img/tumblr-audio.png
--------------------------------------------------------------------------------
/view/img/tumblr-photo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangwei716/30-days-of-react-native/HEAD/view/img/tumblr-photo.png
--------------------------------------------------------------------------------
/view/img/tumblr-quote.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangwei716/30-days-of-react-native/HEAD/view/img/tumblr-quote.png
--------------------------------------------------------------------------------
/android/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | ThirtyDaysOfReactNative
3 |
4 |
--------------------------------------------------------------------------------
/ios/ThirtyDaysOfReactNative/Images.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangwei716/30-days-of-react-native/HEAD/android/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/Entypo.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangwei716/30-days-of-react-native/HEAD/android/app/src/main/assets/fonts/Entypo.ttf
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/Zocial.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangwei716/30-days-of-react-native/HEAD/android/app/src/main/assets/fonts/Zocial.ttf
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/Ionicons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangwei716/30-days-of-react-native/HEAD/android/app/src/main/assets/fonts/Ionicons.ttf
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/Octicons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangwei716/30-days-of-react-native/HEAD/android/app/src/main/assets/fonts/Octicons.ttf
--------------------------------------------------------------------------------
/android/.gradle/2.4/taskArtifacts/fileHashes.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangwei716/30-days-of-react-native/HEAD/android/.gradle/2.4/taskArtifacts/fileHashes.bin
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/EvilIcons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangwei716/30-days-of-react-native/HEAD/android/app/src/main/assets/fonts/EvilIcons.ttf
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/FontAwesome.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangwei716/30-days-of-react-native/HEAD/android/app/src/main/assets/fonts/FontAwesome.ttf
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/Foundation.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangwei716/30-days-of-react-native/HEAD/android/app/src/main/assets/fonts/Foundation.ttf
--------------------------------------------------------------------------------
/android/keystores/debug.keystore.properties:
--------------------------------------------------------------------------------
1 | key.store=debug.keystore
2 | key.alias=androiddebugkey
3 | key.store.password=android
4 | key.alias.password=android
5 |
--------------------------------------------------------------------------------
/android/.gradle/2.4/taskArtifacts/fileSnapshots.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangwei716/30-days-of-react-native/HEAD/android/.gradle/2.4/taskArtifacts/fileSnapshots.bin
--------------------------------------------------------------------------------
/android/.gradle/2.4/taskArtifacts/taskArtifacts.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangwei716/30-days-of-react-native/HEAD/android/.gradle/2.4/taskArtifacts/taskArtifacts.bin
--------------------------------------------------------------------------------
/android/app/src/main/assets/fonts/MaterialIcons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangwei716/30-days-of-react-native/HEAD/android/app/src/main/assets/fonts/MaterialIcons.ttf
--------------------------------------------------------------------------------
/android/.gradle/2.4/taskArtifacts/outputFileStates.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangwei716/30-days-of-react-native/HEAD/android/.gradle/2.4/taskArtifacts/outputFileStates.bin
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangwei716/30-days-of-react-native/HEAD/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangwei716/30-days-of-react-native/HEAD/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangwei716/30-days-of-react-native/HEAD/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangwei716/30-days-of-react-native/HEAD/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/.gradle/2.4/taskArtifacts/cache.properties.lock:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangwei716/30-days-of-react-native/HEAD/android/.gradle/2.4/taskArtifacts/cache.properties.lock
--------------------------------------------------------------------------------
/android/keystores/BUCK:
--------------------------------------------------------------------------------
1 | keystore(
2 | name = 'debug',
3 | store = 'debug.keystore',
4 | properties = 'debug.keystore.properties',
5 | visibility = [
6 | 'PUBLIC',
7 | ],
8 | )
9 |
--------------------------------------------------------------------------------
/ios/ThirtyDaysOfReactNative/Images.xcassets/gl.imageset/gl.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangwei716/30-days-of-react-native/HEAD/ios/ThirtyDaysOfReactNative/Images.xcassets/gl.imageset/gl.png
--------------------------------------------------------------------------------
/ios/ThirtyDaysOfReactNative/Images.xcassets/map.imageset/map.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangwei716/30-days-of-react-native/HEAD/ios/ThirtyDaysOfReactNative/Images.xcassets/map.imageset/map.png
--------------------------------------------------------------------------------
/ios/ThirtyDaysOfReactNative/Images.xcassets/w2.imageset/w2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangwei716/30-days-of-react-native/HEAD/ios/ThirtyDaysOfReactNative/Images.xcassets/w2.imageset/w2.png
--------------------------------------------------------------------------------
/ios/ThirtyDaysOfReactNative/Images.xcassets/w3.imageset/w3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangwei716/30-days-of-react-native/HEAD/ios/ThirtyDaysOfReactNative/Images.xcassets/w3.imageset/w3.png
--------------------------------------------------------------------------------
/ios/ThirtyDaysOfReactNative/Images.xcassets/day1.imageset/day1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangwei716/30-days-of-react-native/HEAD/ios/ThirtyDaysOfReactNative/Images.xcassets/day1.imageset/day1.png
--------------------------------------------------------------------------------
/ios/ThirtyDaysOfReactNative/Images.xcassets/day2.imageset/day2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangwei716/30-days-of-react-native/HEAD/ios/ThirtyDaysOfReactNative/Images.xcassets/day2.imageset/day2.png
--------------------------------------------------------------------------------
/ios/ThirtyDaysOfReactNative/Images.xcassets/day3.imageset/day3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangwei716/30-days-of-react-native/HEAD/ios/ThirtyDaysOfReactNative/Images.xcassets/day3.imageset/day3.png
--------------------------------------------------------------------------------
/ios/ThirtyDaysOfReactNative/Images.xcassets/icon.imageset/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangwei716/30-days-of-react-native/HEAD/ios/ThirtyDaysOfReactNative/Images.xcassets/icon.imageset/icon.png
--------------------------------------------------------------------------------
/ios/ThirtyDaysOfReactNative/Images.xcassets/agrass.imageset/agrass.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangwei716/30-days-of-react-native/HEAD/ios/ThirtyDaysOfReactNative/Images.xcassets/agrass.imageset/agrass.png
--------------------------------------------------------------------------------
/ios/ThirtyDaysOfReactNative/Images.xcassets/banner.imageset/banner.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangwei716/30-days-of-react-native/HEAD/ios/ThirtyDaysOfReactNative/Images.xcassets/banner.imageset/banner.png
--------------------------------------------------------------------------------
/ios/ThirtyDaysOfReactNative/Images.xcassets/packed.imageset/packed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangwei716/30-days-of-react-native/HEAD/ios/ThirtyDaysOfReactNative/Images.xcassets/packed.imageset/packed.png
--------------------------------------------------------------------------------
/ios/ThirtyDaysOfReactNative/Images.xcassets/tumblr.imageset/tumblr.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangwei716/30-days-of-react-native/HEAD/ios/ThirtyDaysOfReactNative/Images.xcassets/tumblr.imageset/tumblr.png
--------------------------------------------------------------------------------
/ios/ThirtyDaysOfReactNative/Images.xcassets/desktop.imageset/desktop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangwei716/30-days-of-react-native/HEAD/ios/ThirtyDaysOfReactNative/Images.xcassets/desktop.imageset/desktop.png
--------------------------------------------------------------------------------
/ios/ThirtyDaysOfReactNative/Images.xcassets/minion1.imageset/minion1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangwei716/30-days-of-react-native/HEAD/ios/ThirtyDaysOfReactNative/Images.xcassets/minion1.imageset/minion1.png
--------------------------------------------------------------------------------
/ios/ThirtyDaysOfReactNative/Images.xcassets/minion2.imageset/minion2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangwei716/30-days-of-react-native/HEAD/ios/ThirtyDaysOfReactNative/Images.xcassets/minion2.imageset/minion2.png
--------------------------------------------------------------------------------
/ios/ThirtyDaysOfReactNative/Images.xcassets/minion3.imageset/minion3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangwei716/30-days-of-react-native/HEAD/ios/ThirtyDaysOfReactNative/Images.xcassets/minion3.imageset/minion3.png
--------------------------------------------------------------------------------
/ios/ThirtyDaysOfReactNative/Images.xcassets/minion4.imageset/minion4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangwei716/30-days-of-react-native/HEAD/ios/ThirtyDaysOfReactNative/Images.xcassets/minion4.imageset/minion4.png
--------------------------------------------------------------------------------
/ios/ThirtyDaysOfReactNative/Images.xcassets/minion5.imageset/minion5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangwei716/30-days-of-react-native/HEAD/ios/ThirtyDaysOfReactNative/Images.xcassets/minion5.imageset/minion5.png
--------------------------------------------------------------------------------
/ios/ThirtyDaysOfReactNative/Images.xcassets/moreinfo.imageset/moreinfo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangwei716/30-days-of-react-native/HEAD/ios/ThirtyDaysOfReactNative/Images.xcassets/moreinfo.imageset/moreinfo.png
--------------------------------------------------------------------------------
/ios/ThirtyDaysOfReactNative/Images.xcassets/bannerBlur.imageset/bannerBlur.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangwei716/30-days-of-react-native/HEAD/ios/ThirtyDaysOfReactNative/Images.xcassets/bannerBlur.imageset/bannerBlur.png
--------------------------------------------------------------------------------
/ios/ThirtyDaysOfReactNative/Images.xcassets/tumblrblur.imageset/tumblrblur.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangwei716/30-days-of-react-native/HEAD/ios/ThirtyDaysOfReactNative/Images.xcassets/tumblrblur.imageset/tumblrblur.png
--------------------------------------------------------------------------------
/ios/ThirtyDaysOfReactNative/Images.xcassets/tumblr-chat.imageset/tumblr-chat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangwei716/30-days-of-react-native/HEAD/ios/ThirtyDaysOfReactNative/Images.xcassets/tumblr-chat.imageset/tumblr-chat.png
--------------------------------------------------------------------------------
/ios/ThirtyDaysOfReactNative/Images.xcassets/tumblr-link.imageset/tumblr-link.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangwei716/30-days-of-react-native/HEAD/ios/ThirtyDaysOfReactNative/Images.xcassets/tumblr-link.imageset/tumblr-link.png
--------------------------------------------------------------------------------
/ios/ThirtyDaysOfReactNative/Images.xcassets/tumblr-text.imageset/tumblr-text.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangwei716/30-days-of-react-native/HEAD/ios/ThirtyDaysOfReactNative/Images.xcassets/tumblr-text.imageset/tumblr-text.png
--------------------------------------------------------------------------------
/ios/ThirtyDaysOfReactNative/Images.xcassets/tumblr-audio.imageset/tumblr-audio.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangwei716/30-days-of-react-native/HEAD/ios/ThirtyDaysOfReactNative/Images.xcassets/tumblr-audio.imageset/tumblr-audio.png
--------------------------------------------------------------------------------
/ios/ThirtyDaysOfReactNative/Images.xcassets/tumblr-photo.imageset/tumblr-photo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangwei716/30-days-of-react-native/HEAD/ios/ThirtyDaysOfReactNative/Images.xcassets/tumblr-photo.imageset/tumblr-photo.png
--------------------------------------------------------------------------------
/ios/ThirtyDaysOfReactNative/Images.xcassets/tumblr-quote.imageset/tumblr-quote.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangwei716/30-days-of-react-native/HEAD/ios/ThirtyDaysOfReactNative/Images.xcassets/tumblr-quote.imageset/tumblr-quote.png
--------------------------------------------------------------------------------
/ios/ThirtyDaysOfReactNative/Images.xcassets/google.imageset/googlelogo_color_272x92dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fangwei716/30-days-of-react-native/HEAD/ios/ThirtyDaysOfReactNative/Images.xcassets/google.imageset/googlelogo_color_272x92dp.png
--------------------------------------------------------------------------------
/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | zipStoreBase=GRADLE_USER_HOME
4 | zipStorePath=wrapper/dists
5 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.4-all.zip
6 |
--------------------------------------------------------------------------------
/view/dayTemplate.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Day
3 | *
4 | */
5 | 'use strict';
6 |
7 | import React,{ Component } from 'react';
8 | import { Image,StyleSheet,Text,TouchableHighlight,View } from 'react-native';
9 | import Util from './utils';
10 |
11 | export default class extends Component{
12 | render() {
13 | return(
14 |
15 | )
16 | }
17 | }
18 |
19 | const styles = StyleSheet.create({
20 |
21 | });
22 |
23 |
--------------------------------------------------------------------------------
/ios/ThirtyDaysOfReactNative/Images.xcassets/day1.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "day1.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/ios/ThirtyDaysOfReactNative/Images.xcassets/day2.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "day2.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/ios/ThirtyDaysOfReactNative/Images.xcassets/day3.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "day3.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/ios/ThirtyDaysOfReactNative/Images.xcassets/gl.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "gl.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/ios/ThirtyDaysOfReactNative/Images.xcassets/icon.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "icon.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/ios/ThirtyDaysOfReactNative/Images.xcassets/map.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "map.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/ios/ThirtyDaysOfReactNative/Images.xcassets/w2.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "w2.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/ios/ThirtyDaysOfReactNative/Images.xcassets/w3.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "w3.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/ios/ThirtyDaysOfReactNative/Images.xcassets/agrass.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "agrass.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/ios/ThirtyDaysOfReactNative/Images.xcassets/banner.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "banner.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/ios/ThirtyDaysOfReactNative/Images.xcassets/packed.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "packed.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/ios/ThirtyDaysOfReactNative/Images.xcassets/tumblr.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "tumblr.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/ios/ThirtyDaysOfReactNative/Images.xcassets/desktop.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "desktop.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/ios/ThirtyDaysOfReactNative/Images.xcassets/minion1.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "minion1.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/ios/ThirtyDaysOfReactNative/Images.xcassets/minion2.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "minion2.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/ios/ThirtyDaysOfReactNative/Images.xcassets/minion3.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "minion3.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/ios/ThirtyDaysOfReactNative/Images.xcassets/minion4.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "minion4.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/ios/ThirtyDaysOfReactNative/Images.xcassets/minion5.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "minion5.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/ios/ThirtyDaysOfReactNative/Images.xcassets/moreinfo.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "moreinfo.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/ios/ThirtyDaysOfReactNative/Images.xcassets/bannerBlur.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "bannerBlur.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/ios/ThirtyDaysOfReactNative/Images.xcassets/tumblr-chat.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "tumblr-chat.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/ios/ThirtyDaysOfReactNative/Images.xcassets/tumblr-link.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "tumblr-link.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/ios/ThirtyDaysOfReactNative/Images.xcassets/tumblr-text.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "tumblr-text.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/ios/ThirtyDaysOfReactNative/Images.xcassets/tumblrblur.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "tumblrblur.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/ios/ThirtyDaysOfReactNative/Images.xcassets/tumblr-audio.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "tumblr-audio.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/ios/ThirtyDaysOfReactNative/Images.xcassets/tumblr-photo.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "tumblr-photo.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/ios/ThirtyDaysOfReactNative/Images.xcassets/tumblr-quote.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "tumblr-quote.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/ios/ThirtyDaysOfReactNative/Images.xcassets/google.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "googlelogo_color_272x92dp.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/ios/ThirtyDaysOfReactNative/AppDelegate.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2015-present, Facebook, Inc.
3 | * All rights reserved.
4 | *
5 | * This source code is licensed under the BSD-style license found in the
6 | * LICENSE file in the root directory of this source tree. An additional grant
7 | * of patent rights can be found in the PATENTS file in the same directory.
8 | */
9 |
10 | #import
11 |
12 | @interface AppDelegate : UIResponder
13 |
14 | @property (nonatomic, strong) UIWindow *window;
15 |
16 | @end
17 |
--------------------------------------------------------------------------------
/ios/ThirtyDaysOfReactNative/main.m:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2015-present, Facebook, Inc.
3 | * All rights reserved.
4 | *
5 | * This source code is licensed under the BSD-style license found in the
6 | * LICENSE file in the root directory of this source tree. An additional grant
7 | * of patent rights can be found in the PATENTS file in the same directory.
8 | */
9 |
10 | #import
11 |
12 | #import "AppDelegate.h"
13 |
14 | int main(int argc, char * argv[]) {
15 | @autoreleasepool {
16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/android/app/src/main/java/com/thirtydaysofreactnative/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.thirtydaysofreactnative;
2 |
3 | import com.facebook.react.ReactActivity;
4 | import com.brentvatne.react.ReactVideoPackage;
5 | import com.oblador.vectoricons.VectorIconsPackage;
6 |
7 | public class MainActivity extends ReactActivity {
8 |
9 | /**
10 | * Returns the name of the main component registered from JavaScript.
11 | * This is used to schedule rendering of the component.
12 | */
13 | @Override
14 | protected String getMainComponentName() {
15 | return "ThirtyDaysOfReactNative";
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | repositories {
5 | jcenter()
6 | }
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:1.3.1'
9 |
10 | // NOTE: Do not place your application dependencies here; they belong
11 | // in the individual module build.gradle files
12 | }
13 | }
14 |
15 | allprojects {
16 | repositories {
17 | mavenLocal()
18 | jcenter()
19 | maven {
20 | // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
21 | url "$rootDir/../node_modules/react-native/android"
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/view/day29.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Day 29
3 | * 3D Touch
4 | * in the index file
5 | */
6 |
7 | 'use strict';
8 |
9 | import React,{ Component } from 'react';
10 | import { Image,StyleSheet,Text,TouchableHighlight,View } from 'react-native';
11 | import Util from './utils';
12 |
13 | export default class extends Component{
14 | render() {
15 | return(
16 |
17 | Try 3D Touch on the home screen icon
18 |
19 | )
20 | }
21 | }
22 |
23 | const styles = StyleSheet.create({
24 | container:{
25 | width: Util.size.width,
26 | height: Util.size.height,
27 | alignItems:"center",
28 | justifyContent: "center"
29 | },
30 | text:{
31 | fontSize:20,
32 | }
33 | });
34 |
35 |
36 |
--------------------------------------------------------------------------------
/view/day4.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Day 4
3 | * bridge to cocoapods
4 | */
5 | 'use strict';
6 |
7 | import React,{ Component } from 'react';
8 | import { Image,StyleSheet,TouchableHighlight,View } from 'react-native';
9 |
10 |
11 | export default class extends Component{
12 | constructor() {
13 | super();
14 | this.state = {
15 | show:false
16 | };
17 | }
18 |
19 | _onImgPress() {
20 | this.setState({
21 | show:false
22 | })
23 | this.setState({
24 | show:true
25 | })
26 | }
27 |
28 | render() {
29 | return(
30 |
31 |
32 | )
33 | }
34 | }
35 |
36 | const styles = StyleSheet.create({
37 | img:{
38 | height: 200,
39 | width: 300
40 | },
41 | });
42 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ThirtyDaysOfReactNative",
3 | "version": "0.0.1",
4 | "private": true,
5 | "author": "fangwei716",
6 | "scripts": {
7 | "start": "node node_modules/react-native/local-cli/cli.js start"
8 | },
9 | "dependencies": {
10 | "gl-react": "^2.2.8",
11 | "gl-react-native": "^2.34.0",
12 | "react": "^15.4.2",
13 | "react-native": "^0.40.0",
14 | "react-native-chart": "^1.0.8-beta",
15 | "react-native-gesture-password": "^0.2.0",
16 | "react-native-linear-gradient": "^1.5.13",
17 | "react-native-maps": "^0.11.0",
18 | "react-native-scrollable-tab-view": "0.6.0",
19 | "react-native-swipe-cards": "0.0.9",
20 | "react-native-swiper": "^1.4.9",
21 | "react-native-vector-icons": "^4.3.0",
22 | "react-native-video": "^0.9.0"
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/view/public/demo2.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Poincare Disk demo
6 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/android/settings.gradle:
--------------------------------------------------------------------------------
1 | rootProject.name = 'ThirtyDaysOfReactNative'
2 |
3 | include ':app'
4 | include ':react-native-linear-gradient'
5 | project(':react-native-linear-gradient').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-linear-gradient/android')
6 | include ':gl-react-native'
7 | project(':gl-react-native').projectDir = new File(rootProject.projectDir, '../node_modules/gl-react-native/android')
8 | include ':react-native-video'
9 | project(':react-native-video').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-video/android')
10 | include ':react-native-vector-icons'
11 | project(':react-native-vector-icons').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-vector-icons/android')
12 | include ':RNGL'
13 | project(':RNGL').projectDir = file('../node_modules/gl-react-native/android')
--------------------------------------------------------------------------------
/view/public/demo1.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Poincare Disk demo
6 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/ios/ThirtyDaysOfReactNativeTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/android/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m
13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
19 |
20 | android.useDeprecatedNdk=true
21 |
--------------------------------------------------------------------------------
/ios/ThirtyDaysOfReactNative/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | }
43 | ],
44 | "info" : {
45 | "version" : 1,
46 | "author" : "xcode"
47 | }
48 | }
--------------------------------------------------------------------------------
/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
9 |
12 |
13 |
19 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/android/app/src/main/java/com/thirtydaysofreactnative/MainApplication.java:
--------------------------------------------------------------------------------
1 | package com.thirtydaysofreactnative;
2 |
3 | import android.app.Application;
4 | import android.util.Log;
5 |
6 | import com.facebook.react.ReactApplication;
7 | import com.BV.LinearGradient.LinearGradientPackage;
8 | import com.projectseptember.RNGL.RNGLPackage;
9 | import com.facebook.react.ReactInstanceManager;
10 | import com.facebook.react.ReactNativeHost;
11 | import com.facebook.react.ReactPackage;
12 | import com.facebook.react.shell.MainReactPackage;
13 | import com.facebook.soloader.SoLoader;
14 |
15 | import java.util.Arrays;
16 | import java.util.List;
17 |
18 | public class MainApplication extends Application implements ReactApplication {
19 |
20 | private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
21 | @Override
22 | protected boolean getUseDeveloperSupport() {
23 | return BuildConfig.DEBUG;
24 | }
25 |
26 | @Override
27 | protected List getPackages() {
28 | return Arrays.asList(
29 | new MainReactPackage(),
30 | new LinearGradientPackage(),
31 | new RNGLPackage()
32 | );
33 | }
34 | };
35 |
36 | @Override
37 | public ReactNativeHost getReactNativeHost() {
38 | return mReactNativeHost;
39 | }
40 |
41 | @Override
42 | public void onCreate() {
43 | super.onCreate();
44 | SoLoader.init(this, /* native exopackage */ false);
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/view/utils.js:
--------------------------------------------------------------------------------
1 | // obtained from react native tutorials
2 |
3 | import React from 'react';
4 | import { PixelRatio } from 'react-native';
5 | import Dimensions from 'Dimensions';
6 |
7 | const Util = {
8 | ratio: PixelRatio.get(),
9 | pixel: 1 / PixelRatio.get(),
10 | size: {
11 | width: Dimensions.get('window').width,
12 | height: Dimensions.get('window').height
13 | },
14 | post(url, data, callback) {
15 | const fetchOptions = {
16 | method: 'POST',
17 | headers: {
18 | 'Accept': 'application/json',
19 | 'Content-Type': 'application/json'
20 | },
21 | body: JSON.stringify(data)
22 | };
23 |
24 | fetch(url, fetchOptions)
25 | .then((response) => {
26 | return response.json()
27 | })
28 | .then((responseData) => {
29 | callback(responseData);
30 | });
31 | },
32 | key: 'BDKHFSDKJFHSDKFHWEFH-REACT-NATIVE',
33 | };
34 |
35 |
36 | // import {StyleSheet, Platform} from 'react-native';
37 |
38 | // export function create(styles: Object): {[name: string]: number} {
39 | // const platformStyles = {};
40 | // Object.keys(styles).forEach((name) => {
41 | // let {ios, android, ...style} = {...styles[name]};
42 | // if (ios && Platform.OS === 'ios') {
43 | // style = {...style, ...ios};
44 | // }
45 | // if (android && Platform.OS === 'android') {
46 | // style = {...style, ...android};
47 | // }
48 | // platformStyles[name] = style;
49 | // });
50 | // return StyleSheet.create(platformStyles);
51 | // }
52 |
53 | export default Util;
--------------------------------------------------------------------------------
/ios/ThirtyDaysOfReactNative/AppDelegate.m:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2015-present, Facebook, Inc.
3 | * All rights reserved.
4 | *
5 | * This source code is licensed under the BSD-style license found in the
6 | * LICENSE file in the root directory of this source tree. An additional grant
7 | * of patent rights can be found in the PATENTS file in the same directory.
8 | */
9 |
10 | #import "AppDelegate.h"
11 |
12 | #import
13 | #import
14 |
15 | @implementation AppDelegate
16 |
17 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
18 | {
19 | NSURL *jsCodeLocation;
20 |
21 | jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index.ios" fallbackResource:nil];
22 |
23 | RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
24 | moduleName:@"ThirtyDaysOfReactNative"
25 | initialProperties:nil
26 | launchOptions:launchOptions];
27 | rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1];
28 |
29 | self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
30 | UIViewController *rootViewController = [UIViewController new];
31 | rootViewController.view = rootView;
32 | self.window.rootViewController = rootViewController;
33 | [self.window makeKeyAndVisible];
34 | return YES;
35 | }
36 |
37 | @end
38 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 |
6 | # Runtime data
7 | pids
8 | *.pid
9 | *.seed
10 |
11 | # Directory for instrumented libs generated by jscoverage/JSCover
12 | lib-cov
13 |
14 | # Coverage directory used by tools like istanbul
15 | coverage
16 |
17 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
18 | .grunt
19 |
20 | # node-waf configuration
21 | .lock-wscript
22 |
23 | # Compiled binary addons (http://nodejs.org/api/addons.html)
24 | build/Release
25 |
26 | # Dependency directory
27 | node_modules
28 |
29 | # Optional npm cache directory
30 | .npm
31 |
32 | # Optional REPL history
33 | .node_repl_history
34 |
35 |
36 | # OSX
37 | #
38 | .DS_Store
39 |
40 | # Xcode
41 | #
42 | build/
43 | *.pbxuser
44 | !default.pbxuser
45 | *.mode1v3
46 | !default.mode1v3
47 | *.mode2v3
48 | !default.mode2v3
49 | *.perspectivev3
50 | !default.perspectivev3
51 | xcuserdata
52 | *.xccheckout
53 | *.moved-aside
54 | DerivedData
55 | *.hmap
56 | *.ipa
57 | *.xcuserstate
58 | <<<<<<< ours
59 | project.xcworkspace
60 | =======
61 | project.xcworkspace
62 |
63 | # Android/IntelliJ
64 | #
65 | build/
66 | .idea
67 | .gradle
68 | local.properties
69 | *.iml
70 |
71 | # node.js
72 | #
73 | node_modules/
74 | npm-debug.log
75 |
76 | # BUCK
77 | buck-out/
78 | \.buckd/
79 | android/app/libs
80 | *.keystore
81 |
82 | # fastlane
83 | #
84 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
85 | # screenshots whenever they are needed.
86 | # For more information about the recommended setup visit:
87 | # https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md
88 |
89 | fastlane/report.xml
90 | fastlane/Preview.html
91 | fastlane/screenshots
92 | >>>>>>> theirs
93 |
--------------------------------------------------------------------------------
/android/app/BUCK:
--------------------------------------------------------------------------------
1 | import re
2 |
3 | # To learn about Buck see [Docs](https://buckbuild.com/).
4 | # To run your application with Buck:
5 | # - install Buck
6 | # - `npm start` - to start the packager
7 | # - `cd android`
8 | # - `keytool -genkey -v -keystore keystores/debug.keystore -storepass android -alias androiddebugkey -keypass android -dname "CN=Android Debug,O=Android,C=US"`
9 | # - `./gradlew :app:copyDownloadableDepsToLibs` - make all Gradle compile dependencies available to Buck
10 | # - `buck install -r android/app` - compile, install and run application
11 | #
12 |
13 | lib_deps = []
14 | for jarfile in glob(['libs/*.jar']):
15 | name = 'jars__' + re.sub(r'^.*/([^/]+)\.jar$', r'\1', jarfile)
16 | lib_deps.append(':' + name)
17 | prebuilt_jar(
18 | name = name,
19 | binary_jar = jarfile,
20 | )
21 |
22 | for aarfile in glob(['libs/*.aar']):
23 | name = 'aars__' + re.sub(r'^.*/([^/]+)\.aar$', r'\1', aarfile)
24 | lib_deps.append(':' + name)
25 | android_prebuilt_aar(
26 | name = name,
27 | aar = aarfile,
28 | )
29 |
30 | android_library(
31 | name = 'all-libs',
32 | exported_deps = lib_deps
33 | )
34 |
35 | android_library(
36 | name = 'app-code',
37 | srcs = glob([
38 | 'src/main/java/**/*.java',
39 | ]),
40 | deps = [
41 | ':all-libs',
42 | ':build_config',
43 | ':res',
44 | ],
45 | )
46 |
47 | android_build_config(
48 | name = 'build_config',
49 | package = 'com.thirtydaysofreactnative',
50 | )
51 |
52 | android_resource(
53 | name = 'res',
54 | res = 'src/main/res',
55 | package = 'com.thirtydaysofreactnative',
56 | )
57 |
58 | android_binary(
59 | name = 'app',
60 | package_type = 'debug',
61 | manifest = 'src/main/AndroidManifest.xml',
62 | keystore = '//android/keystores:debug',
63 | deps = [
64 | ':app-code',
65 | ],
66 | )
67 |
--------------------------------------------------------------------------------
/view/day25.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Day 25
3 | * custom refresh control
4 | * react-native-webbrowser has name space comflicts
5 | * use the module directly
6 | */
7 |
8 | 'use strict';
9 |
10 | import React,{ Component } from 'react';
11 | import { Image,StyleSheet,Text,TouchableHighlight,ActionSheetIOS,View } from 'react-native';
12 | import Util from './utils';
13 | // import Webbrowser from 'react-native-webbrowser';
14 | import Icon from 'react-native-vector-icons/Ionicons';
15 |
16 | export default class extends Component{
17 | _showShareActionSheet() {
18 | console.log(this.refs.browser.state.status);
19 | ActionSheetIOS.showShareActionSheetWithOptions({
20 | url: this.refs.browser.state.currentUrl,
21 | message: this.refs.browser.state.status,
22 | },
23 | (error) => console.log(error),
24 | (success, method) => {
25 | });
26 | }
27 |
28 | render() {
29 | return (
30 |
31 | this._showShareActionSheet()}>
32 |
33 |
34 |
35 | );
36 | }
37 | }
38 |
39 | //
50 |
51 | const styles = StyleSheet.create({
52 | shareIcon:{
53 | position:"absolute",
54 | bottom:0,
55 | left: Util.size.width/2-15,
56 | }
57 | });
58 |
59 |
--------------------------------------------------------------------------------
/view/public/js/sphere.js:
--------------------------------------------------------------------------------
1 | var width = 480,
2 | height = 500,
3 | rotate = [10, -10],
4 | velocity = [.003, -.001],
5 | time = Date.now();
6 |
7 | var projection = d3.geo.orthographic()
8 | .scale(160)
9 | .translate([width / 2, height / 2])
10 | .clipAngle(90 + 1e-6)
11 | .precision(.3);
12 |
13 | var path = d3.geo.path()
14 | .projection(projection);
15 |
16 | var graticule = d3.geo.graticule();
17 |
18 | var m0, o0;
19 |
20 | var drag = d3.behavior.drag()
21 | .on("dragstart", function() {
22 | var proj = projection.rotate();
23 | m0 = [d3.event.sourceEvent.pageX, d3.event.sourceEvent.pageY];
24 | o0 = [-proj[0],-proj[1]];
25 | })
26 | .on("drag", function() {
27 | var m1 = [d3.event.sourceEvent.pageX, d3.event.sourceEvent.pageY],
28 | o1 = [o0[0] + (m1[0] - m0[0]) / 4, o0[1] + (m1[1] - m0[1]) / 4];
29 | projection.rotate([o1[0], -o1[1]]);
30 | path = d3.geo.path().projection(projection);
31 | svg.selectAll("path").attr("d", path);
32 | });
33 |
34 | var svg = d3.select("#sphere").append("svg")
35 | .attr("width", width)
36 | .attr("height", height)
37 | .call(drag);
38 |
39 | svg.append("path")
40 | .datum({type: "Sphere"})
41 | .attr("class", "sphere")
42 | .attr("d", path);
43 |
44 | svg.append("path")
45 | .datum(graticule)
46 | .attr("class", "graticule")
47 | .attr("d", path);
48 |
49 | svg.append("path")
50 | .datum({type: "LineString", coordinates: [[-180, 0], [-90, 0], [0, 0], [90, 0], [180, 0]]})
51 | .attr("class", "equator")
52 | .attr("d", path);
53 |
54 | // var feature = svg.selectAll("path");
55 |
56 | // d3.timer(function() {
57 | // var dt = Date.now() - time;
58 | // projection.rotate([rotate[0] + velocity[0] * dt, rotate[1] + velocity[1] * dt]);
59 | // feature.attr("d", path);
60 | // });
--------------------------------------------------------------------------------
/view/day19.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Day 19
3 | *
4 | */
5 | 'use strict';
6 |
7 | import React,{ Component } from 'react';
8 | import { Image,StyleSheet,StatusBar,Text,AlertIOS,TouchableHighlight,View } from 'react-native';
9 | import Util from './utils';
10 | // import TouchID from 'react-native-touch-id';
11 | import { EnterPassword } from './day16'
12 |
13 | class Main extends Component{
14 | componentDidMount() {
15 | StatusBar.setBarStyle(0);
16 | }
17 |
18 | render() {
19 | return(
20 |
21 | You are in Day19
22 |
23 | );
24 | }
25 | }
26 |
27 | class RequireTouchID extends Component{
28 | constructor() {
29 | super();
30 | this.state = {
31 | enterApp: false
32 | }
33 | }
34 |
35 | componentDidMount() {
36 | StatusBar.setBarStyle(1);
37 | this._touchID();
38 | }
39 |
40 | _enterPassword(){
41 | this.setState({
42 | enterApp: true,
43 | });
44 | }
45 |
46 | _touchID = () => {
47 | TouchID.authenticate('Unlock Day19')
48 | .then(success => {
49 | this.setState({
50 | enterApp: true,
51 | })
52 | })
53 | .catch(error => {
54 |
55 | });
56 | };
57 |
58 | render() {
59 | return (
60 |
61 | { this.state.enterApp?
62 | :
63 | this._enterPassword()} password="123"/>
64 | }
65 |
66 | );
67 | }
68 | }
69 |
70 | export default class extends Component{
71 | render() {
72 | return(
73 |
74 | )
75 | }
76 | }
77 | //
78 |
79 | const styles = StyleSheet.create({
80 | container:{
81 | backgroundColor:"transparent",
82 | height: Util.size.height,
83 | width: Util.size.width,
84 | },
85 | main:{
86 | justifyContent: "center",
87 | alignItems: "center",
88 | height: Util.size.height,
89 | width: Util.size.width,
90 | },
91 | text:{
92 | fontSize: 30
93 | },
94 | });
95 |
96 |
--------------------------------------------------------------------------------
/ios/ThirtyDaysOfReactNative/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | NSAppTransportSecurity
26 |
27 | NSExceptionDomains
28 |
29 | localhost
30 |
31 | NSTemporaryExceptionAllowsInsecureHTTPLoads
32 |
33 |
34 |
35 |
36 | NSLocationWhenInUseUsageDescription
37 |
38 | UIAppFonts
39 |
40 | Entypo.ttf
41 | EvilIcons.ttf
42 | FontAwesome.ttf
43 | Foundation.ttf
44 | Ionicons.ttf
45 | MaterialIcons.ttf
46 | Octicons.ttf
47 | Zocial.ttf
48 |
49 | UILaunchStoryboardName
50 | LaunchScreen
51 | UIRequiredDeviceCapabilities
52 |
53 | armv7
54 |
55 | UISupportedInterfaceOrientations
56 |
57 | UIInterfaceOrientationPortrait
58 | UIInterfaceOrientationLandscapeLeft
59 | UIInterfaceOrientationLandscapeRight
60 |
61 | UIViewControllerBasedStatusBarAppearance
62 |
63 | NSPhotoLibraryUsageDescription
64 | need access
65 |
66 |
--------------------------------------------------------------------------------
/ios/ThirtyDaysOfReactNativeTests/ThirtyDaysOfReactNativeTests.m:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2015-present, Facebook, Inc.
3 | * All rights reserved.
4 | *
5 | * This source code is licensed under the BSD-style license found in the
6 | * LICENSE file in the root directory of this source tree. An additional grant
7 | * of patent rights can be found in the PATENTS file in the same directory.
8 | */
9 |
10 | #import
11 | #import
12 |
13 | #import
14 | #import
15 |
16 | #define TIMEOUT_SECONDS 600
17 | #define TEXT_TO_LOOK_FOR @"Welcome to React Native!"
18 |
19 | @interface ThirtyDaysOfReactNativeTests : XCTestCase
20 |
21 | @end
22 |
23 | @implementation ThirtyDaysOfReactNativeTests
24 |
25 | - (BOOL)findSubviewInView:(UIView *)view matching:(BOOL(^)(UIView *view))test
26 | {
27 | if (test(view)) {
28 | return YES;
29 | }
30 | for (UIView *subview in [view subviews]) {
31 | if ([self findSubviewInView:subview matching:test]) {
32 | return YES;
33 | }
34 | }
35 | return NO;
36 | }
37 |
38 | - (void)testRendersWelcomeScreen
39 | {
40 | UIViewController *vc = [[[[UIApplication sharedApplication] delegate] window] rootViewController];
41 | NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS];
42 | BOOL foundElement = NO;
43 |
44 | __block NSString *redboxError = nil;
45 | RCTSetLogFunction(^(RCTLogLevel level, RCTLogSource source, NSString *fileName, NSNumber *lineNumber, NSString *message) {
46 | if (level >= RCTLogLevelError) {
47 | redboxError = message;
48 | }
49 | });
50 |
51 | while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) {
52 | [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
53 | [[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
54 |
55 | foundElement = [self findSubviewInView:vc.view matching:^BOOL(UIView *view) {
56 | if ([view.accessibilityLabel isEqualToString:TEXT_TO_LOOK_FOR]) {
57 | return YES;
58 | }
59 | return NO;
60 | }];
61 | }
62 |
63 | RCTSetLogFunction(RCTDefaultLogFunction);
64 |
65 | XCTAssertNil(redboxError, @"RedBox error: %@", redboxError);
66 | XCTAssertTrue(foundElement, @"Couldn't find element with text '%@' in %d seconds", TEXT_TO_LOOK_FOR, TIMEOUT_SECONDS);
67 | }
68 |
69 |
70 | @end
71 |
--------------------------------------------------------------------------------
/view/public/js/poincare-disk.js:
--------------------------------------------------------------------------------
1 | var R = 200,
2 | xoff = 50,
3 | yoff = 50;
4 |
5 | var tooltip = d3.select("body")
6 | .append("div")
7 | .style("position", "absolute")
8 | .style("z-index", "10")
9 | .style("visibility", "hidden")
10 | .style("background","rgba(0,0,0,0.7)")
11 | .style("padding","5px")
12 | .style("border-radius","2px")
13 | .style("width","250px")
14 | .style("color","#fff")
15 | .text("a simple tooltip")
16 |
17 | var vis = d3.select("#vis")
18 | .on("mousewheel", blockScroll)
19 | .on("DOMMouseScroll", blockScroll)
20 | .append("svg")
21 | .attr("width", "100%")
22 | .attr("height", "100%")
23 | .attr("pointer-events", "all")
24 | .call(d3.behavior.zoom()
25 | .on("zoom", redraw))
26 | .append("g");
27 |
28 | vis.append("circle")
29 | .attr("class", "line")
30 | .attr("cx", R + xoff)
31 | .attr("cy", R + yoff)
32 | .attr("r", R)
33 |
34 | for (var s=1.5; s<=144; s*=2) {
35 | for (var q1=0; q1<2*Math.PI; q1+=Math.PI/s) {
36 | var q2 = q1 + Math.PI/s;
37 | drawLine(q1, q2);
38 | }
39 | }
40 |
41 | function redraw() {
42 | vis
43 | .attr("transform",
44 | "translate(" + d3.event.translate + ")"
45 | + "scale(" + d3.event.scale + ")")
46 | .style("stroke-width", 1/d3.event.scale);
47 | }
48 |
49 | function drawArc(x1, y1, x2, y2, r1, r2) {
50 | vis.append("path")
51 | .attr("class", "line")
52 | .attr("d", "M" + x1 + "," + y1 + " " +
53 | "A" + r1 + "," + r2 + " 0 0,1 " +
54 | x2 + "," + y2)
55 | .on("mouseover", function(){
56 | return tooltip.style("visibility", "visible")
57 | .text("points:("+Math.floor(x1)+" ,"+Math.floor(y1)+") &("+Math.floor(x2)+" ,"+Math.floor(y2)+") with radius: "+r1);
58 | })
59 | .on("mousemove", function(){return tooltip.style("top", (event.pageY-10)+"px").style("left",(event.pageX+10)+"px");})
60 | .on("mouseout", function(){return tooltip.style("visibility", "hidden");});
61 | }
62 |
63 | function drawLine(q1, q2) {
64 | var f = (q2 - q1) / 2,
65 | dq = Math.abs(f),
66 | r = R * Math.tan(dq),
67 | rp = Math.sqrt(r * r + R * R),
68 | cx = xoff + R + rp * Math.cos(q1 + f),
69 | cy = yoff + R + rp * Math.sin(q1 + f),
70 | beta = Math.PI - dq * 2,
71 | k = Math.PI / 2 + q2;
72 | drawArc(cx + r * Math.cos(k), cy + r * Math.sin(k),
73 | cx + r * Math.cos(k + beta), cy + r * Math.sin(k + beta),
74 | r, r);
75 | }
76 |
77 | function blockScroll() { d3.event.preventDefault(); }
78 |
--------------------------------------------------------------------------------
/android/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
19 | # Disabling obfuscation is useful if you collect stack traces from production crashes
20 | # (unless you are using a system that supports de-obfuscate the stack traces).
21 | -dontobfuscate
22 |
23 | # React Native
24 |
25 | # Keep our interfaces so they can be used by other ProGuard rules.
26 | # See http://sourceforge.net/p/proguard/bugs/466/
27 | -keep,allowobfuscation @interface com.facebook.proguard.annotations.DoNotStrip
28 | -keep,allowobfuscation @interface com.facebook.proguard.annotations.KeepGettersAndSetters
29 | -keep,allowobfuscation @interface com.facebook.common.internal.DoNotStrip
30 |
31 | # Do not strip any method/class that is annotated with @DoNotStrip
32 | -keep @com.facebook.proguard.annotations.DoNotStrip class *
33 | -keep @com.facebook.common.internal.DoNotStrip class *
34 | -keepclassmembers class * {
35 | @com.facebook.proguard.annotations.DoNotStrip *;
36 | @com.facebook.common.internal.DoNotStrip *;
37 | }
38 |
39 | -keepclassmembers @com.facebook.proguard.annotations.KeepGettersAndSetters class * {
40 | void set*(***);
41 | *** get*();
42 | }
43 |
44 | -keep class * extends com.facebook.react.bridge.JavaScriptModule { *; }
45 | -keep class * extends com.facebook.react.bridge.NativeModule { *; }
46 | -keepclassmembers,includedescriptorclasses class * { native ; }
47 | -keepclassmembers class * { @com.facebook.react.uimanager.UIProp ; }
48 | -keepclassmembers class * { @com.facebook.react.uimanager.annotations.ReactProp ; }
49 | -keepclassmembers class * { @com.facebook.react.uimanager.annotations.ReactPropGroup ; }
50 |
51 | -dontwarn com.facebook.react.**
52 |
53 | # okhttp
54 |
55 | -keepattributes Signature
56 | -keepattributes *Annotation*
57 | -keep class okhttp3.** { *; }
58 | -keep interface okhttp3.** { *; }
59 | -dontwarn okhttp3.**
60 |
61 | # okio
62 |
63 | -keep class sun.misc.Unsafe { *; }
64 | -dontwarn java.nio.file.*
65 | -dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement
66 | -dontwarn okio.**
67 |
--------------------------------------------------------------------------------
/android/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/view/day17.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Day 17
3 | * search bar
4 | */
5 | 'use strict';
6 |
7 | import React,{ Component } from 'react';
8 | import { Image,StyleSheet,Text,TouchableHighlight,ScrollView,View } from 'react-native';
9 | import Util from './utils';
10 | // import SearchBar from 'react-native-search-bar';
11 | // import fuzzy from 'fuzzy';
12 |
13 | export default class extends Component{
14 | constructor() {
15 | super();
16 |
17 | const stateData = {"AL": "Alabama","AK": "Alaska","AS": "American Samoa","AZ": "Arizona","AR": "Arkansas","CA": "California","CO": "Colorado","CT": "Connecticut","DE": "Delaware","DC": "District Of Columbia","FM": "Federated States Of Micronesia","FL": "Florida","GA": "Georgia","GU": "Guam","HI": "Hawaii","ID": "Idaho","IL": "Illinois","IN": "Indiana","IA": "Iowa","KS": "Kansas","KY": "Kentucky","LA": "Louisiana","ME": "Maine","MH": "Marshall Islands","MD": "Maryland","MA": "Massachusetts","MI": "Michigan","MN": "Minnesota","MS": "Mississippi","MO": "Missouri","MT": "Montana","NE": "Nebraska","NV": "Nevada","NH": "New Hampshire","NJ": "New Jersey","NM": "New Mexico","NY": "New York","NC": "North Carolina","ND": "North Dakota","MP": "Northern Mariana Islands","OH": "Ohio","OK": "Oklahoma","OR": "Oregon","PW": "Palau","PA": "Pennsylvania","PR": "Puerto Rico","RI": "Rhode Island","SC": "South Carolina","SD": "South Dakota","TN": "Tennessee","TX": "Texas","UT": "Utah","VT": "Vermont","VI": "Virgin Islands","VA": "Virginia","WA": "Washington","WV": "West Virginia","WI": "Wisconsin","WY": "Wyoming"}
18 | this.states = [];
19 | for (let key in stateData) {
20 | if (stateData.hasOwnProperty(key)) {
21 | this.states.push(stateData[key]);
22 | }
23 | }
24 |
25 | this.state = {
26 | states: this.states,
27 | };
28 | }
29 |
30 | _onChangeText(text) {
31 | let results = fuzzy.filter(text, this.states)
32 | let matches = results.map(function(el) { return el.string; });
33 | this.setState({
34 | states: matches,
35 | })
36 | }
37 |
38 | render() {
39 | const statesList = this.state.states.map(function(elem, index) {
40 | return {elem};
41 | })
42 |
43 | return(
44 |
45 | {statesList}
46 |
47 | )
48 | }
49 | }
50 |
51 | // this._onChangeText(text)}
55 | // />
56 |
57 | const styles = StyleSheet.create({
58 | container:{
59 | backgroundColor:"#ffffff",
60 | marginTop: 63
61 | },
62 | list:{
63 | height:40,
64 | paddingLeft:20,
65 | justifyContent:"center",
66 | borderBottomColor:"#aaa",
67 | borderBottomWidth: Util.pixel,
68 | }
69 | });
70 |
71 |
--------------------------------------------------------------------------------
/view/day27.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Day 27
3 | * imessage gradient color
4 | * demo purpuses only
5 | * use https://github.com/tstone/Gradient.js to generate more color options
6 | */
7 | 'use strict';
8 |
9 | import React,{ Component } from 'react';
10 | import { findNodeHandle,Image,StyleSheet,Text,TouchableHighlight,ScrollView,View } from 'react-native';
11 | import Util from './utils';
12 | import LinearGradient from 'react-native-linear-gradient';
13 | import { UIManager } from 'NativeModules';
14 |
15 | export default class extends Component{
16 | constructor() {
17 | super();
18 | this.state = {
19 | color: [['rgba(32,138,246,0.9)', 'rgba(32,138,246,0.92)', 'rgba(32,138,246,0.95)'],['rgba(32,138,246,0.92)', 'rgba(32,138,246,0.95)', 'rgba(32,138,246,0.98)'],['rgba(32,138,246,0.96)', 'rgba(32,138,246,0.98)', 'rgba(32,138,246,1)']],
20 | msg:["An iMessage Gradient effect","Color should change by scroll pageY","testing..."],
21 | }
22 | }
23 |
24 | _handleScroll = (event) => {
25 | for (var i = this.state.msg.length-1; i >= 0; i--) {
26 | this._changeColor(i);
27 | }
28 | };
29 |
30 | _changeColor = (index)=> {
31 | const wHeight = Util.size.height;
32 | let view = this.refs['msg'+index]; // Where view is a ref obtained through
33 | let handle = findNodeHandle(view);
34 | UIManager.measure(handle, (x, y, width, height, pageX, pageY) => {
35 | let initOpacity = Math.pow((pageY/wHeight),2) + 0.5;
36 | let colors = ['rgba(32,138,246,'+initOpacity+')', 'rgba(32,138,246,'+(initOpacity+0.05)+')', 'rgba(32,138,246,'+(initOpacity+0.1)+')'];
37 | let color = this.state.color;
38 | color[index] = colors;
39 | this.setState({
40 | color: color,
41 | })
42 | })
43 | };
44 |
45 | render() {
46 | const {color,msg} = this.state;
47 | const total = msg.length;
48 | const linears = msg.map((elem, index) => {
49 | return (
50 |
51 | {elem}
52 |
53 | );
54 | })
55 | return(
56 |
57 |
58 | {linears}
59 |
60 |
61 | )
62 | }
63 | }
64 |
65 | const styles = StyleSheet.create({
66 | container:{
67 | backgroundColor:"#ffffff",
68 | },
69 | linearGradient: {
70 | // width:90,s
71 | height: 26,
72 | paddingLeft: 15,
73 | paddingRight: 15,
74 | borderRadius: 13,
75 | alignItems:"center",
76 | justifyContent: "center",
77 | position:"absolute",
78 | right:10,
79 | },
80 | text:{
81 | color:"#fff",
82 | backgroundColor:"transparent",
83 | }
84 | });
85 |
86 |
--------------------------------------------------------------------------------
/view/day30.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Day 30
3 | * push notification
4 | */
5 | 'use strict';
6 |
7 | import React,{ Component } from 'react';
8 | import { PushNotificationIOS,StyleSheet,Text,TouchableHighlight,View } from 'react-native';
9 | import Util from './utils';
10 |
11 | class Button extends Component{
12 | render() {
13 | return (
14 |
18 |
19 | {this.props.label}
20 |
21 |
22 | );
23 | }
24 | }
25 |
26 | export default class extends Component{
27 | componentWillMount() {
28 | PushNotificationIOS.addEventListener('notification', this._onNotification);
29 | }
30 |
31 | componentWillUnmount() {
32 | PushNotificationIOS.removeEventListener('notification', this._onNotification);
33 | }
34 |
35 | _onNotification(notification) {
36 |
37 | PushNotificationIOS.presentLocalNotification({
38 | alertBody:notification.getMessage(),
39 | });
40 | let numOfBadge = PushNotificationIOS.getApplicationIconBadgeNumber((num) => {
41 | let add = parseInt(notification.getBadgeCount(), 10);
42 | PushNotificationIOS.setApplicationIconBadgeNumber(num+add);
43 | });
44 |
45 | }
46 |
47 | _sendNotification() {
48 | require('RCTDeviceEventEmitter').emit('remoteNotificationReceived', {
49 | aps: {
50 | alert: 'This is the 30th day of this project',
51 | badge: '1',
52 | sound: 'default',
53 | },
54 | });
55 | }
56 |
57 | render() {
58 | PushNotificationIOS.requestPermissions();
59 | return (
60 |
61 |
77 | );
78 | }
79 | }
80 |
81 | var styles = StyleSheet.create({
82 | container:{
83 | paddingTop:80,
84 | height: Util.size.height,
85 | width: Util.size.width,
86 | alignItems: 'center',
87 | justifyContent: 'center',
88 | backgroundColor: "#fff"
89 | },
90 | button: {
91 | padding: 10,
92 | width: Util.size.width-80,
93 | height:40,
94 | borderRadius:5,
95 | alignItems: 'center',
96 | justifyContent: 'center',
97 | marginBottom:20,
98 | },
99 | buttonLabel: {
100 | color: '#fff',
101 | },
102 | });
103 |
104 |
105 |
106 |
107 |
108 |
--------------------------------------------------------------------------------
/view/day5.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Day 5
3 | * find my location
4 | */
5 | 'use strict';
6 |
7 | import React,{ Component } from 'react';
8 | import { Platform,Image,MapView,StatusBar,StyleSheet,Text,TouchableHighlight,View } from 'react-native';
9 | import Util from './utils';
10 | import Icon from 'react-native-vector-icons/Ionicons';
11 |
12 | export class Map extends Component{
13 | static defaultProps = {
14 | mapType: 'standard',
15 | showsUserLocation: false,
16 | followUserLocation: false,
17 | };
18 |
19 | static propTypes = {
20 | mapType: React.PropTypes.oneOf(['standard', 'satellite','hybrid']),
21 | // mapStyle: View.PropTypes.style,
22 | showsUserLocation: React.PropTypes.bool.isRequired,
23 | followUserLocation: React.PropTypes.bool.isRequired,
24 | };
25 |
26 | constructor() {
27 | super();
28 | this.state = {
29 | isFirstLoad: true,
30 | mapRegion: undefined,
31 | annotations: [],
32 | };
33 | }
34 |
35 | _getAnnotations(region) {
36 | return [{
37 | longitude: region.longitude,
38 | latitude: region.latitude,
39 | title: 'You Are Here',
40 | }];
41 | }
42 |
43 | _onRegionChangeComplete(region) {
44 | if (this.state.isFirstLoad) {
45 | this.setState({
46 | annotations: this._getAnnotations(region),
47 | isFirstLoad: false,
48 | });
49 | }
50 | }
51 |
52 | render() {
53 | return(
54 |
55 | this._onRegionChangeComplete(region)}
61 | region={this.state.mapRegion}
62 | annotations={this.state.annotations}/>
63 |
64 | )
65 | }
66 | }
67 |
68 | export default class extends Component{
69 | constructor() {
70 | super();
71 | this.state = {
72 | showGeo:false
73 | };
74 | }
75 |
76 | componentDidMount() {
77 | if(Platform.OS === "ios"){
78 | StatusBar.setBarStyle(0);
79 | }
80 | }
81 |
82 | _getLocation() {
83 | this.setState({
84 | showGeo: true
85 | })
86 | }
87 |
88 | render() {
89 | return(
90 |
91 |
92 | this._getLocation()}>
93 | Find my location
94 |
95 |
96 | )
97 | }
98 | }
99 |
100 | const styles = StyleSheet.create({
101 | container:{
102 | alignItems: "center",
103 | paddingTop: 60
104 | },
105 | map:{
106 | width: Util.size.width,
107 | height: Util.size.height-120
108 | },
109 | btn:{
110 | backgroundColor:"#00a803",
111 | width: Util.size.width-80,
112 | height: 40,
113 | borderWidth:Util.pixel,
114 | borderColor: "#009302",
115 | borderRadius: 4,
116 | justifyContent:"center",
117 | marginTop:10
118 | },
119 | btnText:{
120 | textAlign:"center",
121 | fontSize:18,
122 | color:"#fff"
123 | },
124 | });
--------------------------------------------------------------------------------
/.flowconfig:
--------------------------------------------------------------------------------
1 | [ignore]
2 | <<<<<<< ours
3 |
4 | # We fork some components by platform.
5 | .*/*.web.js
6 | .*/*.android.js
7 |
8 | # Some modules have their own node_modules with overlap
9 | .*/node_modules/node-haste/.*
10 |
11 | # Ugh
12 | .*/node_modules/babel.*
13 | .*/node_modules/babylon.*
14 | .*/node_modules/invariant.*
15 |
16 | # Ignore react and fbjs where there are overlaps, but don't ignore
17 | # anything that react-native relies on
18 | .*/node_modules/fbjs/lib/Map.js
19 | .*/node_modules/fbjs/lib/Promise.js
20 | .*/node_modules/fbjs/lib/fetch.js
21 | .*/node_modules/fbjs/lib/ExecutionEnvironment.js
22 | .*/node_modules/fbjs/lib/isEmpty.js
23 | .*/node_modules/fbjs/lib/crc32.js
24 | .*/node_modules/fbjs/lib/ErrorUtils.js
25 |
26 | # Flow has a built-in definition for the 'react' module which we prefer to use
27 | # over the currently-untyped source
28 | .*/node_modules/react/react.js
29 | .*/node_modules/react/lib/React.js
30 | .*/node_modules/react/lib/ReactDOM.js
31 |
32 | # Ignore commoner tests
33 | .*/node_modules/commoner/test/.*
34 |
35 | # See https://github.com/facebook/flow/issues/442
36 | .*/react-tools/node_modules/commoner/lib/reader.js
37 |
38 | # Ignore jest
39 | .*/node_modules/jest-cli/.*
40 |
41 | # Ignore Website
42 | .*/website/.*
43 | =======
44 | ; We fork some components by platform
45 | .*/*[.]android.js
46 |
47 | ; Ignore "BUCK" generated dirs
48 | /\.buckd/
49 |
50 | ; Ignore unexpected extra "@providesModule"
51 | .*/node_modules/.*/node_modules/fbjs/.*
52 |
53 | ; Ignore duplicate module providers
54 | ; For RN Apps installed via npm, "Libraries" folder is inside
55 | ; "node_modules/react-native" but in the source repo it is in the root
56 | .*/Libraries/react-native/React.js
57 | .*/Libraries/react-native/ReactNative.js
58 | >>>>>>> theirs
59 |
60 | [include]
61 |
62 | [libs]
63 | node_modules/react-native/Libraries/react-native/react-native-interface.js
64 |
65 | [options]
66 | module.system=haste
67 |
68 | <<<<<<< ours
69 | munge_underscores=true
70 |
71 | module.name_mapper='^image![a-zA-Z0-9$_-]+$' -> 'GlobalImageStub'
72 | 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\)$' -> 'RelativeImageStub'
73 | =======
74 | experimental.strict_type_args=true
75 |
76 | munge_underscores=true
77 |
78 | 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'
79 | >>>>>>> theirs
80 |
81 | suppress_type=$FlowIssue
82 | suppress_type=$FlowFixMe
83 | suppress_type=$FixMe
84 |
85 | <<<<<<< ours
86 | suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(2[0-1]\\|1[0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)
87 | suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(2[0-1]\\|1[0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)?:? #[0-9]+
88 | =======
89 | suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(3[0-6]\\|[1-2][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)
90 | suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(3[0-6]\\|1[0-9]\\|[1-2][0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)?:? #[0-9]+
91 | >>>>>>> theirs
92 | suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy
93 |
94 | [version]
95 | <<<<<<< ours
96 | 0.21.0
97 | =======
98 | ^0.36.0
99 | >>>>>>> theirs
100 |
--------------------------------------------------------------------------------
/view/day21.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Day 21
3 | *
4 | */
5 | 'use strict';
6 |
7 | import React,{ Component } from 'react';
8 | import { Image,StyleSheet,Text,StatusBar,TouchableHighlight,LayoutAnimation,View } from 'react-native';
9 | import Util from './utils';
10 | import { ReminderContainer } from './day20';
11 |
12 | export default class extends Component{
13 | constructor() {
14 | super();
15 | this.listData = [{
16 | title:"Scheduled",
17 | numOfItems:0,
18 | theme:"#979797",
19 | list:[],
20 | },{
21 | title:"Movie",
22 | numOfItems:0,
23 | theme:"#cb7adf",
24 | list:[],
25 | },{
26 | title:"Work",
27 | numOfItems:0,
28 | theme:"#f9005f",
29 | list:[],
30 | },{
31 | title:"Home",
32 | numOfItems:0,
33 | theme:"#00a8f4",
34 | list:[],
35 | },{
36 | title:"Reminder",
37 | numOfItems:0,
38 | theme:"#68d746",
39 | list:[],
40 | },{
41 | title:"Development",
42 | numOfItems:6,
43 | theme:"#fe952b",
44 | list:[{
45 | selected:false,
46 | text:"day20",
47 | },{
48 | selected:false,
49 | text:"day21",
50 | },{
51 | selected:false,
52 | text:"day22",
53 | },{
54 | selected:false,
55 | text:"day23",
56 | },{
57 | selected:false,
58 | text:"day24",
59 | },{
60 | selected:false,
61 | text:"day25",
62 | }],
63 | }];
64 |
65 | this.animations = {
66 | duration: 200,
67 | create: {
68 | type: LayoutAnimation.Types.linear,
69 | },
70 | update: {
71 | type: LayoutAnimation.Types.linear,
72 | springDamping: 0.5,
73 | },
74 | };
75 |
76 | this.state = {
77 | isOn: this.isOn,
78 | init: true,
79 | };
80 | }
81 |
82 | componentDidMount() {
83 | StatusBar.setBarStyle(1);
84 | }
85 |
86 | _switch(index){
87 | const isOn = this.listData.map(() => {
88 | return false;
89 | });
90 | isOn[index] = true;
91 | this.setState({
92 | isOn,
93 | init:false
94 | });
95 | LayoutAnimation.configureNext(this.animations);
96 | }
97 |
98 | _reset() {
99 | const isOn = this.listData.map(() => {
100 | return false;
101 | });
102 | this.setState({
103 | isOn,
104 | init:true
105 | });
106 | LayoutAnimation.configureNext(this.animations);
107 | }
108 |
109 | render() {
110 | const len = this.listData.length;
111 | const lists = this.listData.map((elem,index) => {
112 | return this._switch(index)} key={"list"+index} listData={elem} listStyle={this.state.init?{top:20+index*65}:{top:this.state.isOn[index]? 20:Util.size.height+5*index-5*len}}/>;
113 | })
114 |
115 | return(
116 |
117 |
118 |
119 | {lists}
120 | this._reset()}>
121 |
122 |
123 |
124 | );
125 | }
126 | }
127 |
128 | const styles = StyleSheet.create({
129 | container:{
130 | height: Util.size.height,
131 | width: Util.size.width,
132 | },
133 | reset:{
134 | height:30,
135 | width:Util.size.width,
136 | position:"absolute",
137 | bottom:0,
138 | left:0,
139 | }
140 | });
141 |
142 |
--------------------------------------------------------------------------------
/view/day23.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Day 23
3 | * local webview
4 | * D3.js
5 | */
6 | 'use strict';
7 |
8 | import React,{ Component } from 'react';
9 | import { StyleSheet,TouchableHighlight,NavigatorIOS,Image,Text,View,WebView } from 'react-native';
10 | import Util from './utils';
11 | import Icon from 'react-native-vector-icons/Ionicons';
12 |
13 | class Poincare extends Component{
14 | render() {
15 | return(
16 |
24 | )
25 | }
26 | }
27 |
28 | class Sphere extends Component{
29 | render() {
30 | return(
31 |
39 | )
40 | }
41 | }
42 |
43 | export default class extends Component{
44 | _show(index) {
45 | if (index) {
46 | this.props.navigator.push({
47 | index: 231,
48 | title: "Sphere",
49 | component: Sphere,
50 | hideNav: false,
51 | })
52 | }else{
53 | this.props.navigator.push({
54 | index: 232,
55 | title: "Poincare",
56 | component: Poincare,
57 | hideNav: false,
58 | })
59 | }
60 | }
61 |
62 | render() {
63 | return(
64 |
65 | this._show(0)}>
66 |
67 |
68 |
69 | Poincaré Disk
70 |
71 |
72 |
73 |
74 | this._show(1)}>
75 |
76 |
77 |
78 | Sphere
79 |
80 |
81 |
82 |
83 |
84 | );
85 | }
86 | }
87 |
88 | const styles = StyleSheet.create({
89 | container:{
90 | flex:1,
91 | backgroundColor: "#ffffff"
92 | },
93 | itemWrapper:{
94 | backgroundColor: '#f3f3f3'
95 | },
96 | menu:{
97 | paddingTop:80,
98 | backgroundColor: "#ffffff",
99 | width: Util.size.width,
100 | height: Util.size.height,
101 | },
102 | btn:{
103 | height: 100,
104 | marginBottom:20,
105 | width:375,
106 | },
107 | img:{
108 | height:100,
109 | width:375,
110 | resizeMode:"cover",
111 | },
112 | textContainer:{
113 | height:100,
114 | width:375,
115 | position:"absolute",
116 | top:0,
117 | left:0,
118 | backgroundColor:"rgba(0,0,0,0.3)",
119 | justifyContent:"center",
120 | },
121 | text:{
122 | color:"#fff",
123 | fontSize:25,
124 | fontWeight:"500",
125 | paddingLeft:20,
126 | },
127 | itemNav:{
128 | color:"#fff",
129 | position:"absolute",
130 | right:20,
131 | top:32
132 | }
133 | });
134 |
135 |
--------------------------------------------------------------------------------
/ios/ThirtyDaysOfReactNative/Base.lproj/LaunchScreen.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
21 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/view/day7.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Day 7
3 | * Basic pan gesture
4 | */
5 | 'use strict';
6 |
7 | import React,{ Component } from 'react';
8 | import { Platform,Image,StyleSheet,StatusBar,Text,TouchableHighlight,PanResponder,View } from 'react-native';
9 | import Util from './utils';
10 | import Icon from 'react-native-vector-icons/Ionicons';
11 |
12 | class MoveableCircle extends Component{
13 | constructor() {
14 | super();
15 | this.state = {
16 | color: "rgba(255,255,255,0.7)",
17 | };
18 | }
19 |
20 | _previousLeft = Util.size.width/2-40;
21 | _previousTop = Util.size.height/2-50;
22 | _maxTop = Util.size.height-110;
23 | _maxLeft = Util.size.width-98;
24 | _circleStyles = {};
25 | circle = (null : ?{ setNativeProps(props: Object): void });
26 |
27 | _updatePosition() {
28 | this.circle && this.circle.setNativeProps(this._circleStyles);
29 | }
30 |
31 | _endMove(evt, gestureState) {
32 | this._previousLeft += gestureState.dx;
33 | this._previousTop += gestureState.dy;
34 | this.setState({
35 | color: "rgba(255,255,255,0.7)"
36 | });
37 | }
38 |
39 | componentWillMount() {
40 | this._panResponder = PanResponder.create({
41 | onStartShouldSetPanResponder: (evt, gestureState) => true,
42 | onStartShouldSetPanResponderCapture: (evt, gestureState) => true,
43 | onMoveShouldSetPanResponder: (evt, gestureState) => true,
44 | onMoveShouldSetPanResponderCapture: (evt, gestureState) => true,
45 | onPanResponderGrant: (evt, gestureState) => {
46 | this.setState({
47 | color: "white",
48 | })
49 | },
50 | onPanResponderMove: (evt, gestureState) => {
51 | this._circleStyles.style.left = this._previousLeft + gestureState.dx;
52 | this._circleStyles.style.top = this._previousTop + gestureState.dy;
53 | if (this._circleStyles.style.left<0) {
54 | this._circleStyles.style.left = 0;
55 | };
56 | if (this._circleStyles.style.top<5) {
57 | this._circleStyles.style.top = 5;
58 | };
59 | if (this._circleStyles.style.left>this._maxLeft) {
60 | this._circleStyles.style.left = this._maxLeft;
61 | };
62 | if (this._circleStyles.style.top>this._maxTop) {
63 | this._circleStyles.style.top = this._maxTop;
64 | };
65 | this._updatePosition();
66 | },
67 | onPanResponderTerminationRequest: (evt, gestureState) => true,
68 | onPanResponderRelease: (evt, gestureState) => this._endMove(evt, gestureState),
69 | onPanResponderTerminate: (evt, gestureState) => this._endMove(evt, gestureState),
70 | });
71 |
72 | this._circleStyles = {
73 | style: {
74 | left: this._previousLeft,
75 | top: this._previousTop,
76 | },
77 | };
78 |
79 | }
80 |
81 | componentDidMount() {
82 | this._updatePosition();
83 | }
84 |
85 | render() {
86 | return(
87 | {this.circle = circle;}} style={styles.MoveableCircle} {...this._panResponder.panHandlers}>
88 |
89 |
90 | )
91 | }
92 | }
93 |
94 | export default class extends Component{
95 | componentWillMount() {
96 | if(Platform.OS === "ios"){
97 | StatusBar.setBarStyle(1);
98 | }
99 | }
100 |
101 | render() {
102 | return(
103 |
104 |
105 |
106 |
107 |
108 |
109 | )
110 | }
111 | }
112 |
113 | const styles = StyleSheet.create({
114 | container:{
115 | height:Util.size.height,
116 | width: Util.size.width
117 | },
118 | bg:{
119 | width: Util.size.width,
120 | resizeMode:"stretch",
121 | position:"absolute"
122 | },
123 | circleContainer:{
124 | height:Util.size.height,
125 | width: Util.size.width,
126 | },
127 | MoveableCircle:{
128 | backgroundColor:"transparent",
129 | position:"absolute",
130 | left:0,
131 | right:0
132 | },
133 | });
--------------------------------------------------------------------------------
/view/day15.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Day 15
3 | * pickerIOS, Modal
4 | */
5 | 'use strict';
6 |
7 | import React,{ Component } from 'react';
8 | import { Image,StyleSheet,StatusBar,Text,TouchableHighlight,Modal,View,DatePickerIOS } from 'react-native';
9 | import Util from './utils';
10 |
11 | export default class extends Component{
12 | constructor() {
13 | super();
14 |
15 | const date = new Date();
16 | const time = this._getTime(date);
17 | const timeZoneOffsetInHours= (-1) * (new Date()).getTimezoneOffset() / 60;
18 | let setDate = new Date();
19 | let showModal = false;
20 |
21 | this.state = {time,showModal,setDate,timeZoneOffsetInHours};
22 | }
23 |
24 | componentDidMount() {
25 | StatusBar.setBarStyle(0);
26 | }
27 |
28 | _getTime(date){
29 | const monthNames = [
30 | "January", "February", "March",
31 | "April", "May", "June", "July",
32 | "August", "September", "October",
33 | "November", "December"
34 | ];
35 | const day = date.getDate(),
36 | monthIndex = date.getMonth(),
37 | year = date.getFullYear(),
38 | hour = date.getHours(),
39 | minute = date.getMinutes();
40 | return day + ' ' + monthNames[monthIndex] + ' ' + year + " at "+(hour<10? "0"+hour:hour)+":"+(minute<10? "0"+minute:minute);
41 | }
42 |
43 | _pickTime(){
44 | this.setState({
45 | showModal:true,
46 | });
47 | }
48 |
49 | _setTime(){
50 | this.setState({
51 | time: this._getTime(this.state.setDate),
52 | showModal:false,
53 | });
54 | }
55 |
56 | _closeModal(){
57 | this.setState({showModal:false,});
58 | }
59 |
60 | _onDateChange(date) {
61 | this.setState({setDate: date,});
62 | }
63 |
64 | render() {
65 | return(
66 |
67 | {this.state.time}
68 | this._pickTime()}>
69 | change time
70 |
71 |
75 |
76 |
77 | this._closeModal()}>Cancle
78 | Choose a time
79 | this._setTime()}>Set
80 |
81 |
82 |
88 |
94 |
95 |
96 |
97 |
98 | )
99 | }
100 | }
101 |
102 | const styles = StyleSheet.create({
103 | container:{
104 | alignItems:"center",
105 | justifyContent:"center",
106 | height: Util.size.height,
107 | width: Util.size.width,
108 | paddingBottom:60,
109 | backgroundColor:"#ffffff"
110 | },
111 | date:{
112 | fontSize:25
113 | },
114 | btnText:{
115 | color:"#4285f4",
116 | fontSize:16,
117 | paddingTop:10,
118 | },
119 | modalContainer:{
120 | height: Util.size.height,
121 | width: Util.size.width,
122 | backgroundColor:"#f1f1f1"
123 | },
124 | modalNav:{
125 | position:"absolute",
126 | height:60,
127 | width:Util.size.width,
128 | backgroundColor:"#fff",
129 | flexDirection:"row",
130 | justifyContent:"space-between",
131 | paddingTop:20,
132 | paddingLeft:15,
133 | paddingRight:15
134 | },
135 | modalContent:{
136 | alignItems:"center",
137 | justifyContent:"center",
138 | width:Util.size.width,
139 | height:Util.size.height-60,
140 | marginTop:60
141 | },
142 | navTitle:{
143 | paddingTop:8,
144 | fontWeight:"500",
145 | color:"#222",
146 | fontSize:18
147 | },
148 | });
149 |
--------------------------------------------------------------------------------
/view/day16.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Day 16
3 | * Gesture unlock
4 | * https://github.com/spikef/react-native-gesture-password
5 | */
6 | 'use strict';
7 |
8 | import React,{ Component } from 'react';
9 | import { StatusBar,Image,StyleSheet,Text,View } from 'react-native';
10 | import Util from './utils';
11 | import PasswordGesture from 'react-native-gesture-password';
12 |
13 | export class EnterPassword extends Component{
14 | static propTypes = {
15 | password: React.PropTypes.string.isRequired,
16 | enterPassword: React.PropTypes.func.isRequired,
17 | };
18 |
19 | constructor(props) {
20 | super(props);
21 | this.state = {
22 | password: this.props.password,
23 | message: 'Unlock with your password.',
24 | status: 'normal',
25 | };
26 | }
27 |
28 | onEnd(password) {
29 | if (password == this.state.password) {
30 | this.setState({
31 | status: 'right',
32 | message: 'Password is right, success.'
33 | });
34 | this.props.enterPassword();
35 | } else {
36 | this.setState({
37 | status: 'wrong',
38 | message: 'Password is wrong, try again.'
39 | });
40 | }
41 | }
42 |
43 | onStart() {
44 | this.setState({
45 | status: 'normal',
46 | message: 'Unlock your password.'
47 | });
48 | }
49 |
50 | render() {
51 | return (
52 | this.onStart()}
59 | onEnd={(password) => this.onEnd(password)}
60 | />
61 | );
62 | }
63 | }
64 |
65 | class SetPassword extends Component{
66 | static propTypes = {
67 | password: React.PropTypes.string.isRequired,
68 | setPassword: React.PropTypes.func.isRequired,
69 | };
70 |
71 | constructor(props) {
72 | super(props);
73 | this.state = {
74 | password: this.props.password,
75 | message: 'Please set your password.',
76 | status: 'normal',
77 | };
78 | }
79 |
80 | onEnd(password) {
81 | if ( this.state.password === '' ) {
82 | this.state.password = password;
83 | this.setState({
84 | status: 'normal',
85 | message: 'Please input your password secondly.',
86 | });
87 | } else {
88 | if ( password === this.state.password ) {
89 | this.setState({
90 | status: 'right',
91 | message: 'Your password is set',
92 | });
93 | this.props.setPassword(password);
94 | } else {
95 | this.setState({
96 | status: 'wrong',
97 | message: 'Not the same, try again.',
98 | });
99 | }
100 | }
101 | }
102 |
103 | onStart() {
104 | if ( this.state.password === '') {
105 | this.setState({
106 | message: 'Please set your password.',
107 | });
108 | } else {
109 | this.setState({
110 | message: 'Please input your password secondly.',
111 | });
112 | }
113 | }
114 |
115 | render() {
116 | return (
117 | this.onStart()}
124 | onEnd={(password) => this.onEnd(password)}
125 | />
126 | );
127 | }
128 | }
129 |
130 | export default class extends Component{
131 | constructor() {
132 | super();
133 | this.state = {
134 | password: '',
135 | hasSet: false,
136 | enterApp: false,
137 | };
138 | }
139 |
140 | _setPassword(password) {
141 | this.setState({
142 | password: password,
143 | hasSet: true,
144 | })
145 | }
146 |
147 | _enterPassword(){
148 | this.setState({
149 | enterApp: true,
150 | });
151 | }
152 |
153 | componentDidMount() {
154 | StatusBar.setBarStyle(1);
155 | }
156 |
157 | render() {
158 | return(
159 |
160 | {this.state.hasSet?: this._setPassword(password)} password={this.state.password}/>}
161 | {this.state.hasSet&&!this.state.enterApp? this._enterPassword()} password={this.state.password}/>:}
162 | {this.state.enterApp?You are in the app!:}
163 |
164 | )
165 | }
166 | }
167 |
168 | const styles = StyleSheet.create({
169 | container:{
170 | backgroundColor:"transparent",
171 | height: Util.size.height,
172 | width: Util.size.width,
173 | },
174 | setPg:{
175 | backgroundColor:"#012642",
176 | },
177 | app:{
178 | backgroundColor:"#012642",
179 | height: Util.size.height,
180 | width: Util.size.width,
181 | alignItems:"center",
182 | justifyContent:"center",
183 | },
184 | appText:{
185 | color:"#fff",
186 | fontSize:25,
187 | }
188 | });
189 |
190 |
--------------------------------------------------------------------------------
/view/day22.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Day 22
3 | *
4 | */
5 | 'use strict';
6 |
7 | import React,{ Component } from 'react';
8 | import { Image,StyleSheet,StatusBar,Text,TextInput,TouchableWithoutFeedback,Animated,Easing,View } from 'react-native';
9 | import Util from './utils';
10 | import Icon from 'react-native-vector-icons/Ionicons';
11 |
12 | export default class extends Component{
13 | constructor() {
14 | super();
15 |
16 | this.state = {
17 | scale: new Animated.Value(1),
18 | on: 0,
19 | scaleOn: 0,
20 | }
21 | }
22 |
23 | componentDidMount() {
24 | StatusBar.setBarStyle(0);
25 | }
26 |
27 | _onMic() {
28 | this.setState({
29 | on:1,
30 | });
31 | Animated.timing(
32 | this.state.scale,
33 | {toValue: 20,
34 | duration: 200,
35 | easing: Easing.elastic(1),
36 | },
37 | ).start(() => {
38 | this.setState({
39 | scaleOn:1,
40 | });
41 | });
42 | }
43 |
44 | _offMic() {
45 | this.setState({
46 | scaleOn:0,
47 | });
48 | Animated.timing(
49 | this.state.scale,
50 | {toValue: 1,
51 | duration: 200,
52 | easing: Easing.elastic(1),
53 | },
54 | ).start(() => {
55 | this.setState({
56 | on:0,
57 | });
58 | });
59 | }
60 |
61 | render() {
62 | return(
63 |
64 |
65 |
66 | SIGN IN
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 | this._onMic()}>
78 |
79 | {this.state.on?
80 |
81 |
82 | :
83 | }
84 |
85 |
86 |
87 |
88 | {this.state.scaleOn?
89 |
90 | Speak Now
91 | this._offMic()}>
92 |
93 |
94 | :
95 | }
96 |
97 | )
98 | }
99 | }
100 |
101 | const styles = StyleSheet.create({
102 | container:{
103 | height:Util.size.height,
104 | width:Util.size.width,
105 | paddingTop:30,
106 | backgroundColor:"#f2f2f2",
107 | },
108 | nav:{
109 | alignItems:"center",
110 | justifyContent:"space-between",
111 | height:30,
112 | flexDirection:"row",
113 | paddingLeft:25,
114 | paddingRight:25,
115 | },
116 | navText:{
117 | color:"#969696",
118 | fontSize:18,
119 | },
120 | content:{
121 | paddingTop: 120,
122 | },
123 | logo:{
124 | height:50,
125 | resizeMode:"contain"
126 | },
127 | btn:{
128 | width:Util.size.width,
129 | alignItems:"center",
130 | justifyContent:"center"
131 | },
132 | btnContent:{
133 | width:50,
134 | height:50,
135 | borderRadius:25,
136 | backgroundColor:"#fff",
137 | alignItems:"center",
138 | justifyContent:"center",
139 | shadowColor: "#000",
140 | shadowOpacity: 0.3,
141 | shadowRadius: 2,
142 | shadowOffset: {
143 | height: 1,
144 | width: 0,
145 | }
146 | },
147 | input:{
148 | width: Util.size.width-100,
149 | height: 40,
150 | paddingLeft:10,
151 | },
152 | inputContainer:{
153 | width: Util.size.width-80,
154 | height: 40,
155 | marginTop:40,
156 | marginBottom:40,
157 | backgroundColor:"#fff",
158 | shadowColor: "#888",
159 | shadowOpacity: 0.3,
160 | shadowRadius: 1,
161 | shadowOffset: {
162 | height: 1,
163 | width: 0,
164 | }
165 | },
166 | scaleText:{
167 | color:"#969696",
168 | fontSize:25,
169 | paddingLeft:25,
170 | paddingTop:50,
171 | backgroundColor:"#fff",
172 | },
173 | scaleContainer:{
174 | position: "absolute",
175 | height:Util.size.height,
176 | width:Util.size.width,
177 | top:0,
178 | left:0,
179 | },
180 | closeIcon:{
181 | height:50,
182 | width:50,
183 | position:"absolute",
184 | bottom: 0,
185 | left:30,
186 | backgroundColor:"#fff",
187 | }
188 | });
189 |
190 |
--------------------------------------------------------------------------------
/view/day11.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Day 11
3 | * OpenGL
4 | * Example from https://github.com/ProjectSeptemberInc/gl-react-native/blob/master/example/src/Simple/index.js
5 | */
6 | 'use strict';
7 |
8 | import React,{ Component } from 'react';
9 | import { Image,StyleSheet,Slider,StatusBar,Text,TouchableHighlight,View,ScrollView } from 'react-native';
10 | import Util from './utils';
11 | import GL from "gl-react";
12 | import { Surface } from "gl-react-native";
13 |
14 | const shaders = GL.Shaders.create({
15 | helloGL: {
16 | frag: `
17 | precision highp float;
18 | varying vec2 uv;
19 | uniform float value;
20 | void main () {
21 | gl_FragColor = vec4(uv.x, uv.y, value, 1.0);
22 | }
23 | `
24 | },
25 | saturation: {
26 | frag: `
27 | precision highp float;
28 | varying vec2 uv;
29 | uniform sampler2D image;
30 | uniform float factor;
31 | void main () {
32 | vec4 c = texture2D(image, uv);
33 | const vec3 W = vec3(0.2125, 0.7154, 0.0721);
34 | gl_FragColor = vec4(mix(vec3(dot(c.rgb, W)), c.rgb, factor), c.a);
35 | }
36 | `
37 | },
38 | pieProgress: {
39 | frag: `
40 | precision mediump float;
41 | varying vec2 uv;
42 | uniform vec4 colorInside, colorOutside;
43 | uniform float radius;
44 | uniform float progress;
45 | uniform vec2 dim;
46 | const vec2 center = vec2(0.5);
47 | const float PI = acos(-1.0);
48 | void main () {
49 | vec2 norm = dim / min(dim.x, dim.y);
50 | vec2 p = uv * norm - (norm-1.0)/2.0;
51 | vec2 delta = p - center;
52 | float inside =
53 | step(length(delta), radius) *
54 | step((PI + atan(delta.y, - 1.0 * delta.x)) / (2.0 * PI), progress);
55 | gl_FragColor = mix(
56 | colorOutside,
57 | colorInside,
58 | inside
59 | );
60 | }
61 | `
62 | }
63 | });
64 |
65 | const HelloGL = GL.createComponent(
66 | ({value}) =>
67 | ,
68 | { displayName: "HelloGL" }
69 | );
70 |
71 | const Saturation = GL.createComponent(
72 | ({ factor, image, ...rest }) =>
73 | ,
78 | { displayName: "Saturation" });
79 |
80 | const PieProgress = GL.createComponent(
81 | ({
82 | width,
83 | height,
84 | progress,
85 | colorInside,
86 | colorOutside,
87 | radius
88 | }) =>
89 | ,
99 | {
100 | displayName: "PieProgress",
101 | defaultProps: {
102 | colorInside: [0, 0, 0, 0],
103 | colorOutside: [0, 0, 0, 0.8],
104 | radius: 0.4
105 | }
106 | });
107 |
108 | export default class extends Component{
109 | constructor() {
110 | super();
111 | this.state = {
112 | value:0,
113 | saturationFactor:1,
114 | progress:0
115 | };
116 | }
117 |
118 | componentDidMount() {
119 | StatusBar.setBarStyle(0);
120 | }
121 |
122 | render() {
123 | let {value,saturationFactor,progress} = this.state;
124 | return(
125 |
126 | Gradients:
127 | this.setState({value: value})} />
131 |
132 |
135 |
136 | Satuation:
137 | this.setState({saturationFactor: value})} />
141 |
142 |
146 |
147 | Progress Pie:
148 | this.setState({progress: value})} />
152 |
153 |
154 |
155 |
156 | )
157 | }
158 | }
159 |
160 | const styles = StyleSheet.create({
161 | container:{
162 | marginTop: 63,
163 | backgroundColor:"#ffffff"
164 | },
165 | titleContainer:{
166 | alignItems:"center",
167 | borderTopWidth: Util.pixel,
168 | borderTopColor: "#aaa",
169 | borderBottomWidth: Util.pixel,
170 | borderBottomColor: "#aaa",
171 | paddingTop:5,
172 | paddingBottom:5
173 | },
174 | text:{
175 | fontSize:16,
176 | },
177 | });
178 |
--------------------------------------------------------------------------------
/view/day10.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Day 10
3 | *
4 | */
5 | 'use strict';
6 |
7 | import React,{ Component } from 'react';
8 | import { Image,StyleSheet,Text,TouchableWithoutFeedback,TouchableHighlight,StatusBar,Animated,Easing,View } from 'react-native';
9 | import Util from './utils';
10 | // import {BlurView} from 'react-native-blur';
11 |
12 | export default class extends Component{
13 | constructor() {
14 | super();
15 | this.state = {
16 | shift: new Animated.Value(-120),
17 | show:false,
18 | };
19 | }
20 |
21 | _pushMenu() {
22 | this.setState({
23 | show: true,
24 | });
25 |
26 | Animated.timing(
27 | this.state.shift,
28 | {toValue: Util.size.width === 375? 50:30,
29 | duration: 200,
30 | delay:100,
31 | easing: Easing.elastic(1),
32 | },
33 | ).start();
34 | }
35 |
36 | _popMenu() {
37 | Animated.timing(
38 | this.state.shift,
39 | {toValue: -120,
40 | duration: 200,
41 | delay:100,
42 | easing: Easing.elastic(1),
43 | },
44 | ).start();
45 |
46 | setTimeout(()=>{
47 | this.setState({
48 | show: false,
49 | })
50 | },500);
51 | }
52 |
53 | componentDidMount() {
54 | StatusBar.setBarStyle(1);
55 | }
56 |
57 | render() {
58 | return(
59 |
60 | this._pushMenu()}>
61 |
62 |
63 | {this.state.show?
64 |
65 |
66 |
67 | Text
68 |
69 |
70 |
71 | Photo
72 |
73 |
74 |
75 | Quote
76 |
77 |
78 |
79 | Link
80 |
81 |
82 |
83 | Chat
84 |
85 |
86 |
87 | Audio
88 |
89 | this._popMenu()}>
90 | NeverMind
91 |
92 | :
93 |
94 | }
95 |
96 | )
97 | }
98 | }
99 |
100 | const styles = StyleSheet.create({
101 | imgContainer:{
102 | height: Util.size.height,
103 | width: Util.size.width,
104 | position:"absolute",
105 | top:0,
106 | left:0
107 | },
108 | img:{
109 | resizeMode:"contain",
110 | height: Util.size.height-10,
111 | width: Util.size.width,
112 | marginTop:15
113 | },
114 | menu:{
115 | height: Util.size.height,
116 | width: Util.size.width,
117 | resizeMode:"cover",
118 | position:"absolute",
119 | top:0,
120 | left:0
121 | },
122 | blur:{
123 | height: Util.size.height,
124 | width: Util.size.width,
125 | },
126 | menuImg:{
127 | width:120,
128 | height:100,
129 | resizeMode:"contain",
130 | },
131 | menuText:{
132 | width:120,
133 | textAlign:"center",
134 | color:"#fff",
135 | backgroundColor: "transparent"
136 | },
137 | menuItem1:{
138 | position:"absolute",
139 | left: 50,
140 | top: 80
141 | },
142 | menuItem3:{
143 | position:"absolute",
144 | left:50,
145 | top: 250
146 | },
147 | menuItem5:{
148 | position:"absolute",
149 | left:50,
150 | top: 420
151 | },
152 | menuItem2:{
153 | position:"absolute",
154 | right:50,
155 | top: 80
156 | },
157 | menuItem4:{
158 | position:"absolute",
159 | right:50,
160 | top: 250
161 | },
162 | menuItem6:{
163 | position:"absolute",
164 | right:50,
165 | top: 420
166 | },
167 | dismissBtn:{
168 | position:"absolute",
169 | width:Util.size.width,
170 | left:0,
171 | bottom:50,
172 | },
173 | dismiss:{
174 | textAlign:"center",
175 | color:"rgba(255,255,255,0.2)",
176 | fontWeight:"700",
177 | backgroundColor: "transparent"
178 | },
179 | });
180 |
--------------------------------------------------------------------------------
/view/day26.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Day 26
3 | * swipe and switch
4 | */
5 | 'use strict';
6 |
7 | import React,{ Component } from 'react';
8 | import { Image,StyleSheet,Text,TouchableHighlight,LayoutAnimation,PanResponder,View } from 'react-native';
9 | import Util from './utils';
10 | import Day22 from './day22';
11 | import Day24 from './day24';
12 | import Day20 from './day20';
13 |
14 | class Menu extends Component{
15 | render() {
16 | return(
17 |
18 | this.props.getDay(0)}>
19 |
20 | Day 22
21 |
22 |
23 | this.props.getDay(1)}>
24 |
25 | Day 24
26 |
27 |
28 | this.props.getDay(2)}>
29 |
30 | Day 20
31 |
32 |
33 |
34 | )
35 | }
36 | }
37 |
38 | class Main extends Component{
39 | _previousLeft = 0;
40 | _maxLeft = 150;
41 | _mainStyles = {};
42 | main = (null : ?{ setNativeProps(props: Object): void });
43 | // _CustomLayoutLinear = {
44 | // duration: 200,
45 | // create: {
46 | // type: LayoutAnimation.Types.linear,
47 | // property: LayoutAnimation.Properties.left,
48 | // },
49 | // update: {
50 | // type: LayoutAnimation.Types.curveEaseInEaseOut,
51 | // },
52 | // };
53 | _CustomLayoutLinear = LayoutAnimation.Presets.linear;
54 |
55 | componentWillMount() {
56 | this._panResponder = PanResponder.create({
57 | onStartShouldSetPanResponder: (evt, gestureState) => true,
58 | onMoveShouldSetPanResponder: (evt, gestureState) => {
59 | // return gestureState.dy/gestureState.dx!=0;
60 | return true
61 | },
62 | onPanResponderGrant: (evt, gestureState) => {
63 | console.log("1")
64 | },
65 | onPanResponderMove: (evt, gestureState) => {
66 | this._mainStyles.style.left = this._previousLeft + gestureState.dx;
67 | if (this._mainStyles.style.left > this._maxLeft) {
68 | this._mainStyles.style.left = this._maxLeft;
69 | };
70 | if (this._mainStyles.style.left < 0) {
71 | this._mainStyles.style.left = 0;
72 | };
73 | this._updatePosition();
74 | LayoutAnimation.configureNext(this._CustomLayoutLinear);
75 | },
76 | onPanResponderTerminationRequest: (evt, gestureState) => true,
77 | onPanResponderRelease: (evt, gestureState) => this._endMove(evt, gestureState),
78 | onPanResponderTerminate: (evt, gestureState) => this._endMove(evt, gestureState),
79 | onShouldBlockNativeResponder: (event, gestureState) => true,
80 | });
81 |
82 | this._mainStyles = {
83 | style: {
84 | left: this._previousLeft,
85 | },
86 | };
87 | }
88 |
89 | _updatePosition() {
90 | this.main && this.main.setNativeProps(this._mainStyles);
91 | }
92 |
93 | _endMove(evt,gestureState) {
94 | if (this._mainStyles.style.left > this._maxLeft/2) {
95 | this._mainStyles.style.left = this._maxLeft;
96 | };
97 | if (this._mainStyles.style.left <= this._maxLeft/2) {
98 | this._mainStyles.style.left = 0;
99 | };
100 | this._updatePosition();
101 | LayoutAnimation.configureNext(this._CustomLayoutLinear);
102 | }
103 |
104 | componentWillReceiveProps() {
105 | this.main.setNativeProps({style:{left:0}});
106 | this._previousLeft = 0;
107 | LayoutAnimation.configureNext(LayoutAnimation.Presets.spring);
108 | }
109 |
110 | render() {
111 | const Day = this.props.day;
112 | return(
113 | {this.main = main;}} {...this._panResponder.panHandlers} style={styles.main}>
114 |
115 |
116 | )
117 | }
118 | }
119 |
120 | export default class extends Component{
121 | constructor(){
122 | super();
123 | this.state = {
124 | day: Day22,
125 | };
126 | }
127 |
128 | _getDay(index) {
129 | console.log("what")
130 | let day;
131 | switch(index){
132 | case 0:
133 | day = Day22;
134 | break;
135 | case 1:
136 | day = Day24;
137 | break;
138 | case 2:
139 | day = Day20;
140 | break;
141 | }
142 | this.setState({
143 | day,
144 | });
145 | }
146 |
147 | render() {
148 | return(
149 |
150 |
153 | )
154 | }
155 | }
156 |
157 | const styles = StyleSheet.create({
158 | menuContainer:{
159 | height: Util.size.height,
160 | width: Util.size.width,
161 | backgroundColor:"#893D54",
162 | justifyContent:"center",
163 | },
164 | menu:{
165 | height:50,
166 | justifyContent:"center",
167 | width:150,
168 | borderBottomColor:"#fff",
169 | borderBottomWidth: Util.pixel,
170 | },
171 | menuText:{
172 | color:"#fff",
173 | textAlign:"center",
174 | fontSize:18,
175 | },
176 | main:{
177 | width:Util.size.width,
178 | height: Util.size.height,
179 | position:"absolute",
180 | left:0,
181 | top:0,
182 | backgroundColor:"#fff",
183 | }
184 | });
185 |
186 |
--------------------------------------------------------------------------------
/view/day6.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Day 6
3 | * spotify welcome screen
4 | */
5 | 'use strict';
6 |
7 | import React,{ Component } from 'react';
8 | import { Animated,Image,ScrollView,StatusBar,StyleSheet,Text,TouchableHighlight,View } from 'react-native';
9 | import Video from 'react-native-video';
10 | import Util from './utils';
11 | import Swiper from 'react-native-swiper';
12 | import Icon from 'react-native-vector-icons/FontAwesome';
13 |
14 | class Intro extends Component{
15 | render() {
16 | return(
17 |
18 |
19 |
20 |
21 |
22 |
23 | Spotify
24 |
25 |
26 |
27 | }
29 | activeDot={}>
30 |
31 | Welcome
32 | Sign up for free music on your phone,tablet
33 | and computer.
34 |
35 |
36 | Browse
37 | Explore top tracks, new releases and the right
38 | playlist for every moment
39 |
40 |
41 | Search
42 | Looking for that special album or artist? Just
43 | search and hit play!
44 |
45 |
46 | Running
47 | Music that perfectly matches
48 | your tempo.
49 |
50 |
51 | Your Library
52 | Save any song,album or artist to your own
53 | music collection.
54 |
55 |
56 |
57 |
58 |
59 | LOG IN
60 |
61 |
62 | SIGN UP
63 |
64 |
65 |
66 | );
67 | }
68 | }
69 |
70 | export default class extends Component{
71 | componentDidMount() {
72 | StatusBar.setBarStyle(1);
73 | }
74 |
75 | render() {
76 | return(
77 |
78 |
79 |
80 | )
81 | }
82 | }
83 |
84 | //
87 |
88 | const styles = StyleSheet.create({
89 | container:{
90 | height:Util.size.height,
91 | width:Util.size.width
92 | },
93 | backgroundFixed: {
94 | position: 'absolute',
95 | top: 0,
96 | left: 0,
97 | bottom: 0,
98 | right: 0,
99 | },
100 | sliders: {
101 | position: 'absolute',
102 | width: Util.size.width,
103 | bottom: 70,
104 | left:0
105 | },
106 | slide: {
107 | flex: 1,
108 | height: Util.size.height-200,
109 | justifyContent: 'flex-end',
110 | alignItems: 'center',
111 | paddingBottom:50
112 | },
113 | slideText:{
114 | color: "#fff",
115 | textAlign:"center"
116 | },
117 | slideTextTitle:{
118 | color: "#fff",
119 | textAlign:"center",
120 | fontWeight:"700"
121 | },
122 | logo:{
123 | alignItems:"center",
124 | position:"absolute",
125 | width: Util.size.width,
126 | top: 50,
127 | left: 0,
128 | flexDirection:"row",
129 | alignItems:"center",
130 | justifyContent:"center"
131 | },
132 | logoText:{
133 | color:"#fff",
134 | textAlign:"left",
135 | fontSize: 35,
136 | fontWeight:"700",
137 | backgroundColor:"transparent",
138 | },
139 | logoIconContainer:{
140 | backgroundColor:"transparent",
141 | paddingRight:5,
142 | marginTop:5
143 | },
144 | logoTextContainer:{
145 | backgroundColor:"transparent"
146 | },
147 | btnContainer:{
148 | position:"absolute",
149 | width: Util.size.width,
150 | bottom: 0,
151 | left: 0,
152 | height: 40,
153 | flexDirection: "row"
154 | },
155 | btn:{
156 | flex:1,
157 | alignItems:"center",
158 | justifyContent:"center"
159 | },
160 | btnText:{
161 | color:"#fff",
162 | fontWeight:"500",
163 | fontSize:14
164 | },
165 | });
--------------------------------------------------------------------------------
/ios/ThirtyDaysOfReactNative.xcodeproj/xcshareddata/xcschemes/ThirtyDaysOfReactNative.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
29 |
35 |
36 |
37 |
43 |
49 |
50 |
51 |
52 |
53 |
58 |
59 |
61 |
67 |
68 |
69 |
70 |
71 |
77 |
78 |
79 |
80 |
81 |
82 |
92 |
94 |
100 |
101 |
102 |
103 |
104 |
105 |
111 |
113 |
119 |
120 |
121 |
122 |
124 |
125 |
128 |
129 |
130 |
--------------------------------------------------------------------------------
/android/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # For Cygwin, ensure paths are in UNIX format before anything is touched.
46 | if $cygwin ; then
47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
48 | fi
49 |
50 | # Attempt to set APP_HOME
51 | # Resolve links: $0 may be a link
52 | PRG="$0"
53 | # Need this for relative symlinks.
54 | while [ -h "$PRG" ] ; do
55 | ls=`ls -ld "$PRG"`
56 | link=`expr "$ls" : '.*-> \(.*\)$'`
57 | if expr "$link" : '/.*' > /dev/null; then
58 | PRG="$link"
59 | else
60 | PRG=`dirname "$PRG"`"/$link"
61 | fi
62 | done
63 | SAVED="`pwd`"
64 | cd "`dirname \"$PRG\"`/" >&-
65 | APP_HOME="`pwd -P`"
66 | cd "$SAVED" >&-
67 |
68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
69 |
70 | # Determine the Java command to use to start the JVM.
71 | if [ -n "$JAVA_HOME" ] ; then
72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
73 | # IBM's JDK on AIX uses strange locations for the executables
74 | JAVACMD="$JAVA_HOME/jre/sh/java"
75 | else
76 | JAVACMD="$JAVA_HOME/bin/java"
77 | fi
78 | if [ ! -x "$JAVACMD" ] ; then
79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
80 |
81 | Please set the JAVA_HOME variable in your environment to match the
82 | location of your Java installation."
83 | fi
84 | else
85 | JAVACMD="java"
86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
87 |
88 | Please set the JAVA_HOME variable in your environment to match the
89 | location of your Java installation."
90 | fi
91 |
92 | # Increase the maximum file descriptors if we can.
93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
94 | MAX_FD_LIMIT=`ulimit -H -n`
95 | if [ $? -eq 0 ] ; then
96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
97 | MAX_FD="$MAX_FD_LIMIT"
98 | fi
99 | ulimit -n $MAX_FD
100 | if [ $? -ne 0 ] ; then
101 | warn "Could not set maximum file descriptor limit: $MAX_FD"
102 | fi
103 | else
104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
105 | fi
106 | fi
107 |
108 | # For Darwin, add options to specify how the application appears in the dock
109 | if $darwin; then
110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
111 | fi
112 |
113 | # For Cygwin, switch paths to Windows format before running java
114 | if $cygwin ; then
115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
158 | function splitJvmOpts() {
159 | JVM_OPTS=("$@")
160 | }
161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
163 |
164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
165 |
--------------------------------------------------------------------------------
/view/day13.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Day 13
3 | * A twitter tweet UI
4 | */
5 | 'use strict';
6 |
7 | import React,{ Component } from 'react';
8 | import { Image,StyleSheet,StatusBar,CameraRoll,Text,TextInput,TouchableHighlight,View } from 'react-native';
9 | import Util from './utils';
10 | import Icon from 'react-native-vector-icons/Ionicons';
11 |
12 | class FunctionView extends Component{
13 | static defaultProps = {
14 | numOfText: 140,
15 | };
16 |
17 | static propTypes = {
18 | numOfText: React.PropTypes.number.isRequired,
19 | };
20 |
21 | constructor() {
22 | super();
23 | this.state = {
24 | images: [],
25 | };
26 | }
27 |
28 | componentDidMount() {
29 | const fetchParams = {
30 | first: 4,
31 | };
32 | CameraRoll.getPhotos(fetchParams).done((data) => this.storeImages(data), (err) => this.logImageError(err));
33 | }
34 |
35 | storeImages(data) {
36 | const assets = data.edges;
37 | const images = assets.map((asset) => asset.node.image);
38 | this.setState({
39 | images: images,
40 | });
41 | }
42 |
43 | logImageError(err) {
44 | console.log(err);
45 | }
46 |
47 | render() {
48 | return(
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 | {this.props.numOfText}
59 |
60 | 发推
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 | { this.state.images.map((image,index) => ) }
72 |
73 |
74 | )
75 | }
76 | }
77 |
78 | export default class extends Component{
79 | constructor() {
80 | super();
81 | this.state = {
82 | numOfText:140,
83 | };
84 | }
85 |
86 | componentDidMount() {
87 | StatusBar.setBarStyle(0);
88 | }
89 |
90 | _updateTextNum(text) {
91 | let remain = 140 - text.length;
92 | this.setState({
93 | numOfText:remain,
94 | });
95 | }
96 |
97 | render() {
98 | return(
99 |
100 |
101 |
102 |
103 |
104 | this._updateTextNum(text)}>
113 |
114 |
115 | )
116 | }
117 | }
118 |
119 | const styles = StyleSheet.create({
120 | container:{
121 | paddingTop:30,
122 | height:Util.size.height,
123 | backgroundColor: "#ffffff"
124 | },
125 | icon:{
126 | width:30,
127 | height:30,
128 | borderRadius:5,
129 | },
130 | iconContainer:{
131 | paddingLeft:15,
132 | paddingRight:15,
133 | flexDirection:"row",
134 | justifyContent:"space-between",
135 | },
136 | textArea:{
137 | height:335,
138 | padding:15,
139 | fontSize:20
140 | },
141 | functionContainer:{
142 | height:275,
143 | width:375,
144 | position:"absolute",
145 | bottom:0,
146 | left:0,
147 | borderTopWidth:1,
148 | borderTopColor:"#a0adb7"
149 | },
150 | functionIconContainer:{
151 | height:50,
152 | alignItems:"center",
153 | justifyContent:"space-between",
154 | flexDirection:"row",
155 | borderBottomWidth:1,
156 | borderBottomColor:"#ccd6dd"
157 | },
158 | functionIcon:{
159 | width:210,
160 | flexDirection:"row",
161 | justifyContent:"space-around"
162 | },
163 | functionBtn:{
164 | width:110,
165 | flexDirection:"row",
166 | justifyContent:"space-around",
167 | alignItems:"center",
168 | },
169 | btn:{
170 | height:35,
171 | width:60,
172 | alignItems:"center",
173 | justifyContent:"center",
174 | borderRadius:6,
175 | borderColor:"#ccd6dd",
176 | borderWidth:1
177 | },
178 | activeBtn:{
179 | height:35,
180 | width:60,
181 | alignItems:"center",
182 | justifyContent:"center",
183 | borderRadius:6,
184 | backgroundColor:"#2aa2ef"
185 | },
186 | text:{
187 | color:"#ccd6dd",
188 | fontSize:18
189 | },
190 | btnText:{
191 | color:"#ccd6dd",
192 | fontSize:14
193 | },
194 | activeBtnText:{
195 | color:"#fff",
196 | fontSize:14
197 | },
198 | imageGrid:{
199 | flexDirection:"row",
200 | flexWrap:"wrap"
201 | },
202 | imageIcon:{
203 | width: Util.size.width/3,
204 | height:113,
205 | alignItems:"center",
206 | justifyContent:"center",
207 | borderRightColor:"#ddd",
208 | borderBottomColor:"#ddd",
209 | borderRightWidth:1,
210 | borderBottomWidth:1
211 | },
212 | image:{
213 | width: Util.size.width/3,
214 | height:113,
215 | },
216 | });
217 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 30 Days of React Native
2 | 30 days of React Native examples/demos.
3 |
4 |
5 | 
6 |
7 | This project is inspired by
8 |
9 | 100 Days of Swift (http://samvlu.com/) &
10 |
11 | 30DaysofSwift (https://github.com/allenwong/30DaysofSwift)
12 |
13 | ## Upgrade to RN@0.34
14 |
15 | This is a branch under development to upgrade RN to v0.40 & compatible with Xcode 8.
16 |
17 | ## Change
18 |
19 | 1. Remove cocoapodes & libraries that do not support Andriod
20 | 2. Use Navigator instead of NavigatorIOS
21 |
22 | ## Installation
23 | Require node.js, npm install -g react-native-cli , xcode
24 |
25 | \#1 `$ npm install`
26 |
27 | IOS
28 |
29 | \#2 run ios/ThirtyDaysOfReactNative.xcodeproj
30 |
31 | Android
32 |
33 | \# TODO
34 |
35 | ## Compatibility
36 |
37 | Not tested yet.
38 |
39 | ## Running on Device
40 |
41 | https://facebook.github.io/react-native/docs/running-on-device-ios.html#content
42 |
43 | ## Known Bugs
44 |
45 | ## Day 1
46 | An IOS-system-like stop watch.
47 |
48 | Fully functioned as the system app.
49 |
50 | 
51 |
52 | ## Day 2
53 | An IOS-system-like weather app.
54 |
55 | The animation is partially done.
56 |
57 | 
58 |
59 | ## Day 3
60 | The Twitter app entrance animation.
61 |
62 | 
63 |
64 | ## Day 4
65 | TO BE UPDATED
66 |
67 | ## Day 5
68 | MapView and find Geo location.
69 |
70 | 
71 |
72 | ## Day 6
73 | TO BE UPDATED
74 |
75 | ## Day 7
76 | Pan gesture basic. Move a baseball around.
77 |
78 | 
79 |
80 | ## Day 8
81 | Google map style swipe menu
82 |
83 | 
84 |
85 | ## Day 9
86 | Layout of Twitter user page
87 |
88 | 
89 |
90 | ## Day 10
91 | Tumblr menu animation
92 |
93 | 
94 |
95 | ## Day 11
96 | Using OpenGL with React native
97 |
98 | Reference: https://github.com/ProjectSeptemberInc/gl-react-native
99 |
100 | 
101 |
102 | ## Day 12
103 | TO BE UPDATED
104 |
105 | ## Day 13
106 | A tweet UI
107 |
108 | 
109 |
110 | ## Day 14
111 | A tinder swipe
112 |
113 | Reference:https://github.com/meteor-factory/react-native-tinder-swipe-cards
114 |
115 | 
116 |
117 | ## Day 15
118 | TO BE UPDATED
119 |
120 | ## Day 16
121 | Unlock with gesture
122 |
123 | Reference:https://github.com/spikef/react-native-gesture-password
124 |
125 | 
126 |
127 | ## Day 17
128 | Native search bar and Fuzzy search
129 |
130 | Reference:https://github.com/umhan35/react-native-search-bar
131 |
132 | 
133 |
134 | ## Day 18
135 | Sortable. drag and reorder the blocks.
136 |
137 | 
138 |
139 | ## Day 19
140 | Unlock app with touchID
141 |
142 | Reference:https://github.com/naoufal/react-native-touch-id
143 |
144 | 
145 |
146 | ## Day 20
147 | Sigle page Reminder
148 |
149 | 
150 |
151 | ## Day 21
152 | Multi page Reminder
153 |
154 | 
155 |
156 | ## Day 22
157 | Google Now
158 |
159 | 
160 |
161 | ## Day 23
162 | Local WebView
163 | An example using D3.js
164 |
165 | 
166 |
167 | ## Day 24
168 | Youtube scrollable tab
169 |
170 | Reference: https://github.com/brentvatne/react-native-scrollable-tab-view
171 |
172 | 
173 |
174 | ## Day 25
175 | TO BE UPDATED
176 |
177 | ## Day 26
178 | TO BE UPDATED
179 |
180 | ## Day 27
181 | iMessage Gradient. The chat bubble changes its gradient color with its pageY.
182 |
183 | Reference: https://github.com/brentvatne/react-native-linear-gradient
184 |
185 | 
186 |
187 | ## Day 28
188 | iMessage Image Picker.
189 |
190 | 
191 |
192 | ## Day 29
193 | TO BE UPDATED
194 |
195 | ## Day 30
196 | Push Notification.
197 |
198 | 
199 |
200 |
201 | ## License
202 |
203 | ThirtyDaysOfReactNative is under the MIT license.
204 |
--------------------------------------------------------------------------------
/android/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: "com.android.application"
2 |
3 | import com.android.build.OutputFile
4 |
5 | /**
6 | * The react.gradle file registers a task for each build variant (e.g. bundleDebugJsAndAssets
7 | * and bundleReleaseJsAndAssets).
8 | * These basically call `react-native bundle` with the correct arguments during the Android build
9 | * cycle. By default, bundleDebugJsAndAssets is skipped, as in debug/dev mode we prefer to load the
10 | * bundle directly from the development server. Below you can see all the possible configurations
11 | * and their defaults. If you decide to add a configuration block, make sure to add it before the
12 | * `apply from: "../../node_modules/react-native/react.gradle"` line.
13 | *
14 | * project.ext.react = [
15 | * // the name of the generated asset file containing your JS bundle
16 | * bundleAssetName: "index.android.bundle",
17 | *
18 | * // the entry file for bundle generation
19 | * entryFile: "index.android.js",
20 | *
21 | * // whether to bundle JS and assets in debug mode
22 | * bundleInDebug: false,
23 | *
24 | * // whether to bundle JS and assets in release mode
25 | * bundleInRelease: true,
26 | *
27 | * // whether to bundle JS and assets in another build variant (if configured).
28 | * // See http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Build-Variants
29 | * // The configuration property can be in the following formats
30 | * // 'bundleIn${productFlavor}${buildType}'
31 | * // 'bundleIn${buildType}'
32 | * // bundleInFreeDebug: true,
33 | * // bundleInPaidRelease: true,
34 | * // bundleInBeta: true,
35 | *
36 | * // the root of your project, i.e. where "package.json" lives
37 | * root: "../../",
38 | *
39 | * // where to put the JS bundle asset in debug mode
40 | * jsBundleDirDebug: "$buildDir/intermediates/assets/debug",
41 | *
42 | * // where to put the JS bundle asset in release mode
43 | * jsBundleDirRelease: "$buildDir/intermediates/assets/release",
44 | *
45 | * // where to put drawable resources / React Native assets, e.g. the ones you use via
46 | * // require('./image.png')), in debug mode
47 | * resourcesDirDebug: "$buildDir/intermediates/res/merged/debug",
48 | *
49 | * // where to put drawable resources / React Native assets, e.g. the ones you use via
50 | * // require('./image.png')), in release mode
51 | * resourcesDirRelease: "$buildDir/intermediates/res/merged/release",
52 | *
53 | * // by default the gradle tasks are skipped if none of the JS files or assets change; this means
54 | * // that we don't look at files in android/ or ios/ to determine whether the tasks are up to
55 | * // date; if you have any other folders that you want to ignore for performance reasons (gradle
56 | * // indexes the entire tree), add them here. Alternatively, if you have JS files in android/
57 | * // for example, you might want to remove it from here.
58 | * inputExcludes: ["android/**", "ios/**"],
59 | *
60 | * // override which node gets called and with what additional arguments
61 | * nodeExecutableAndArgs: ["node"]
62 | *
63 | * // supply additional arguments to the packager
64 | * extraPackagerArgs: []
65 | * ]
66 | */
67 |
68 | apply from: "../../node_modules/react-native/react.gradle"
69 |
70 | /**
71 | * Set this to true to create two separate APKs instead of one:
72 | * - An APK that only works on ARM devices
73 | * - An APK that only works on x86 devices
74 | * The advantage is the size of the APK is reduced by about 4MB.
75 | * Upload all the APKs to the Play Store and people will download
76 | * the correct one based on the CPU architecture of their device.
77 | */
78 | def enableSeparateBuildPerCPUArchitecture = false
79 |
80 | /**
81 | * Run Proguard to shrink the Java bytecode in release builds.
82 | */
83 | def enableProguardInReleaseBuilds = false
84 |
85 | android {
86 | compileSdkVersion 23
87 | buildToolsVersion "23.0.1"
88 |
89 | defaultConfig {
90 | applicationId "com.thirtydaysofreactnative"
91 | minSdkVersion 16
92 | targetSdkVersion 22
93 | versionCode 1
94 | versionName "1.0"
95 | ndk {
96 | abiFilters "armeabi-v7a", "x86"
97 | }
98 | }
99 | splits {
100 | abi {
101 | reset()
102 | enable enableSeparateBuildPerCPUArchitecture
103 | universalApk false // If true, also generate a universal APK
104 | include "armeabi-v7a", "x86"
105 | }
106 | }
107 | buildTypes {
108 | release {
109 | minifyEnabled enableProguardInReleaseBuilds
110 | proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
111 | }
112 | }
113 | // applicationVariants are e.g. debug, release
114 | applicationVariants.all { variant ->
115 | variant.outputs.each { output ->
116 | // For each separate APK per architecture, set a unique version code as described here:
117 | // http://tools.android.com/tech-docs/new-build-system/user-guide/apk-splits
118 | def versionCodes = ["armeabi-v7a":1, "x86":2]
119 | def abi = output.getFilter(OutputFile.ABI)
120 | if (abi != null) { // null for the universal-debug, universal-release variants
121 | output.versionCodeOverride =
122 | versionCodes.get(abi) * 1048576 + defaultConfig.versionCode
123 | }
124 | }
125 | }
126 | }
127 |
128 | dependencies {
129 | compile project(':RNGL')
130 | compile project(':react-native-linear-gradient')
131 | compile project(':gl-react-native')
132 | compile project(':react-native-video')
133 | compile project(':react-native-vector-icons')
134 | compile fileTree(dir: "libs", include: ["*.jar"])
135 | compile "com.android.support:appcompat-v7:23.0.1"
136 | compile "com.facebook.react:react-native:+" // From node_modules
137 | }
138 |
139 | // Run this once to be able to run the application with BUCK
140 | // puts all compile dependencies into folder libs for BUCK to use
141 | task copyDownloadableDepsToLibs(type: Copy) {
142 | from configurations.compile
143 | into 'libs'
144 | }
145 |
146 | //pluins
147 | apply from: "../../node_modules/react-native-vector-icons/fonts.gradle"
148 |
--------------------------------------------------------------------------------
/view/day28.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Day 28
3 | *
4 | */
5 | 'use strict';
6 |
7 | import React,{ Component } from 'react';
8 | import { Image,StyleSheet,Text,TouchableHighlight,TouchableWithoutFeedback,LayoutAnimation,ScrollView,CameraRoll,View } from 'react-native';
9 | import Util from './utils';
10 | import Icon from 'react-native-vector-icons/Ionicons';
11 |
12 | export default class extends Component{
13 | constructor() {
14 | super();
15 | this.state = {
16 | images: [],
17 | widths: [],
18 | active: false,
19 | showBtn: false,
20 | selected: [],
21 | };
22 | }
23 |
24 | componentDidMount() {
25 | const fetchParams = {
26 | first: 10,
27 | };
28 | CameraRoll.getPhotos(fetchParams).done((data) => this.storeImages(data), (err) => this.logImageError(err));
29 | }
30 |
31 | storeImages(data) {
32 | const assets = data.edges;
33 | const images = assets.map((asset) => asset.node.image);
34 | const widths = [];
35 | const selected = [];
36 | for (var i = 0; i < images.length; i++) {
37 | if (i == images.length - 1) {
38 | Image.getSize(images[i].uri, (w, h) => {
39 | widths.push((w/h)*130);
40 | selected.push(false);
41 | this.setState({images,widths,selected});
42 | })
43 | }else{
44 | Image.getSize(images[i].uri, (w, h) => {
45 | widths.push((w/h)*130);
46 | selected.push(false);
47 | })
48 | }
49 | }
50 | }
51 |
52 | logImageError(err) {
53 | console.log(err);
54 | }
55 |
56 | _select(index) {
57 | let {selected} = this.state;
58 | selected[index] = true;
59 | this.setState({
60 | active: true,
61 | selected,
62 | });
63 | LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
64 | }
65 |
66 | _showBtn() {
67 | this.setState({
68 | showBtn: true,
69 | });
70 | }
71 |
72 | _hideBtn() {
73 | this.setState({
74 | showBtn: false,
75 | });
76 | }
77 |
78 | render() {
79 | const {active,selected,widths,showBtn} = this.state;
80 | return(
81 |
82 | this._showBtn()}>
83 |
84 |
85 | {showBtn?
86 |
87 |
88 |
89 |
90 |
91 | { this.state.images.map((image,index) => {
92 | return(
93 | this._select(index)}>
94 |
95 |
96 | {active?
97 | (selected[index]?
98 | :
99 | ):
100 |
101 | }
102 |
103 |
104 |
105 | )
106 | })
107 | }
108 |
109 |
110 |
111 |
112 | Library
113 |
114 |
115 | Camera
116 |
117 |
118 | this._hideBtn()} style={styles.btnContainer}>
119 |
120 | Cancle
121 |
122 |
123 | :
124 |
125 | }
126 |
127 | )
128 | }
129 | }
130 |
131 | const styles = StyleSheet.create({
132 | container:{
133 | height: Util.size.height,
134 | width: Util.size.width,
135 | backgroundColor:"#f9f9f9",
136 | },
137 | bg:{
138 | marginTop: 20,
139 | height: Util.size.height - 20,
140 | width: Util.size.width,
141 | },
142 | btn:{
143 | width: Util.size.width-20,
144 | height:50,
145 | backgroundColor:"#fff",
146 | borderRadius:10,
147 | marginTop:5,
148 | alignItems:"center",
149 | justifyContent:"center",
150 | flexDirection:"column",
151 | },
152 | imgContainer:{
153 | flex:3,
154 | width:Util.size.width-20,
155 | },
156 | innderBtn:{
157 | height:50,
158 | width:Util.size.width-20,
159 | alignItems:"center",
160 | justifyContent:"center",
161 | },
162 | btnContainer:{
163 | backgroundColor:"transparent",
164 | },
165 | drop:{
166 | height: Util.size.height,
167 | width: Util.size.width,
168 | backgroundColor:"rgba(0,0,0,0.2)",
169 | position:"absolute",
170 | left:0,
171 | top:0,
172 | flexDirection:"column",
173 | justifyContent:"flex-end",
174 | paddingBottom:10,
175 | alignItems:"center",
176 | },
177 | blur:{
178 | flex:1,
179 | height:45,
180 | },
181 | btnText:{
182 | color:"#0089fa",
183 | fontSize:18,
184 | fontWeight:"500",
185 | },
186 | image:{
187 | height:140,
188 | width:100,
189 | marginRight:5,
190 | alignItems:"flex-end",
191 | justifyContent:"flex-end",
192 | paddingBottom:5,
193 | paddingRight:10,
194 | },
195 | imgContent:{
196 | height:150,
197 | paddingTop:5,
198 | paddingBottom:5,
199 | paddingLeft:5,
200 | flexDirection:"row",
201 | flexWrap:"wrap",
202 | },
203 | icon:{
204 | backgroundColor:"transparent",
205 | }
206 | });
207 |
208 |
--------------------------------------------------------------------------------
/view/day24.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Day 24
3 | *
4 | */
5 | 'use strict';
6 |
7 | import React,{ Component } from 'react';
8 | import { Image,StyleSheet,Text,TouchableHighlight,TouchableOpacity,StatusBar,Animated,ScrollView,View } from 'react-native';
9 | import Util from './utils';
10 | import Icon from 'react-native-vector-icons/Ionicons';
11 | import ScrollableTabView from 'react-native-scrollable-tab-view';
12 |
13 | class HomePage extends Component{
14 | render() {
15 | return(
16 |
17 |
18 |
19 | )
20 | }
21 | }
22 |
23 | class PopularPage extends Component{
24 | render() {
25 | return(
26 |
27 |
28 |
29 | )
30 | }
31 | }
32 |
33 | class SubscribePage extends Component{
34 | render() {
35 | return(
36 |
37 |
38 |
39 | )
40 | }
41 | }
42 |
43 | class MinePage extends Component{
44 | render() {
45 | return(
46 |
47 |
48 |
49 | )
50 | }
51 | }
52 |
53 | var FacebookTabBar = React.createClass({
54 | selectedTabIcons: [],
55 | unselectedTabIcons: [],
56 |
57 | propTypes: {
58 | goToPage: React.PropTypes.func,
59 | activeTab: React.PropTypes.number,
60 | tabs: React.PropTypes.array
61 | },
62 |
63 | renderTabOption(name, page) {
64 | var isTabActive = this.props.activeTab === page;
65 |
66 | return (
67 | this.props.goToPage(page)} style={styles.tab}>
68 | { this.selectedTabIcons[page] = icon }}/>
70 | { this.unselectedTabIcons[page] = icon }}/>
72 |
73 | );
74 | },
75 |
76 | componentDidMount() {
77 | this.setAnimationValue({value: this.props.activeTab});
78 | this._listener = this.props.scrollValue.addListener(this.setAnimationValue);
79 | },
80 |
81 | setAnimationValue({value}) {
82 | var currentPage = this.props.activeTab;
83 |
84 | this.unselectedTabIcons.forEach((icon, i) => {
85 | var iconRef = icon;
86 |
87 | if (!icon.setNativeProps && icon !== null) {
88 | iconRef = icon.refs.icon_image
89 | }
90 |
91 | if (value - i >= 0 && value - i <= 1) {
92 | iconRef.setNativeProps({ style: {opacity: value - i} });
93 | }
94 | if (i - value >= 0 && i - value <= 1) {
95 | iconRef.setNativeProps({ style: {opacity: i - value} });
96 | }
97 | });
98 | },
99 |
100 | render() {
101 | var containerWidth = this.props.containerWidth;
102 | var numberOfTabs = this.props.tabs.length;
103 | var tabUnderlineStyle = {
104 | position: 'absolute',
105 | width: containerWidth / numberOfTabs,
106 | height: 3,
107 | backgroundColor: '#fff',
108 | bottom: 0,
109 | };
110 |
111 | var left = this.props.scrollValue.interpolate({
112 | inputRange: [0, 1], outputRange: [0, containerWidth / numberOfTabs]
113 | });
114 |
115 | return (
116 |
117 |
118 | {this.props.tabs.map((tab, i) => this.renderTabOption(tab, i))}
119 |
120 |
121 |
122 | );
123 | },
124 | });
125 |
126 | export default class extends Component{
127 | constructor() {
128 | super();
129 | this.state = {
130 | title: "首页",
131 | };
132 | }
133 |
134 | componentDidMount() {
135 | StatusBar.setBarStyle(1);
136 | }
137 |
138 | _updateTitle(obj) {
139 | const {i} = obj;
140 | let title = "";
141 | switch(i) {
142 | case 0:
143 | title = "首页";
144 | break;
145 | case 1:
146 | title = "时下流行";
147 | break;
148 | case 2:
149 | title = "订阅";
150 | break;
151 | case 3:
152 | title = "帐户";
153 | break;
154 | }
155 | this.setState({
156 | title
157 | });
158 | }
159 |
160 | render() {
161 | return(
162 |
163 |
164 |
165 | {this.state.title}
166 |
167 |
168 |
169 |
170 |
171 | this._updateTitle(obj)}
173 | renderTabBar={() => }>
174 |
175 |
176 |
177 |
178 |
179 |
180 | )
181 | }
182 | }
183 |
184 | const styles = StyleSheet.create({
185 | navBg:{
186 | backgroundColor:"#c11f1e",
187 | width:Util.size.width,
188 | height:20,
189 | },
190 | nav:{
191 | backgroundColor:"#e32524",
192 | width:Util.size.width,
193 | height:55,
194 | flexDirection:"row",
195 | justifyContent:"space-between",
196 | paddingTop:15,
197 | paddingLeft:20,
198 | paddingRight:10,
199 | },
200 | tab: {
201 | flex: 1,
202 | alignItems: 'center',
203 | justifyContent: 'center',
204 | paddingBottom: 10,
205 | },
206 | tabs: {
207 | height: 45,
208 | flexDirection: 'row',
209 | paddingTop: 5,
210 | borderWidth: 1,
211 | borderTopWidth: 0,
212 | borderLeftWidth: 0,
213 | borderRightWidth: 0,
214 | borderBottomColor: 'rgba(0,0,0,0.05)',
215 | backgroundColor:"#e32524"
216 | },
217 | icon: {
218 | position: 'absolute',
219 | top: 0,
220 | left: 35,
221 | },
222 | img: {
223 | width:375,
224 | height: 550,
225 | },
226 | title:{
227 | color:"#fff",
228 | fontSize:20,
229 | },
230 | iconContainer:{
231 | flexDirection:"row",
232 | justifyContent:"space-between",
233 | width:60,
234 | }
235 | });
236 |
237 |
--------------------------------------------------------------------------------
/view/day20.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Day 20
3 | * Reminder
4 | */
5 | 'use strict';
6 |
7 | import React,{ Component } from 'react';
8 | import { Image,StyleSheet,StatusBar,Text,TextInput,LayoutAnimation,TouchableHighlight,View } from 'react-native';
9 | import Util from './utils';
10 | // import {BlurView,VibrancyView} from 'react-native-blur';
11 | import Icon from 'react-native-vector-icons/Ionicons';
12 |
13 | export class ReminderContainer extends Component{
14 | static defaultProps = {
15 | listData:{
16 | title:"提醒事项",
17 | numOfItems:0,
18 | theme:"#fe952b",
19 | list:[]
20 | },
21 | };
22 |
23 | static propTypes = {
24 | listData: React.PropTypes.object,
25 | switch: React.PropTypes.func,
26 | };
27 |
28 | constructor(props) {
29 | super(props);
30 | this.state = {
31 | listData: this.props.listData,
32 | numOfItems: this.props.listData.numOfItems,
33 | }
34 | this.animations = {
35 | duration: 200,
36 | create: {
37 | type: LayoutAnimation.Types.linear,
38 | },
39 | update: {
40 | type: LayoutAnimation.Types.linear,
41 | springDamping: 0.7,
42 | },
43 | };
44 | }
45 |
46 | _done(index) {
47 | const listData = this.state.listData;
48 | listData.list[index].selected = !listData.list[index].selected;
49 | const numOfItems = this.state.numOfItems - 1;
50 | this.setState({
51 | listData,
52 | numOfItems,
53 | });
54 | LayoutAnimation.configureNext(this.animations);
55 | }
56 |
57 | _addList(text) {
58 | const listData = this.state.listData;
59 | const numOfItems = this.state.numOfItems + 1;
60 | listData.list.push({
61 | selected:false,
62 | text
63 | })
64 | this.refs.addList.setNativeProps({text: ''});
65 | this.setState({
66 | listData,
67 | numOfItems,
68 | })
69 | }
70 |
71 | render() {
72 | const listData = this.state.listData;
73 | const list = listData.list.map((elem,index) => {
74 | return (
75 |
76 | this._done(index)}>
77 |
78 |
79 |
80 |
81 |
82 |
83 | );
84 | })
85 | list.push(
86 |
87 |
88 |
89 |
90 |
91 | this._addList(event.nativeEvent.text)} style={styles.inputText}/>
92 |
93 |
94 | );
95 | return(
96 |
97 |
98 |
99 |
100 |
101 | {listData.title}
102 | {this.state.numOfItems}
103 |
104 |
105 |
106 | {list}
107 |
108 |
109 |
110 | );
111 | }
112 | }
113 |
114 | export default class extends Component{
115 | constructor() {
116 | super();
117 | this.listData = {
118 | title:"Development",
119 | numOfItems:6,
120 | theme:"#fe952b",
121 | list:[{
122 | selected:false,
123 | text:"day20",
124 | },{
125 | selected:false,
126 | text:"day21",
127 | },{
128 | selected:false,
129 | text:"day22",
130 | },{
131 | selected:false,
132 | text:"day23",
133 | },{
134 | selected:false,
135 | text:"day24",
136 | },{
137 | selected:false,
138 | text:"day25",
139 | }],
140 | };
141 | }
142 |
143 | componentDidMount() {
144 | StatusBar.setBarStyle(1);
145 | }
146 |
147 | render() {
148 | return(
149 |
150 |
151 |
152 |
153 |
154 | );
155 | }
156 | }
157 |
158 | const styles = StyleSheet.create({
159 | container:{
160 | height: Util.size.height,
161 | width: Util.size.width,
162 | },
163 | reminderContainer:{
164 | height: Util.size.height-65,
165 | width:Util.size.width,
166 | borderRadius: 10,
167 | position:"absolute",
168 | top:20,
169 | left:0,
170 | backgroundColor:"#fff",
171 | shadowColor: "#000",
172 | shadowOpacity: 0.3,
173 | shadowRadius: 2,
174 | shadowOffset: {
175 | height: -1,
176 | width: 0,
177 | }
178 | },
179 | reminderBg:{
180 | height: Util.size.height-65,
181 | width:Util.size.width,
182 | borderRadius: 10,
183 | resizeMode:"cover",
184 | opacity:0.5,
185 | },
186 | reminderContent:{
187 | height: Util.size.height-65,
188 | width:Util.size.width,
189 | backgroundColor:"transparent",
190 | position:"absolute",
191 | top:0,
192 | left:0,
193 | },
194 | reminderTitleContainer:{
195 | height: 65,
196 | width: Util.size.width,
197 | flexDirection:"row",
198 | justifyContent:"space-between",
199 | paddingLeft:15,
200 | paddingRight:15,
201 | alignItems:"center"
202 | },
203 | reminderTitle:{
204 | fontSize:28,
205 | fontWeight:"300",
206 | textShadowColor:"#ccc",
207 | textShadowOffset:{width:0, height:1,},
208 | textShadowRadius:1,
209 | },
210 | reminderListContainer:{
211 | flex:1,
212 | borderTopColor:"#ccc",
213 | borderTopWidth:1,
214 | },
215 | reminderList:{
216 | flexDirection:"row",
217 | paddingLeft:15,
218 | height:45,
219 | width:Util.size.width,
220 | justifyContent:"space-between",
221 | alignItems:"center"
222 | },
223 | check:{
224 | backgroundColor:"transparent",
225 | borderWidth:1,
226 | borderColor:"#c6c6c6",
227 | width:22,
228 | height:22,
229 | borderRadius:11,
230 | shadowOffset:{
231 | width: 0,
232 | height: 1,
233 | },
234 | shadowRadius:1,
235 | shadowColor: '#aaa',
236 | shadowOpacity: 0.3,
237 | justifyContent:"center",
238 | alignItems:"center"
239 | },
240 | fill:{
241 | width:16,
242 | height:16,
243 | borderRadius:8,
244 | },
245 | input:{
246 | width:Util.size.width-50,
247 | height:45,
248 | borderBottomWidth:1,
249 | borderBottomColor:"#ccc",
250 | },
251 | inputText:{
252 | height:43,
253 | color:"#363636",
254 | },
255 | addIcon:{
256 | paddingLeft: 5
257 | }
258 | });
259 |
260 |
--------------------------------------------------------------------------------
/view/day8.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Day 8
3 | * Swipe left
4 | */
5 | 'use strict';
6 |
7 | import React,{ Component } from 'react';
8 | import { Image,StyleSheet,StatusBar,Text,TouchableHighlight,PanResponder,LayoutAnimation,ScrollView,View } from 'react-native';
9 | import { Map } from './day5';
10 | import Util from './utils';
11 | import Icon from 'react-native-vector-icons/FontAwesome';
12 |
13 | class Menu extends Component{
14 | render() {
15 | return(
16 |
17 |
18 |
19 | {true}}>
20 |
21 |
22 | 你的地点
23 |
24 |
25 | {true}}>
26 |
27 |
28 | 你的贡献
29 |
30 |
31 | {true}}>
32 |
33 |
34 | 离线区域
35 |
36 |
37 |
38 |
39 | {true}}>
40 |
41 |
42 | 实时路况
43 |
44 |
45 | {true}}>
46 |
47 |
48 | 公交线路
49 |
50 |
51 | {true}}>
52 |
53 |
54 | 骑车线路
55 |
56 |
57 | {true}}>
58 |
59 |
60 | 卫星图像
61 |
62 |
63 | {true}}>
64 |
65 |
66 | 地形
67 |
68 |
69 |
70 |
71 | )
72 | }
73 | }
74 |
75 | export default class extends Component{
76 | constructor() {
77 | super();
78 | this.state = {
79 | showDrop:false
80 | }
81 | }
82 |
83 | _previousLeft = -0.7*Util.size.width-10;
84 | _previousOpacity = 0;
85 | _minLeft = -0.7*Util.size.width-10;
86 | _menuStyles = {};
87 | _dropStyle = {};
88 | // _CustomLayoutLinear = {
89 | // duration: 200,
90 | // create: {
91 | // type: LayoutAnimation.Types.linear,
92 | // property: LayoutAnimation.Properties.left,
93 | // },
94 | // update: {
95 | // type: LayoutAnimation.Types.curveEaseInEaseOut,
96 | // },
97 | // };
98 | _CustomLayoutLinear = LayoutAnimation.Presets.linear;
99 | menu = (null : ?{ setNativeProps(props: Object): void });
100 | drop = (null : ?{ setNativeProps(props: Object): void });
101 |
102 | _updatePosition() {
103 | this.menu && this.menu.setNativeProps(this._menuStyles);
104 | this.drop && this.drop.setNativeProps(this._dropStyles);
105 | }
106 |
107 | _endMove(evt, gestureState) {
108 | if (gestureState.vx<0||gestureState.dx<0){
109 | this._menuStyles.style.left = this._minLeft;
110 | this._dropStyles.style.opacity = 0;
111 | this._previousLeft = this._minLeft;
112 | this._previousOpacity = 0;
113 | this.setState({
114 | showDrop:false
115 | })
116 | }
117 | if(gestureState.vx>0||gestureState.dx>0){
118 | this._menuStyles.style.left = 0;
119 | this._dropStyles.style.opacity = 1;
120 | this._previousLeft = 0;
121 | this._previousOpacity = 1;
122 | }
123 | this._updatePosition();
124 | LayoutAnimation.configureNext(this._CustomLayoutLinear);
125 | }
126 |
127 | componentWillMount() {
128 | this._panResponder = PanResponder.create({
129 | onStartShouldSetPanResponder: (evt, gestureState) => true,
130 | onMoveShouldSetPanResponder: (evt, gestureState) => {
131 | return gestureState.dy/gestureState.dx!=0;
132 | },
133 | onPanResponderGrant: (evt, gestureState) => {
134 | this.setState({
135 | showDrop:true
136 | })
137 | },
138 | onPanResponderMove: (evt, gestureState) => {
139 | this._menuStyles.style.left = this._previousLeft + gestureState.dx;
140 | this._dropStyles.style.opacity = this._previousOpacity+Math.pow(gestureState.dx/(-this._minLeft),0.5);
141 | if (this._menuStyles.style.left>0) {
142 | this._menuStyles.style.left = 0;
143 | this._dropStyles.style.opacity = 1;
144 | };
145 | if (this._menuStyles.style.left < this._minLeft) {
146 | this._menuStyles.style.left = this._minLeft;
147 | this._dropStyles.style.opacity = 0;
148 | };
149 | this._updatePosition();
150 | LayoutAnimation.configureNext(this._CustomLayoutLinear);
151 | },
152 | onPanResponderTerminationRequest: (evt, gestureState) => true,
153 | onPanResponderRelease: (evt, gestureState) => this._endMove(evt, gestureState),
154 | onPanResponderTerminate: (evt, gestureState) => this._endMove(evt, gestureState),
155 | onShouldBlockNativeResponder: (event, gestureState) => true,
156 | });
157 |
158 | this._menuStyles = {
159 | style: {
160 | left: this._previousLeft,
161 | },
162 | };
163 | this._dropStyles = {
164 | style: {
165 | opacity: this._previousOpacity,
166 | },
167 | };
168 |
169 | }
170 |
171 | componentDidMount() {
172 | this._updatePosition();
173 | StatusBar.setBarStyle(1);
174 | }
175 |
176 | render () {
177 | return(
178 |
179 |
180 | {this.state.showDrop? {this.drop = drop;}}>:}
181 | {this.menu = menu;}}>
182 |
183 |
184 |
185 | )
186 | }
187 | }
188 |
189 | const styles = StyleSheet.create({
190 | container:{
191 | height:Util.size.height,
192 | width: Util.size.width,
193 | },
194 | map:{
195 | width: Util.size.width,
196 | height: Util.size.height
197 | },
198 | sideMenu:{
199 | height: Util.size.height,
200 | width: 0.7*Util.size.width+20,
201 | position:"absolute",
202 | top:0,
203 | backgroundColor:"transparent",
204 | left: -0.7*Util.size.width-10,
205 | },
206 | sideMenuContainer:{
207 | height: Util.size.height,
208 | width: 0.7*Util.size.width,
209 | backgroundColor:"#fff",
210 | shadowColor: "#000",
211 | shadowOpacity: 0.3,
212 | shadowRadius: 5,
213 | shadowOffset: {
214 | height: 0,
215 | width: 2
216 | }
217 | },
218 | drop:{
219 | height: Util.size.height,
220 | width: Util.size.width,
221 | position:"absolute",
222 | top:0,
223 | left:0,
224 | opacity:0,
225 | backgroundColor:"rgba(0,0,0,0.6)"
226 | },
227 | img:{
228 | width: 0.7*Util.size.width,
229 | resizeMode:"contain",
230 | height:0.7*Util.size.width/1.754,
231 | },
232 | btn:{
233 | flexDirection:"row",
234 | alignItems:"center",
235 | paddingTop:15,
236 | paddingBottom:15,
237 | backgroundColor:"#fff"
238 | },
239 | btnIcon:{
240 | flex:1,
241 | textAlign:"center",
242 | color:"#555"
243 | },
244 | btnText:{
245 | flex:3,
246 | fontSize:14,
247 | fontWeight:"500",
248 | paddingLeft:20,
249 | color:"#454545"
250 | },
251 | btnContainer:{
252 | paddingTop:10,
253 | borderBottomWidth: Util.pixel,
254 | borderBottomColor:"#bbb"
255 | },
256 | });
257 |
--------------------------------------------------------------------------------
/view/day14.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Day 14
3 | * Tinder Like Swipe
4 | * know bugs. simg of png win't change no matter how. Other properties changes fine.
5 | * but changes to gif works fine
6 | * Maybe bugs internally
7 | */
8 | 'use strict';
9 |
10 | import React,{ Component } from 'react';
11 | import { Image,StyleSheet,StatusBar,Text,TouchableHighlight,PanResponder,Animated,LayoutAnimation,View } from 'react-native';
12 | import Util from './utils';
13 | import Icon from 'react-native-vector-icons/Ionicons';
14 | import SwipeCards from 'react-native-swipe-cards';
15 |
16 | class Card extends Component{
17 | static propTypes = {
18 | top: React.PropTypes.number.isRequired,
19 | left: React.PropTypes.number.isRequired,
20 | width: React.PropTypes.number.isRequired,
21 | img: React.PropTypes.string.isRequired,
22 | };
23 |
24 | render(){
25 | return(
26 |
27 |
28 |
29 |
30 | {this.props.name}, very old
31 |
32 |
33 |
34 |
35 | 0
36 |
37 |
38 |
39 | 0
40 |
41 |
42 |
43 |
44 | )
45 | }
46 | }
47 |
48 | class SCard extends Component{
49 | static propTypes = {
50 | id: React.PropTypes.string.isRequired,
51 | top: React.PropTypes.number.isRequired,
52 | width: React.PropTypes.number.isRequired,
53 | img: React.PropTypes.string.isRequired,
54 | };
55 |
56 | render(){
57 | return(
58 |
59 |
60 |
61 |
62 | {this.props.name}, very old
63 |
64 |
65 |
66 |
67 | 0
68 |
69 |
70 |
71 | 0
72 |
73 |
74 |
75 |
76 | )
77 | }
78 | }
79 |
80 | class SwipeCard extends Component{
81 | constructor() {
82 | super();
83 | const simgs=["minion1","minion2","minion3","minion4","minion5"];
84 | // const simgs = ["https://media.giphy.com/media/GfXFVHUzjlbOg/giphy.gif","https://media.giphy.com/media/irTuv1L1T34TC/giphy.gif","https://media.giphy.com/media/LkLL0HJerdXMI/giphy.gif","https://media.giphy.com/media/fFBmUMzFL5zRS/giphy.gif","https://media.giphy.com/media/oDLDbBgf0dkis/giphy.gif"];
85 | const names=["Stuart","Bob","Kevin","Dave","Jerry"];
86 | const cards = simgs.map(function(elem, index) {
87 | return {id:"sc"+index,img:simgs[4-index], name:names[4-index], top:13+index*4, width:Util.size.width-22-index*4,}
88 | })
89 |
90 | this.state = {
91 | cards,
92 | };
93 | }
94 |
95 | handleYup(card) {
96 | this.props.next();
97 | }
98 |
99 | handleNope(card) {
100 | this.props.next()
101 | }
102 |
103 | render() {
104 | return (
105 | }
108 | handleYup={() => this.handleYup()}
109 | handleNope={() => this.handleNope()}
110 | showYup={false}
111 | showNope={false}
112 | />
113 | )
114 | }
115 | }
116 |
117 | class Cards extends Component{
118 | constructor() {
119 | super();
120 | const imgs = ["minion1","minion2","minion3","minion4"];
121 | const names = ["Stuart","Bob","Kevin","Dave","Jerry"];
122 |
123 | this.state = {imgs,names,};
124 | }
125 |
126 | componentDidMount() {
127 | StatusBar.setBarStyle(0);
128 | }
129 |
130 | _next() {
131 | const imgs = this.state.imgs;
132 | imgs.pop();
133 | this.setState({imgs,});
134 | }
135 |
136 | render() {
137 | const {names,} = this.state;
138 | const cards = this.state.imgs.map(function(elem, index) {
139 | return
140 | });
141 | return (
142 |
143 | {cards}
144 | this._next()}/>
145 |
146 | );
147 | }
148 | }
149 |
150 | export default class extends Component{
151 | render() {
152 | return(
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 | )
176 | }
177 | }
178 |
179 | const styles = StyleSheet.create({
180 | container:{
181 | backgroundColor:"#fff",
182 | height:Util.size.height,
183 | width:Util.size.width
184 | },
185 | nav:{
186 | width:Util.size.width,
187 | flexDirection:"row",
188 | justifyContent:"space-between",
189 | height:60,
190 | paddingTop:20,
191 | paddingBottom:5,
192 | paddingLeft:15,
193 | paddingRight:15,
194 | backgroundColor:"#fff",
195 | borderBottomColor:"#ebebeb",
196 | borderBottomWidth:1
197 | },
198 | card:{
199 | width:Util.size.width-20,
200 | height:410,
201 | borderRadius:5,
202 | borderWidth:1,
203 | borderColor:"#e1e1e1",
204 | position:"absolute",
205 | left:10,
206 | top:70,
207 | backgroundColor:"#fff"
208 | },
209 | scard:{
210 | width:Util.size.width-20,
211 | height:410,
212 | borderRadius:5,
213 | borderWidth:1,
214 | borderColor:"#e1e1e1",
215 | position:"relative",
216 | backgroundColor:"#fff",
217 | top:13
218 | },
219 | logo:{
220 | width:91,
221 | height:39
222 | },
223 | cardInfo:{
224 | flexDirection:"row",
225 | justifyContent:"space-between",
226 | alignItems:"center",
227 | height:60,
228 | paddingLeft:20,
229 | paddingRight:5
230 | },
231 | cardText:{
232 | fontSize:20,
233 | fontWeight:"500",
234 | color:"#423e39"
235 | },
236 | cardIcon:{
237 | flexDirection:"row"
238 | },
239 | cardIconContainer:{
240 | width:50,
241 | flexDirection:"row",
242 | alignItems:"center",
243 | },
244 | cardIconText:{
245 | paddingLeft:5,
246 | fontWeight:"500",
247 | fontSize:16
248 | },
249 | actionContainer:{
250 | paddingLeft:7.5,
251 | paddingRight:7.5,
252 | flexDirection:"row",
253 | alignItems:"flex-start",
254 | top: 520,
255 | position:"absolute",
256 | },
257 | smallAction:{
258 | width: Util.size.width===375?70:60,
259 | height:Util.size.width===375?70:60,
260 | borderColor:"#f5f5f5",
261 | borderWidth:10,
262 | borderRadius:35,
263 | alignItems:"center",
264 | justifyContent:"center",
265 | position:"relative",
266 | paddingTop:5
267 | },
268 | largeAction:{
269 | width: Util.size.width===375?110:100,
270 | height:Util.size.width===375?110:100,
271 | borderColor:"#f5f5f5",
272 | borderWidth:10,
273 | borderRadius:55,
274 | alignItems:"center",
275 | justifyContent:"center",
276 | paddingTop:5
277 | },
278 | });
279 |
--------------------------------------------------------------------------------
/view/day1.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Day 1
3 | * A stop watch
4 | */
5 | 'use strict';
6 |
7 | import React,{ Component } from 'react';
8 | import { Platform,ListView,StyleSheet,StatusBar,Text,TouchableHighlight,View } from 'react-native';
9 | import Util from './utils';
10 |
11 | class WatchFace extends Component{
12 | static propTypes = {
13 | sectionTime: React.PropTypes.string.isRequired,
14 | totalTime: React.PropTypes.string.isRequired,
15 | };
16 |
17 | render() {
18 | return(
19 |
20 | {this.props.sectionTime}
21 | {this.props.totalTime}
22 |
23 | )
24 | }
25 | }
26 |
27 | class WatchControl extends Component{
28 | static propTypes = {
29 | stopWatch: React.PropTypes.func.isRequired,
30 | clearRecord: React.PropTypes.func.isRequired,
31 | startWatch: React.PropTypes.func.isRequired,
32 | addRecord: React.PropTypes.func.isRequired,
33 | };
34 |
35 | constructor(props){
36 | super(props);
37 | this.state = {
38 | watchOn: false,
39 | startBtnText: "启动",
40 | startBtnColor: "#60B644",
41 | stopBtnText: "计次",
42 | underlayColor:"#fff",
43 | };
44 | }
45 |
46 | _startWatch() {
47 | if (!this.state.watchOn) {
48 | this.props.startWatch()
49 | this.setState({
50 | startBtnText: "停止",
51 | startBtnColor: "#ff0044",
52 | stopBtnText: "计次",
53 | underlayColor:"#eee",
54 | watchOn: true
55 | })
56 | }else{
57 | this.props.stopWatch()
58 | this.setState({
59 | startBtnText: "启动",
60 | startBtnColor: "#60B644",
61 | stopBtnText: "复位",
62 | underlayColor:"#eee",
63 | watchOn: false
64 | })
65 | }
66 | }
67 |
68 | _addRecord() {
69 | if (this.state.watchOn) {
70 | this.props.addRecord()
71 | }else{
72 | this.props.clearRecord()
73 | this.setState({
74 | stopBtnText: "计次"
75 | })
76 | }
77 | }
78 |
79 | render() {
80 | return(
81 |
82 |
83 | this._addRecord()}>
84 | {this.state.stopBtnText}
85 |
86 |
87 |
88 | this._startWatch()}>
89 | {this.state.startBtnText}
90 |
91 |
92 |
93 | )
94 | }
95 | }
96 |
97 | class WatchRecord extends Component{
98 | static propTypes = {
99 | record: React.PropTypes.array.isRequired,
100 | };
101 |
102 | render() {
103 | let ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2}),
104 | theDataSource = ds.cloneWithRows(this.props.record);
105 | return (
106 |
110 |
111 | {rowData.title}
112 |
113 | {rowData.time}
114 |
115 | }/>
116 | );
117 | }
118 | }
119 |
120 | export default class extends Component{
121 | constructor() {
122 | super();
123 | this.state = {
124 | stopWatch: false,
125 | resetWatch: true,
126 | intialTime: 0,
127 | currentTime:0,
128 | recordTime:0,
129 | timeAccumulation:0,
130 | totalTime: "00:00.00",
131 | sectionTime: "00:00.00",
132 | recordCounter: 0,
133 | record:[
134 | {title:"",time:""},
135 | {title:"",time:""},
136 | {title:"",time:""},
137 | {title:"",time:""},
138 | {title:"",time:""},
139 | {title:"",time:""},
140 | {title:"",time:""}
141 | ],
142 | };
143 | }
144 |
145 | componentWillUnmount() {
146 | this._stopWatch();
147 | this._clearRecord();
148 | }
149 |
150 | componentDidMount() {
151 | if(Platform.OS === "ios"){
152 | StatusBar.setBarStyle(0);
153 | }
154 | }
155 |
156 | _startWatch() {
157 | if (this.state.resetWatch) {
158 | this.setState({
159 | stopWatch: false,
160 | resetWatch: false,
161 | timeAccumulation:0,
162 | initialTime: (new Date()).getTime()
163 | })
164 | }else{
165 | this.setState({
166 | stopWatch: false,
167 | initialTime: (new Date()).getTime()
168 | })
169 | }
170 | let milSecond, second, minute, countingTime, secmilSecond, secsecond, secminute, seccountingTime;
171 | let interval = setInterval(
172 | () => {
173 | this.setState({
174 | currentTime: (new Date()).getTime()
175 | })
176 | countingTime = this.state.timeAccumulation + this.state.currentTime - this.state.initialTime;
177 | minute = Math.floor(countingTime/(60*1000));
178 | second = Math.floor((countingTime-6000*minute)/1000);
179 | milSecond = Math.floor((countingTime%1000)/10);
180 | seccountingTime = countingTime - this.state.recordTime;
181 | secminute = Math.floor(seccountingTime/(60*1000));
182 | secsecond = Math.floor((seccountingTime-6000*secminute)/1000);
183 | secmilSecond = Math.floor((seccountingTime%1000)/10);
184 | this.setState({
185 | totalTime: (minute<10? "0"+minute:minute)+":"+(second<10? "0"+second:second)+"."+(milSecond<10? "0"+milSecond:milSecond),
186 | sectionTime: (secminute<10? "0"+secminute:secminute)+":"+(secsecond<10? "0"+secsecond:secsecond)+"."+(secmilSecond<10? "0"+secmilSecond:secmilSecond),
187 | })
188 | if (this.state.stopWatch) {
189 | this.setState({
190 | timeAccumulation: countingTime
191 | })
192 | clearInterval(interval)
193 | };
194 | },10);
195 | }
196 |
197 | _stopWatch() {
198 | this.setState({
199 | stopWatch: true
200 | })
201 | }
202 |
203 | _addRecord() {
204 | let {recordCounter, record} = this.state;
205 | recordCounter++;
206 | if (recordCounter<8) {
207 | record.pop();
208 | }
209 | record.unshift({title:"计次"+recordCounter,time:this.state.sectionTime});
210 | this.setState({
211 | recordTime: this.state.timeAccumulation + this.state.currentTime - this.state.initialTime,
212 | recordCounter: recordCounter,
213 | record: record
214 | })
215 | //use refs to call functions within other sub component
216 | //can force to update the states
217 | // this.refs.record._updateData();
218 | }
219 |
220 | _clearRecord() {
221 | this.setState({
222 | stopWatch: false,
223 | resetWatch: true,
224 | intialTime: 0,
225 | currentTime:0,
226 | recordTime:0,
227 | timeAccumulation:0,
228 | totalTime: "00:00.00",
229 | sectionTime: "00:00.00",
230 | recordCounter: 0,
231 | record:[
232 | {title:"",time:""},
233 | {title:"",time:""},
234 | {title:"",time:""},
235 | {title:"",time:""},
236 | {title:"",time:""},
237 | {title:"",time:""},
238 | {title:"",time:""}
239 | ],
240 | });
241 | }
242 |
243 | render(){
244 | return(
245 |
246 |
247 | this._addRecord()} clearRecord={()=>this._clearRecord()} startWatch={()=>this._startWatch()} stopWatch={()=>this._stopWatch()}>
248 |
249 |
250 | )
251 | }
252 | }
253 |
254 | const styles = StyleSheet.create({
255 | watchContainer:{
256 | alignItems: "center",
257 | backgroundColor: "#f3f3f3",
258 | marginTop: 60,
259 | },
260 | watchFaceContainer:{
261 | width: Util.size.width,
262 | paddingTop: 50, paddingLeft: 30, paddingRight:30, paddingBottom:40,
263 | backgroundColor: "#fff",
264 | borderBottomWidth: 1, borderBottomColor:"#ddd",
265 | height: 170,
266 | },
267 | sectionTime:{
268 | fontSize: 20,
269 | fontWeight:"100",
270 | paddingRight: 30,
271 | color: "#555",
272 | position:"absolute",
273 | left:Util.size.width-140,
274 | top:30
275 | },
276 | totalTime:{
277 | fontSize: Util.size.width === 375? 70:60,
278 | fontWeight: "100",
279 | color: "#222",
280 | paddingLeft:20
281 | },
282 | watchControlContainer:{
283 | width: Util.size.width,
284 | height: 100,
285 | flexDirection:"row",
286 | backgroundColor: '#f3f3f3',
287 | paddingTop: 30, paddingLeft: 60, paddingRight:60, paddingBottom:0,
288 | },
289 | btnStart:{
290 | width: 70,
291 | height: 70,
292 | borderRadius: 35,
293 | backgroundColor:"#fff",
294 | alignItems:"center",
295 | justifyContent:"center"
296 | },
297 | btnStop:{
298 | width: 70,
299 | height: 70,
300 | borderRadius: 35,
301 | backgroundColor:"#fff",
302 | alignItems:"center",
303 | justifyContent:"center"
304 | },
305 | btnStartText:{
306 | fontSize:14,
307 | backgroundColor:"transparent"
308 | },
309 | btnStopText:{
310 | fontSize:14,
311 | backgroundColor:"transparent",
312 | color:"#555"
313 | },
314 | recordList:{
315 | width: Util.size.width,
316 | height: Util.size.height - 300,
317 | paddingLeft: 15,
318 | },
319 | recordItem:{
320 | height: 40,
321 | borderBottomWidth:Util.pixel,borderBottomColor:"#bbb",
322 | paddingTop: 5, paddingLeft: 10, paddingRight:10, paddingBottom:5,
323 | flexDirection:"row",
324 | alignItems:"center"
325 | },
326 | recordItemTitle:{
327 | backgroundColor:"transparent",
328 | flex:1,
329 | textAlign:"left",
330 | paddingLeft:20,
331 | color:"#777"
332 | },
333 | recordItemTime:{
334 | backgroundColor:"transparent",
335 | flex:1,
336 | textAlign:"right",
337 | paddingRight:20,
338 | color:"#222"
339 | },
340 | });
--------------------------------------------------------------------------------