├── .babelrc ├── .buckconfig ├── .eslintrc ├── .flowconfig ├── .gitattributes ├── .gitignore ├── .watchmanconfig ├── LICENSE ├── README.md ├── android ├── app │ ├── BUCK │ ├── build.gradle │ ├── proguard-rules.pro │ └── src │ │ └── main │ │ ├── AndroidManifest.xml │ │ ├── assets │ │ └── fonts │ │ │ ├── Entypo.ttf │ │ │ ├── EvilIcons.ttf │ │ │ ├── FontAwesome.ttf │ │ │ ├── Foundation.ttf │ │ │ ├── Ionicons.ttf │ │ │ ├── MaterialCommunityIcons.ttf │ │ │ ├── MaterialIcons.ttf │ │ │ ├── Octicons.ttf │ │ │ ├── SimpleLineIcons.ttf │ │ │ └── Zocial.ttf │ │ ├── java │ │ └── com │ │ │ └── mobilecenterreactnativeapp │ │ │ ├── MainActivity.java │ │ │ └── MainApplication.java │ │ └── res │ │ ├── mipmap-hdpi │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxhdpi │ │ └── ic_launcher.png │ │ └── values │ │ ├── strings.xml │ │ └── styles.xml ├── build.gradle ├── gradle.properties ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── keystores │ ├── BUCK │ └── debug.keystore.properties └── settings.gradle ├── index.android.js ├── index.ios.js ├── ios ├── MobileCenterReactNativeApp.xcodeproj │ ├── project.pbxproj │ └── xcshareddata │ │ └── xcschemes │ │ └── MobileCenterReactNativeApp.xcscheme ├── MobileCenterReactNativeApp │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Base.lproj │ │ └── LaunchScreen.xib │ ├── Images.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── Info.plist │ └── main.m └── MobileCenterReactNativeAppTests │ ├── Info.plist │ └── MobileCenterReactNativeAppTests.m ├── js ├── actions │ ├── apps.js │ ├── login.js │ └── types.js ├── components │ ├── Container │ │ └── container.js │ ├── app │ │ └── manageApp.js │ ├── button.js │ ├── loading.js │ ├── navigationDrawer.js │ └── tabicon.js ├── config.js ├── containers │ ├── app │ │ ├── AnalyticsContainer.js │ │ ├── BuildContainer.js │ │ ├── CrashContainer.js │ │ ├── DistributeContainer.js │ │ ├── Start │ │ │ └── ManageAppContainer.js │ │ ├── StartContainer.js │ │ └── TestContainer.js │ ├── appContainer.js │ ├── appsContainer.js │ ├── loginContainer.js │ └── mobilecenter.js ├── img │ ├── app-analytics.png │ ├── app-build.png │ ├── app-crashes.png │ ├── app-distribute.png │ ├── app-test.png │ └── splash.png ├── pages │ ├── App.js │ ├── Apps.js │ ├── Login.js │ ├── Notification.js │ ├── Splash.js │ ├── User.js │ └── app │ │ ├── Analytics.js │ │ ├── Build.js │ │ ├── Crash.js │ │ ├── Distribute.js │ │ ├── Start.js │ │ ├── Start │ │ └── ManageApp.js │ │ └── Test.js ├── reducers │ ├── __tests__ │ │ ├── apps.spec.js │ │ └── login.spec.js │ ├── apps.js │ ├── index.js │ ├── login.js │ └── routes.js ├── sagas │ ├── __tests__ │ │ ├── apps.spec.js │ │ └── login.spec.js │ ├── apps.js │ ├── index.js │ └── login.js ├── setup.js ├── store │ └── configureStore.js └── utils │ ├── RequestUtil.js │ ├── StorageUtil.js │ └── ToastUtil.js ├── jsconfig.json ├── package.json ├── storybook ├── addons.js ├── index.android.js ├── index.ios.js └── stories │ ├── Button │ ├── index.android.js │ └── index.ios.js │ ├── CenterView │ ├── index.js │ └── style.js │ ├── Welcome │ └── index.js │ └── index.js ├── wireframe.md └── yarn.lock /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["react-native"] 3 | } -------------------------------------------------------------------------------- /.buckconfig: -------------------------------------------------------------------------------- 1 | 2 | [android] 3 | target = Google Inc.:Google APIs:23 4 | 5 | [maven_repositories] 6 | central = https://repo1.maven.org/maven2 7 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "airbnb", 3 | "env": { 4 | "browser": true, 5 | "node": true, 6 | "jest": true 7 | }, 8 | "ecmaFeatures": { 9 | "forOf": true, 10 | "jsx": true, 11 | "es6": true 12 | }, 13 | "rules": { 14 | "comma-dangle": 0, 15 | "react/prop-types": 0, 16 | "no-use-before-define": 0, 17 | "radix": 0, 18 | "no-param-reassign": 0, 19 | "react/jsx-filename-extension": 0, 20 | "no-mixed-operators": 0, 21 | "import/prefer-default-export": 0, 22 | "import/no-extraneous-dependencies": 0, 23 | "no-plusplus": 0, 24 | "react/prefer-stateless-function": 0, 25 | "class-methods-use-this": 0 26 | } 27 | } -------------------------------------------------------------------------------- /.flowconfig: -------------------------------------------------------------------------------- 1 | [ignore] 2 | ; We fork some components by platform 3 | .*/*[.]android.js 4 | 5 | ; Ignore "BUCK" generated dirs 6 | /\.buckd/ 7 | 8 | ; Ignore unexpected extra "@providesModule" 9 | .*/node_modules/.*/node_modules/fbjs/.* 10 | 11 | ; Ignore duplicate module providers 12 | ; For RN Apps installed via npm, "Libraries" folder is inside 13 | ; "node_modules/react-native" but in the source repo it is in the root 14 | .*/Libraries/react-native/React.js 15 | .*/Libraries/react-native/ReactNative.js 16 | 17 | [include] 18 | 19 | [libs] 20 | node_modules/react-native/Libraries/react-native/react-native-interface.js 21 | node_modules/react-native/flow 22 | flow/ 23 | 24 | [options] 25 | module.system=haste 26 | 27 | experimental.strict_type_args=true 28 | 29 | munge_underscores=true 30 | 31 | 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' 32 | 33 | suppress_type=$FlowIssue 34 | suppress_type=$FlowFixMe 35 | suppress_type=$FixMe 36 | 37 | suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(3[0-6]\\|[1-2][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\) 38 | 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]+ 39 | suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy 40 | 41 | unsafe.enable_getters_and_setters=true 42 | 43 | [version] 44 | ^0.36.0 45 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.pbxproj -text 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | .vscode/ 6 | 7 | # Xcode 8 | # 9 | build/ 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata 19 | *.xccheckout 20 | *.moved-aside 21 | DerivedData 22 | *.hmap 23 | *.ipa 24 | *.xcuserstate 25 | project.xcworkspace 26 | 27 | # Android/IntelliJ 28 | # 29 | build/ 30 | .idea 31 | .gradle 32 | local.properties 33 | *.iml 34 | 35 | # node.js 36 | # 37 | node_modules/ 38 | npm-debug.log 39 | 40 | # BUCK 41 | buck-out/ 42 | \.buckd/ 43 | android/app/libs 44 | *.keystore 45 | 46 | # fastlane 47 | # 48 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 49 | # screenshots whenever they are needed. 50 | # For more information about the recommended setup visit: 51 | # https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md 52 | 53 | fastlane/report.xml 54 | fastlane/Preview.html 55 | fastlane/screenshots 56 | 57 | js/experiment/ 58 | temp.md -------------------------------------------------------------------------------- /.watchmanconfig: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Mobile Center Mobile App 2 | 3 | Copyright (c) Microsoft Corporation 4 | 5 | All rights reserved. 6 | 7 | MIT License 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # App Center Mobile App 2 | 3 | # 4 | 5 | [Visual Studio App Center](https://www.visualstudio.com/vs/app-center/) is mission control to help mobile developers build mobile apps. 6 | 7 | Visual Studio App Center Mobile App complements App Center portal to let mobile developers track developed apps' usage from customers in a light and mobile manner. The source code is 100% based on **React/React Native/Redux**. 8 | 9 | **Notes** Visual Studio App Center App will support all features that you (avid mobile developer) want. It is not a duplicate of App Center portal. Thus, we care your ideas. Open issues now to let us know what we should go next. 10 | 11 | ## Code Structure 12 | 13 | Under **js** folder: 14 | 15 | - **actions**: Action and Action Creator 16 | - **sagas**: Saga asyn request (encapsulation of actions) 17 | - **reducers**: State Controllers 18 | - **utils**: REST API Calls 19 | - **store**: Redux Store 20 | - **containers**: [Container Components](https://github.com/reactjs/redux/blob/master/docs/basics/UsageWithReact.md) 21 | - **pages**: [Presentational Components](https://github.com/reactjs/redux/blob/master/docs/basics/UsageWithReact.md) 22 | - **components**: React Components, use [react-storybook](https://github.com/storybooks/react-storybook) to polish 23 | 24 | ## Working Units -- Sync with Backlog 25 | 26 | - **login**: User can login via Github/ MSA / Mobile Center Account. 27 | - **apps**: User can view all apps they have access too and navigate to each app they have access to. 28 | - **user**: User Information 29 | - **notification**: notification of apps (build, distribution, crash, analytics) 30 | - **app**: User can view an app information 31 | - **app.distribution.view**: User can view all distribution groups for an app. 32 | - **app.distribution.addemail**: User can add new user emails to a distribution group. 33 | - **app.distribution.group**: User can create/ delete distribution group. 34 | 35 | ## TODO List 36 | 37 | Search for the **TODO** tag in the code base to check for incomplete tasks. 38 | 39 | - Code-Push 40 | - Continuous Integration with Fastlane and Bitrise, [Article](http://blog.thebakery.io/continuous-integration-for-react-native-applications-with-fastlane-and-bitrise-ios-version/) 41 | - Mobile Center React Native SDK to track app usage by developers, [mobile-center-sdk-react-native](https://github.com/Microsoft/mobile-center-sdk-react-native) 42 | - Push Notification (per app configuration),[react-native-push-notification](https://github.com/zo0r/react-native-push-notification) 43 | - Redux Immutable State, [redux-immutable](https://github.com/gajus/redux-immutable) 44 | - Reselect : efficient rendering computation. 45 | 46 | ## Third Party Tools and APIs 47 | 48 | _We would like to thank and appreciate the efforts that the below library authors have made. We build upon your shoulders._ 49 | 50 | - [Microsoft Code Push](https://github.com/Microsoft/react-native-code-push) for dynamic update 51 | - [Redux](https://github.com/reactjs/redux) is a predictable state container for reading application, together with [React Native](https://github.com/facebook/react-native) 52 | - [Redux-Saga](https://github.com/yelouafi/redux-saga/) is a library that aims to make side effects in reading application easier and better 53 | - [react-native-router-flux](https://github.com/aksonov/react-native-router-flux) is a router for reading based on new react native navigation API and redux 54 | - [Jest](https://facebook.github.io/jest/) for testing [React Native](https://github.com/facebook/react-native) components and UT 55 | - [Eslint](https://github.com/eslint/eslint) is a tool for identifying and reporting on patterns found in reading application code 56 | - [redux-devtools](https://github.com/gaearon/redux-devtools) DevTools for Redux with hot reloading, action replay, and customizable UI 57 | 58 | ## Build 59 | 60 | TODO, check with a new setup in a machine. 61 | 62 | 74 | 75 | 76 | 77 | ``` 78 | npm install 79 | react-native start 80 | ``` 81 | 84 | 85 | 88 | 89 | # Contributing 90 | 91 | There are several ways to contribute to the current app: 92 | 93 | 1. **Full stack contribution**: If you want to implement one [func sync with backlog](#Working Units -- Sync with Backlog), you need to implement actions, sagas, reducers, api calls, container and presentational containers. __Please make sure to write the saga and reducer jest tests, all tests should be passed for a PR.__ Here it is [Microsoft Mobile Center REST API End Point](https://docs.mobile.azure.com/api/). 94 | 95 | 2. **UI contribution**: Design is the most important factor other than implementation, feel free to [react-storybook](https://github.com/storybooks/react-storybook) to share your design idea and refactor the react components. 96 | 97 | 3. **Performance contribution**: Pick the right tool can greatly accelerate our development life cycle, we believe it. In terms of the development, react community is a fast changing world, we love it. Feel free to tell us what libraries we should use to further improve the dev-cycle or the running performance. 98 | 99 | 4. **Idea contribution**: Have you used the [Mobile Center Portal](https://mobile.azure.com/)? We believe you did. The key design philosophy of mobile version is to let developers retrieve app usage data from customizable notification mechanism. Developers only want to fetch data or message, view them in the mobile. They can further do the app update through the web portal. Do you agree with it? If not, can you tell us your opinions? If yes, what other special requirements do you think about? Tell us, we will add it in to fullfill your needs. 100 | 101 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. 102 | -------------------------------------------------------------------------------- /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.mobilecenterreactnativeapp', 50 | ) 51 | 52 | android_resource( 53 | name = 'res', 54 | res = 'src/main/res', 55 | package = 'com.mobilecenterreactnativeapp', 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 | -------------------------------------------------------------------------------- /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 | apply from: "../../node_modules/react-native-code-push/android/codepush.gradle" 70 | 71 | /** 72 | * Set this to true to create two separate APKs instead of one: 73 | * - An APK that only works on ARM devices 74 | * - An APK that only works on x86 devices 75 | * The advantage is the size of the APK is reduced by about 4MB. 76 | * Upload all the APKs to the Play Store and people will download 77 | * the correct one based on the CPU architecture of their device. 78 | */ 79 | def enableSeparateBuildPerCPUArchitecture = false 80 | 81 | /** 82 | * Run Proguard to shrink the Java bytecode in release builds. 83 | */ 84 | def enableProguardInReleaseBuilds = false 85 | 86 | android { 87 | compileSdkVersion 23 88 | buildToolsVersion "23.0.1" 89 | 90 | defaultConfig { 91 | applicationId "com.mobilecenterreactnativeapp" 92 | minSdkVersion 16 93 | targetSdkVersion 22 94 | versionCode 1 95 | versionName "1.0" 96 | ndk { 97 | abiFilters "armeabi-v7a", "x86" 98 | } 99 | } 100 | splits { 101 | abi { 102 | reset() 103 | enable enableSeparateBuildPerCPUArchitecture 104 | universalApk false // If true, also generate a universal APK 105 | include "armeabi-v7a", "x86" 106 | } 107 | } 108 | buildTypes { 109 | release { 110 | minifyEnabled enableProguardInReleaseBuilds 111 | proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" 112 | } 113 | } 114 | // applicationVariants are e.g. debug, release 115 | applicationVariants.all { variant -> 116 | variant.outputs.each { output -> 117 | // For each separate APK per architecture, set a unique version code as described here: 118 | // http://tools.android.com/tech-docs/new-build-system/user-guide/apk-splits 119 | def versionCodes = ["armeabi-v7a":1, "x86":2] 120 | def abi = output.getFilter(OutputFile.ABI) 121 | if (abi != null) { // null for the universal-debug, universal-release variants 122 | output.versionCodeOverride = 123 | versionCodes.get(abi) * 1048576 + defaultConfig.versionCode 124 | } 125 | } 126 | } 127 | } 128 | 129 | dependencies { 130 | compile project(':react-native-vector-icons') 131 | compile project(':react-native-send-intent') 132 | compile project(':react-native-push-notification') 133 | compile project(':react-native-code-push') 134 | compile project(':react-native-device-info') 135 | compile fileTree(dir: "libs", include: ["*.jar"]) 136 | compile "com.android.support:appcompat-v7:23.0.1" 137 | compile "com.facebook.react:react-native:+" // From node_modules 138 | } 139 | 140 | // Run this once to be able to run the application with BUCK 141 | // puts all compile dependencies into folder libs for BUCK to use 142 | task copyDownloadableDepsToLibs(type: Copy) { 143 | from configurations.compile 144 | into 'libs' 145 | } 146 | -------------------------------------------------------------------------------- /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/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/assets/fonts/Entypo.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/app-center-app-react-native/427a789994677c410b1bfc0378e9eb5355cd58ac/android/app/src/main/assets/fonts/Entypo.ttf -------------------------------------------------------------------------------- /android/app/src/main/assets/fonts/EvilIcons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/app-center-app-react-native/427a789994677c410b1bfc0378e9eb5355cd58ac/android/app/src/main/assets/fonts/EvilIcons.ttf -------------------------------------------------------------------------------- /android/app/src/main/assets/fonts/FontAwesome.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/app-center-app-react-native/427a789994677c410b1bfc0378e9eb5355cd58ac/android/app/src/main/assets/fonts/FontAwesome.ttf -------------------------------------------------------------------------------- /android/app/src/main/assets/fonts/Foundation.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/app-center-app-react-native/427a789994677c410b1bfc0378e9eb5355cd58ac/android/app/src/main/assets/fonts/Foundation.ttf -------------------------------------------------------------------------------- /android/app/src/main/assets/fonts/Ionicons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/app-center-app-react-native/427a789994677c410b1bfc0378e9eb5355cd58ac/android/app/src/main/assets/fonts/Ionicons.ttf -------------------------------------------------------------------------------- /android/app/src/main/assets/fonts/MaterialCommunityIcons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/app-center-app-react-native/427a789994677c410b1bfc0378e9eb5355cd58ac/android/app/src/main/assets/fonts/MaterialCommunityIcons.ttf -------------------------------------------------------------------------------- /android/app/src/main/assets/fonts/MaterialIcons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/app-center-app-react-native/427a789994677c410b1bfc0378e9eb5355cd58ac/android/app/src/main/assets/fonts/MaterialIcons.ttf -------------------------------------------------------------------------------- /android/app/src/main/assets/fonts/Octicons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/app-center-app-react-native/427a789994677c410b1bfc0378e9eb5355cd58ac/android/app/src/main/assets/fonts/Octicons.ttf -------------------------------------------------------------------------------- /android/app/src/main/assets/fonts/SimpleLineIcons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/app-center-app-react-native/427a789994677c410b1bfc0378e9eb5355cd58ac/android/app/src/main/assets/fonts/SimpleLineIcons.ttf -------------------------------------------------------------------------------- /android/app/src/main/assets/fonts/Zocial.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/app-center-app-react-native/427a789994677c410b1bfc0378e9eb5355cd58ac/android/app/src/main/assets/fonts/Zocial.ttf -------------------------------------------------------------------------------- /android/app/src/main/java/com/mobilecenterreactnativeapp/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.mobilecenterreactnativeapp; 2 | 3 | import com.facebook.react.ReactActivity; 4 | 5 | public class MainActivity extends ReactActivity { 6 | 7 | /** 8 | * Returns the name of the main component registered from JavaScript. 9 | * This is used to schedule rendering of the component. 10 | */ 11 | @Override 12 | protected String getMainComponentName() { 13 | return "MobileCenterReactNativeApp"; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /android/app/src/main/java/com/mobilecenterreactnativeapp/MainApplication.java: -------------------------------------------------------------------------------- 1 | package com.mobilecenterreactnativeapp; 2 | 3 | import android.app.Application; 4 | import android.util.Log; 5 | 6 | import com.facebook.react.ReactApplication; 7 | import com.oblador.vectoricons.VectorIconsPackage; 8 | import com.burnweb.rnsendintent.RNSendIntentPackage; 9 | import com.dieam.reactnativepushnotification.ReactNativePushNotificationPackage; 10 | import com.microsoft.codepush.react.CodePush; 11 | import com.learnium.RNDeviceInfo.RNDeviceInfo; 12 | import com.facebook.react.ReactInstanceManager; 13 | import com.facebook.react.ReactNativeHost; 14 | import com.facebook.react.ReactPackage; 15 | import com.facebook.react.shell.MainReactPackage; 16 | import com.facebook.soloader.SoLoader; 17 | 18 | import java.util.Arrays; 19 | import java.util.List; 20 | 21 | public class MainApplication extends Application implements ReactApplication { 22 | 23 | private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) { 24 | 25 | @Override 26 | protected String getJSBundleFile() { 27 | return CodePush.getJSBundleFile(); 28 | } 29 | 30 | @Override 31 | protected boolean getUseDeveloperSupport() { 32 | return BuildConfig.DEBUG; 33 | } 34 | 35 | @Override 36 | protected List getPackages() { 37 | return Arrays.asList( 38 | new MainReactPackage(), 39 | new VectorIconsPackage(), 40 | new RNSendIntentPackage(), 41 | new ReactNativePushNotificationPackage(), 42 | new CodePush(null, getApplicationContext(), BuildConfig.DEBUG), 43 | new RNDeviceInfo() 44 | ); 45 | } 46 | }; 47 | 48 | @Override 49 | public ReactNativeHost getReactNativeHost() { 50 | return mReactNativeHost; 51 | } 52 | 53 | @Override 54 | public void onCreate() { 55 | super.onCreate(); 56 | SoLoader.init(this, /* native exopackage */ false); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/app-center-app-react-native/427a789994677c410b1bfc0378e9eb5355cd58ac/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/app-center-app-react-native/427a789994677c410b1bfc0378e9eb5355cd58ac/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/app-center-app-react-native/427a789994677c410b1bfc0378e9eb5355cd58ac/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/app-center-app-react-native/427a789994677c410b1bfc0378e9eb5355cd58ac/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | MobileCenterReactNativeApp 4 | 5 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/app-center-app-react-native/427a789994677c410b1bfc0378e9eb5355cd58ac/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /android/keystores/BUCK: -------------------------------------------------------------------------------- 1 | keystore( 2 | name = 'debug', 3 | store = 'debug.keystore', 4 | properties = 'debug.keystore.properties', 5 | visibility = [ 6 | 'PUBLIC', 7 | ], 8 | ) 9 | -------------------------------------------------------------------------------- /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/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'MobileCenterReactNativeApp' 2 | include ':react-native-vector-icons' 3 | project(':react-native-vector-icons').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-vector-icons/android') 4 | include ':react-native-send-intent' 5 | project(':react-native-send-intent').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-send-intent/android') 6 | include ':react-native-push-notification' 7 | project(':react-native-push-notification').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-push-notification/android') 8 | include ':react-native-code-push' 9 | project(':react-native-code-push').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-code-push/android/app') 10 | include ':react-native-device-info' 11 | project(':react-native-device-info').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-device-info/android') 12 | 13 | include ':app' 14 | -------------------------------------------------------------------------------- /index.android.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Microsoft Mobile Center App 3 | * 4 | * Copyright (c) Microsoft Corporation 5 | * 6 | * All rights reserved. 7 | * 8 | * MIT License 9 | * 10 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 11 | * software and associated documentation files (the "Software"), to deal in the Software 12 | * without restriction, including without limitation the rights to use, copy, modify, 13 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 14 | * permit persons to whom the Software is furnished to do so, subject to the following 15 | * conditions: 16 | * 17 | * The above copyright notice and this permission notice shall be included in all copies or 18 | * substantial portions of the Software. THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF 19 | * ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 21 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR 23 | * THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | * 25 | */ 26 | 27 | import { AppRegistry } from 'react-native'; 28 | import setup from './js/setup'; 29 | 30 | export default setup; 31 | 32 | AppRegistry.registerComponent('MobileCenterReactNativeApp', () => setup); 33 | -------------------------------------------------------------------------------- /index.ios.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Microsoft Mobile Center App 3 | * 4 | * Copyright (c) Microsoft Corporation 5 | * 6 | * All rights reserved. 7 | * 8 | * MIT License 9 | * 10 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 11 | * software and associated documentation files (the "Software"), to deal in the Software 12 | * without restriction, including without limitation the rights to use, copy, modify, 13 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 14 | * permit persons to whom the Software is furnished to do so, subject to the following 15 | * conditions: 16 | * 17 | * The above copyright notice and this permission notice shall be included in all copies or 18 | * substantial portions of the Software. THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF 19 | * ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 21 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR 23 | * THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | * 25 | */ 26 | 27 | import { AppRegistry } from 'react-native'; 28 | import setup from './js/setup'; 29 | 30 | export default setup; 31 | 32 | AppRegistry.registerComponent('MobileCenterReactNativeApp', () => setup); 33 | -------------------------------------------------------------------------------- /ios/MobileCenterReactNativeApp.xcodeproj/xcshareddata/xcschemes/MobileCenterReactNativeApp.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 | -------------------------------------------------------------------------------- /ios/MobileCenterReactNativeApp/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/MobileCenterReactNativeApp/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 | #import 12 | 13 | #import 14 | #import 15 | 16 | @implementation AppDelegate 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 19 | { 20 | NSURL *jsCodeLocation; 21 | 22 | 23 | #ifdef DEBUG 24 | jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index.ios" fallbackResource:nil]; 25 | #else 26 | jsCodeLocation = [CodePush bundleURL]; 27 | #endif 28 | 29 | RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation 30 | moduleName:@"MobileCenterReactNativeApp" 31 | initialProperties:nil 32 | launchOptions:launchOptions]; 33 | rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1]; 34 | 35 | self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; 36 | UIViewController *rootViewController = [UIViewController new]; 37 | rootViewController.view = rootView; 38 | self.window.rootViewController = rootViewController; 39 | [self.window makeKeyAndVisible]; 40 | return YES; 41 | } 42 | 43 | @end 44 | -------------------------------------------------------------------------------- /ios/MobileCenterReactNativeApp/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 | -------------------------------------------------------------------------------- /ios/MobileCenterReactNativeApp/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 | } -------------------------------------------------------------------------------- /ios/MobileCenterReactNativeApp/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 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UIViewControllerBasedStatusBarAppearance 38 | 39 | NSLocationWhenInUseUsageDescription 40 | 41 | NSAppTransportSecurity 42 | 43 | NSExceptionDomains 44 | 45 | localhost 46 | 47 | NSExceptionAllowsInsecureHTTPLoads 48 | 49 | 50 | 51 | 52 | CodePushDeploymentKey 53 | deployment-key-here 54 | UIAppFonts 55 | 56 | Entypo.ttf 57 | EvilIcons.ttf 58 | FontAwesome.ttf 59 | Foundation.ttf 60 | Ionicons.ttf 61 | MaterialCommunityIcons.ttf 62 | MaterialIcons.ttf 63 | Octicons.ttf 64 | SimpleLineIcons.ttf 65 | Zocial.ttf 66 | 67 | 68 | -------------------------------------------------------------------------------- /ios/MobileCenterReactNativeApp/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 | -------------------------------------------------------------------------------- /ios/MobileCenterReactNativeAppTests/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 | -------------------------------------------------------------------------------- /ios/MobileCenterReactNativeAppTests/MobileCenterReactNativeAppTests.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 MobileCenterReactNativeAppTests : XCTestCase 20 | 21 | @end 22 | 23 | @implementation MobileCenterReactNativeAppTests 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 | -------------------------------------------------------------------------------- /js/actions/apps.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Microsoft Mobile Center App 3 | * 4 | * Copyright (c) Microsoft Corporation 5 | * 6 | * All rights reserved. 7 | * 8 | * MIT License 9 | * 10 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 11 | * software and associated documentation files (the "Software"), to deal in the Software 12 | * without restriction, including without limitation the rights to use, copy, modify, 13 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 14 | * permit persons to whom the Software is furnished to do so, subject to the following 15 | * conditions: 16 | * 17 | * The above copyright notice and this permission notice shall be included in all copies or 18 | * substantial portions of the Software. THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF 19 | * ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 21 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR 23 | * THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | * 25 | */ 26 | 27 | import { REQUEST_APPS, RECEIVE_APPS } from './types'; 28 | 29 | export function requestAppList(tokenId) { 30 | return { 31 | type: REQUEST_APPS, 32 | tokenId, 33 | }; 34 | } 35 | 36 | export function receiveAppList(tokenId, json) { 37 | return { 38 | type: RECEIVE_APPS, 39 | tokenId, 40 | apps: json.data.children.map(child => child.data), 41 | receivedAt: Date.now() 42 | }; 43 | } 44 | -------------------------------------------------------------------------------- /js/actions/login.js: -------------------------------------------------------------------------------- 1 | import { LOGIN_REQUEST, LOGIN_SUCCESS , LOGIN_ERROR } from './types'; 2 | 3 | export function loginRequest({ username, password }) { 4 | return { 5 | type: LOGIN_REQUEST, 6 | username, 7 | password 8 | }; 9 | } 10 | 11 | export function loginSuccess(response) { 12 | return { 13 | type: LOGIN_SUCCESS, 14 | response 15 | }; 16 | } 17 | 18 | export function loginError(error) { 19 | return { 20 | type: LOGIN_ERROR, 21 | error 22 | }; 23 | } 24 | -------------------------------------------------------------------------------- /js/actions/types.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Microsoft Mobile Center App 3 | * 4 | * Copyright (c) Microsoft Corporation 5 | * 6 | * All rights reserved. 7 | * 8 | * MIT License 9 | * 10 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 11 | * software and associated documentation files (the "Software"), to deal in the Software 12 | * without restriction, including without limitation the rights to use, copy, modify, 13 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 14 | * permit persons to whom the Software is furnished to do so, subject to the following 15 | * conditions: 16 | * 17 | * The above copyright notice and this permission notice shall be included in all copies or 18 | * substantial portions of the Software. THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF 19 | * ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 21 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR 23 | * THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | * 25 | */ 26 | 27 | // REST APIs 28 | // https://docs.mobile.azure.com/api/#/ 29 | 30 | export const LOGIN_REQUEST = 'LOGIN_REQUEST'; 31 | export const LOGIN_SUCCESS = 'LOGIN_SUCCESS'; 32 | export const LOGIN_ERROR = 'LOGIN_ERROR'; 33 | 34 | export const LOGOUT_REQUEST = 'LOGOUT_REQUEST'; 35 | export const LOGOUT_SUCCESS = 'LOGOUT_SUCCESS'; 36 | export const LOGOUT_ERROR = 'LOGOUT_ERROR'; 37 | 38 | export const REQUEST_APPS = 'REQUEST_APP_LIST'; 39 | export const RECEIVE_APPS = 'RECEIVE_APP_LIST'; 40 | export const RECEIVE_APPS_ERROR = 'RECEIVE_APP_LIST_ERROR'; 41 | 42 | export const REQUEST_USER = 'REQUEST_USER'; 43 | export const FETCH_USER = 'FETCH_USER'; 44 | export const RECEIVE_USER = 'RECEIVE_USER'; 45 | -------------------------------------------------------------------------------- /js/components/Container/container.js: -------------------------------------------------------------------------------- 1 | export const Container = ({ children }) => ( 2 | { children } 3 | ); 4 | -------------------------------------------------------------------------------- /js/components/app/manageApp.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {StyleSheet, Text, View} from "react-native"; 3 | import Button from 'react-native-button'; 4 | import { Actions } from 'react-native-router-flux'; 5 | 6 | const styles = StyleSheet.create({ 7 | container: { 8 | flex: 1, 9 | justifyContent: 'center', 10 | alignItems: 'center', 11 | backgroundColor: '#F5FCFF', 12 | borderWidth: 2, 13 | borderColor: 'red', 14 | }, 15 | }); 16 | 17 | const ManageApp = () => { 18 | return ( 19 | 20 | Manage App 21 | 22 | ); 23 | }; 24 | 25 | export default ManageApp; 26 | -------------------------------------------------------------------------------- /js/components/button.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Microsoft Mobile Center App 3 | * 4 | * Copyright (c) Microsoft Corporation 5 | * 6 | * All rights reserved. 7 | * 8 | * MIT License 9 | * 10 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 11 | * software and associated documentation files (the "Software"), to deal in the Software 12 | * without restriction, including without limitation the rights to use, copy, modify, 13 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 14 | * permit persons to whom the Software is furnished to do so, subject to the following 15 | * conditions: 16 | * 17 | * The above copyright notice and this permission notice shall be included in all copies or 18 | * substantial portions of the Software. THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF 19 | * ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 21 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR 23 | * THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | * 25 | */ 26 | 27 | import React, { PropTypes } from 'react'; 28 | import { 29 | View, 30 | Text, 31 | TouchableOpacity 32 | } from 'react-native'; 33 | 34 | const propTypes = { 35 | onPress: PropTypes.func, 36 | disabled: PropTypes.bool, 37 | style: Text.propTypes.style, 38 | containerStyle: View.propTypes.style, 39 | text: PropTypes.string, 40 | activeOpacity: PropTypes.number 41 | }; 42 | 43 | const Button = ({ onPress, disabled, style, containerStyle, text, activeOpacity }) => ( 44 | 50 | 51 | {text} 52 | 53 | 54 | ); 55 | 56 | Button.propTypes = propTypes; 57 | 58 | Button.defaultProps = { 59 | onPress() {}, 60 | disabled: false, 61 | activeOpacity: 0.8 62 | }; 63 | 64 | export default Button; -------------------------------------------------------------------------------- /js/components/loading.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Microsoft Mobile Center App 3 | * 4 | * Copyright (c) Microsoft Corporation 5 | * 6 | * All rights reserved. 7 | * 8 | * MIT License 9 | * 10 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 11 | * software and associated documentation files (the "Software"), to deal in the Software 12 | * without restriction, including without limitation the rights to use, copy, modify, 13 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 14 | * permit persons to whom the Software is furnished to do so, subject to the following 15 | * conditions: 16 | * 17 | * The above copyright notice and this permission notice shall be included in all copies or 18 | * substantial portions of the Software. THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF 19 | * ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 21 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR 23 | * THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | * 25 | */ 26 | 27 | import React from 'react'; 28 | import { ActivityIndicator, Text, StyleSheet, View } from 'react-native'; 29 | 30 | const LoadingView = () => { 31 | 32 | 36 | Loading Data... 37 | ; 38 | }; 39 | 40 | const styles = StyleSheet.create({ 41 | loading: { 42 | flex: 1, 43 | alignItems: 'center', 44 | justifyContent: 'center', 45 | backgroundColor: 'white' 46 | }, 47 | loadingText: { 48 | marginTop: 10, 49 | textAlign: 'center' 50 | } 51 | }); 52 | 53 | export default LoadingView; 54 | -------------------------------------------------------------------------------- /js/components/navigationDrawer.js: -------------------------------------------------------------------------------- 1 | import React, { PropTypes } from 'react'; 2 | import Drawer from 'react-native-drawer'; 3 | import { DefaultRenderer, Actions } from 'react-native-router-flux'; 4 | import ManageApp from './app/manageApp'; 5 | 6 | const propTypes = { 7 | navigationState: PropTypes.object, 8 | } 9 | 10 | class NavigationDrawer extends React.Component { 11 | render() { 12 | const state = this.props.navigationState; 13 | const children = state.children; 14 | return ( 15 | } 18 | side="right" 19 | > 20 | 21 | 22 | ); 23 | } 24 | } 25 | 26 | NavigationDrawer.propTypes = propTypes; 27 | 28 | export default NavigationDrawer; 29 | -------------------------------------------------------------------------------- /js/components/tabicon.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Microsoft Mobile Center App 3 | * 4 | * Copyright (c) Microsoft Corporation 5 | * 6 | * All rights reserved. 7 | * 8 | * MIT License 9 | * 10 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 11 | * software and associated documentation files (the "Software"), to deal in the Software 12 | * without restriction, including without limitation the rights to use, copy, modify, 13 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 14 | * permit persons to whom the Software is furnished to do so, subject to the following 15 | * conditions: 16 | * 17 | * The above copyright notice and this permission notice shall be included in all copies or 18 | * substantial portions of the Software. THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF 19 | * ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 21 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR 23 | * THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | * 25 | */ 26 | 27 | import React from 'react'; 28 | import { 29 | View, 30 | Text, 31 | StyleSheet 32 | } from 'react-native'; 33 | import Icon from 'react-native-vector-icons/Ionicons'; 34 | 35 | export default class TabIcon extends React.Component { 36 | render() { 37 | return ( 38 | 39 | 44 | 45 | {this.props.title} 46 | 47 | 48 | ); 49 | } 50 | } 51 | 52 | const styles = StyleSheet.create({ 53 | container: { 54 | flexDirection: 'column', 55 | alignItems: 'center' 56 | }, 57 | title: { 58 | fontSize: 14 59 | } 60 | }); 61 | -------------------------------------------------------------------------------- /js/config.js: -------------------------------------------------------------------------------- 1 | export const TOKENID = '1938077bc136d1b81c65c4d74fc4f593d9c28b02'; -------------------------------------------------------------------------------- /js/containers/app/AnalyticsContainer.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { connect } from 'react-redux'; 3 | import Analytics from '../../pages/app/Analytics'; 4 | 5 | class AnalyticsContainer extends React.Component { 6 | render() { 7 | return ( 8 | 9 | ); 10 | } 11 | } 12 | 13 | export default connect()(AnalyticsContainer); 14 | -------------------------------------------------------------------------------- /js/containers/app/BuildContainer.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { connect } from 'react-redux'; 3 | import Build from '../../pages/app/Build'; 4 | 5 | class BuildContainer extends React.Component { 6 | render() { 7 | return ( 8 | 9 | ); 10 | } 11 | } 12 | 13 | export default connect()(BuildContainer); 14 | -------------------------------------------------------------------------------- /js/containers/app/CrashContainer.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { connect } from 'react-redux'; 3 | import Crash from '../../pages/app/Crash'; 4 | 5 | class CrashContainer extends React.Component { 6 | render() { 7 | return ( 8 | 9 | ); 10 | } 11 | } 12 | 13 | export default connect()(CrashContainer); 14 | -------------------------------------------------------------------------------- /js/containers/app/DistributeContainer.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { connect } from 'react-redux'; 3 | import Distribute from '../../pages/app/Distribute'; 4 | 5 | class DistributeContainer extends React.Component { 6 | render() { 7 | return ( 8 | 9 | ); 10 | } 11 | } 12 | 13 | export default connect()(DistributeContainer); 14 | -------------------------------------------------------------------------------- /js/containers/app/Start/ManageAppContainer.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { connect } from 'react-redux'; 3 | import ManageApp from '../../../pages/app/Start/ManageApp'; 4 | 5 | class ManageAppContainer extends React.Component { 6 | render() { 7 | return ( 8 | 9 | ); 10 | } 11 | } 12 | 13 | export default connect()(ManageAppContainer); 14 | -------------------------------------------------------------------------------- /js/containers/app/StartContainer.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { connect } from 'react-redux'; 3 | import Start from '../../pages/app/Start'; 4 | 5 | class StartContainer extends React.Component { 6 | render() { 7 | return ( 8 | 9 | ); 10 | } 11 | } 12 | 13 | export default connect()(StartContainer); 14 | -------------------------------------------------------------------------------- /js/containers/app/TestContainer.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { connect } from 'react-redux'; 3 | import Test from '../../pages/app/Test'; 4 | 5 | class TestContainer extends React.Component { 6 | render() { 7 | return ( 8 | 9 | ); 10 | } 11 | } 12 | 13 | export default connect()(TestContainer); 14 | -------------------------------------------------------------------------------- /js/containers/appContainer.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { connect } from 'react-redux'; 3 | import App from '../pages/App'; 4 | 5 | class AppContainer extends React.Component { 6 | render() { 7 | return ( 8 | 9 | ); 10 | } 11 | } 12 | 13 | export default connect()(AppContainer); 14 | -------------------------------------------------------------------------------- /js/containers/appsContainer.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Microsoft Mobile Center App 3 | * 4 | * Copyright (c) Microsoft Corporation 5 | * 6 | * All rights reserved. 7 | * 8 | * MIT License 9 | * 10 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 11 | * software and associated documentation files (the "Software"), to deal in the Software 12 | * without restriction, including without limitation the rights to use, copy, modify, 13 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 14 | * permit persons to whom the Software is furnished to do so, subject to the following 15 | * conditions: 16 | * 17 | * The above copyright notice and this permission notice shall be included in all copies or 18 | * substantial portions of the Software. THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF 19 | * ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 21 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR 23 | * THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | * 25 | */ 26 | 27 | import React from 'react'; 28 | import { connect } from 'react-redux'; 29 | import Apps from '../pages/Apps'; 30 | 31 | class AppsContainer extends React.Component { 32 | render() { 33 | return ( 34 | 35 | ); 36 | } 37 | } 38 | 39 | export default connect()(AppsContainer); 40 | -------------------------------------------------------------------------------- /js/containers/loginContainer.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { connect } from 'react-redux'; 3 | import Login from '../pages/Login'; 4 | 5 | class LoginContainer extends React.Component { 6 | render() { 7 | return ( 8 | 9 | ); 10 | } 11 | } 12 | 13 | export default connect()(LoginContainer); 14 | -------------------------------------------------------------------------------- /js/containers/mobilecenter.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Microsoft Mobile Center App 3 | * 4 | * Copyright (c) Microsoft Corporation 5 | * 6 | * All rights reserved. 7 | * 8 | * MIT License 9 | * 10 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 11 | * software and associated documentation files (the "Software"), to deal in the Software 12 | * without restriction, including without limitation the rights to use, copy, modify, 13 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 14 | * permit persons to whom the Software is furnished to do so, subject to the following 15 | * conditions: 16 | * 17 | * The above copyright notice and this permission notice shall be included in all copies or 18 | * substantial portions of the Software. THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF 19 | * ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 21 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR 23 | * THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | * 25 | */ 26 | 27 | import React from 'react'; 28 | import { StyleSheet, Navigator, Image } from 'react-native'; 29 | import { Router, Scene, ActionConst, Actions } from 'react-native-router-flux'; 30 | import { connect } from 'react-redux'; 31 | import User from '../pages/User'; 32 | import Notification from '../pages/Notification'; 33 | import AppsContainer from './appsContainer'; 34 | import AppContainer from './appContainer'; 35 | import StartContainer from './app/StartContainer'; 36 | import BuildContainer from './app/BuildContainer'; 37 | import TestContainer from './app/TestContainer'; 38 | import DistributeContainer from './app/DistributeContainer'; 39 | import CrashContainer from './app/CrashContainer'; 40 | import AnalyticsContainer from './app/AnalyticsContainer'; 41 | 42 | import Drawer from 'react-native-drawer'; 43 | import Login from './loginContainer'; 44 | import TabIcon from '../components/tabicon'; 45 | import Splash from '../pages/Splash'; 46 | import NavigationDrawer from '../components/navigationDrawer'; 47 | import ManageApp from '../components/app/manageApp'; 48 | 49 | const RouterWithRedux = connect()(Router); 50 | 51 | // const appBuildImg = require('../img/app-build.png'); 52 | // const appTestImg = require('../img/app-test.png'); 53 | // const appDistributeImg = require('../img/app-distribute.png'); 54 | // const appCrashImg = require('../img/app-crashes.png'); 55 | // const appAnalyticsImg = require('../img/app-analytics.png'); 56 | 57 | class MobileCenter extends React.Component { 58 | render() { 59 | return ( 60 | 65 | 66 | 67 | 68 | 69 | 76 | 83 | 90 | 91 | 92 | 93 | 98 | Actions.pop()} 105 | leftTitle="Back" 106 | /> 107 | Actions.pop()} 114 | leftTitle="Back" 115 | /> 116 | Actions.pop()} 123 | leftTitle="Back" 124 | /> 125 | Actions.pop()} 132 | leftTitle="Back" 133 | /> 134 | Actions.pop()} 141 | leftTitle="Back" 142 | /> 143 | Actions.pop()} 150 | leftTitle="Back" 151 | /> 152 | 153 | 154 | 155 | 156 | ); 157 | } 158 | } 159 | 160 | const getSceneStyle = (props, computedProps) => { 161 | const style = { 162 | flex: 1, 163 | backgroundColor: '#fff', 164 | shadowColor: null, 165 | shadowOffset: null, 166 | shadowOpacity: null, 167 | shadowRadius: null, 168 | }; 169 | if (computedProps.isActive) { 170 | style.marginTop = computedProps.hideNavBar ? 171 | 0 : Navigator.NavigationBar.Styles.General.TotalNavHeight; 172 | style.marginBottom = computedProps.hideTabBar ? 0 : 50; 173 | } 174 | return style; 175 | }; 176 | 177 | const styles = StyleSheet.create({ 178 | navBar: { 179 | backgroundColor: '#3e9ce9' 180 | }, 181 | navBarTitle: { 182 | color: '#fff', 183 | fontSize: 20, 184 | } 185 | }); 186 | 187 | const drawerStyles = { 188 | drawer: { shadowColor: '#000000', shadowOpacity: 0.8, shadowRadius: 3 }, 189 | main: { paddingLeft: 3 }, 190 | }; 191 | 192 | const tabstyles = StyleSheet.create({ 193 | container: { flex: 1, 194 | backgroundColor: 'transparent', 195 | justifyContent: 'center', 196 | alignItems: 'center', 197 | }, 198 | tabBarStyle: { 199 | backgroundColor: '#eee', 200 | }, 201 | tabBarSelectedItemStyle: { 202 | backgroundColor: '#ddd', 203 | }, 204 | }); 205 | 206 | export default MobileCenter; 207 | -------------------------------------------------------------------------------- /js/img/app-analytics.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/app-center-app-react-native/427a789994677c410b1bfc0378e9eb5355cd58ac/js/img/app-analytics.png -------------------------------------------------------------------------------- /js/img/app-build.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/app-center-app-react-native/427a789994677c410b1bfc0378e9eb5355cd58ac/js/img/app-build.png -------------------------------------------------------------------------------- /js/img/app-crashes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/app-center-app-react-native/427a789994677c410b1bfc0378e9eb5355cd58ac/js/img/app-crashes.png -------------------------------------------------------------------------------- /js/img/app-distribute.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/app-center-app-react-native/427a789994677c410b1bfc0378e9eb5355cd58ac/js/img/app-distribute.png -------------------------------------------------------------------------------- /js/img/app-test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/app-center-app-react-native/427a789994677c410b1bfc0378e9eb5355cd58ac/js/img/app-test.png -------------------------------------------------------------------------------- /js/img/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/app-center-app-react-native/427a789994677c410b1bfc0378e9eb5355cd58ac/js/img/splash.png -------------------------------------------------------------------------------- /js/pages/App.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/app-center-app-react-native/427a789994677c410b1bfc0378e9eb5355cd58ac/js/pages/App.js -------------------------------------------------------------------------------- /js/pages/Apps.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Microsoft Mobile Center App 3 | * 4 | * Copyright (c) Microsoft Corporation 5 | * 6 | * All rights reserved. 7 | * 8 | * MIT License 9 | * 10 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 11 | * software and associated documentation files (the "Software"), to deal in the Software 12 | * without restriction, including without limitation the rights to use, copy, modify, 13 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 14 | * permit persons to whom the Software is furnished to do so, subject to the following 15 | * conditions: 16 | * 17 | * The above copyright notice and this permission notice shall be included in all copies or 18 | * substantial portions of the Software. THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF 19 | * ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 21 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR 23 | * THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | * 25 | */ 26 | 27 | import React, { propTypes } from 'react'; 28 | import { StyleSheet, 29 | ListView, 30 | View, 31 | Platform, 32 | Text, 33 | TouchableOpacity, 34 | Alert, 35 | Image, 36 | Button 37 | } from 'react-native'; 38 | import { Actions } from 'react-native-router-flux'; 39 | 40 | const mockData = [ 41 | { 42 | appName: 'Calculator-Test', 43 | abbrName: 'C', 44 | userName: 'buptkang' 45 | }, 46 | { 47 | appName: 'Moody', 48 | abbrName: 'Moody', 49 | userName: 'buptkang' 50 | } 51 | ]; 52 | 53 | export default class Apps extends React.Component { 54 | 55 | constructor(props) { 56 | super(props); 57 | const ds = new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !== r2 }); 58 | this.state = { 59 | dataSource: ds.cloneWithRows(mockData), 60 | }; 61 | this.onPressApp = this.onPressApp.bind(this); 62 | } 63 | 64 | onPressApp(app) { 65 | Actions.tabbar2(); 66 | } 67 | 68 | renderApp(app) { 69 | return ( 70 | this.onPressApp(app)}> 71 | 72 | 73 | 74 | {app.abbrName} 75 | 76 | 77 | 78 | 79 | {app.appName} 80 | 81 | 82 | 83 | {app.userName} 84 | 85 | 86 | 87 | 88 | 89 | ); 90 | } 91 | 92 | render() { 93 | return ( 94 | 95 | this.renderApp(row)} 99 | /> 100 | 101 | ); 102 | } 103 | } 104 | 105 | const styles = StyleSheet.create({ 106 | base: { 107 | flex: 1 108 | }, 109 | container: { 110 | flex: 1, 111 | flexDirection: 'column', 112 | paddingTop: Platform.OS === 'ios' ? 10 : 0 113 | }, 114 | containerItem: { 115 | flexDirection: 'row', 116 | justifyContent: 'center', 117 | alignItems: 'center', 118 | backgroundColor: '#fcfcfc', 119 | padding: 10, 120 | borderBottomColor: '#ddd', 121 | borderBottomWidth: 1 122 | }, 123 | title: { 124 | fontSize: 18, 125 | textAlign: 'left', 126 | color: 'black' 127 | }, 128 | listView: { 129 | backgroundColor: '#eeeeec' 130 | }, 131 | no_data: { 132 | flex: 1, 133 | alignItems: 'center', 134 | justifyContent: 'center', 135 | paddingBottom: 100 136 | }, 137 | drawerContent: { 138 | flexDirection: 'row', 139 | alignItems: 'center', 140 | padding: 15, 141 | borderBottomWidth: 1, 142 | borderBottomColor: '#ddd' 143 | }, 144 | drawerTitleContent: { 145 | height: 120, 146 | justifyContent: 'flex-end', 147 | padding: 20, 148 | backgroundColor: '#3e9ce9' 149 | }, 150 | drawerIcon: { 151 | width: 30, 152 | height: 30, 153 | marginLeft: 5 154 | }, 155 | drawerTitle: { 156 | fontSize: 20, 157 | textAlign: 'left', 158 | color: '#fcfcfc' 159 | }, 160 | drawerText: { 161 | fontSize: 18, 162 | marginLeft: 15, 163 | textAlign: 'center', 164 | color: 'black' 165 | }, 166 | footerContainer: { 167 | flex: 1, 168 | flexDirection: 'row', 169 | justifyContent: 'center', 170 | alignItems: 'center', 171 | padding: 5 172 | }, 173 | footerText: { 174 | textAlign: 'center', 175 | fontSize: 16, 176 | marginLeft: 10 177 | }, 178 | itemImg: { 179 | width: 88, 180 | height: 66, 181 | marginRight: 10 182 | }, 183 | itemRightContent: { 184 | flex: 1, 185 | flexDirection: 'column' 186 | }, 187 | itemRightBottom: { 188 | flex: 1, 189 | flexDirection: 'row', 190 | alignItems: 'center' 191 | }, 192 | userName: { 193 | flex: 1, 194 | fontSize: 14, 195 | color: '#87CEFA', 196 | marginTop: 5, 197 | marginRight: 5 198 | }, 199 | timeAgo: { 200 | fontSize: 14, 201 | color: '#aaaaaa', 202 | marginTop: 5 203 | }, 204 | refreshControlBase: { 205 | backgroundColor: 'transparent' 206 | }, 207 | tab: { 208 | paddingBottom: 0 209 | }, 210 | tabText: { 211 | fontSize: 16 212 | }, 213 | tabBarUnderline: { 214 | backgroundColor: '#3e9ce9', 215 | height: 2 216 | } 217 | }); 218 | 219 | Apps.propTypes = propTypes; 220 | -------------------------------------------------------------------------------- /js/pages/Login.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Microsoft Mobile Center App 3 | * 4 | * Copyright (c) Microsoft Corporation 5 | * 6 | * All rights reserved. 7 | * 8 | * MIT License 9 | * 10 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 11 | * software and associated documentation files (the "Software"), to deal in the Software 12 | * without restriction, including without limitation the rights to use, copy, modify, 13 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 14 | * permit persons to whom the Software is furnished to do so, subject to the following 15 | * conditions: 16 | * 17 | * The above copyright notice and this permission notice shall be included in all copies or 18 | * substantial portions of the Software. THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF 19 | * ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 21 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR 23 | * THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | * 25 | */ 26 | import React, { PropTypes } from 'react'; 27 | import { StyleSheet, Text, 28 | View, TextInput, TouchableHighlight, Alert } from 'react-native'; 29 | import { Actions } from 'react-native-router-flux'; 30 | 31 | export default class Login extends React.Component { 32 | constructor(props) { 33 | super(props); 34 | this.state = { username: 'default', password: 'default' }; 35 | } 36 | 37 | onPress() { 38 | Actions.tabbar(); 39 | } 40 | 41 | render() { 42 | // const {login, dispatch} = this.props; 43 | return ( 44 | 45 | this.setState({ username })} 48 | value={this.state.username} 49 | /> 50 | this.setState({ password })} 53 | value={this.state.password} 54 | /> 55 | 59 | Submit 60 | 61 | 62 | ); 63 | } 64 | } 65 | 66 | let styles = StyleSheet.create({ 67 | container: { 68 | justifyContent: 'center', 69 | marginTop: 50, 70 | padding: 20, 71 | backgroundColor: '#ffffff', 72 | }, 73 | title: { 74 | fontSize: 30, 75 | alignSelf: 'center', 76 | marginBottom: 30 77 | }, 78 | buttonText: { 79 | fontSize: 18, 80 | color: 'white', 81 | alignSelf: 'center' 82 | }, 83 | button: { 84 | height: 36, 85 | backgroundColor: '#48BBEC', 86 | borderColor: '#48BBEC', 87 | borderWidth: 1, 88 | borderRadius: 8, 89 | marginBottom: 10, 90 | alignSelf: 'stretch', 91 | justifyContent: 'center' 92 | } 93 | }); 94 | -------------------------------------------------------------------------------- /js/pages/Notification.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Microsoft Mobile Center App 3 | * 4 | * Copyright (c) Microsoft Corporation 5 | * 6 | * All rights reserved. 7 | * 8 | * MIT License 9 | * 10 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 11 | * software and associated documentation files (the "Software"), to deal in the Software 12 | * without restriction, including without limitation the rights to use, copy, modify, 13 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 14 | * permit persons to whom the Software is furnished to do so, subject to the following 15 | * conditions: 16 | * 17 | * The above copyright notice and this permission notice shall be included in all copies or 18 | * substantial portions of the Software. THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF 19 | * ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 21 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR 23 | * THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | * 25 | */ 26 | 27 | import React from 'react'; 28 | import { Text, View } from 'react-native'; 29 | 30 | // TODO: Add Notification functions 31 | 32 | export default class Notification extends React.Component { 33 | render() { 34 | return ( 35 | 36 | Push Notification 37 | 38 | ); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /js/pages/Splash.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { 3 | Dimensions, 4 | Animated 5 | } from 'react-native'; 6 | import { Actions } from 'react-native-router-flux'; 7 | import store from 'react-native-simple-store'; 8 | 9 | const maxHeight = Dimensions.get('window').height; 10 | const maxWidth = Dimensions.get('window').width; 11 | const splashImg = require('../img/splash.png'); 12 | 13 | export default class Splash extends React.Component { 14 | constructor(props) { 15 | super(props); 16 | this.state = { 17 | bounceValue: new Animated.Value(0.4) 18 | }; 19 | } 20 | 21 | componentDidMount() { 22 | Animated.timing( 23 | this.state.bounceValue, { toValue: 2.0, duration: 1000 } 24 | ).start(); 25 | this.timer = setTimeout(() => { 26 | store.get('isInit') 27 | .then((isInit) => { 28 | if (!isInit) { 29 | Actions.login(); 30 | } 31 | }); 32 | }, 1000); 33 | } 34 | 35 | componentWillUnmount() { 36 | clearTimeout(this.timer); 37 | } 38 | 39 | render() { 40 | return ( 41 | 47 | ); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /js/pages/User.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Microsoft Mobile Center App 3 | * 4 | * Copyright (c) Microsoft Corporation 5 | * 6 | * All rights reserved. 7 | * 8 | * MIT License 9 | * 10 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 11 | * software and associated documentation files (the "Software"), to deal in the Software 12 | * without restriction, including without limitation the rights to use, copy, modify, 13 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 14 | * permit persons to whom the Software is furnished to do so, subject to the following 15 | * conditions: 16 | * 17 | * The above copyright notice and this permission notice shall be included in all copies or 18 | * substantial portions of the Software. THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF 19 | * ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 21 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR 23 | * THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | * 25 | */ 26 | 27 | import React from 'react'; 28 | import { Text, View } from 'react-native'; 29 | 30 | // TODO: User Information 31 | 32 | export default class User extends React.Component { 33 | render() { 34 | return ( 35 | 36 | Render User Information. 37 | 38 | ); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /js/pages/app/Analytics.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Microsoft Mobile Center App 3 | * 4 | * Copyright (c) Microsoft Corporation 5 | * 6 | * All rights reserved. 7 | * 8 | * MIT License 9 | * 10 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 11 | * software and associated documentation files (the "Software"), to deal in the Software 12 | * without restriction, including without limitation the rights to use, copy, modify, 13 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 14 | * permit persons to whom the Software is furnished to do so, subject to the following 15 | * conditions: 16 | * 17 | * The above copyright notice and this permission notice shall be included in all copies or 18 | * substantial portions of the Software. THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF 19 | * ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 21 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR 23 | * THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | * 25 | */ 26 | 27 | import React from 'react'; 28 | import { Text, View } from 'react-native'; 29 | 30 | export default class Analytics extends React.Component { 31 | render() { 32 | return ( 33 | 34 | Analytics 35 | 36 | ); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /js/pages/app/Build.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Microsoft Mobile Center App 3 | * 4 | * Copyright (c) Microsoft Corporation 5 | * 6 | * All rights reserved. 7 | * 8 | * MIT License 9 | * 10 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 11 | * software and associated documentation files (the "Software"), to deal in the Software 12 | * without restriction, including without limitation the rights to use, copy, modify, 13 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 14 | * permit persons to whom the Software is furnished to do so, subject to the following 15 | * conditions: 16 | * 17 | * The above copyright notice and this permission notice shall be included in all copies or 18 | * substantial portions of the Software. THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF 19 | * ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 21 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR 23 | * THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | * 25 | */ 26 | 27 | import React from 'react'; 28 | import { Text, View, ListView, StyleSheet, Platform, TextInput } from 'react-native'; 29 | import SearchBar from 'react-native-search-bar'; 30 | import Button from 'react-native-button'; 31 | 32 | import Drawer from 'react-native-drawer'; 33 | 34 | import ManageApp from '../../containers/app/Start/ManageAppContainer'; 35 | 36 | export default class Build extends React.Component { 37 | 38 | constructor() { 39 | super(); 40 | const ds = new ListView.DataSource({ 41 | rowHasChanged: (r1, r2) => r1 !== r2, 42 | sectionHeaderHasChanged: (s1, s2) => s1 !== s2 43 | }); 44 | 45 | this.state = { 46 | dataSource: ds.cloneWithRows(['Branches ', ' Status', ' Last Commit', ' Last build']), 47 | }; 48 | } 49 | 50 | renderRow(rowData) { 51 | return {rowData}; 52 | } 53 | 54 | renderHeader(rowHeader) { 55 | return { rowHeader } ; 56 | } 57 | 58 | renderSectionHeader(sectionData, sectionID) { 59 | return ( 60 | 61 | 62 | {sectionData} 63 | 64 | 65 | ); 66 | } 67 | 68 | render() { 69 | return ( 70 | this.drawer = c} 72 | type="overlay" 73 | openDrawerOffset={0.2} 74 | panCloseMask={0.2} 75 | content={} 76 | side="right" 77 | tapToClose 78 | negotiatePan 79 | > 80 | 81 | 85 | 91 | 92 | 100 | 101 | 102 | ); 103 | } 104 | } 105 | 106 | var styles = StyleSheet.create({ 107 | listview: { 108 | backgroundColor: '#B0C4DE', 109 | }, 110 | header: { 111 | height: 40, 112 | justifyContent: 'center', 113 | alignItems: 'center', 114 | backgroundColor: '#3B5998', 115 | flexDirection: 'row', 116 | }, 117 | text: { 118 | color: 'white', 119 | paddingHorizontal: 8, 120 | }, 121 | rowText: { 122 | color: '#888888', 123 | }, 124 | thumbText: { 125 | fontSize: 20, 126 | color: '#888888', 127 | }, 128 | buttonContents: { 129 | flexDirection: 'row', 130 | justifyContent: 'center', 131 | alignItems: 'center', 132 | marginHorizontal: 5, 133 | marginVertical: 3, 134 | padding: 5, 135 | backgroundColor: '#EAEAEA', 136 | borderRadius: 3, 137 | paddingVertical: 10, 138 | }, 139 | img: { 140 | width: 64, 141 | height: 64, 142 | marginHorizontal: 10, 143 | backgroundColor: 'transparent', 144 | }, 145 | section: { 146 | flexDirection: 'column', 147 | justifyContent: 'center', 148 | alignItems: 'flex-start', 149 | padding: 6, 150 | backgroundColor: '#5890ff', 151 | }, 152 | }); 153 | -------------------------------------------------------------------------------- /js/pages/app/Crash.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Microsoft Mobile Center App 3 | * 4 | * Copyright (c) Microsoft Corporation 5 | * 6 | * All rights reserved. 7 | * 8 | * MIT License 9 | * 10 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 11 | * software and associated documentation files (the "Software"), to deal in the Software 12 | * without restriction, including without limitation the rights to use, copy, modify, 13 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 14 | * permit persons to whom the Software is furnished to do so, subject to the following 15 | * conditions: 16 | * 17 | * The above copyright notice and this permission notice shall be included in all copies or 18 | * substantial portions of the Software. THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF 19 | * ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 21 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR 23 | * THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | * 25 | */ 26 | 27 | import React from 'react'; 28 | import { Text, View } from 'react-native'; 29 | 30 | export default class Crash extends React.Component { 31 | render() { 32 | return ( 33 | 34 | Crash 35 | 36 | ); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /js/pages/app/Distribute.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Microsoft Mobile Center App 3 | * 4 | * Copyright (c) Microsoft Corporation 5 | * 6 | * All rights reserved. 7 | * 8 | * MIT License 9 | * 10 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 11 | * software and associated documentation files (the "Software"), to deal in the Software 12 | * without restriction, including without limitation the rights to use, copy, modify, 13 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 14 | * permit persons to whom the Software is furnished to do so, subject to the following 15 | * conditions: 16 | * 17 | * The above copyright notice and this permission notice shall be included in all copies or 18 | * substantial portions of the Software. THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF 19 | * ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 21 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR 23 | * THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | * 25 | */ 26 | 27 | import React from 'react'; 28 | import { Text, View, StyleSheet, ScrollView, Image } from 'react-native'; 29 | 30 | import Button from 'react-native-button'; 31 | 32 | import { 33 | Card, 34 | CardImage, 35 | CardTitle, 36 | CardContent, 37 | CardAction 38 | } from 'react-native-card-view'; 39 | 40 | export default class Distribute extends React.Component { 41 | 42 | _renderTitle (title) { 43 | return ( 44 | 45 | {title} 46 | 47 | ) 48 | } 49 | 50 | render() { 51 | return ( 52 | 53 | 54 | 55 | 56 | Collaborators 57 | 58 | 59 | Who do you collaborate with? 60 | 61 | 62 | 63 | 64 | Alpha Testers 65 | 66 | 67 | With whom? 68 | 69 | 70 | 71 | 72 | ); 73 | } 74 | } 75 | 76 | const styles = StyleSheet.create({ 77 | container: { 78 | flex: 1, 79 | marginTop: 60, 80 | marginBottom: 60 81 | }, 82 | title: { 83 | fontSize: 16, 84 | backgroundColor: 'transparent' 85 | }, 86 | button: { 87 | marginRight: 10 88 | }, 89 | card: { 90 | width: 300 91 | } 92 | }); 93 | -------------------------------------------------------------------------------- /js/pages/app/Start.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Microsoft Mobile Center App 3 | * 4 | * Copyright (c) Microsoft Corporation 5 | * 6 | * All rights reserved. 7 | * 8 | * MIT License 9 | * 10 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 11 | * software and associated documentation files (the "Software"), to deal in the Software 12 | * without restriction, including without limitation the rights to use, copy, modify, 13 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 14 | * permit persons to whom the Software is furnished to do so, subject to the following 15 | * conditions: 16 | * 17 | * The above copyright notice and this permission notice shall be included in all copies or 18 | * substantial portions of the Software. THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF 19 | * ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 21 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR 23 | * THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | * 25 | */ 26 | 27 | import React from 'react'; 28 | import { Text, View } from 'react-native'; 29 | import Button from 'react-native-button'; 30 | import Drawer from 'react-native-drawer'; 31 | 32 | import ManageApp from '../../containers/app/Start/ManageAppContainer'; 33 | 34 | export default class Start extends React.Component { 35 | 36 | render() { 37 | return ( 38 | this.drawer = c} 40 | type="overlay" 41 | openDrawerOffset={0.2} 42 | panCloseMask={0.2} 43 | content={} 44 | side="right" 45 | tapToClose 46 | negotiatePan 47 | > 48 | 49 | 57 | Add Mobile Center’s SDK to your app. 58 | 59 | 1. Integrate using CocoaPods 60 | 2. Start the SDK 61 | 3. Explore Data 62 | 63 | 64 | ); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /js/pages/app/Start/ManageApp.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Microsoft Mobile Center App 3 | * 4 | * Copyright (c) Microsoft Corporation 5 | * 6 | * All rights reserved. 7 | * 8 | * MIT License 9 | * 10 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 11 | * software and associated documentation files (the "Software"), to deal in the Software 12 | * without restriction, including without limitation the rights to use, copy, modify, 13 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 14 | * permit persons to whom the Software is furnished to do so, subject to the following 15 | * conditions: 16 | * 17 | * The above copyright notice and this permission notice shall be included in all copies or 18 | * substantial portions of the Software. THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF 19 | * ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 21 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR 23 | * THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | * 25 | */ 26 | 27 | import React from 'react'; 28 | import { StyleSheet, Text, View } from 'react-native'; 29 | 30 | const styles = StyleSheet.create({ 31 | container: { 32 | flex: 1, 33 | justifyContent: 'center', 34 | alignItems: 'center', 35 | backgroundColor: '#F5FCFF', 36 | borderWidth: 2, 37 | borderColor: 'red', 38 | }, 39 | }); 40 | 41 | export default class ManageApp extends React.Component { 42 | render() { 43 | return ( 44 | 45 | Wow, managemy app 46 | 47 | ); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /js/pages/app/Test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Microsoft Mobile Center App 3 | * 4 | * Copyright (c) Microsoft Corporation 5 | * 6 | * All rights reserved. 7 | * 8 | * MIT License 9 | * 10 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 11 | * software and associated documentation files (the "Software"), to deal in the Software 12 | * without restriction, including without limitation the rights to use, copy, modify, 13 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 14 | * permit persons to whom the Software is furnished to do so, subject to the following 15 | * conditions: 16 | * 17 | * The above copyright notice and this permission notice shall be included in all copies or 18 | * substantial portions of the Software. THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF 19 | * ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 21 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR 23 | * THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | * 25 | */ 26 | 27 | import React from 'react'; 28 | import { Text, View } from 'react-native'; 29 | 30 | export default class Test extends React.Component { 31 | render() { 32 | return ( 33 | 34 | Mobile Center Test includes a free trial for UI testing. 35 | 36 | ); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /js/reducers/__tests__/apps.spec.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Microsoft Mobile Center App 3 | * 4 | * Copyright (c) Microsoft Corporation 5 | * 6 | * All rights reserved. 7 | * 8 | * MIT License 9 | * 10 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 11 | * software and associated documentation files (the "Software"), to deal in the Software 12 | * without restriction, including without limitation the rights to use, copy, modify, 13 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 14 | * permit persons to whom the Software is furnished to do so, subject to the following 15 | * conditions: 16 | * 17 | * The above copyright notice and this permission notice shall be included in all copies or 18 | * substantial portions of the Software. THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF 19 | * ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 21 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR 23 | * THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | * 25 | */ 26 | 27 | import apps from '../apps'; 28 | import {REQUEST_APPS, RECEIVE_APPS, RECEIVE_APPS_ERROR} from '../../actions/types'; 29 | 30 | describe('Reducers/ apps', () => { 31 | function getInitState() { 32 | return { 33 | status: 'init' 34 | }; 35 | } 36 | let state = {}; 37 | beforeEach(() => { 38 | state = getInitState(); 39 | }); 40 | 41 | it('should handle initial state', () => { 42 | expect( 43 | apps(state, {}) 44 | ).toEqual( 45 | { status: 'init' } 46 | ); 47 | }); 48 | it('should handle request apps', () => { 49 | expect( 50 | apps(state, { 51 | type: REQUEST_APPS 52 | }) 53 | ).toEqual({ 54 | status: 'isFetching' 55 | }); 56 | }); 57 | it('should handle request apps success', () => { 58 | expect(apps(state, { 59 | type: RECEIVE_APPS, 60 | response: { 61 | apps: ['BOA', 'Chase'], 62 | receivedAt: '12314' 63 | } 64 | })).toEqual({ 65 | status: 'receiveapps', 66 | apps: ['BOA', 'Chase'], 67 | lastUpdated: '12314' 68 | }); 69 | }); 70 | it('should handle request apps error', () => { 71 | expect(apps(state, { 72 | type: RECEIVE_APPS_ERROR, 73 | error: 'error message' 74 | })).toEqual({ 75 | status: 'error', 76 | error: 'error message' 77 | }); 78 | }); 79 | }); 80 | -------------------------------------------------------------------------------- /js/reducers/__tests__/login.spec.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Microsoft Mobile Center App 3 | * 4 | * Copyright (c) Microsoft Corporation 5 | * 6 | * All rights reserved. 7 | * 8 | * MIT License 9 | * 10 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 11 | * software and associated documentation files (the "Software"), to deal in the Software 12 | * without restriction, including without limitation the rights to use, copy, modify, 13 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 14 | * permit persons to whom the Software is furnished to do so, subject to the following 15 | * conditions: 16 | * 17 | * The above copyright notice and this permission notice shall be included in all copies or 18 | * substantial portions of the Software. THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF 19 | * ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 21 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR 23 | * THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | * 25 | */ 26 | 27 | import login from '../login'; 28 | import { LOGIN_REQUEST, LOGIN_SUCCESS, LOGIN_ERROR } from '../../actions/types'; 29 | 30 | describe('Reducers/ login', () => { 31 | 32 | function getInitState() { 33 | return { 34 | status: 'init' 35 | }; 36 | } 37 | 38 | let state = {}; 39 | beforeEach(() => { 40 | state = getInitState(); 41 | }); 42 | 43 | it('should handle initial state', () => { 44 | expect( 45 | login(state, {}) 46 | ).toEqual( 47 | { status: 'init' } 48 | ); 49 | }); 50 | 51 | it('should handle request login', () => { 52 | expect( 53 | login(state, { 54 | type: LOGIN_REQUEST 55 | }) 56 | ).toEqual({ 57 | status: 'loading' 58 | }); 59 | }); 60 | 61 | it('should handle login success', () => { 62 | expect(login(state, { 63 | type: LOGIN_SUCCESS, 64 | response: { 65 | username: 'denny', 66 | token: '12314' 67 | } 68 | })).toEqual({ 69 | status: 'logined', 70 | username: 'denny', 71 | token: '12314' 72 | }); 73 | }); 74 | 75 | it('should handle login error', () => { 76 | expect(login(state, { 77 | type: LOGIN_ERROR, 78 | error: 'error message' 79 | })).toEqual({ 80 | status: 'error', 81 | error: 'error message' 82 | }); 83 | }); 84 | }); 85 | -------------------------------------------------------------------------------- /js/reducers/apps.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Microsoft Mobile Center App 3 | * 4 | * Copyright (c) Microsoft Corporation 5 | * 6 | * All rights reserved. 7 | * 8 | * MIT License 9 | * 10 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 11 | * software and associated documentation files (the "Software"), to deal in the Software 12 | * without restriction, including without limitation the rights to use, copy, modify, 13 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 14 | * permit persons to whom the Software is furnished to do so, subject to the following 15 | * conditions: 16 | * 17 | * The above copyright notice and this permission notice shall be included in all copies or 18 | * substantial portions of the Software. THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF 19 | * ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 21 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR 23 | * THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | * 25 | */ 26 | 27 | import { REQUEST_APPS, RECEIVE_APPS, RECEIVE_APPS_ERROR } from '../actions/types'; 28 | 29 | export default function apps(state = { 30 | status: 'init', 31 | }, action) { 32 | switch (action.type) { 33 | case REQUEST_APPS: 34 | return Object.assign({}, state, { 35 | status: 'isFetching', 36 | }); 37 | case RECEIVE_APPS: 38 | return Object.assign({}, state, { 39 | status: 'receiveapps', 40 | apps: action.response.apps, 41 | lastUpdated: action.response.receivedAt 42 | }); 43 | case RECEIVE_APPS_ERROR: 44 | return { 45 | status: 'error', 46 | error: action.error 47 | }; 48 | default: 49 | return state; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /js/reducers/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Microsoft Mobile Center App 3 | * 4 | * Copyright (c) Microsoft Corporation 5 | * 6 | * All rights reserved. 7 | * 8 | * MIT License 9 | * 10 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 11 | * software and associated documentation files (the "Software"), to deal in the Software 12 | * without restriction, including without limitation the rights to use, copy, modify, 13 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 14 | * permit persons to whom the Software is furnished to do so, subject to the following 15 | * conditions: 16 | * 17 | * The above copyright notice and this permission notice shall be included in all copies or 18 | * substantial portions of the Software. THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF 19 | * ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 21 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR 23 | * THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | * 25 | */ 26 | 27 | import { combineReducers } from 'redux'; 28 | import app from './apps'; 29 | import routes from './routes'; 30 | import login from './login'; 31 | 32 | const rootReducer = combineReducers({ 33 | app, 34 | routes, 35 | login 36 | }); 37 | 38 | export default rootReducer; -------------------------------------------------------------------------------- /js/reducers/login.js: -------------------------------------------------------------------------------- 1 | import { LOGIN_REQUEST, LOGIN_SUCCESS , LOGIN_ERROR } from '../actions/types'; 2 | 3 | export default function login(state = { 4 | status: 'init' 5 | }, action) { 6 | switch (action.type) { 7 | case LOGIN_REQUEST: 8 | return { 9 | status: 'loading' 10 | }; 11 | case LOGIN_SUCCESS: 12 | return { 13 | status: 'logined', 14 | username: action.response.username, 15 | token: action.response.token 16 | }; 17 | case LOGIN_ERROR: 18 | return { 19 | status: 'error', 20 | error: action.error 21 | }; 22 | default: 23 | return state; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /js/reducers/routes.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Microsoft Mobile Center App 3 | * 4 | * Copyright (c) Microsoft Corporation 5 | * 6 | * All rights reserved. 7 | * 8 | * MIT License 9 | * 10 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 11 | * software and associated documentation files (the "Software"), to deal in the Software 12 | * without restriction, including without limitation the rights to use, copy, modify, 13 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 14 | * permit persons to whom the Software is furnished to do so, subject to the following 15 | * conditions: 16 | * 17 | * The above copyright notice and this permission notice shall be included in all copies or 18 | * substantial portions of the Software. THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF 19 | * ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 21 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR 23 | * THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | * 25 | */ 26 | 27 | import { ActionConst } from 'react-native-router-flux'; 28 | 29 | const initialState = { 30 | scene: {}, 31 | }; 32 | 33 | export default function reducer(state = initialState, action = {}) { 34 | switch (action.type) { 35 | case ActionConst.FOCUS: 36 | return Object.assign({}, state, { 37 | scene: action.scene 38 | }); 39 | default: 40 | return state; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /js/sagas/__tests__/apps.spec.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Microsoft Mobile Center App 3 | * 4 | * Copyright (c) Microsoft Corporation 5 | * 6 | * All rights reserved. 7 | * 8 | * MIT License 9 | * 10 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 11 | * software and associated documentation files (the "Software"), to deal in the Software 12 | * without restriction, including without limitation the rights to use, copy, modify, 13 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 14 | * permit persons to whom the Software is furnished to do so, subject to the following 15 | * conditions: 16 | * 17 | * The above copyright notice and this permission notice shall be included in all copies or 18 | * substantial portions of the Software. THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF 19 | * ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 21 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR 23 | * THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | * 25 | */ 26 | 27 | import { takeEvery, call, put, fork } from 'redux-saga/effects'; 28 | import { REQUEST_APPS, RECEIVE_APPS, RECEIVE_APPS_ERROR } from '../../actions/types'; 29 | import { fetchApps, fetchAppsFlow, watchFetchAppList } from '../apps'; 30 | import { appsAPI } from '../../utils/RequestUtil'; 31 | 32 | describe('Sagas/ apps', () => { 33 | 34 | describe('watchFetchAppList', () => { 35 | const generator = watchFetchAppList(); 36 | it('should take every fetch app request', () => { 37 | const expected = takeEvery(REQUEST_APPS, fetchAppsFlow); 38 | const actual = generator.next().value; 39 | expect(expected.name).toEqual(actual.name); 40 | }); 41 | }); 42 | 43 | describe('fetchAppsFlow', () => { 44 | const generator = fetchAppsFlow({ tokenId: '1938077bc136d1b81c65c4d74fc4f593d9c28b02' }); 45 | it('should fork a fetchApps test', () => { 46 | const expected = fork(fetchApps, { tokenId: '1938077bc136d1b81c65c4d74fc4f593d9c28b02' }); 47 | const actual = generator.next().value; 48 | expect(expected).toEqual(actual); 49 | }); 50 | }); 51 | 52 | describe('fetchApps', () => { 53 | const generator = fetchApps({ tokenId: '1938077bc136d1b81c65c4d74fc4f593d9c28b02' }); 54 | it('should call appsAPI', () => { 55 | const expected = call(appsAPI, 56 | { tokenId: '1938077bc136d1b81c65c4d74fc4f593d9c28b02' } 57 | ); 58 | const actual = generator.next().value; 59 | expect(expected).toEqual(actual); 60 | }); 61 | 62 | it('should handle fetchApps success', () => { 63 | const getResponse = () => ({ token: 'faketoken' }); 64 | const expected = put({ 65 | type: RECEIVE_APPS, 66 | response: { token: 'faketoken' } 67 | }); 68 | const actual = generator.next(getResponse()).value; 69 | expect(expected).toEqual(actual); 70 | }); 71 | 72 | it('should handle fetchApps error', () => { 73 | const error = 'error message'; 74 | const expected = put({ 75 | type: RECEIVE_APPS_ERROR, 76 | error: 'error message' 77 | }); 78 | const actual = generator.throw(error).value; 79 | expect(expected).toEqual(actual); 80 | }); 81 | }); 82 | }); 83 | -------------------------------------------------------------------------------- /js/sagas/__tests__/login.spec.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Microsoft Mobile Center App 3 | * 4 | * Copyright (c) Microsoft Corporation 5 | * 6 | * All rights reserved. 7 | * 8 | * MIT License 9 | * 10 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 11 | * software and associated documentation files (the "Software"), to deal in the Software 12 | * without restriction, including without limitation the rights to use, copy, modify, 13 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 14 | * permit persons to whom the Software is furnished to do so, subject to the following 15 | * conditions: 16 | * 17 | * The above copyright notice and this permission notice shall be included in all copies or 18 | * substantial portions of the Software. THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF 19 | * ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 21 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR 23 | * THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | * 25 | */ 26 | 27 | import { takeEvery, call, put, fork } from 'redux-saga/effects'; 28 | import { LOGIN_REQUEST, LOGIN_SUCCESS, LOGIN_ERROR } from '../../actions/types'; 29 | import { watchRequestLogin, loginFlow, authorize } from '../login'; 30 | import { loginAPI } from '../../utils/RequestUtil'; 31 | 32 | describe('Sagas/ login', () => { 33 | describe('watchRequestLogin', () => { 34 | const generator = watchRequestLogin(); 35 | it('should take every login request', () => { 36 | const expected = takeEvery(LOGIN_REQUEST, loginFlow); 37 | const actual = generator.next().value; 38 | expect(expected.name).toEqual(actual.name); 39 | }); 40 | }); 41 | describe('loginFlow', () => { 42 | const generator = loginFlow({ 43 | type: LOGIN_REQUEST, 44 | username: 'buptkang@gmail.com', 45 | password: 'Kb@241307684' 46 | }); 47 | it('should fork a authorize test', () => { 48 | const expected = fork(authorize, { 49 | username: 'buptkang@gmail.com', 50 | password: 'Kb@241307684' 51 | }); 52 | const actual = generator.next().value; 53 | expect(expected).toEqual(actual); 54 | }); 55 | }); 56 | 57 | describe('Authorize', () => { 58 | const generator = authorize({ 59 | username: 'buptkang@gmail.com', 60 | password: 'Kb@241307684' 61 | }); 62 | 63 | it('should call loginAPI', () => { 64 | const expected = call(loginAPI, { 65 | username: 'buptkang@gmail.com', 66 | password: 'Kb@241307684' 67 | }); 68 | const actual = generator.next().value; 69 | expect(expected).toEqual(actual); 70 | }); 71 | 72 | it('should handle login success', () => { 73 | const getResponse = () => ({ 74 | username: 'denny', 75 | token: 'fake token' 76 | }); 77 | const expected = put({ 78 | type: LOGIN_SUCCESS, 79 | response: { 80 | username: 'denny', 81 | token: 'fake token' 82 | } 83 | }); 84 | const actual = generator.next(getResponse()).value; 85 | expect(expected).toEqual(actual); 86 | }); 87 | 88 | it('should handle login error', () => { 89 | const error = 'error message'; 90 | const expected = put({ 91 | type: LOGIN_ERROR, 92 | error: 'error message' 93 | }); 94 | const actual = generator.throw(error).value; 95 | expect(expected).toEqual(actual); 96 | }); 97 | }); 98 | }); 99 | -------------------------------------------------------------------------------- /js/sagas/apps.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Microsoft Mobile Center App 3 | * 4 | * Copyright (c) Microsoft Corporation 5 | * 6 | * All rights reserved. 7 | * 8 | * MIT License 9 | * 10 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 11 | * software and associated documentation files (the "Software"), to deal in the Software 12 | * without restriction, including without limitation the rights to use, copy, modify, 13 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 14 | * permit persons to whom the Software is furnished to do so, subject to the following 15 | * conditions: 16 | * 17 | * The above copyright notice and this permission notice shall be included in all copies or 18 | * substantial portions of the Software. THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF 19 | * ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 21 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR 23 | * THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | * 25 | */ 26 | 27 | import { takeEvery, put, call, fork } from 'redux-saga/effects'; 28 | import { REQUEST_APPS, RECEIVE_APPS, RECEIVE_APPS_ERROR } from '../actions/types'; 29 | import { toastShort } from '../utils/ToastUtil'; 30 | import { appsAPI } from '../utils/RequestUtil'; 31 | 32 | export function* watchFetchAppList() { 33 | yield takeEvery(REQUEST_APPS, fetchAppsFlow); 34 | } 35 | 36 | export function* fetchAppsFlow(action) { 37 | yield fork(fetchApps, 38 | { tokenId: action.tokenId }); 39 | } 40 | 41 | export function* fetchApps({ tokenId }) { 42 | try { 43 | const response = yield call(appsAPI, { 44 | tokenId 45 | }); 46 | yield put({ 47 | type: RECEIVE_APPS, 48 | response 49 | }); 50 | } catch (error) { 51 | yield put({ 52 | type: RECEIVE_APPS_ERROR, 53 | error 54 | }); 55 | toastShort('Network Error, Please Retry!!!'); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /js/sagas/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Microsoft Mobile Center App 3 | * 4 | * Copyright (c) Microsoft Corporation 5 | * 6 | * All rights reserved. 7 | * 8 | * MIT License 9 | * 10 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 11 | * software and associated documentation files (the "Software"), to deal in the Software 12 | * without restriction, including without limitation the rights to use, copy, modify, 13 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 14 | * permit persons to whom the Software is furnished to do so, subject to the following 15 | * conditions: 16 | * 17 | * The above copyright notice and this permission notice shall be included in all copies or 18 | * substantial portions of the Software. THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF 19 | * ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 21 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR 23 | * THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | * 25 | */ 26 | import { fork } from 'redux-saga/effects'; 27 | 28 | import { watchFetchAppList } from './apps'; 29 | import { watchRequestLogin } from './login'; 30 | 31 | export default function* rootSaga(){ 32 | yield [ 33 | fork(watchRequestLogin), 34 | fork(watchFetchAppList) 35 | ]; 36 | } 37 | -------------------------------------------------------------------------------- /js/sagas/login.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Microsoft Mobile Center App 3 | * 4 | * Copyright (c) Microsoft Corporation 5 | * 6 | * All rights reserved. 7 | * 8 | * MIT License 9 | * 10 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 11 | * software and associated documentation files (the "Software"), to deal in the Software 12 | * without restriction, including without limitation the rights to use, copy, modify, 13 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 14 | * permit persons to whom the Software is furnished to do so, subject to the following 15 | * conditions: 16 | * 17 | * The above copyright notice and this permission notice shall be included in all copies or 18 | * substantial portions of the Software. THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF 19 | * ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 21 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR 23 | * THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | * 25 | */ 26 | 27 | import { } from 'redux-saga'; 28 | import { takeEvery, call, put, fork } from 'redux-saga/effects'; 29 | 30 | import { LOGIN_REQUEST, LOGIN_SUCCESS, LOGIN_ERROR } from '../actions/types'; 31 | 32 | import { loginAPI } from '../utils/RequestUtil'; 33 | 34 | export function* watchRequestLogin() { 35 | yield takeEvery(LOGIN_REQUEST, loginFlow); 36 | } 37 | 38 | export function* loginFlow(action) { 39 | yield fork(authorize, 40 | {username: action.username, password: action.password }); 41 | } 42 | 43 | export function* authorize({username, password}) { 44 | try { 45 | const response = yield call(loginAPI, { 46 | username, 47 | password 48 | }); 49 | yield put({ 50 | type: LOGIN_SUCCESS, 51 | response 52 | }); 53 | } catch (error) { 54 | yield put({ 55 | type: LOGIN_ERROR, 56 | error 57 | }); 58 | } 59 | } -------------------------------------------------------------------------------- /js/setup.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Microsoft Mobile Center App 3 | * 4 | * Copyright (c) Microsoft Corporation 5 | * 6 | * All rights reserved. 7 | * 8 | * MIT License 9 | * 10 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 11 | * software and associated documentation files (the "Software"), to deal in the Software 12 | * without restriction, including without limitation the rights to use, copy, modify, 13 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 14 | * permit persons to whom the Software is furnished to do so, subject to the following 15 | * conditions: 16 | * 17 | * The above copyright notice and this permission notice shall be included in all copies or 18 | * substantial portions of the Software. THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF 19 | * ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 21 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR 23 | * THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | * 25 | */ 26 | 27 | import React from 'react'; 28 | import { Provider } from 'react-redux'; 29 | import configureStore from './store/configureStore'; 30 | import rootSaga from './sagas/index'; 31 | import MobileCenter from './containers/mobilecenter'; 32 | 33 | const store = configureStore(); 34 | store.runSaga(rootSaga); 35 | 36 | const setup = () => ( 37 | 38 | 39 | 40 | ); 41 | 42 | export default setup; -------------------------------------------------------------------------------- /js/store/configureStore.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Microsoft Mobile Center App 3 | * 4 | * Copyright (c) Microsoft Corporation 5 | * 6 | * All rights reserved. 7 | * 8 | * MIT License 9 | * 10 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 11 | * software and associated documentation files (the "Software"), to deal in the Software 12 | * without restriction, including without limitation the rights to use, copy, modify, 13 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 14 | * permit persons to whom the Software is furnished to do so, subject to the following 15 | * conditions: 16 | * 17 | * The above copyright notice and this permission notice shall be included in all copies or 18 | * substantial portions of the Software. THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF 19 | * ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 21 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR 23 | * THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | * 25 | */ 26 | 27 | import { createStore, applyMiddleware } from 'redux'; 28 | import createSagaMiddleware, { END } from 'redux-saga'; 29 | 30 | import rootReducer from '../reducers/index'; 31 | 32 | const middlewares = []; 33 | const createLogger = require('redux-logger'); 34 | 35 | // configure saga middleware 36 | const sagaMiddleware = createSagaMiddleware(); 37 | middlewares.push(sagaMiddleware); 38 | 39 | if (process.env.NODE_ENV === 'development'){ 40 | const logger = createLogger(); 41 | middlewares.push(logger); 42 | } 43 | const createStoreWithMiddleware = applyMiddleware(...middlewares)(createStore); 44 | 45 | export default function configureStore(initialState) { 46 | const store = createStoreWithMiddleware(rootReducer, initialState); 47 | window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__(); 48 | // install saga run 49 | store.runSaga = sagaMiddleware.run; 50 | store.close = () => store.dispatch(END); 51 | return store; 52 | } 53 | -------------------------------------------------------------------------------- /js/utils/RequestUtil.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Microsoft Mobile Center App 3 | * 4 | * Copyright (c) Microsoft Corporation 5 | * 6 | * All rights reserved. 7 | * 8 | * MIT License 9 | * 10 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 11 | * software and associated documentation files (the "Software"), to deal in the Software 12 | * without restriction, including without limitation the rights to use, copy, modify, 13 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 14 | * permit persons to whom the Software is furnished to do so, subject to the following 15 | * conditions: 16 | * 17 | * The above copyright notice and this permission notice shall be included in all copies or 18 | * substantial portions of the Software. THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF 19 | * ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 21 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR 23 | * THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | * 25 | */ 26 | 27 | function checkStatus(response) { 28 | if (response.status >= 200 && response.status < 300) { 29 | return response; 30 | } 31 | const error = new Error(response.statusText); 32 | error.response = response; 33 | throw error; 34 | } 35 | 36 | function parseJSON(response) { 37 | return response.json(); 38 | } 39 | 40 | function fetchAPI(url, options) { 41 | return fetch(url, options) 42 | .then(checkStatus) 43 | .then(parseJSON); 44 | } 45 | 46 | export function loginAPI({ username, password }) { 47 | return fetchAPI('https://api.mobile.azure.com/v0.1/api_tokens', { 48 | headers: { 49 | 'Content-Type': 'application/json' 50 | }, 51 | method: 'POST', 52 | body: JSON.stringify({ username, password }) 53 | }); 54 | } 55 | 56 | export function appsAPI({ tokenID }) { 57 | return fetchAPI('https://api.mobile.azure.com/v0.1/apps', { 58 | headers: { 59 | 'Content-Type': 'applicatin/json', 60 | 'X-API-Token': tokenID 61 | }, 62 | method: 'GET' 63 | }); 64 | } 65 | -------------------------------------------------------------------------------- /js/utils/StorageUtil.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Microsoft Mobile Center App 3 | * 4 | * Copyright (c) Microsoft Corporation 5 | * 6 | * All rights reserved. 7 | * 8 | * MIT License 9 | * 10 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 11 | * software and associated documentation files (the "Software"), to deal in the Software 12 | * without restriction, including without limitation the rights to use, copy, modify, 13 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 14 | * permit persons to whom the Software is furnished to do so, subject to the following 15 | * conditions: 16 | * 17 | * The above copyright notice and this permission notice shall be included in all copies or 18 | * substantial portions of the Software. THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF 19 | * ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 21 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR 23 | * THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | * 25 | */ 26 | 27 | import React from 'react-native'; 28 | 29 | const { AsyncStorage } = React; 30 | 31 | class DeviceStorage { 32 | static get(key){ 33 | return AsyncStorage.getItem(key) 34 | .then((value) => { 35 | const jsonValue = JSON.parse(value); 36 | return jsonValue; 37 | }); 38 | } 39 | 40 | static save(key, value){ 41 | return AsyncStorage.setItem(key, JSON.stringify(value)); 42 | } 43 | 44 | static update(key, value){ 45 | return DeviceStorage.get(key) 46 | .then((item) => { 47 | value = typeof value === 'string' ? value : Object.assign({}, item, value); 48 | return AsyncStorage.setItem(key, JSON.stringify(value)); 49 | }); 50 | } 51 | 52 | static delete(key){ 53 | return AsyncStorage.removeItem(key); 54 | } 55 | } 56 | 57 | export default DeviceStorage; -------------------------------------------------------------------------------- /js/utils/ToastUtil.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Microsoft Mobile Center App 3 | * 4 | * Copyright (c) Microsoft Corporation 5 | * 6 | * All rights reserved. 7 | * 8 | * MIT License 9 | * 10 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 11 | * software and associated documentation files (the "Software"), to deal in the Software 12 | * without restriction, including without limitation the rights to use, copy, modify, 13 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 14 | * permit persons to whom the Software is furnished to do so, subject to the following 15 | * conditions: 16 | * 17 | * The above copyright notice and this permission notice shall be included in all copies or 18 | * substantial portions of the Software. THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF 19 | * ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 21 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR 23 | * THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | * 25 | */ 26 | 27 | import { 28 | Alert, 29 | ToastAndroid, 30 | Platform 31 | } from 'react-native'; 32 | 33 | export const toastShort = (content, isAlert) => { 34 | if (isAlert || Platform.OS === 'ios') { 35 | Alert.alert( 36 | 'Alert', 37 | content.toString() 38 | ); 39 | } else { 40 | ToastAndroid.show(content.toString(), ToastAndroid.SHORT); 41 | } 42 | }; 43 | 44 | -------------------------------------------------------------------------------- /jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowJs": true, 4 | "allowSyntheticDefaultImports": true 5 | }, 6 | "exclude": [ 7 | "node_modules" 8 | ] 9 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "MobileCenterReactNativeApp", 3 | "version": "0.0.1", 4 | "private": true, 5 | "scripts": { 6 | "start": "node node_modules/react-native/local-cli/cli.js start", 7 | "test": "jest", 8 | "lint": "eslint .", 9 | "storybook": "storybook start -p 7007" 10 | }, 11 | "dependencies": { 12 | "buffer": "^5.0.2", 13 | "moment": "^2.17.1", 14 | "react": "~15.4.0-rc.4", 15 | "react-native": "0.40.0", 16 | "react-native-button": "^1.8.2", 17 | "react-native-card-view": "0.0.3", 18 | "react-native-code-push": "^1.17.0-beta", 19 | "react-native-css": "^1.2.47", 20 | "react-native-device-info": "^0.9.9", 21 | "react-native-drawer": "^2.3.0", 22 | "react-native-push-notification": "^2.2.1", 23 | "react-native-router-flux": "^3.37.0", 24 | "react-native-scrollable-tab-view": "^0.7.0", 25 | "react-native-search-bar": "^3.0.0", 26 | "react-native-searchbar": "^1.8.0", 27 | "react-native-send-intent": "^1.0.14", 28 | "react-native-simple-store": "^1.1.0", 29 | "react-native-storage": "^0.1.5", 30 | "react-native-vector-icons": "^4.0.0", 31 | "react-redux": "^5.0.2", 32 | "react-toolbox": "^2.0.0-beta.6", 33 | "redux": "^3.6.0", 34 | "redux-logger": "^2.7.4", 35 | "redux-persist": "^4.0.1", 36 | "redux-saga": "^0.14.2", 37 | "redux-thunk": "^2.1.0", 38 | "reselect": "^2.5.4", 39 | "tcomb-form-native": "^0.6.5" 40 | }, 41 | "devDependencies": { 42 | "babel-jest": "18.0.0", 43 | "babel-preset-react-native": "1.9.1", 44 | "eslint": "^3.13.1", 45 | "eslint-config-airbnb": "^14.0.0", 46 | "eslint-plugin-import": "^2.2.0", 47 | "eslint-plugin-jsx-a11y": "^3.0.2", 48 | "eslint-plugin-react": "^6.9.0", 49 | "jest": "18.1.0", 50 | "react-test-renderer": "~15.4.0-rc.4", 51 | "redux-devtools": "^3.3.2", 52 | "@kadira/react-native-storybook": "^2.0.0" 53 | }, 54 | "jest": { 55 | "preset": "react-native" 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /storybook/addons.js: -------------------------------------------------------------------------------- 1 | import '@kadira/react-native-storybook/addons'; 2 | -------------------------------------------------------------------------------- /storybook/index.android.js: -------------------------------------------------------------------------------- 1 | import { AppRegistry } from 'react-native'; 2 | import { getStorybookUI, configure } from '@kadira/react-native-storybook'; 3 | 4 | // import stories 5 | configure(() => { 6 | require('./stories'); 7 | }, module); 8 | 9 | const StorybookUI = getStorybookUI({port: 7007, host: 'localhost'}); 10 | AppRegistry.registerComponent('MobileCenterReactNativeApp', () => StorybookUI); 11 | -------------------------------------------------------------------------------- /storybook/index.ios.js: -------------------------------------------------------------------------------- 1 | import { AppRegistry } from 'react-native'; 2 | import { getStorybookUI, configure } from '@kadira/react-native-storybook'; 3 | 4 | // import stories 5 | configure(() => { 6 | require('./stories'); 7 | }, module); 8 | 9 | const StorybookUI = getStorybookUI({port: 7007, host: 'localhost'}); 10 | AppRegistry.registerComponent('MobileCenterReactNativeApp', () => StorybookUI); 11 | -------------------------------------------------------------------------------- /storybook/stories/Button/index.android.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { TouchableNativeFeedback } from 'react-native'; 3 | 4 | export default function Button(props) { 5 | return ( 6 | 7 | {props.children} 8 | 9 | ); 10 | } 11 | -------------------------------------------------------------------------------- /storybook/stories/Button/index.ios.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { TouchableHighlight } from 'react-native'; 3 | 4 | export default function Button(props) { 5 | return ( 6 | 7 | {props.children} 8 | 9 | ); 10 | } 11 | -------------------------------------------------------------------------------- /storybook/stories/CenterView/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { View } from 'react-native'; 3 | import style from './style'; 4 | 5 | export default function CenterView(props) { 6 | return ( 7 | 8 | {props.children} 9 | 10 | ); 11 | } 12 | -------------------------------------------------------------------------------- /storybook/stories/CenterView/style.js: -------------------------------------------------------------------------------- 1 | export default { 2 | main: { 3 | flex: 1, 4 | justifyContent: 'center', 5 | alignItems: 'center', 6 | backgroundColor: '#F5FCFF', 7 | }, 8 | }; 9 | -------------------------------------------------------------------------------- /storybook/stories/Welcome/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { View, Text } from 'react-native'; 3 | 4 | export default class Welcome extends React.Component { 5 | styles = { 6 | wrapper: { 7 | flex: 1, 8 | padding: 24, 9 | justifyContent: 'center', 10 | }, 11 | header: { 12 | fontSize: 18, 13 | marginBottom: 18, 14 | }, 15 | content: { 16 | fontSize: 12, 17 | marginBottom: 10, 18 | lineHeight: 18, 19 | }, 20 | } 21 | 22 | showApp(e) { 23 | e.preventDefault(); 24 | if(this.props.showApp) this.props.showApp(); 25 | } 26 | 27 | render() { 28 | return ( 29 | 30 | Welcome to React Native Storybook 31 | This is a UI Component development environment for your React Native app. Here you can display and interact with your UI components as stories. A story is a single state of one or more UI components. You can have as many stories as you want. In other words a story is like a visual test case. 32 | We have added some stories inside the "storybook/stories" directory for examples. Try editing the "storybook/stories/Welcome.js" file to edit this message. 33 | 34 | ); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /storybook/stories/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Text } from 'react-native'; 3 | import { storiesOf, action, linkTo } from '@kadira/react-native-storybook'; 4 | 5 | import Button from './Button'; 6 | import CenterView from './CenterView'; 7 | import Welcome from './Welcome'; 8 | 9 | storiesOf('Welcome', module) 10 | .add('to Storybook', () => ( 11 | 12 | )); 13 | 14 | storiesOf('Button', module) 15 | .addDecorator(getStory => ( 16 | {getStory()} 17 | )) 18 | .add('with text', () => ( 19 | 22 | )) 23 | .add('with some emoji', () => ( 24 | 27 | )); 28 | -------------------------------------------------------------------------------- /wireframe.md: -------------------------------------------------------------------------------- 1 | login form 2 | 3 | route to 4 | 5 | apps scene 6 | ( 7 | search bar, 8 | app list, 9 | ) 10 | 11 | app scene 12 | ( 13 | side menu versus 14 | side menu ( 15 | Getting Started 16 | Build 17 | Test 18 | Distribute 19 | Table 20 | Identity 21 | Crashes 22 | Analytics 23 | ) 24 | ) 25 | 26 | MyApps, Notification,Settings --------------------------------------------------------------------------------