├── .gitignore
├── .travis.yml
├── README.md
├── frontend
├── .babelrc
├── .buckconfig
├── .editorconfig
├── .eslintrc.json
├── .gitattributes
├── .gitignore
├── .watchmanconfig
├── TODO.md
├── android
│ ├── app
│ │ ├── BUCK
│ │ ├── build.gradle
│ │ ├── proguard-rules.pro
│ │ └── src
│ │ │ └── main
│ │ │ ├── AndroidManifest.xml
│ │ │ ├── java
│ │ │ └── com
│ │ │ │ └── frontend
│ │ │ │ ├── MainActivity.java
│ │ │ │ └── MainApplication.java
│ │ │ └── res
│ │ │ ├── mipmap-hdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-mdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xhdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xxxhdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.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.js
├── ios
│ ├── Resources
│ │ ├── CrimsonText-Bold.ttf
│ │ ├── CrimsonText-BoldItalic.ttf
│ │ ├── CrimsonText-Italic.ttf
│ │ ├── CrimsonText-Regular.ttf
│ │ ├── Nunito-Bold.ttf
│ │ ├── Nunito-BoldItalic.ttf
│ │ ├── Nunito-ExtraBold.ttf
│ │ ├── Nunito-ExtraBoldItalic.ttf
│ │ ├── Nunito-Italic.ttf
│ │ ├── Nunito-Light.ttf
│ │ ├── Nunito-LightItalic.ttf
│ │ ├── Nunito-Regular.ttf
│ │ ├── Nunito-SemiBold.ttf
│ │ ├── Nunito-SemiBoldItalic.ttf
│ │ ├── Spectral-Bold.ttf
│ │ ├── Spectral-BoldItalic.ttf
│ │ ├── Spectral-Italic.ttf
│ │ ├── Spectral-Medium.ttf
│ │ ├── Spectral-MediumItalic.ttf
│ │ ├── Spectral-Regular.ttf
│ │ ├── Spectral-SemiBold.ttf
│ │ ├── Spectral-SemiBoldItalic.ttf
│ │ ├── paper-bg.png
│ │ └── wood-bg.png
│ ├── frontend-tvOS
│ │ └── Info.plist
│ ├── frontend-tvOSTests
│ │ └── Info.plist
│ ├── frontend.xcodeproj
│ │ ├── project.pbxproj
│ │ └── xcshareddata
│ │ │ └── xcschemes
│ │ │ ├── frontend-tvOS.xcscheme
│ │ │ └── frontend.xcscheme
│ ├── frontend
│ │ ├── AppDelegate.h
│ │ ├── AppDelegate.m
│ │ ├── Base.lproj
│ │ │ └── LaunchScreen.xib
│ │ ├── Images.xcassets
│ │ │ ├── AppIcon.appiconset
│ │ │ │ └── Contents.json
│ │ │ └── Contents.json
│ │ ├── Info.plist
│ │ └── main.m
│ └── frontendTests
│ │ ├── Info.plist
│ │ └── frontendTests.m
├── jest.config.js
├── package.json
├── post
│ └── one.md
├── rn-cli.config.js
├── src
│ ├── App.json
│ ├── App.tsx
│ ├── components
│ │ ├── BookFlatList.tsx
│ │ ├── Button.tsx
│ │ ├── ErrorText.ts
│ │ ├── Filter.tsx
│ │ ├── Heading.ts
│ │ ├── Sans.tsx
│ │ ├── Strong.ts
│ │ ├── Text.ts
│ │ ├── TextInput.tsx
│ │ ├── Touchable.ts
│ │ ├── Wrapper.ts
│ │ ├── dText.ts
│ │ └── index.ts
│ ├── layouts
│ │ ├── DefaultLayout.tsx
│ │ └── index.ts
│ ├── pages
│ │ ├── Create.tsx
│ │ ├── Detail.tsx
│ │ ├── List.tsx
│ │ ├── Login.tsx
│ │ ├── Register.tsx
│ │ └── index.ts
│ ├── services
│ │ └── graphql.ts
│ ├── theme.ts
│ └── utils.ts
├── test
│ └── test.test.ts
├── tsconfig.json
└── yarn.lock
├── server
├── .babelrc
├── .editorconfig
├── .eslintrc.json
├── index.js
├── package.json
├── src
│ ├── modules
│ │ ├── author
│ │ │ ├── AuthorLoader.js
│ │ │ ├── AuthorModel.js
│ │ │ └── AuthorType.js
│ │ ├── book
│ │ │ ├── BookLoader.js
│ │ │ ├── BookModel.js
│ │ │ └── BookType.js
│ │ ├── date
│ │ │ └── DateType.js
│ │ └── user
│ │ │ ├── UserLoader.js
│ │ │ ├── UserModel.js
│ │ │ └── UserType.js
│ └── services
│ │ └── database.js
└── yarn.lock
└── yarn.lock
/.gitignore:
--------------------------------------------------------------------------------
1 | # Jest
2 | #
3 | .jest/
4 |
5 | .DS_Store
6 | # OSX
7 | #
8 | .DS_Store
9 |
10 | # Xcode
11 | #
12 | build/
13 | *.pbxuser
14 | !default.pbxuser
15 | *.mode1v3
16 | !default.mode1v3
17 | *.mode2v3
18 | !default.mode2v3
19 | *.perspectivev3
20 | !default.perspectivev3
21 | xcuserdata
22 | *.xccheckout
23 | *.moved-aside
24 | DerivedData
25 | *.hmap
26 | *.ipa
27 | *.xcuserstate
28 | project.xcworkspace
29 |
30 | # Android/IntelliJ
31 | #
32 | build/
33 | .idea
34 | .gradle
35 | local.properties
36 | *.iml
37 |
38 | # node.js
39 | #
40 | node_modules/
41 | npm-debug.log
42 | yarn-error.log
43 |
44 | # BUCK
45 | buck-out/
46 | \.buckd/
47 | *.keystore
48 |
49 | # fastlane
50 | #
51 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
52 | # screenshots whenever they are needed.
53 | # For more information about the recommended setup visit:
54 | # https://docs.fastlane.tools/best-practices/source-control/
55 |
56 | */fastlane/report.xml
57 | */fastlane/Preview.html
58 | */fastlane/screenshots
59 |
60 | # Bundle artifact
61 | *.jsbundle
62 |
63 | # Design files
64 | *.psd
65 | *.psb
66 | *.ai
67 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - v8
4 | script:
5 | - npm run lint && npm test -- --coverage
6 | cache:
7 | - yarn
8 | after_success:
9 | - bash <(curl -s https://codecov.io/bash)
10 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | ## ⭐️ How to play with it
19 |
20 | > You'll need a mac running [node](https://nodejs.org/en/), [yarn](https://yarnpkg.com/) (or npm) and [Xcode](https://developer.apple.com/xcode/) installed with Simulator.
21 |
22 | - on a terminal tab...
23 | - `$ git clone https://github.com/Thomazella/rn-zero-hero.git`
24 | - `$ cd rn-zero-hero` to enter the repo.
25 | - `$ cd server`
26 | - `$ yarn && yarn start` to install dependencies and lift server.
27 | - on another terminal tab...
28 | - `$ cd -` To go back to the repo
29 | - `$ cd frontend`
30 | - `$ yarn && yarn start` To start Metro Bundler.
31 | - on yet another terminal tab...
32 |
33 | >You'll need: `react-native-cli` installed globally _(`npm i -g react-native-cli`)_
34 |
35 | >**OR**
36 |
37 | >Xcode.
38 |
39 | #### 🤖 React native cli
40 |
41 | - `$ react-native run-ios` To compile the project and launch the Simulator.
42 |
43 | #### 🛠 Xcode
44 |
45 | - `$ Open ios/frontend.xcodeproj` To launch the Xcode project. Click the build button ▶️ and hang tight, it'll launch the Simulator soon.
46 |
47 | ### 👩🏻💻 App login
48 | | | |
49 | |--|--|
50 | |user| foton |
51 | |pass| foton |
52 |
53 | Or create your user. :)
54 |
--------------------------------------------------------------------------------
/frontend/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | [
4 | "@babel/preset-env",
5 | {
6 | "targets": {
7 | "esmodules": "true"
8 | }
9 | }
10 | ],
11 | "module:metro-react-native-babel-preset"
12 | ],
13 | "ignore": ["android/*", "ios/*"],
14 | "plugins": [
15 | "@babel/plugin-transform-flow-strip-types",
16 | "@babel/plugin-proposal-class-properties",
17 | "@babel/plugin-proposal-export-namespace-from",
18 | "@babel/plugin-proposal-json-strings",
19 | "@babel/plugin-proposal-throw-expressions",
20 | "@babel/plugin-syntax-dynamic-import",
21 | "@babel/plugin-syntax-import-meta"
22 | ]
23 | }
24 |
--------------------------------------------------------------------------------
/frontend/.buckconfig:
--------------------------------------------------------------------------------
1 |
2 | [android]
3 | target = Google Inc.:Google APIs:23
4 |
5 | [maven_repositories]
6 | central = https://repo1.maven.org/maven2
7 |
--------------------------------------------------------------------------------
/frontend/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig helps developers define and maintain consistent
2 | # coding styles between different editors and IDEs
3 | # editorconfig.org
4 |
5 | root = true
6 |
7 | [*]
8 |
9 | # Change these settings to your own preference
10 | indent_style = space
11 | indent_size = 2
12 |
13 | # We recommend you to keep these unchanged
14 | end_of_line = lf
15 | charset = utf-8
16 | trim_trailing_whitespace = true
17 | insert_final_newline = true
18 |
19 | [*.md]
20 | trim_trailing_whitespace = false
--------------------------------------------------------------------------------
/frontend/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "es6": true,
4 | "jest": true
5 | },
6 | "extends": [
7 | "eslint:recommended",
8 | "prettier/react",
9 | "airbnb",
10 | "plugin:prettier/recommended"
11 | ],
12 | "parserOptions": {
13 | "sourceType": "module"
14 | },
15 | "rules": {
16 | "linebreak-style": ["error", "unix"],
17 | "react/jsx-filename-extension": "off"
18 | },
19 | "parser": "typescript-eslint-parser"
20 | }
21 |
--------------------------------------------------------------------------------
/frontend/.gitattributes:
--------------------------------------------------------------------------------
1 | *.pbxproj -text
2 |
--------------------------------------------------------------------------------
/frontend/.gitignore:
--------------------------------------------------------------------------------
1 | # Jest
2 | #
3 | .jest/
4 |
5 | .DS_Store
6 | # OSX
7 | #
8 | .DS_Store
9 |
10 | # Xcode
11 | #
12 | build/
13 | *.pbxuser
14 | !default.pbxuser
15 | *.mode1v3
16 | !default.mode1v3
17 | *.mode2v3
18 | !default.mode2v3
19 | *.perspectivev3
20 | !default.perspectivev3
21 | xcuserdata
22 | *.xccheckout
23 | *.moved-aside
24 | DerivedData
25 | *.hmap
26 | *.ipa
27 | *.xcuserstate
28 | project.xcworkspace
29 |
30 | # Android/IntelliJ
31 | #
32 | build/
33 | .idea
34 | .gradle
35 | local.properties
36 | *.iml
37 |
38 | # node.js
39 | #
40 | node_modules/
41 | npm-debug.log
42 | yarn-error.log
43 |
44 | # BUCK
45 | buck-out/
46 | \.buckd/
47 | *.keystore
48 |
49 | # fastlane
50 | #
51 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
52 | # screenshots whenever they are needed.
53 | # For more information about the recommended setup visit:
54 | # https://docs.fastlane.tools/best-practices/source-control/
55 |
56 | */fastlane/report.xml
57 | */fastlane/Preview.html
58 | */fastlane/screenshots
59 |
60 | # Bundle artifact
61 | *.jsbundle
62 |
--------------------------------------------------------------------------------
/frontend/.watchmanconfig:
--------------------------------------------------------------------------------
1 | {}
--------------------------------------------------------------------------------
/frontend/TODO.md:
--------------------------------------------------------------------------------
1 | # React Native Fullstack: Zer0 to Hero
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | *awesome logo goes here*
10 |
11 |
12 | ## Initial working version
13 |
14 | ### How to play with it
15 |
16 | - Clone the repo
17 | - `cd` into it
18 | - `cd` into `server/`
19 | - `yarn && yarn start`
20 | - `cd -` To go back to the repo
21 | - `cd` into `frontend/`
22 | - `yarn && yarn start` To start Metro Bundler
23 |
24 | >Now you need: `react-native-cli` installed globally (`npm i -g react-native-cli`)
25 |
26 | >OR
27 |
28 | >Xcode.
29 |
30 | #### React native cli
31 |
32 | - `react-native run-ios` To compile the project and launch the Simulator.
33 |
34 | #### Xcode
35 |
36 | - `Open ios/frontend.xcodeproj` To launch the Xcode project. Click the build button and hang tight, it'll launch the Simulator soon.
37 |
38 | ### What's to be improved
39 |
40 | #### Done
41 | ✔ use flatList
42 | ✔ get some feedback
43 |
44 | #### Modern design
45 | rounded buttons
46 | gradients
47 | dark bg gradient
48 |
49 |
50 | #### Expensive
51 | ✔ make things pretty
52 | - CI
53 | - unit tests
54 | - detox e2e
55 | ✔ fix TS
56 |
57 | #### Regular
58 | V add pagination to List using meta-data ({fetchMore})
59 | V Id everything in backed
60 | V see if dataid func on constructor works o => o.id
61 | V send token in headers
62 | X Use Query
63 | V sort by recent todos server-side https://stackoverflow.com/questions/47624681/sort-by-reverse-order-mongoose?rq=1
64 | xb add TS on server
65 | ✔b add MongoDB & Mongoose
66 |
67 | ✔ moved styles to styled
68 | ✔ Use Mutation and Query from `react-apollo` to leverage the loading state
69 | use Activity indicator to show loading states
70 | ✔ ApolloConsumer -> graphql HOC
71 | ✔ Ditch react-power-plug in cases where the JSX is full of complicated handlers that can be moved to an instance method in the class. E.g. `() => this.doFoo()`
72 |
73 | #### Cheap
74 | ✔ use theme provider to provide a color.main prop
75 | ✔ Button -> touchable opacity
76 | ✔ Remove redux
77 | ✔ refactor server files, move auth code to Auth module
78 | ✔ queries in component
79 | ✔ refactor \n in texts to two `s
80 | ✔ use reverse to sort items by new first!
81 | ✔ make queries required (!) where it makes sense
82 | ✔ destruct in args `(parent, { name, genre, authorId }) => {`
83 |
84 | #### Bugs
85 | - firing a second addBook mutation from same user doesn't update UI even tho book is added on server. (CACHE)
86 |
87 | ### App login
88 |
89 | | | | |
90 | |--|--|--|
91 | |user| Foton | _case-**in**sensitive_ |
92 | |pass| foton | _case-sensitive_ |
93 |
94 | Or create your user. :)
--------------------------------------------------------------------------------
/frontend/android/app/BUCK:
--------------------------------------------------------------------------------
1 | # To learn about Buck see [Docs](https://buckbuild.com/).
2 | # To run your application with Buck:
3 | # - install Buck
4 | # - `npm start` - to start the packager
5 | # - `cd android`
6 | # - `keytool -genkey -v -keystore keystores/debug.keystore -storepass android -alias androiddebugkey -keypass android -dname "CN=Android Debug,O=Android,C=US"`
7 | # - `./gradlew :app:copyDownloadableDepsToLibs` - make all Gradle compile dependencies available to Buck
8 | # - `buck install -r android/app` - compile, install and run application
9 | #
10 |
11 | lib_deps = []
12 |
13 | for jarfile in glob(['libs/*.jar']):
14 | name = 'jars__' + jarfile[jarfile.rindex('/') + 1: jarfile.rindex('.jar')]
15 | lib_deps.append(':' + name)
16 | prebuilt_jar(
17 | name = name,
18 | binary_jar = jarfile,
19 | )
20 |
21 | for aarfile in glob(['libs/*.aar']):
22 | name = 'aars__' + aarfile[aarfile.rindex('/') + 1: aarfile.rindex('.aar')]
23 | lib_deps.append(':' + name)
24 | android_prebuilt_aar(
25 | name = name,
26 | aar = aarfile,
27 | )
28 |
29 | android_library(
30 | name = "all-libs",
31 | exported_deps = lib_deps,
32 | )
33 |
34 | android_library(
35 | name = "app-code",
36 | srcs = glob([
37 | "src/main/java/**/*.java",
38 | ]),
39 | deps = [
40 | ":all-libs",
41 | ":build_config",
42 | ":res",
43 | ],
44 | )
45 |
46 | android_build_config(
47 | name = "build_config",
48 | package = "com.frontend",
49 | )
50 |
51 | android_resource(
52 | name = "res",
53 | package = "com.frontend",
54 | res = "src/main/res",
55 | )
56 |
57 | android_binary(
58 | name = "app",
59 | keystore = "//android/keystores:debug",
60 | manifest = "src/main/AndroidManifest.xml",
61 | package_type = "debug",
62 | deps = [
63 | ":app-code",
64 | ],
65 | )
66 |
--------------------------------------------------------------------------------
/frontend/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 | * // whether to disable dev mode in custom build variants (by default only disabled in release)
37 | * // for example: to disable dev mode in the staging build type (if configured)
38 | * devDisabledInStaging: true,
39 | * // The configuration property can be in the following formats
40 | * // 'devDisabledIn${productFlavor}${buildType}'
41 | * // 'devDisabledIn${buildType}'
42 | *
43 | * // the root of your project, i.e. where "package.json" lives
44 | * root: "../../",
45 | *
46 | * // where to put the JS bundle asset in debug mode
47 | * jsBundleDirDebug: "$buildDir/intermediates/assets/debug",
48 | *
49 | * // where to put the JS bundle asset in release mode
50 | * jsBundleDirRelease: "$buildDir/intermediates/assets/release",
51 | *
52 | * // where to put drawable resources / React Native assets, e.g. the ones you use via
53 | * // require('./image.png')), in debug mode
54 | * resourcesDirDebug: "$buildDir/intermediates/res/merged/debug",
55 | *
56 | * // where to put drawable resources / React Native assets, e.g. the ones you use via
57 | * // require('./image.png')), in release mode
58 | * resourcesDirRelease: "$buildDir/intermediates/res/merged/release",
59 | *
60 | * // by default the gradle tasks are skipped if none of the JS files or assets change; this means
61 | * // that we don't look at files in android/ or ios/ to determine whether the tasks are up to
62 | * // date; if you have any other folders that you want to ignore for performance reasons (gradle
63 | * // indexes the entire tree), add them here. Alternatively, if you have JS files in android/
64 | * // for example, you might want to remove it from here.
65 | * inputExcludes: ["android/**", "ios/**"],
66 | *
67 | * // override which node gets called and with what additional arguments
68 | * nodeExecutableAndArgs: ["node"],
69 | *
70 | * // supply additional arguments to the packager
71 | * extraPackagerArgs: []
72 | * ]
73 | */
74 |
75 | project.ext.react = [
76 | entryFile: "index.js"
77 | ]
78 |
79 | apply from: "../../node_modules/react-native/react.gradle"
80 |
81 | /**
82 | * Set this to true to create two separate APKs instead of one:
83 | * - An APK that only works on ARM devices
84 | * - An APK that only works on x86 devices
85 | * The advantage is the size of the APK is reduced by about 4MB.
86 | * Upload all the APKs to the Play Store and people will download
87 | * the correct one based on the CPU architecture of their device.
88 | */
89 | def enableSeparateBuildPerCPUArchitecture = false
90 |
91 | /**
92 | * Run Proguard to shrink the Java bytecode in release builds.
93 | */
94 | def enableProguardInReleaseBuilds = false
95 |
96 | android {
97 | compileSdkVersion rootProject.ext.compileSdkVersion
98 | buildToolsVersion rootProject.ext.buildToolsVersion
99 |
100 | defaultConfig {
101 | applicationId "com.frontend"
102 | minSdkVersion rootProject.ext.minSdkVersion
103 | targetSdkVersion rootProject.ext.targetSdkVersion
104 | versionCode 1
105 | versionName "1.0"
106 | ndk {
107 | abiFilters "armeabi-v7a", "x86"
108 | }
109 | }
110 | splits {
111 | abi {
112 | reset()
113 | enable enableSeparateBuildPerCPUArchitecture
114 | universalApk false // If true, also generate a universal APK
115 | include "armeabi-v7a", "x86"
116 | }
117 | }
118 | buildTypes {
119 | release {
120 | minifyEnabled enableProguardInReleaseBuilds
121 | proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
122 | }
123 | }
124 | // applicationVariants are e.g. debug, release
125 | applicationVariants.all { variant ->
126 | variant.outputs.each { output ->
127 | // For each separate APK per architecture, set a unique version code as described here:
128 | // http://tools.android.com/tech-docs/new-build-system/user-guide/apk-splits
129 | def versionCodes = ["armeabi-v7a":1, "x86":2]
130 | def abi = output.getFilter(OutputFile.ABI)
131 | if (abi != null) { // null for the universal-debug, universal-release variants
132 | output.versionCodeOverride =
133 | versionCodes.get(abi) * 1048576 + defaultConfig.versionCode
134 | }
135 | }
136 | }
137 | }
138 |
139 | dependencies {
140 | implementation fileTree(dir: "libs", include: ["*.jar"])
141 | implementation "com.android.support:appcompat-v7:${rootProject.ext.supportLibVersion}"
142 | implementation "com.facebook.react:react-native:+" // From node_modules
143 | }
144 |
145 | // Run this once to be able to run the application with BUCK
146 | // puts all compile dependencies into folder libs for BUCK to use
147 | task copyDownloadableDepsToLibs(type: Copy) {
148 | from configurations.compile
149 | into 'libs'
150 | }
151 |
--------------------------------------------------------------------------------
/frontend/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 |
--------------------------------------------------------------------------------
/frontend/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
13 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/frontend/android/app/src/main/java/com/frontend/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.frontend;
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 "frontend";
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/frontend/android/app/src/main/java/com/frontend/MainApplication.java:
--------------------------------------------------------------------------------
1 | package com.frontend;
2 |
3 | import android.app.Application;
4 |
5 | import com.facebook.react.ReactApplication;
6 | import com.facebook.react.ReactNativeHost;
7 | import com.facebook.react.ReactPackage;
8 | import com.facebook.react.shell.MainReactPackage;
9 | import com.facebook.soloader.SoLoader;
10 |
11 | import java.util.Arrays;
12 | import java.util.List;
13 |
14 | public class MainApplication extends Application implements ReactApplication {
15 |
16 | private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
17 | @Override
18 | public boolean getUseDeveloperSupport() {
19 | return BuildConfig.DEBUG;
20 | }
21 |
22 | @Override
23 | protected List getPackages() {
24 | return Arrays.asList(
25 | new MainReactPackage()
26 | );
27 | }
28 |
29 | @Override
30 | protected String getJSMainModuleName() {
31 | return "index";
32 | }
33 | };
34 |
35 | @Override
36 | public ReactNativeHost getReactNativeHost() {
37 | return mReactNativeHost;
38 | }
39 |
40 | @Override
41 | public void onCreate() {
42 | super.onCreate();
43 | SoLoader.init(this, /* native exopackage */ false);
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/frontend/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcodes0/rn-zero-hero/6c05c904cfa7f52ef54d502ddbcf935f27185b1f/frontend/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/frontend/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcodes0/rn-zero-hero/6c05c904cfa7f52ef54d502ddbcf935f27185b1f/frontend/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/frontend/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcodes0/rn-zero-hero/6c05c904cfa7f52ef54d502ddbcf935f27185b1f/frontend/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/frontend/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcodes0/rn-zero-hero/6c05c904cfa7f52ef54d502ddbcf935f27185b1f/frontend/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/frontend/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcodes0/rn-zero-hero/6c05c904cfa7f52ef54d502ddbcf935f27185b1f/frontend/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/frontend/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcodes0/rn-zero-hero/6c05c904cfa7f52ef54d502ddbcf935f27185b1f/frontend/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/frontend/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcodes0/rn-zero-hero/6c05c904cfa7f52ef54d502ddbcf935f27185b1f/frontend/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/frontend/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcodes0/rn-zero-hero/6c05c904cfa7f52ef54d502ddbcf935f27185b1f/frontend/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/frontend/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcodes0/rn-zero-hero/6c05c904cfa7f52ef54d502ddbcf935f27185b1f/frontend/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/frontend/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcodes0/rn-zero-hero/6c05c904cfa7f52ef54d502ddbcf935f27185b1f/frontend/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/frontend/android/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | frontend
3 |
4 |
--------------------------------------------------------------------------------
/frontend/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/frontend/android/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | ext {
5 | buildToolsVersion = "27.0.3"
6 | minSdkVersion = 16
7 | compileSdkVersion = 27
8 | targetSdkVersion = 26
9 | supportLibVersion = "27.1.1"
10 | }
11 | repositories {
12 | jcenter()
13 | google()
14 | }
15 | dependencies {
16 | classpath 'com.android.tools.build:gradle:3.1.4'
17 |
18 | // NOTE: Do not place your application dependencies here; they belong
19 | // in the individual module build.gradle files
20 | }
21 | }
22 |
23 | allprojects {
24 | repositories {
25 | mavenLocal()
26 | jcenter()
27 | maven {
28 | // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
29 | url "$rootDir/../node_modules/react-native/android"
30 | }
31 | google()
32 | }
33 | }
34 |
35 |
36 | task wrapper(type: Wrapper) {
37 | gradleVersion = '4.4'
38 | distributionUrl = distributionUrl.replace("bin", "all")
39 | }
40 |
--------------------------------------------------------------------------------
/frontend/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 |
--------------------------------------------------------------------------------
/frontend/android/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcodes0/rn-zero-hero/6c05c904cfa7f52ef54d502ddbcf935f27185b1f/frontend/android/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/frontend/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-4.4-all.zip
6 |
--------------------------------------------------------------------------------
/frontend/android/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Attempt to set APP_HOME
10 | # Resolve links: $0 may be a link
11 | PRG="$0"
12 | # Need this for relative symlinks.
13 | while [ -h "$PRG" ] ; do
14 | ls=`ls -ld "$PRG"`
15 | link=`expr "$ls" : '.*-> \(.*\)$'`
16 | if expr "$link" : '/.*' > /dev/null; then
17 | PRG="$link"
18 | else
19 | PRG=`dirname "$PRG"`"/$link"
20 | fi
21 | done
22 | SAVED="`pwd`"
23 | cd "`dirname \"$PRG\"`/" >/dev/null
24 | APP_HOME="`pwd -P`"
25 | cd "$SAVED" >/dev/null
26 |
27 | APP_NAME="Gradle"
28 | APP_BASE_NAME=`basename "$0"`
29 |
30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
31 | DEFAULT_JVM_OPTS=""
32 |
33 | # Use the maximum available, or set MAX_FD != -1 to use that value.
34 | MAX_FD="maximum"
35 |
36 | warn () {
37 | echo "$*"
38 | }
39 |
40 | die () {
41 | echo
42 | echo "$*"
43 | echo
44 | exit 1
45 | }
46 |
47 | # OS specific support (must be 'true' or 'false').
48 | cygwin=false
49 | msys=false
50 | darwin=false
51 | nonstop=false
52 | case "`uname`" in
53 | CYGWIN* )
54 | cygwin=true
55 | ;;
56 | Darwin* )
57 | darwin=true
58 | ;;
59 | MINGW* )
60 | msys=true
61 | ;;
62 | NONSTOP* )
63 | nonstop=true
64 | ;;
65 | esac
66 |
67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
68 |
69 | # Determine the Java command to use to start the JVM.
70 | if [ -n "$JAVA_HOME" ] ; then
71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
72 | # IBM's JDK on AIX uses strange locations for the executables
73 | JAVACMD="$JAVA_HOME/jre/sh/java"
74 | else
75 | JAVACMD="$JAVA_HOME/bin/java"
76 | fi
77 | if [ ! -x "$JAVACMD" ] ; then
78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
79 |
80 | Please set the JAVA_HOME variable in your environment to match the
81 | location of your Java installation."
82 | fi
83 | else
84 | JAVACMD="java"
85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
86 |
87 | Please set the JAVA_HOME variable in your environment to match the
88 | location of your Java installation."
89 | fi
90 |
91 | # Increase the maximum file descriptors if we can.
92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
93 | MAX_FD_LIMIT=`ulimit -H -n`
94 | if [ $? -eq 0 ] ; then
95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
96 | MAX_FD="$MAX_FD_LIMIT"
97 | fi
98 | ulimit -n $MAX_FD
99 | if [ $? -ne 0 ] ; then
100 | warn "Could not set maximum file descriptor limit: $MAX_FD"
101 | fi
102 | else
103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
104 | fi
105 | fi
106 |
107 | # For Darwin, add options to specify how the application appears in the dock
108 | if $darwin; then
109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
110 | fi
111 |
112 | # For Cygwin, switch paths to Windows format before running java
113 | if $cygwin ; then
114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
116 | JAVACMD=`cygpath --unix "$JAVACMD"`
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 | # Escape application args
158 | save () {
159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
160 | echo " "
161 | }
162 | APP_ARGS=$(save "$@")
163 |
164 | # Collect all arguments for the java command, following the shell quoting and substitution rules
165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
166 |
167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
169 | cd "$(dirname "$0")"
170 | fi
171 |
172 | exec "$JAVACMD" "$@"
173 |
--------------------------------------------------------------------------------
/frontend/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 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
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 Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/frontend/android/keystores/BUCK:
--------------------------------------------------------------------------------
1 | keystore(
2 | name = "debug",
3 | properties = "debug.keystore.properties",
4 | store = "debug.keystore",
5 | visibility = [
6 | "PUBLIC",
7 | ],
8 | )
9 |
--------------------------------------------------------------------------------
/frontend/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 |
--------------------------------------------------------------------------------
/frontend/android/settings.gradle:
--------------------------------------------------------------------------------
1 | rootProject.name = 'frontend'
2 |
3 | include ':app'
4 |
--------------------------------------------------------------------------------
/frontend/index.js:
--------------------------------------------------------------------------------
1 | /** @format */
2 |
3 | import { AppRegistry } from "react-native";
4 | import App from "./src/App.tsx";
5 | import { name as appName } from "./src/App.json";
6 |
7 | AppRegistry.registerComponent(appName, () => App);
8 |
--------------------------------------------------------------------------------
/frontend/ios/Resources/CrimsonText-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcodes0/rn-zero-hero/6c05c904cfa7f52ef54d502ddbcf935f27185b1f/frontend/ios/Resources/CrimsonText-Bold.ttf
--------------------------------------------------------------------------------
/frontend/ios/Resources/CrimsonText-BoldItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcodes0/rn-zero-hero/6c05c904cfa7f52ef54d502ddbcf935f27185b1f/frontend/ios/Resources/CrimsonText-BoldItalic.ttf
--------------------------------------------------------------------------------
/frontend/ios/Resources/CrimsonText-Italic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcodes0/rn-zero-hero/6c05c904cfa7f52ef54d502ddbcf935f27185b1f/frontend/ios/Resources/CrimsonText-Italic.ttf
--------------------------------------------------------------------------------
/frontend/ios/Resources/CrimsonText-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcodes0/rn-zero-hero/6c05c904cfa7f52ef54d502ddbcf935f27185b1f/frontend/ios/Resources/CrimsonText-Regular.ttf
--------------------------------------------------------------------------------
/frontend/ios/Resources/Nunito-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcodes0/rn-zero-hero/6c05c904cfa7f52ef54d502ddbcf935f27185b1f/frontend/ios/Resources/Nunito-Bold.ttf
--------------------------------------------------------------------------------
/frontend/ios/Resources/Nunito-BoldItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcodes0/rn-zero-hero/6c05c904cfa7f52ef54d502ddbcf935f27185b1f/frontend/ios/Resources/Nunito-BoldItalic.ttf
--------------------------------------------------------------------------------
/frontend/ios/Resources/Nunito-ExtraBold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcodes0/rn-zero-hero/6c05c904cfa7f52ef54d502ddbcf935f27185b1f/frontend/ios/Resources/Nunito-ExtraBold.ttf
--------------------------------------------------------------------------------
/frontend/ios/Resources/Nunito-ExtraBoldItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcodes0/rn-zero-hero/6c05c904cfa7f52ef54d502ddbcf935f27185b1f/frontend/ios/Resources/Nunito-ExtraBoldItalic.ttf
--------------------------------------------------------------------------------
/frontend/ios/Resources/Nunito-Italic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcodes0/rn-zero-hero/6c05c904cfa7f52ef54d502ddbcf935f27185b1f/frontend/ios/Resources/Nunito-Italic.ttf
--------------------------------------------------------------------------------
/frontend/ios/Resources/Nunito-Light.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcodes0/rn-zero-hero/6c05c904cfa7f52ef54d502ddbcf935f27185b1f/frontend/ios/Resources/Nunito-Light.ttf
--------------------------------------------------------------------------------
/frontend/ios/Resources/Nunito-LightItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcodes0/rn-zero-hero/6c05c904cfa7f52ef54d502ddbcf935f27185b1f/frontend/ios/Resources/Nunito-LightItalic.ttf
--------------------------------------------------------------------------------
/frontend/ios/Resources/Nunito-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcodes0/rn-zero-hero/6c05c904cfa7f52ef54d502ddbcf935f27185b1f/frontend/ios/Resources/Nunito-Regular.ttf
--------------------------------------------------------------------------------
/frontend/ios/Resources/Nunito-SemiBold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcodes0/rn-zero-hero/6c05c904cfa7f52ef54d502ddbcf935f27185b1f/frontend/ios/Resources/Nunito-SemiBold.ttf
--------------------------------------------------------------------------------
/frontend/ios/Resources/Nunito-SemiBoldItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcodes0/rn-zero-hero/6c05c904cfa7f52ef54d502ddbcf935f27185b1f/frontend/ios/Resources/Nunito-SemiBoldItalic.ttf
--------------------------------------------------------------------------------
/frontend/ios/Resources/Spectral-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcodes0/rn-zero-hero/6c05c904cfa7f52ef54d502ddbcf935f27185b1f/frontend/ios/Resources/Spectral-Bold.ttf
--------------------------------------------------------------------------------
/frontend/ios/Resources/Spectral-BoldItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcodes0/rn-zero-hero/6c05c904cfa7f52ef54d502ddbcf935f27185b1f/frontend/ios/Resources/Spectral-BoldItalic.ttf
--------------------------------------------------------------------------------
/frontend/ios/Resources/Spectral-Italic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcodes0/rn-zero-hero/6c05c904cfa7f52ef54d502ddbcf935f27185b1f/frontend/ios/Resources/Spectral-Italic.ttf
--------------------------------------------------------------------------------
/frontend/ios/Resources/Spectral-Medium.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcodes0/rn-zero-hero/6c05c904cfa7f52ef54d502ddbcf935f27185b1f/frontend/ios/Resources/Spectral-Medium.ttf
--------------------------------------------------------------------------------
/frontend/ios/Resources/Spectral-MediumItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcodes0/rn-zero-hero/6c05c904cfa7f52ef54d502ddbcf935f27185b1f/frontend/ios/Resources/Spectral-MediumItalic.ttf
--------------------------------------------------------------------------------
/frontend/ios/Resources/Spectral-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcodes0/rn-zero-hero/6c05c904cfa7f52ef54d502ddbcf935f27185b1f/frontend/ios/Resources/Spectral-Regular.ttf
--------------------------------------------------------------------------------
/frontend/ios/Resources/Spectral-SemiBold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcodes0/rn-zero-hero/6c05c904cfa7f52ef54d502ddbcf935f27185b1f/frontend/ios/Resources/Spectral-SemiBold.ttf
--------------------------------------------------------------------------------
/frontend/ios/Resources/Spectral-SemiBoldItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcodes0/rn-zero-hero/6c05c904cfa7f52ef54d502ddbcf935f27185b1f/frontend/ios/Resources/Spectral-SemiBoldItalic.ttf
--------------------------------------------------------------------------------
/frontend/ios/Resources/paper-bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcodes0/rn-zero-hero/6c05c904cfa7f52ef54d502ddbcf935f27185b1f/frontend/ios/Resources/paper-bg.png
--------------------------------------------------------------------------------
/frontend/ios/Resources/wood-bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tcodes0/rn-zero-hero/6c05c904cfa7f52ef54d502ddbcf935f27185b1f/frontend/ios/Resources/wood-bg.png
--------------------------------------------------------------------------------
/frontend/ios/frontend-tvOS/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 |
44 | NSExceptionDomains
45 |
46 | localhost
47 |
48 | NSExceptionAllowsInsecureHTTPLoads
49 |
50 |
51 |
52 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/frontend/ios/frontend-tvOSTests/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 |
--------------------------------------------------------------------------------
/frontend/ios/frontend.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */; };
11 | 00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */; };
12 | 00C302E81ABCBA2D00DB3ED1 /* libRCTImage.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302C01ABCB91800DB3ED1 /* libRCTImage.a */; };
13 | 00C302E91ABCBA2D00DB3ED1 /* libRCTNetwork.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302DC1ABCB9D200DB3ED1 /* libRCTNetwork.a */; };
14 | 00C302EA1ABCBA2D00DB3ED1 /* libRCTVibration.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302E41ABCB9EE00DB3ED1 /* libRCTVibration.a */; };
15 | 00E356F31AD99517003FC87E /* frontendTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* frontendTests.m */; };
16 | 057BEAEF216785EE00E1CC13 /* Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB61A68108700A75B9A /* Info.plist */; };
17 | 057BEAF02167860400E1CC13 /* Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB61A68108700A75B9A /* Info.plist */; };
18 | 057BEAF52167899600E1CC13 /* Spectral-BoldItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 057BEAF12167899600E1CC13 /* Spectral-BoldItalic.ttf */; };
19 | 057BEAF62167899600E1CC13 /* Spectral-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 057BEAF22167899600E1CC13 /* Spectral-Regular.ttf */; };
20 | 057BEAF72167899600E1CC13 /* Spectral-Italic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 057BEAF32167899600E1CC13 /* Spectral-Italic.ttf */; };
21 | 057BEAF82167899600E1CC13 /* Spectral-Bold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 057BEAF42167899600E1CC13 /* Spectral-Bold.ttf */; };
22 | 057BEAFD21679CA200E1CC13 /* CrimsonText-Italic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 057BEAF921679CA100E1CC13 /* CrimsonText-Italic.ttf */; };
23 | 057BEAFE21679CA200E1CC13 /* CrimsonText-Bold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 057BEAFA21679CA200E1CC13 /* CrimsonText-Bold.ttf */; };
24 | 057BEAFF21679CA200E1CC13 /* CrimsonText-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 057BEAFB21679CA200E1CC13 /* CrimsonText-Regular.ttf */; };
25 | 057BEB0021679CA200E1CC13 /* CrimsonText-BoldItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 057BEAFC21679CA200E1CC13 /* CrimsonText-BoldItalic.ttf */; };
26 | 057BEB052167D35800E1CC13 /* Spectral-MediumItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 057BEB012167D35700E1CC13 /* Spectral-MediumItalic.ttf */; };
27 | 057BEB062167D35800E1CC13 /* Spectral-SemiBoldItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 057BEB022167D35700E1CC13 /* Spectral-SemiBoldItalic.ttf */; };
28 | 057BEB072167D35800E1CC13 /* Spectral-SemiBold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 057BEB032167D35700E1CC13 /* Spectral-SemiBold.ttf */; };
29 | 057BEB082167D35800E1CC13 /* Spectral-Medium.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 057BEB042167D35800E1CC13 /* Spectral-Medium.ttf */; };
30 | 05F8407A216A3BE700CF85DB /* Nunito-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 05F8404B216A3BE600CF85DB /* Nunito-Regular.ttf */; };
31 | 05F8407B216A3BE700CF85DB /* Nunito-BoldItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 05F84071216A3BE600CF85DB /* Nunito-BoldItalic.ttf */; };
32 | 05F8407C216A3BE700CF85DB /* Nunito-ExtraBoldItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 05F84072216A3BE700CF85DB /* Nunito-ExtraBoldItalic.ttf */; };
33 | 05F8407D216A3BE700CF85DB /* Nunito-Bold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 05F84073216A3BE700CF85DB /* Nunito-Bold.ttf */; };
34 | 05F8407E216A3BE700CF85DB /* Nunito-Italic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 05F84074216A3BE700CF85DB /* Nunito-Italic.ttf */; };
35 | 05F8407F216A3BE700CF85DB /* Nunito-ExtraBold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 05F84075216A3BE700CF85DB /* Nunito-ExtraBold.ttf */; };
36 | 05F84080216A3BE700CF85DB /* Nunito-SemiBoldItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 05F84076216A3BE700CF85DB /* Nunito-SemiBoldItalic.ttf */; };
37 | 05F84081216A3BE700CF85DB /* Nunito-SemiBold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 05F84077216A3BE700CF85DB /* Nunito-SemiBold.ttf */; };
38 | 05F84082216A3BE700CF85DB /* Nunito-Light.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 05F84078216A3BE700CF85DB /* Nunito-Light.ttf */; };
39 | 05F84083216A3BE700CF85DB /* Nunito-LightItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 05F84079216A3BE700CF85DB /* Nunito-LightItalic.ttf */; };
40 | 11D1A2F320CAFA9E000508D9 /* libRCTAnimation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5E9157331DD0AC6500FF2AA8 /* libRCTAnimation.a */; };
41 | 133E29F31AD74F7200F7D852 /* libRCTLinking.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 78C398B91ACF4ADC00677621 /* libRCTLinking.a */; };
42 | 139105C61AF99C1200B5F7CC /* libRCTSettings.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 139105C11AF99BAD00B5F7CC /* libRCTSettings.a */; };
43 | 139FDEF61B0652A700C62182 /* libRCTWebSocket.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 139FDEF41B06529B00C62182 /* libRCTWebSocket.a */; };
44 | 13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; };
45 | 13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB11A68108700A75B9A /* LaunchScreen.xib */; };
46 | 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
47 | 13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
48 | 140ED2AC1D01E1AD002B40FF /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 146834041AC3E56700842450 /* libReact.a */; };
49 | 146834051AC3E58100842450 /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 146834041AC3E56700842450 /* libReact.a */; };
50 | 2D02E4BC1E0B4A80006451C7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; };
51 | 2D02E4BD1E0B4A84006451C7 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
52 | 2D02E4BF1E0B4AB3006451C7 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
53 | 2D02E4C21E0B4AEC006451C7 /* libRCTAnimation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5E9157351DD0AC6500FF2AA8 /* libRCTAnimation.a */; };
54 | 2D02E4C31E0B4AEC006451C7 /* libRCTImage-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DAD3E841DF850E9000B6D8A /* libRCTImage-tvOS.a */; };
55 | 2D02E4C41E0B4AEC006451C7 /* libRCTLinking-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DAD3E881DF850E9000B6D8A /* libRCTLinking-tvOS.a */; };
56 | 2D02E4C51E0B4AEC006451C7 /* libRCTNetwork-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DAD3E8C1DF850E9000B6D8A /* libRCTNetwork-tvOS.a */; };
57 | 2D02E4C61E0B4AEC006451C7 /* libRCTSettings-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DAD3E901DF850E9000B6D8A /* libRCTSettings-tvOS.a */; };
58 | 2D02E4C71E0B4AEC006451C7 /* libRCTText-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DAD3E941DF850E9000B6D8A /* libRCTText-tvOS.a */; };
59 | 2D02E4C81E0B4AEC006451C7 /* libRCTWebSocket-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DAD3E991DF850E9000B6D8A /* libRCTWebSocket-tvOS.a */; };
60 | 2D16E6881FA4F8E400B85C8A /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2D16E6891FA4F8E400B85C8A /* libReact.a */; };
61 | 2DCD954D1E0B4F2C00145EB5 /* frontendTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* frontendTests.m */; };
62 | 2DF0FFEE2056DD460020B375 /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DAD3EA31DF850E9000B6D8A /* libReact.a */; };
63 | 832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 832341B51AAA6A8300B99B32 /* libRCTText.a */; };
64 | ADBDB9381DFEBF1600ED6528 /* libRCTBlob.a in Frameworks */ = {isa = PBXBuildFile; fileRef = ADBDB9271DFEBF0700ED6528 /* libRCTBlob.a */; };
65 | /* End PBXBuildFile section */
66 |
67 | /* Begin PBXContainerItemProxy section */
68 | 00C302AB1ABCB8CE00DB3ED1 /* PBXContainerItemProxy */ = {
69 | isa = PBXContainerItemProxy;
70 | containerPortal = 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */;
71 | proxyType = 2;
72 | remoteGlobalIDString = 134814201AA4EA6300B7C361;
73 | remoteInfo = RCTActionSheet;
74 | };
75 | 00C302B91ABCB90400DB3ED1 /* PBXContainerItemProxy */ = {
76 | isa = PBXContainerItemProxy;
77 | containerPortal = 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */;
78 | proxyType = 2;
79 | remoteGlobalIDString = 134814201AA4EA6300B7C361;
80 | remoteInfo = RCTGeolocation;
81 | };
82 | 00C302BF1ABCB91800DB3ED1 /* PBXContainerItemProxy */ = {
83 | isa = PBXContainerItemProxy;
84 | containerPortal = 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */;
85 | proxyType = 2;
86 | remoteGlobalIDString = 58B5115D1A9E6B3D00147676;
87 | remoteInfo = RCTImage;
88 | };
89 | 00C302DB1ABCB9D200DB3ED1 /* PBXContainerItemProxy */ = {
90 | isa = PBXContainerItemProxy;
91 | containerPortal = 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */;
92 | proxyType = 2;
93 | remoteGlobalIDString = 58B511DB1A9E6C8500147676;
94 | remoteInfo = RCTNetwork;
95 | };
96 | 00C302E31ABCB9EE00DB3ED1 /* PBXContainerItemProxy */ = {
97 | isa = PBXContainerItemProxy;
98 | containerPortal = 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */;
99 | proxyType = 2;
100 | remoteGlobalIDString = 832C81801AAF6DEF007FA2F7;
101 | remoteInfo = RCTVibration;
102 | };
103 | 00E356F41AD99517003FC87E /* PBXContainerItemProxy */ = {
104 | isa = PBXContainerItemProxy;
105 | containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */;
106 | proxyType = 1;
107 | remoteGlobalIDString = 13B07F861A680F5B00A75B9A;
108 | remoteInfo = frontend;
109 | };
110 | 139105C01AF99BAD00B5F7CC /* PBXContainerItemProxy */ = {
111 | isa = PBXContainerItemProxy;
112 | containerPortal = 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */;
113 | proxyType = 2;
114 | remoteGlobalIDString = 134814201AA4EA6300B7C361;
115 | remoteInfo = RCTSettings;
116 | };
117 | 139FDEF31B06529B00C62182 /* PBXContainerItemProxy */ = {
118 | isa = PBXContainerItemProxy;
119 | containerPortal = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */;
120 | proxyType = 2;
121 | remoteGlobalIDString = 3C86DF461ADF2C930047B81A;
122 | remoteInfo = RCTWebSocket;
123 | };
124 | 146834031AC3E56700842450 /* PBXContainerItemProxy */ = {
125 | isa = PBXContainerItemProxy;
126 | containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
127 | proxyType = 2;
128 | remoteGlobalIDString = 83CBBA2E1A601D0E00E9B192;
129 | remoteInfo = React;
130 | };
131 | 2D02E4911E0B4A5D006451C7 /* PBXContainerItemProxy */ = {
132 | isa = PBXContainerItemProxy;
133 | containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */;
134 | proxyType = 1;
135 | remoteGlobalIDString = 2D02E47A1E0B4A5D006451C7;
136 | remoteInfo = "frontend-tvOS";
137 | };
138 | 2D16E6711FA4F8DC00B85C8A /* PBXContainerItemProxy */ = {
139 | isa = PBXContainerItemProxy;
140 | containerPortal = ADBDB91F1DFEBF0600ED6528 /* RCTBlob.xcodeproj */;
141 | proxyType = 2;
142 | remoteGlobalIDString = ADD01A681E09402E00F6D226;
143 | remoteInfo = "RCTBlob-tvOS";
144 | };
145 | 2D16E6831FA4F8DC00B85C8A /* PBXContainerItemProxy */ = {
146 | isa = PBXContainerItemProxy;
147 | containerPortal = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */;
148 | proxyType = 2;
149 | remoteGlobalIDString = 3DBE0D001F3B181A0099AA32;
150 | remoteInfo = fishhook;
151 | };
152 | 2D16E6851FA4F8DC00B85C8A /* PBXContainerItemProxy */ = {
153 | isa = PBXContainerItemProxy;
154 | containerPortal = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */;
155 | proxyType = 2;
156 | remoteGlobalIDString = 3DBE0D0D1F3B181C0099AA32;
157 | remoteInfo = "fishhook-tvOS";
158 | };
159 | 2DF0FFDE2056DD460020B375 /* PBXContainerItemProxy */ = {
160 | isa = PBXContainerItemProxy;
161 | containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
162 | proxyType = 2;
163 | remoteGlobalIDString = EBF21BDC1FC498900052F4D5;
164 | remoteInfo = jsinspector;
165 | };
166 | 2DF0FFE02056DD460020B375 /* PBXContainerItemProxy */ = {
167 | isa = PBXContainerItemProxy;
168 | containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
169 | proxyType = 2;
170 | remoteGlobalIDString = EBF21BFA1FC4989A0052F4D5;
171 | remoteInfo = "jsinspector-tvOS";
172 | };
173 | 2DF0FFE22056DD460020B375 /* PBXContainerItemProxy */ = {
174 | isa = PBXContainerItemProxy;
175 | containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
176 | proxyType = 2;
177 | remoteGlobalIDString = 139D7ECE1E25DB7D00323FB7;
178 | remoteInfo = "third-party";
179 | };
180 | 2DF0FFE42056DD460020B375 /* PBXContainerItemProxy */ = {
181 | isa = PBXContainerItemProxy;
182 | containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
183 | proxyType = 2;
184 | remoteGlobalIDString = 3D383D3C1EBD27B6005632C8;
185 | remoteInfo = "third-party-tvOS";
186 | };
187 | 2DF0FFE62056DD460020B375 /* PBXContainerItemProxy */ = {
188 | isa = PBXContainerItemProxy;
189 | containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
190 | proxyType = 2;
191 | remoteGlobalIDString = 139D7E881E25C6D100323FB7;
192 | remoteInfo = "double-conversion";
193 | };
194 | 2DF0FFE82056DD460020B375 /* PBXContainerItemProxy */ = {
195 | isa = PBXContainerItemProxy;
196 | containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
197 | proxyType = 2;
198 | remoteGlobalIDString = 3D383D621EBD27B9005632C8;
199 | remoteInfo = "double-conversion-tvOS";
200 | };
201 | 2DF0FFEA2056DD460020B375 /* PBXContainerItemProxy */ = {
202 | isa = PBXContainerItemProxy;
203 | containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
204 | proxyType = 2;
205 | remoteGlobalIDString = 9936F3131F5F2E4B0010BF04;
206 | remoteInfo = privatedata;
207 | };
208 | 2DF0FFEC2056DD460020B375 /* PBXContainerItemProxy */ = {
209 | isa = PBXContainerItemProxy;
210 | containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
211 | proxyType = 2;
212 | remoteGlobalIDString = 9936F32F1F5F2E5B0010BF04;
213 | remoteInfo = "privatedata-tvOS";
214 | };
215 | 3DAD3E831DF850E9000B6D8A /* PBXContainerItemProxy */ = {
216 | isa = PBXContainerItemProxy;
217 | containerPortal = 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */;
218 | proxyType = 2;
219 | remoteGlobalIDString = 2D2A283A1D9B042B00D4039D;
220 | remoteInfo = "RCTImage-tvOS";
221 | };
222 | 3DAD3E871DF850E9000B6D8A /* PBXContainerItemProxy */ = {
223 | isa = PBXContainerItemProxy;
224 | containerPortal = 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */;
225 | proxyType = 2;
226 | remoteGlobalIDString = 2D2A28471D9B043800D4039D;
227 | remoteInfo = "RCTLinking-tvOS";
228 | };
229 | 3DAD3E8B1DF850E9000B6D8A /* PBXContainerItemProxy */ = {
230 | isa = PBXContainerItemProxy;
231 | containerPortal = 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */;
232 | proxyType = 2;
233 | remoteGlobalIDString = 2D2A28541D9B044C00D4039D;
234 | remoteInfo = "RCTNetwork-tvOS";
235 | };
236 | 3DAD3E8F1DF850E9000B6D8A /* PBXContainerItemProxy */ = {
237 | isa = PBXContainerItemProxy;
238 | containerPortal = 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */;
239 | proxyType = 2;
240 | remoteGlobalIDString = 2D2A28611D9B046600D4039D;
241 | remoteInfo = "RCTSettings-tvOS";
242 | };
243 | 3DAD3E931DF850E9000B6D8A /* PBXContainerItemProxy */ = {
244 | isa = PBXContainerItemProxy;
245 | containerPortal = 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */;
246 | proxyType = 2;
247 | remoteGlobalIDString = 2D2A287B1D9B048500D4039D;
248 | remoteInfo = "RCTText-tvOS";
249 | };
250 | 3DAD3E981DF850E9000B6D8A /* PBXContainerItemProxy */ = {
251 | isa = PBXContainerItemProxy;
252 | containerPortal = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */;
253 | proxyType = 2;
254 | remoteGlobalIDString = 2D2A28881D9B049200D4039D;
255 | remoteInfo = "RCTWebSocket-tvOS";
256 | };
257 | 3DAD3EA21DF850E9000B6D8A /* PBXContainerItemProxy */ = {
258 | isa = PBXContainerItemProxy;
259 | containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
260 | proxyType = 2;
261 | remoteGlobalIDString = 2D2A28131D9B038B00D4039D;
262 | remoteInfo = "React-tvOS";
263 | };
264 | 3DAD3EA41DF850E9000B6D8A /* PBXContainerItemProxy */ = {
265 | isa = PBXContainerItemProxy;
266 | containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
267 | proxyType = 2;
268 | remoteGlobalIDString = 3D3C059A1DE3340900C268FA;
269 | remoteInfo = yoga;
270 | };
271 | 3DAD3EA61DF850E9000B6D8A /* PBXContainerItemProxy */ = {
272 | isa = PBXContainerItemProxy;
273 | containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
274 | proxyType = 2;
275 | remoteGlobalIDString = 3D3C06751DE3340C00C268FA;
276 | remoteInfo = "yoga-tvOS";
277 | };
278 | 3DAD3EA81DF850E9000B6D8A /* PBXContainerItemProxy */ = {
279 | isa = PBXContainerItemProxy;
280 | containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
281 | proxyType = 2;
282 | remoteGlobalIDString = 3D3CD9251DE5FBEC00167DC4;
283 | remoteInfo = cxxreact;
284 | };
285 | 3DAD3EAA1DF850E9000B6D8A /* PBXContainerItemProxy */ = {
286 | isa = PBXContainerItemProxy;
287 | containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
288 | proxyType = 2;
289 | remoteGlobalIDString = 3D3CD9321DE5FBEE00167DC4;
290 | remoteInfo = "cxxreact-tvOS";
291 | };
292 | 3DAD3EAC1DF850E9000B6D8A /* PBXContainerItemProxy */ = {
293 | isa = PBXContainerItemProxy;
294 | containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
295 | proxyType = 2;
296 | remoteGlobalIDString = 3D3CD90B1DE5FBD600167DC4;
297 | remoteInfo = jschelpers;
298 | };
299 | 3DAD3EAE1DF850E9000B6D8A /* PBXContainerItemProxy */ = {
300 | isa = PBXContainerItemProxy;
301 | containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
302 | proxyType = 2;
303 | remoteGlobalIDString = 3D3CD9181DE5FBD800167DC4;
304 | remoteInfo = "jschelpers-tvOS";
305 | };
306 | 5E9157321DD0AC6500FF2AA8 /* PBXContainerItemProxy */ = {
307 | isa = PBXContainerItemProxy;
308 | containerPortal = 5E91572D1DD0AC6500FF2AA8 /* RCTAnimation.xcodeproj */;
309 | proxyType = 2;
310 | remoteGlobalIDString = 134814201AA4EA6300B7C361;
311 | remoteInfo = RCTAnimation;
312 | };
313 | 5E9157341DD0AC6500FF2AA8 /* PBXContainerItemProxy */ = {
314 | isa = PBXContainerItemProxy;
315 | containerPortal = 5E91572D1DD0AC6500FF2AA8 /* RCTAnimation.xcodeproj */;
316 | proxyType = 2;
317 | remoteGlobalIDString = 2D2A28201D9B03D100D4039D;
318 | remoteInfo = "RCTAnimation-tvOS";
319 | };
320 | 78C398B81ACF4ADC00677621 /* PBXContainerItemProxy */ = {
321 | isa = PBXContainerItemProxy;
322 | containerPortal = 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */;
323 | proxyType = 2;
324 | remoteGlobalIDString = 134814201AA4EA6300B7C361;
325 | remoteInfo = RCTLinking;
326 | };
327 | 832341B41AAA6A8300B99B32 /* PBXContainerItemProxy */ = {
328 | isa = PBXContainerItemProxy;
329 | containerPortal = 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */;
330 | proxyType = 2;
331 | remoteGlobalIDString = 58B5119B1A9E6C1200147676;
332 | remoteInfo = RCTText;
333 | };
334 | ADBDB9261DFEBF0700ED6528 /* PBXContainerItemProxy */ = {
335 | isa = PBXContainerItemProxy;
336 | containerPortal = ADBDB91F1DFEBF0600ED6528 /* RCTBlob.xcodeproj */;
337 | proxyType = 2;
338 | remoteGlobalIDString = 358F4ED71D1E81A9004DF814;
339 | remoteInfo = RCTBlob;
340 | };
341 | /* End PBXContainerItemProxy section */
342 |
343 | /* Begin PBXFileReference section */
344 | 008F07F21AC5B25A0029DE68 /* main.jsbundle */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = main.jsbundle; sourceTree = ""; };
345 | 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTActionSheet.xcodeproj; path = "../node_modules/react-native/Libraries/ActionSheetIOS/RCTActionSheet.xcodeproj"; sourceTree = ""; };
346 | 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTGeolocation.xcodeproj; path = "../node_modules/react-native/Libraries/Geolocation/RCTGeolocation.xcodeproj"; sourceTree = ""; };
347 | 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTImage.xcodeproj; path = "../node_modules/react-native/Libraries/Image/RCTImage.xcodeproj"; sourceTree = ""; };
348 | 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTNetwork.xcodeproj; path = "../node_modules/react-native/Libraries/Network/RCTNetwork.xcodeproj"; sourceTree = ""; };
349 | 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTVibration.xcodeproj; path = "../node_modules/react-native/Libraries/Vibration/RCTVibration.xcodeproj"; sourceTree = ""; };
350 | 00E356EE1AD99517003FC87E /* frontendTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = frontendTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
351 | 00E356F11AD99517003FC87E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
352 | 00E356F21AD99517003FC87E /* frontendTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = frontendTests.m; sourceTree = ""; };
353 | 057BEAF12167899600E1CC13 /* Spectral-BoldItalic.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Spectral-BoldItalic.ttf"; sourceTree = ""; };
354 | 057BEAF22167899600E1CC13 /* Spectral-Regular.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Spectral-Regular.ttf"; sourceTree = ""; };
355 | 057BEAF32167899600E1CC13 /* Spectral-Italic.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Spectral-Italic.ttf"; sourceTree = ""; };
356 | 057BEAF42167899600E1CC13 /* Spectral-Bold.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Spectral-Bold.ttf"; sourceTree = ""; };
357 | 057BEAF921679CA100E1CC13 /* CrimsonText-Italic.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "CrimsonText-Italic.ttf"; sourceTree = ""; };
358 | 057BEAFA21679CA200E1CC13 /* CrimsonText-Bold.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "CrimsonText-Bold.ttf"; sourceTree = ""; };
359 | 057BEAFB21679CA200E1CC13 /* CrimsonText-Regular.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "CrimsonText-Regular.ttf"; sourceTree = ""; };
360 | 057BEAFC21679CA200E1CC13 /* CrimsonText-BoldItalic.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "CrimsonText-BoldItalic.ttf"; sourceTree = ""; };
361 | 057BEB012167D35700E1CC13 /* Spectral-MediumItalic.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Spectral-MediumItalic.ttf"; sourceTree = ""; };
362 | 057BEB022167D35700E1CC13 /* Spectral-SemiBoldItalic.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Spectral-SemiBoldItalic.ttf"; sourceTree = ""; };
363 | 057BEB032167D35700E1CC13 /* Spectral-SemiBold.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Spectral-SemiBold.ttf"; sourceTree = ""; };
364 | 057BEB042167D35800E1CC13 /* Spectral-Medium.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Spectral-Medium.ttf"; sourceTree = ""; };
365 | 05F8404B216A3BE600CF85DB /* Nunito-Regular.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Nunito-Regular.ttf"; sourceTree = ""; };
366 | 05F84071216A3BE600CF85DB /* Nunito-BoldItalic.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Nunito-BoldItalic.ttf"; sourceTree = ""; };
367 | 05F84072216A3BE700CF85DB /* Nunito-ExtraBoldItalic.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Nunito-ExtraBoldItalic.ttf"; sourceTree = ""; };
368 | 05F84073216A3BE700CF85DB /* Nunito-Bold.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Nunito-Bold.ttf"; sourceTree = ""; };
369 | 05F84074216A3BE700CF85DB /* Nunito-Italic.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Nunito-Italic.ttf"; sourceTree = ""; };
370 | 05F84075216A3BE700CF85DB /* Nunito-ExtraBold.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Nunito-ExtraBold.ttf"; sourceTree = ""; };
371 | 05F84076216A3BE700CF85DB /* Nunito-SemiBoldItalic.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Nunito-SemiBoldItalic.ttf"; sourceTree = ""; };
372 | 05F84077216A3BE700CF85DB /* Nunito-SemiBold.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Nunito-SemiBold.ttf"; sourceTree = ""; };
373 | 05F84078216A3BE700CF85DB /* Nunito-Light.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Nunito-Light.ttf"; sourceTree = ""; };
374 | 05F84079216A3BE700CF85DB /* Nunito-LightItalic.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Nunito-LightItalic.ttf"; sourceTree = ""; };
375 | 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTSettings.xcodeproj; path = "../node_modules/react-native/Libraries/Settings/RCTSettings.xcodeproj"; sourceTree = ""; };
376 | 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTWebSocket.xcodeproj; path = "../node_modules/react-native/Libraries/WebSocket/RCTWebSocket.xcodeproj"; sourceTree = ""; };
377 | 13B07F961A680F5B00A75B9A /* frontend.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = frontend.app; sourceTree = BUILT_PRODUCTS_DIR; };
378 | 13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = frontend/AppDelegate.h; sourceTree = ""; };
379 | 13B07FB01A68108700A75B9A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = frontend/AppDelegate.m; sourceTree = ""; };
380 | 13B07FB21A68108700A75B9A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; };
381 | 13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = frontend/Images.xcassets; sourceTree = ""; };
382 | 13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = frontend/Info.plist; sourceTree = ""; };
383 | 13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = frontend/main.m; sourceTree = ""; };
384 | 146833FF1AC3E56700842450 /* React.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = React.xcodeproj; path = "../node_modules/react-native/React/React.xcodeproj"; sourceTree = ""; };
385 | 2D02E47B1E0B4A5D006451C7 /* frontend-tvOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "frontend-tvOS.app"; sourceTree = BUILT_PRODUCTS_DIR; };
386 | 2D02E4901E0B4A5D006451C7 /* frontend-tvOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "frontend-tvOSTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
387 | 2D16E6891FA4F8E400B85C8A /* libReact.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libReact.a; sourceTree = BUILT_PRODUCTS_DIR; };
388 | 5E91572D1DD0AC6500FF2AA8 /* RCTAnimation.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTAnimation.xcodeproj; path = "../node_modules/react-native/Libraries/NativeAnimation/RCTAnimation.xcodeproj"; sourceTree = ""; };
389 | 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTLinking.xcodeproj; path = "../node_modules/react-native/Libraries/LinkingIOS/RCTLinking.xcodeproj"; sourceTree = ""; };
390 | 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = "../node_modules/react-native/Libraries/Text/RCTText.xcodeproj"; sourceTree = ""; };
391 | ADBDB91F1DFEBF0600ED6528 /* RCTBlob.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTBlob.xcodeproj; path = "../node_modules/react-native/Libraries/Blob/RCTBlob.xcodeproj"; sourceTree = ""; };
392 | /* End PBXFileReference section */
393 |
394 | /* Begin PBXFrameworksBuildPhase section */
395 | 00E356EB1AD99517003FC87E /* Frameworks */ = {
396 | isa = PBXFrameworksBuildPhase;
397 | buildActionMask = 2147483647;
398 | files = (
399 | 140ED2AC1D01E1AD002B40FF /* libReact.a in Frameworks */,
400 | );
401 | runOnlyForDeploymentPostprocessing = 0;
402 | };
403 | 13B07F8C1A680F5B00A75B9A /* Frameworks */ = {
404 | isa = PBXFrameworksBuildPhase;
405 | buildActionMask = 2147483647;
406 | files = (
407 | ADBDB9381DFEBF1600ED6528 /* libRCTBlob.a in Frameworks */,
408 | 11D1A2F320CAFA9E000508D9 /* libRCTAnimation.a in Frameworks */,
409 | 146834051AC3E58100842450 /* libReact.a in Frameworks */,
410 | 00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */,
411 | 00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */,
412 | 00C302E81ABCBA2D00DB3ED1 /* libRCTImage.a in Frameworks */,
413 | 133E29F31AD74F7200F7D852 /* libRCTLinking.a in Frameworks */,
414 | 00C302E91ABCBA2D00DB3ED1 /* libRCTNetwork.a in Frameworks */,
415 | 139105C61AF99C1200B5F7CC /* libRCTSettings.a in Frameworks */,
416 | 832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */,
417 | 00C302EA1ABCBA2D00DB3ED1 /* libRCTVibration.a in Frameworks */,
418 | 139FDEF61B0652A700C62182 /* libRCTWebSocket.a in Frameworks */,
419 | );
420 | runOnlyForDeploymentPostprocessing = 0;
421 | };
422 | 2D02E4781E0B4A5D006451C7 /* Frameworks */ = {
423 | isa = PBXFrameworksBuildPhase;
424 | buildActionMask = 2147483647;
425 | files = (
426 | 2D16E6881FA4F8E400B85C8A /* libReact.a in Frameworks */,
427 | 2D02E4C21E0B4AEC006451C7 /* libRCTAnimation.a in Frameworks */,
428 | 2D02E4C31E0B4AEC006451C7 /* libRCTImage-tvOS.a in Frameworks */,
429 | 2D02E4C41E0B4AEC006451C7 /* libRCTLinking-tvOS.a in Frameworks */,
430 | 2D02E4C51E0B4AEC006451C7 /* libRCTNetwork-tvOS.a in Frameworks */,
431 | 2D02E4C61E0B4AEC006451C7 /* libRCTSettings-tvOS.a in Frameworks */,
432 | 2D02E4C71E0B4AEC006451C7 /* libRCTText-tvOS.a in Frameworks */,
433 | 2D02E4C81E0B4AEC006451C7 /* libRCTWebSocket-tvOS.a in Frameworks */,
434 | );
435 | runOnlyForDeploymentPostprocessing = 0;
436 | };
437 | 2D02E48D1E0B4A5D006451C7 /* Frameworks */ = {
438 | isa = PBXFrameworksBuildPhase;
439 | buildActionMask = 2147483647;
440 | files = (
441 | 2DF0FFEE2056DD460020B375 /* libReact.a in Frameworks */,
442 | );
443 | runOnlyForDeploymentPostprocessing = 0;
444 | };
445 | /* End PBXFrameworksBuildPhase section */
446 |
447 | /* Begin PBXGroup section */
448 | 00C302A81ABCB8CE00DB3ED1 /* Products */ = {
449 | isa = PBXGroup;
450 | children = (
451 | 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */,
452 | );
453 | name = Products;
454 | sourceTree = "";
455 | };
456 | 00C302B61ABCB90400DB3ED1 /* Products */ = {
457 | isa = PBXGroup;
458 | children = (
459 | 00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */,
460 | );
461 | name = Products;
462 | sourceTree = "";
463 | };
464 | 00C302BC1ABCB91800DB3ED1 /* Products */ = {
465 | isa = PBXGroup;
466 | children = (
467 | 00C302C01ABCB91800DB3ED1 /* libRCTImage.a */,
468 | 3DAD3E841DF850E9000B6D8A /* libRCTImage-tvOS.a */,
469 | );
470 | name = Products;
471 | sourceTree = "";
472 | };
473 | 00C302D41ABCB9D200DB3ED1 /* Products */ = {
474 | isa = PBXGroup;
475 | children = (
476 | 00C302DC1ABCB9D200DB3ED1 /* libRCTNetwork.a */,
477 | 3DAD3E8C1DF850E9000B6D8A /* libRCTNetwork-tvOS.a */,
478 | );
479 | name = Products;
480 | sourceTree = "";
481 | };
482 | 00C302E01ABCB9EE00DB3ED1 /* Products */ = {
483 | isa = PBXGroup;
484 | children = (
485 | 00C302E41ABCB9EE00DB3ED1 /* libRCTVibration.a */,
486 | );
487 | name = Products;
488 | sourceTree = "";
489 | };
490 | 00E356EF1AD99517003FC87E /* frontendTests */ = {
491 | isa = PBXGroup;
492 | children = (
493 | 00E356F21AD99517003FC87E /* frontendTests.m */,
494 | 00E356F01AD99517003FC87E /* Supporting Files */,
495 | );
496 | path = frontendTests;
497 | sourceTree = "";
498 | };
499 | 00E356F01AD99517003FC87E /* Supporting Files */ = {
500 | isa = PBXGroup;
501 | children = (
502 | 00E356F11AD99517003FC87E /* Info.plist */,
503 | );
504 | name = "Supporting Files";
505 | sourceTree = "";
506 | };
507 | 057BEAC92167847400E1CC13 /* Resources */ = {
508 | isa = PBXGroup;
509 | children = (
510 | 057BEAF42167899600E1CC13 /* Spectral-Bold.ttf */,
511 | 057BEAFA21679CA200E1CC13 /* CrimsonText-Bold.ttf */,
512 | 05F84073216A3BE700CF85DB /* Nunito-Bold.ttf */,
513 | 05F84071216A3BE600CF85DB /* Nunito-BoldItalic.ttf */,
514 | 05F84075216A3BE700CF85DB /* Nunito-ExtraBold.ttf */,
515 | 05F84072216A3BE700CF85DB /* Nunito-ExtraBoldItalic.ttf */,
516 | 05F84074216A3BE700CF85DB /* Nunito-Italic.ttf */,
517 | 05F84078216A3BE700CF85DB /* Nunito-Light.ttf */,
518 | 05F84079216A3BE700CF85DB /* Nunito-LightItalic.ttf */,
519 | 05F8404B216A3BE600CF85DB /* Nunito-Regular.ttf */,
520 | 05F84077216A3BE700CF85DB /* Nunito-SemiBold.ttf */,
521 | 05F84076216A3BE700CF85DB /* Nunito-SemiBoldItalic.ttf */,
522 | 057BEB042167D35800E1CC13 /* Spectral-Medium.ttf */,
523 | 057BEB012167D35700E1CC13 /* Spectral-MediumItalic.ttf */,
524 | 057BEB032167D35700E1CC13 /* Spectral-SemiBold.ttf */,
525 | 057BEB022167D35700E1CC13 /* Spectral-SemiBoldItalic.ttf */,
526 | 057BEAFC21679CA200E1CC13 /* CrimsonText-BoldItalic.ttf */,
527 | 057BEAF921679CA100E1CC13 /* CrimsonText-Italic.ttf */,
528 | 057BEAFB21679CA200E1CC13 /* CrimsonText-Regular.ttf */,
529 | 057BEAF12167899600E1CC13 /* Spectral-BoldItalic.ttf */,
530 | 057BEAF32167899600E1CC13 /* Spectral-Italic.ttf */,
531 | 057BEAF22167899600E1CC13 /* Spectral-Regular.ttf */,
532 | );
533 | path = Resources;
534 | sourceTree = "";
535 | };
536 | 139105B71AF99BAD00B5F7CC /* Products */ = {
537 | isa = PBXGroup;
538 | children = (
539 | 139105C11AF99BAD00B5F7CC /* libRCTSettings.a */,
540 | 3DAD3E901DF850E9000B6D8A /* libRCTSettings-tvOS.a */,
541 | );
542 | name = Products;
543 | sourceTree = "";
544 | };
545 | 139FDEE71B06529A00C62182 /* Products */ = {
546 | isa = PBXGroup;
547 | children = (
548 | 139FDEF41B06529B00C62182 /* libRCTWebSocket.a */,
549 | 3DAD3E991DF850E9000B6D8A /* libRCTWebSocket-tvOS.a */,
550 | 2D16E6841FA4F8DC00B85C8A /* libfishhook.a */,
551 | 2D16E6861FA4F8DC00B85C8A /* libfishhook-tvOS.a */,
552 | );
553 | name = Products;
554 | sourceTree = "";
555 | };
556 | 13B07FAE1A68108700A75B9A /* frontend */ = {
557 | isa = PBXGroup;
558 | children = (
559 | 008F07F21AC5B25A0029DE68 /* main.jsbundle */,
560 | 13B07FAF1A68108700A75B9A /* AppDelegate.h */,
561 | 13B07FB01A68108700A75B9A /* AppDelegate.m */,
562 | 13B07FB51A68108700A75B9A /* Images.xcassets */,
563 | 13B07FB61A68108700A75B9A /* Info.plist */,
564 | 13B07FB11A68108700A75B9A /* LaunchScreen.xib */,
565 | 13B07FB71A68108700A75B9A /* main.m */,
566 | );
567 | name = frontend;
568 | sourceTree = "";
569 | };
570 | 146834001AC3E56700842450 /* Products */ = {
571 | isa = PBXGroup;
572 | children = (
573 | 146834041AC3E56700842450 /* libReact.a */,
574 | 3DAD3EA31DF850E9000B6D8A /* libReact.a */,
575 | 3DAD3EA51DF850E9000B6D8A /* libyoga.a */,
576 | 3DAD3EA71DF850E9000B6D8A /* libyoga.a */,
577 | 3DAD3EA91DF850E9000B6D8A /* libcxxreact.a */,
578 | 3DAD3EAB1DF850E9000B6D8A /* libcxxreact.a */,
579 | 3DAD3EAD1DF850E9000B6D8A /* libjschelpers.a */,
580 | 3DAD3EAF1DF850E9000B6D8A /* libjschelpers.a */,
581 | 2DF0FFDF2056DD460020B375 /* libjsinspector.a */,
582 | 2DF0FFE12056DD460020B375 /* libjsinspector-tvOS.a */,
583 | 2DF0FFE32056DD460020B375 /* libthird-party.a */,
584 | 2DF0FFE52056DD460020B375 /* libthird-party.a */,
585 | 2DF0FFE72056DD460020B375 /* libdouble-conversion.a */,
586 | 2DF0FFE92056DD460020B375 /* libdouble-conversion.a */,
587 | 2DF0FFEB2056DD460020B375 /* libprivatedata.a */,
588 | 2DF0FFED2056DD460020B375 /* libprivatedata-tvOS.a */,
589 | );
590 | name = Products;
591 | sourceTree = "";
592 | };
593 | 2D16E6871FA4F8E400B85C8A /* Frameworks */ = {
594 | isa = PBXGroup;
595 | children = (
596 | 2D16E6891FA4F8E400B85C8A /* libReact.a */,
597 | );
598 | name = Frameworks;
599 | sourceTree = "";
600 | };
601 | 5E91572E1DD0AC6500FF2AA8 /* Products */ = {
602 | isa = PBXGroup;
603 | children = (
604 | 5E9157331DD0AC6500FF2AA8 /* libRCTAnimation.a */,
605 | 5E9157351DD0AC6500FF2AA8 /* libRCTAnimation.a */,
606 | );
607 | name = Products;
608 | sourceTree = "";
609 | };
610 | 78C398B11ACF4ADC00677621 /* Products */ = {
611 | isa = PBXGroup;
612 | children = (
613 | 78C398B91ACF4ADC00677621 /* libRCTLinking.a */,
614 | 3DAD3E881DF850E9000B6D8A /* libRCTLinking-tvOS.a */,
615 | );
616 | name = Products;
617 | sourceTree = "";
618 | };
619 | 832341AE1AAA6A7D00B99B32 /* Libraries */ = {
620 | isa = PBXGroup;
621 | children = (
622 | 5E91572D1DD0AC6500FF2AA8 /* RCTAnimation.xcodeproj */,
623 | 146833FF1AC3E56700842450 /* React.xcodeproj */,
624 | 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */,
625 | ADBDB91F1DFEBF0600ED6528 /* RCTBlob.xcodeproj */,
626 | 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */,
627 | 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */,
628 | 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */,
629 | 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */,
630 | 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */,
631 | 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */,
632 | 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */,
633 | 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */,
634 | );
635 | name = Libraries;
636 | sourceTree = "";
637 | };
638 | 832341B11AAA6A8300B99B32 /* Products */ = {
639 | isa = PBXGroup;
640 | children = (
641 | 832341B51AAA6A8300B99B32 /* libRCTText.a */,
642 | 3DAD3E941DF850E9000B6D8A /* libRCTText-tvOS.a */,
643 | );
644 | name = Products;
645 | sourceTree = "";
646 | };
647 | 83CBB9F61A601CBA00E9B192 = {
648 | isa = PBXGroup;
649 | children = (
650 | 057BEAC92167847400E1CC13 /* Resources */,
651 | 13B07FAE1A68108700A75B9A /* frontend */,
652 | 832341AE1AAA6A7D00B99B32 /* Libraries */,
653 | 00E356EF1AD99517003FC87E /* frontendTests */,
654 | 83CBBA001A601CBA00E9B192 /* Products */,
655 | 2D16E6871FA4F8E400B85C8A /* Frameworks */,
656 | );
657 | indentWidth = 2;
658 | sourceTree = "";
659 | tabWidth = 2;
660 | usesTabs = 0;
661 | };
662 | 83CBBA001A601CBA00E9B192 /* Products */ = {
663 | isa = PBXGroup;
664 | children = (
665 | 13B07F961A680F5B00A75B9A /* frontend.app */,
666 | 00E356EE1AD99517003FC87E /* frontendTests.xctest */,
667 | 2D02E47B1E0B4A5D006451C7 /* frontend-tvOS.app */,
668 | 2D02E4901E0B4A5D006451C7 /* frontend-tvOSTests.xctest */,
669 | );
670 | name = Products;
671 | sourceTree = "";
672 | };
673 | ADBDB9201DFEBF0600ED6528 /* Products */ = {
674 | isa = PBXGroup;
675 | children = (
676 | ADBDB9271DFEBF0700ED6528 /* libRCTBlob.a */,
677 | 2D16E6721FA4F8DC00B85C8A /* libRCTBlob-tvOS.a */,
678 | );
679 | name = Products;
680 | sourceTree = "";
681 | };
682 | /* End PBXGroup section */
683 |
684 | /* Begin PBXNativeTarget section */
685 | 00E356ED1AD99517003FC87E /* frontendTests */ = {
686 | isa = PBXNativeTarget;
687 | buildConfigurationList = 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "frontendTests" */;
688 | buildPhases = (
689 | 00E356EA1AD99517003FC87E /* Sources */,
690 | 00E356EB1AD99517003FC87E /* Frameworks */,
691 | 00E356EC1AD99517003FC87E /* Resources */,
692 | );
693 | buildRules = (
694 | );
695 | dependencies = (
696 | 00E356F51AD99517003FC87E /* PBXTargetDependency */,
697 | );
698 | name = frontendTests;
699 | productName = frontendTests;
700 | productReference = 00E356EE1AD99517003FC87E /* frontendTests.xctest */;
701 | productType = "com.apple.product-type.bundle.unit-test";
702 | };
703 | 13B07F861A680F5B00A75B9A /* frontend */ = {
704 | isa = PBXNativeTarget;
705 | buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "frontend" */;
706 | buildPhases = (
707 | 13B07F871A680F5B00A75B9A /* Sources */,
708 | 13B07F8C1A680F5B00A75B9A /* Frameworks */,
709 | 13B07F8E1A680F5B00A75B9A /* Resources */,
710 | 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */,
711 | );
712 | buildRules = (
713 | );
714 | dependencies = (
715 | );
716 | name = frontend;
717 | productName = "Hello World";
718 | productReference = 13B07F961A680F5B00A75B9A /* frontend.app */;
719 | productType = "com.apple.product-type.application";
720 | };
721 | 2D02E47A1E0B4A5D006451C7 /* frontend-tvOS */ = {
722 | isa = PBXNativeTarget;
723 | buildConfigurationList = 2D02E4BA1E0B4A5E006451C7 /* Build configuration list for PBXNativeTarget "frontend-tvOS" */;
724 | buildPhases = (
725 | 2D02E4771E0B4A5D006451C7 /* Sources */,
726 | 2D02E4781E0B4A5D006451C7 /* Frameworks */,
727 | 2D02E4791E0B4A5D006451C7 /* Resources */,
728 | 2D02E4CB1E0B4B27006451C7 /* Bundle React Native Code And Images */,
729 | );
730 | buildRules = (
731 | );
732 | dependencies = (
733 | );
734 | name = "frontend-tvOS";
735 | productName = "frontend-tvOS";
736 | productReference = 2D02E47B1E0B4A5D006451C7 /* frontend-tvOS.app */;
737 | productType = "com.apple.product-type.application";
738 | };
739 | 2D02E48F1E0B4A5D006451C7 /* frontend-tvOSTests */ = {
740 | isa = PBXNativeTarget;
741 | buildConfigurationList = 2D02E4BB1E0B4A5E006451C7 /* Build configuration list for PBXNativeTarget "frontend-tvOSTests" */;
742 | buildPhases = (
743 | 2D02E48C1E0B4A5D006451C7 /* Sources */,
744 | 2D02E48D1E0B4A5D006451C7 /* Frameworks */,
745 | 2D02E48E1E0B4A5D006451C7 /* Resources */,
746 | );
747 | buildRules = (
748 | );
749 | dependencies = (
750 | 2D02E4921E0B4A5D006451C7 /* PBXTargetDependency */,
751 | );
752 | name = "frontend-tvOSTests";
753 | productName = "frontend-tvOSTests";
754 | productReference = 2D02E4901E0B4A5D006451C7 /* frontend-tvOSTests.xctest */;
755 | productType = "com.apple.product-type.bundle.unit-test";
756 | };
757 | /* End PBXNativeTarget section */
758 |
759 | /* Begin PBXProject section */
760 | 83CBB9F71A601CBA00E9B192 /* Project object */ = {
761 | isa = PBXProject;
762 | attributes = {
763 | LastUpgradeCheck = 0940;
764 | ORGANIZATIONNAME = Facebook;
765 | TargetAttributes = {
766 | 00E356ED1AD99517003FC87E = {
767 | CreatedOnToolsVersion = 6.2;
768 | TestTargetID = 13B07F861A680F5B00A75B9A;
769 | };
770 | 2D02E47A1E0B4A5D006451C7 = {
771 | CreatedOnToolsVersion = 8.2.1;
772 | ProvisioningStyle = Automatic;
773 | };
774 | 2D02E48F1E0B4A5D006451C7 = {
775 | CreatedOnToolsVersion = 8.2.1;
776 | ProvisioningStyle = Automatic;
777 | TestTargetID = 2D02E47A1E0B4A5D006451C7;
778 | };
779 | };
780 | };
781 | buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "frontend" */;
782 | compatibilityVersion = "Xcode 3.2";
783 | developmentRegion = English;
784 | hasScannedForEncodings = 0;
785 | knownRegions = (
786 | en,
787 | Base,
788 | );
789 | mainGroup = 83CBB9F61A601CBA00E9B192;
790 | productRefGroup = 83CBBA001A601CBA00E9B192 /* Products */;
791 | projectDirPath = "";
792 | projectReferences = (
793 | {
794 | ProductGroup = 00C302A81ABCB8CE00DB3ED1 /* Products */;
795 | ProjectRef = 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */;
796 | },
797 | {
798 | ProductGroup = 5E91572E1DD0AC6500FF2AA8 /* Products */;
799 | ProjectRef = 5E91572D1DD0AC6500FF2AA8 /* RCTAnimation.xcodeproj */;
800 | },
801 | {
802 | ProductGroup = ADBDB9201DFEBF0600ED6528 /* Products */;
803 | ProjectRef = ADBDB91F1DFEBF0600ED6528 /* RCTBlob.xcodeproj */;
804 | },
805 | {
806 | ProductGroup = 00C302B61ABCB90400DB3ED1 /* Products */;
807 | ProjectRef = 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */;
808 | },
809 | {
810 | ProductGroup = 00C302BC1ABCB91800DB3ED1 /* Products */;
811 | ProjectRef = 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */;
812 | },
813 | {
814 | ProductGroup = 78C398B11ACF4ADC00677621 /* Products */;
815 | ProjectRef = 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */;
816 | },
817 | {
818 | ProductGroup = 00C302D41ABCB9D200DB3ED1 /* Products */;
819 | ProjectRef = 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */;
820 | },
821 | {
822 | ProductGroup = 139105B71AF99BAD00B5F7CC /* Products */;
823 | ProjectRef = 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */;
824 | },
825 | {
826 | ProductGroup = 832341B11AAA6A8300B99B32 /* Products */;
827 | ProjectRef = 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */;
828 | },
829 | {
830 | ProductGroup = 00C302E01ABCB9EE00DB3ED1 /* Products */;
831 | ProjectRef = 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */;
832 | },
833 | {
834 | ProductGroup = 139FDEE71B06529A00C62182 /* Products */;
835 | ProjectRef = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */;
836 | },
837 | {
838 | ProductGroup = 146834001AC3E56700842450 /* Products */;
839 | ProjectRef = 146833FF1AC3E56700842450 /* React.xcodeproj */;
840 | },
841 | );
842 | projectRoot = "";
843 | targets = (
844 | 13B07F861A680F5B00A75B9A /* frontend */,
845 | 00E356ED1AD99517003FC87E /* frontendTests */,
846 | 2D02E47A1E0B4A5D006451C7 /* frontend-tvOS */,
847 | 2D02E48F1E0B4A5D006451C7 /* frontend-tvOSTests */,
848 | );
849 | };
850 | /* End PBXProject section */
851 |
852 | /* Begin PBXReferenceProxy section */
853 | 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */ = {
854 | isa = PBXReferenceProxy;
855 | fileType = archive.ar;
856 | path = libRCTActionSheet.a;
857 | remoteRef = 00C302AB1ABCB8CE00DB3ED1 /* PBXContainerItemProxy */;
858 | sourceTree = BUILT_PRODUCTS_DIR;
859 | };
860 | 00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */ = {
861 | isa = PBXReferenceProxy;
862 | fileType = archive.ar;
863 | path = libRCTGeolocation.a;
864 | remoteRef = 00C302B91ABCB90400DB3ED1 /* PBXContainerItemProxy */;
865 | sourceTree = BUILT_PRODUCTS_DIR;
866 | };
867 | 00C302C01ABCB91800DB3ED1 /* libRCTImage.a */ = {
868 | isa = PBXReferenceProxy;
869 | fileType = archive.ar;
870 | path = libRCTImage.a;
871 | remoteRef = 00C302BF1ABCB91800DB3ED1 /* PBXContainerItemProxy */;
872 | sourceTree = BUILT_PRODUCTS_DIR;
873 | };
874 | 00C302DC1ABCB9D200DB3ED1 /* libRCTNetwork.a */ = {
875 | isa = PBXReferenceProxy;
876 | fileType = archive.ar;
877 | path = libRCTNetwork.a;
878 | remoteRef = 00C302DB1ABCB9D200DB3ED1 /* PBXContainerItemProxy */;
879 | sourceTree = BUILT_PRODUCTS_DIR;
880 | };
881 | 00C302E41ABCB9EE00DB3ED1 /* libRCTVibration.a */ = {
882 | isa = PBXReferenceProxy;
883 | fileType = archive.ar;
884 | path = libRCTVibration.a;
885 | remoteRef = 00C302E31ABCB9EE00DB3ED1 /* PBXContainerItemProxy */;
886 | sourceTree = BUILT_PRODUCTS_DIR;
887 | };
888 | 139105C11AF99BAD00B5F7CC /* libRCTSettings.a */ = {
889 | isa = PBXReferenceProxy;
890 | fileType = archive.ar;
891 | path = libRCTSettings.a;
892 | remoteRef = 139105C01AF99BAD00B5F7CC /* PBXContainerItemProxy */;
893 | sourceTree = BUILT_PRODUCTS_DIR;
894 | };
895 | 139FDEF41B06529B00C62182 /* libRCTWebSocket.a */ = {
896 | isa = PBXReferenceProxy;
897 | fileType = archive.ar;
898 | path = libRCTWebSocket.a;
899 | remoteRef = 139FDEF31B06529B00C62182 /* PBXContainerItemProxy */;
900 | sourceTree = BUILT_PRODUCTS_DIR;
901 | };
902 | 146834041AC3E56700842450 /* libReact.a */ = {
903 | isa = PBXReferenceProxy;
904 | fileType = archive.ar;
905 | path = libReact.a;
906 | remoteRef = 146834031AC3E56700842450 /* PBXContainerItemProxy */;
907 | sourceTree = BUILT_PRODUCTS_DIR;
908 | };
909 | 2D16E6721FA4F8DC00B85C8A /* libRCTBlob-tvOS.a */ = {
910 | isa = PBXReferenceProxy;
911 | fileType = archive.ar;
912 | path = "libRCTBlob-tvOS.a";
913 | remoteRef = 2D16E6711FA4F8DC00B85C8A /* PBXContainerItemProxy */;
914 | sourceTree = BUILT_PRODUCTS_DIR;
915 | };
916 | 2D16E6841FA4F8DC00B85C8A /* libfishhook.a */ = {
917 | isa = PBXReferenceProxy;
918 | fileType = archive.ar;
919 | path = libfishhook.a;
920 | remoteRef = 2D16E6831FA4F8DC00B85C8A /* PBXContainerItemProxy */;
921 | sourceTree = BUILT_PRODUCTS_DIR;
922 | };
923 | 2D16E6861FA4F8DC00B85C8A /* libfishhook-tvOS.a */ = {
924 | isa = PBXReferenceProxy;
925 | fileType = archive.ar;
926 | path = "libfishhook-tvOS.a";
927 | remoteRef = 2D16E6851FA4F8DC00B85C8A /* PBXContainerItemProxy */;
928 | sourceTree = BUILT_PRODUCTS_DIR;
929 | };
930 | 2DF0FFDF2056DD460020B375 /* libjsinspector.a */ = {
931 | isa = PBXReferenceProxy;
932 | fileType = archive.ar;
933 | path = libjsinspector.a;
934 | remoteRef = 2DF0FFDE2056DD460020B375 /* PBXContainerItemProxy */;
935 | sourceTree = BUILT_PRODUCTS_DIR;
936 | };
937 | 2DF0FFE12056DD460020B375 /* libjsinspector-tvOS.a */ = {
938 | isa = PBXReferenceProxy;
939 | fileType = archive.ar;
940 | path = "libjsinspector-tvOS.a";
941 | remoteRef = 2DF0FFE02056DD460020B375 /* PBXContainerItemProxy */;
942 | sourceTree = BUILT_PRODUCTS_DIR;
943 | };
944 | 2DF0FFE32056DD460020B375 /* libthird-party.a */ = {
945 | isa = PBXReferenceProxy;
946 | fileType = archive.ar;
947 | path = "libthird-party.a";
948 | remoteRef = 2DF0FFE22056DD460020B375 /* PBXContainerItemProxy */;
949 | sourceTree = BUILT_PRODUCTS_DIR;
950 | };
951 | 2DF0FFE52056DD460020B375 /* libthird-party.a */ = {
952 | isa = PBXReferenceProxy;
953 | fileType = archive.ar;
954 | path = "libthird-party.a";
955 | remoteRef = 2DF0FFE42056DD460020B375 /* PBXContainerItemProxy */;
956 | sourceTree = BUILT_PRODUCTS_DIR;
957 | };
958 | 2DF0FFE72056DD460020B375 /* libdouble-conversion.a */ = {
959 | isa = PBXReferenceProxy;
960 | fileType = archive.ar;
961 | path = "libdouble-conversion.a";
962 | remoteRef = 2DF0FFE62056DD460020B375 /* PBXContainerItemProxy */;
963 | sourceTree = BUILT_PRODUCTS_DIR;
964 | };
965 | 2DF0FFE92056DD460020B375 /* libdouble-conversion.a */ = {
966 | isa = PBXReferenceProxy;
967 | fileType = archive.ar;
968 | path = "libdouble-conversion.a";
969 | remoteRef = 2DF0FFE82056DD460020B375 /* PBXContainerItemProxy */;
970 | sourceTree = BUILT_PRODUCTS_DIR;
971 | };
972 | 2DF0FFEB2056DD460020B375 /* libprivatedata.a */ = {
973 | isa = PBXReferenceProxy;
974 | fileType = archive.ar;
975 | path = libprivatedata.a;
976 | remoteRef = 2DF0FFEA2056DD460020B375 /* PBXContainerItemProxy */;
977 | sourceTree = BUILT_PRODUCTS_DIR;
978 | };
979 | 2DF0FFED2056DD460020B375 /* libprivatedata-tvOS.a */ = {
980 | isa = PBXReferenceProxy;
981 | fileType = archive.ar;
982 | path = "libprivatedata-tvOS.a";
983 | remoteRef = 2DF0FFEC2056DD460020B375 /* PBXContainerItemProxy */;
984 | sourceTree = BUILT_PRODUCTS_DIR;
985 | };
986 | 3DAD3E841DF850E9000B6D8A /* libRCTImage-tvOS.a */ = {
987 | isa = PBXReferenceProxy;
988 | fileType = archive.ar;
989 | path = "libRCTImage-tvOS.a";
990 | remoteRef = 3DAD3E831DF850E9000B6D8A /* PBXContainerItemProxy */;
991 | sourceTree = BUILT_PRODUCTS_DIR;
992 | };
993 | 3DAD3E881DF850E9000B6D8A /* libRCTLinking-tvOS.a */ = {
994 | isa = PBXReferenceProxy;
995 | fileType = archive.ar;
996 | path = "libRCTLinking-tvOS.a";
997 | remoteRef = 3DAD3E871DF850E9000B6D8A /* PBXContainerItemProxy */;
998 | sourceTree = BUILT_PRODUCTS_DIR;
999 | };
1000 | 3DAD3E8C1DF850E9000B6D8A /* libRCTNetwork-tvOS.a */ = {
1001 | isa = PBXReferenceProxy;
1002 | fileType = archive.ar;
1003 | path = "libRCTNetwork-tvOS.a";
1004 | remoteRef = 3DAD3E8B1DF850E9000B6D8A /* PBXContainerItemProxy */;
1005 | sourceTree = BUILT_PRODUCTS_DIR;
1006 | };
1007 | 3DAD3E901DF850E9000B6D8A /* libRCTSettings-tvOS.a */ = {
1008 | isa = PBXReferenceProxy;
1009 | fileType = archive.ar;
1010 | path = "libRCTSettings-tvOS.a";
1011 | remoteRef = 3DAD3E8F1DF850E9000B6D8A /* PBXContainerItemProxy */;
1012 | sourceTree = BUILT_PRODUCTS_DIR;
1013 | };
1014 | 3DAD3E941DF850E9000B6D8A /* libRCTText-tvOS.a */ = {
1015 | isa = PBXReferenceProxy;
1016 | fileType = archive.ar;
1017 | path = "libRCTText-tvOS.a";
1018 | remoteRef = 3DAD3E931DF850E9000B6D8A /* PBXContainerItemProxy */;
1019 | sourceTree = BUILT_PRODUCTS_DIR;
1020 | };
1021 | 3DAD3E991DF850E9000B6D8A /* libRCTWebSocket-tvOS.a */ = {
1022 | isa = PBXReferenceProxy;
1023 | fileType = archive.ar;
1024 | path = "libRCTWebSocket-tvOS.a";
1025 | remoteRef = 3DAD3E981DF850E9000B6D8A /* PBXContainerItemProxy */;
1026 | sourceTree = BUILT_PRODUCTS_DIR;
1027 | };
1028 | 3DAD3EA31DF850E9000B6D8A /* libReact.a */ = {
1029 | isa = PBXReferenceProxy;
1030 | fileType = archive.ar;
1031 | path = libReact.a;
1032 | remoteRef = 3DAD3EA21DF850E9000B6D8A /* PBXContainerItemProxy */;
1033 | sourceTree = BUILT_PRODUCTS_DIR;
1034 | };
1035 | 3DAD3EA51DF850E9000B6D8A /* libyoga.a */ = {
1036 | isa = PBXReferenceProxy;
1037 | fileType = archive.ar;
1038 | path = libyoga.a;
1039 | remoteRef = 3DAD3EA41DF850E9000B6D8A /* PBXContainerItemProxy */;
1040 | sourceTree = BUILT_PRODUCTS_DIR;
1041 | };
1042 | 3DAD3EA71DF850E9000B6D8A /* libyoga.a */ = {
1043 | isa = PBXReferenceProxy;
1044 | fileType = archive.ar;
1045 | path = libyoga.a;
1046 | remoteRef = 3DAD3EA61DF850E9000B6D8A /* PBXContainerItemProxy */;
1047 | sourceTree = BUILT_PRODUCTS_DIR;
1048 | };
1049 | 3DAD3EA91DF850E9000B6D8A /* libcxxreact.a */ = {
1050 | isa = PBXReferenceProxy;
1051 | fileType = archive.ar;
1052 | path = libcxxreact.a;
1053 | remoteRef = 3DAD3EA81DF850E9000B6D8A /* PBXContainerItemProxy */;
1054 | sourceTree = BUILT_PRODUCTS_DIR;
1055 | };
1056 | 3DAD3EAB1DF850E9000B6D8A /* libcxxreact.a */ = {
1057 | isa = PBXReferenceProxy;
1058 | fileType = archive.ar;
1059 | path = libcxxreact.a;
1060 | remoteRef = 3DAD3EAA1DF850E9000B6D8A /* PBXContainerItemProxy */;
1061 | sourceTree = BUILT_PRODUCTS_DIR;
1062 | };
1063 | 3DAD3EAD1DF850E9000B6D8A /* libjschelpers.a */ = {
1064 | isa = PBXReferenceProxy;
1065 | fileType = archive.ar;
1066 | path = libjschelpers.a;
1067 | remoteRef = 3DAD3EAC1DF850E9000B6D8A /* PBXContainerItemProxy */;
1068 | sourceTree = BUILT_PRODUCTS_DIR;
1069 | };
1070 | 3DAD3EAF1DF850E9000B6D8A /* libjschelpers.a */ = {
1071 | isa = PBXReferenceProxy;
1072 | fileType = archive.ar;
1073 | path = libjschelpers.a;
1074 | remoteRef = 3DAD3EAE1DF850E9000B6D8A /* PBXContainerItemProxy */;
1075 | sourceTree = BUILT_PRODUCTS_DIR;
1076 | };
1077 | 5E9157331DD0AC6500FF2AA8 /* libRCTAnimation.a */ = {
1078 | isa = PBXReferenceProxy;
1079 | fileType = archive.ar;
1080 | path = libRCTAnimation.a;
1081 | remoteRef = 5E9157321DD0AC6500FF2AA8 /* PBXContainerItemProxy */;
1082 | sourceTree = BUILT_PRODUCTS_DIR;
1083 | };
1084 | 5E9157351DD0AC6500FF2AA8 /* libRCTAnimation.a */ = {
1085 | isa = PBXReferenceProxy;
1086 | fileType = archive.ar;
1087 | path = libRCTAnimation.a;
1088 | remoteRef = 5E9157341DD0AC6500FF2AA8 /* PBXContainerItemProxy */;
1089 | sourceTree = BUILT_PRODUCTS_DIR;
1090 | };
1091 | 78C398B91ACF4ADC00677621 /* libRCTLinking.a */ = {
1092 | isa = PBXReferenceProxy;
1093 | fileType = archive.ar;
1094 | path = libRCTLinking.a;
1095 | remoteRef = 78C398B81ACF4ADC00677621 /* PBXContainerItemProxy */;
1096 | sourceTree = BUILT_PRODUCTS_DIR;
1097 | };
1098 | 832341B51AAA6A8300B99B32 /* libRCTText.a */ = {
1099 | isa = PBXReferenceProxy;
1100 | fileType = archive.ar;
1101 | path = libRCTText.a;
1102 | remoteRef = 832341B41AAA6A8300B99B32 /* PBXContainerItemProxy */;
1103 | sourceTree = BUILT_PRODUCTS_DIR;
1104 | };
1105 | ADBDB9271DFEBF0700ED6528 /* libRCTBlob.a */ = {
1106 | isa = PBXReferenceProxy;
1107 | fileType = archive.ar;
1108 | path = libRCTBlob.a;
1109 | remoteRef = ADBDB9261DFEBF0700ED6528 /* PBXContainerItemProxy */;
1110 | sourceTree = BUILT_PRODUCTS_DIR;
1111 | };
1112 | /* End PBXReferenceProxy section */
1113 |
1114 | /* Begin PBXResourcesBuildPhase section */
1115 | 00E356EC1AD99517003FC87E /* Resources */ = {
1116 | isa = PBXResourcesBuildPhase;
1117 | buildActionMask = 2147483647;
1118 | files = (
1119 | 057BEAF02167860400E1CC13 /* Info.plist in Resources */,
1120 | );
1121 | runOnlyForDeploymentPostprocessing = 0;
1122 | };
1123 | 13B07F8E1A680F5B00A75B9A /* Resources */ = {
1124 | isa = PBXResourcesBuildPhase;
1125 | buildActionMask = 2147483647;
1126 | files = (
1127 | 057BEAF82167899600E1CC13 /* Spectral-Bold.ttf in Resources */,
1128 | 05F8407E216A3BE700CF85DB /* Nunito-Italic.ttf in Resources */,
1129 | 057BEB072167D35800E1CC13 /* Spectral-SemiBold.ttf in Resources */,
1130 | 057BEB082167D35800E1CC13 /* Spectral-Medium.ttf in Resources */,
1131 | 057BEAF72167899600E1CC13 /* Spectral-Italic.ttf in Resources */,
1132 | 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */,
1133 | 05F8407F216A3BE700CF85DB /* Nunito-ExtraBold.ttf in Resources */,
1134 | 057BEB052167D35800E1CC13 /* Spectral-MediumItalic.ttf in Resources */,
1135 | 057BEAFE21679CA200E1CC13 /* CrimsonText-Bold.ttf in Resources */,
1136 | 05F8407D216A3BE700CF85DB /* Nunito-Bold.ttf in Resources */,
1137 | 05F8407B216A3BE700CF85DB /* Nunito-BoldItalic.ttf in Resources */,
1138 | 057BEAFF21679CA200E1CC13 /* CrimsonText-Regular.ttf in Resources */,
1139 | 057BEAF52167899600E1CC13 /* Spectral-BoldItalic.ttf in Resources */,
1140 | 05F84083216A3BE700CF85DB /* Nunito-LightItalic.ttf in Resources */,
1141 | 057BEAF62167899600E1CC13 /* Spectral-Regular.ttf in Resources */,
1142 | 05F84082216A3BE700CF85DB /* Nunito-Light.ttf in Resources */,
1143 | 05F84080216A3BE700CF85DB /* Nunito-SemiBoldItalic.ttf in Resources */,
1144 | 05F8407A216A3BE700CF85DB /* Nunito-Regular.ttf in Resources */,
1145 | 057BEB0021679CA200E1CC13 /* CrimsonText-BoldItalic.ttf in Resources */,
1146 | 057BEAFD21679CA200E1CC13 /* CrimsonText-Italic.ttf in Resources */,
1147 | 13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */,
1148 | 05F84081216A3BE700CF85DB /* Nunito-SemiBold.ttf in Resources */,
1149 | 057BEAEF216785EE00E1CC13 /* Info.plist in Resources */,
1150 | 057BEB062167D35800E1CC13 /* Spectral-SemiBoldItalic.ttf in Resources */,
1151 | 05F8407C216A3BE700CF85DB /* Nunito-ExtraBoldItalic.ttf in Resources */,
1152 | );
1153 | runOnlyForDeploymentPostprocessing = 0;
1154 | };
1155 | 2D02E4791E0B4A5D006451C7 /* Resources */ = {
1156 | isa = PBXResourcesBuildPhase;
1157 | buildActionMask = 2147483647;
1158 | files = (
1159 | 2D02E4BD1E0B4A84006451C7 /* Images.xcassets in Resources */,
1160 | );
1161 | runOnlyForDeploymentPostprocessing = 0;
1162 | };
1163 | 2D02E48E1E0B4A5D006451C7 /* Resources */ = {
1164 | isa = PBXResourcesBuildPhase;
1165 | buildActionMask = 2147483647;
1166 | files = (
1167 | );
1168 | runOnlyForDeploymentPostprocessing = 0;
1169 | };
1170 | /* End PBXResourcesBuildPhase section */
1171 |
1172 | /* Begin PBXShellScriptBuildPhase section */
1173 | 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */ = {
1174 | isa = PBXShellScriptBuildPhase;
1175 | buildActionMask = 2147483647;
1176 | files = (
1177 | );
1178 | inputPaths = (
1179 | );
1180 | name = "Bundle React Native code and images";
1181 | outputPaths = (
1182 | );
1183 | runOnlyForDeploymentPostprocessing = 0;
1184 | shellPath = /bin/sh;
1185 | shellScript = "export NODE_BINARY=node\n../node_modules/react-native/scripts/react-native-xcode.sh";
1186 | };
1187 | 2D02E4CB1E0B4B27006451C7 /* Bundle React Native Code And Images */ = {
1188 | isa = PBXShellScriptBuildPhase;
1189 | buildActionMask = 2147483647;
1190 | files = (
1191 | );
1192 | inputPaths = (
1193 | );
1194 | name = "Bundle React Native Code And Images";
1195 | outputPaths = (
1196 | );
1197 | runOnlyForDeploymentPostprocessing = 0;
1198 | shellPath = /bin/sh;
1199 | shellScript = "export NODE_BINARY=node\n../node_modules/react-native/scripts/react-native-xcode.sh";
1200 | };
1201 | /* End PBXShellScriptBuildPhase section */
1202 |
1203 | /* Begin PBXSourcesBuildPhase section */
1204 | 00E356EA1AD99517003FC87E /* Sources */ = {
1205 | isa = PBXSourcesBuildPhase;
1206 | buildActionMask = 2147483647;
1207 | files = (
1208 | 00E356F31AD99517003FC87E /* frontendTests.m in Sources */,
1209 | );
1210 | runOnlyForDeploymentPostprocessing = 0;
1211 | };
1212 | 13B07F871A680F5B00A75B9A /* Sources */ = {
1213 | isa = PBXSourcesBuildPhase;
1214 | buildActionMask = 2147483647;
1215 | files = (
1216 | 13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */,
1217 | 13B07FC11A68108700A75B9A /* main.m in Sources */,
1218 | );
1219 | runOnlyForDeploymentPostprocessing = 0;
1220 | };
1221 | 2D02E4771E0B4A5D006451C7 /* Sources */ = {
1222 | isa = PBXSourcesBuildPhase;
1223 | buildActionMask = 2147483647;
1224 | files = (
1225 | 2D02E4BF1E0B4AB3006451C7 /* main.m in Sources */,
1226 | 2D02E4BC1E0B4A80006451C7 /* AppDelegate.m in Sources */,
1227 | );
1228 | runOnlyForDeploymentPostprocessing = 0;
1229 | };
1230 | 2D02E48C1E0B4A5D006451C7 /* Sources */ = {
1231 | isa = PBXSourcesBuildPhase;
1232 | buildActionMask = 2147483647;
1233 | files = (
1234 | 2DCD954D1E0B4F2C00145EB5 /* frontendTests.m in Sources */,
1235 | );
1236 | runOnlyForDeploymentPostprocessing = 0;
1237 | };
1238 | /* End PBXSourcesBuildPhase section */
1239 |
1240 | /* Begin PBXTargetDependency section */
1241 | 00E356F51AD99517003FC87E /* PBXTargetDependency */ = {
1242 | isa = PBXTargetDependency;
1243 | target = 13B07F861A680F5B00A75B9A /* frontend */;
1244 | targetProxy = 00E356F41AD99517003FC87E /* PBXContainerItemProxy */;
1245 | };
1246 | 2D02E4921E0B4A5D006451C7 /* PBXTargetDependency */ = {
1247 | isa = PBXTargetDependency;
1248 | target = 2D02E47A1E0B4A5D006451C7 /* frontend-tvOS */;
1249 | targetProxy = 2D02E4911E0B4A5D006451C7 /* PBXContainerItemProxy */;
1250 | };
1251 | /* End PBXTargetDependency section */
1252 |
1253 | /* Begin PBXVariantGroup section */
1254 | 13B07FB11A68108700A75B9A /* LaunchScreen.xib */ = {
1255 | isa = PBXVariantGroup;
1256 | children = (
1257 | 13B07FB21A68108700A75B9A /* Base */,
1258 | );
1259 | name = LaunchScreen.xib;
1260 | path = frontend;
1261 | sourceTree = "";
1262 | };
1263 | /* End PBXVariantGroup section */
1264 |
1265 | /* Begin XCBuildConfiguration section */
1266 | 00E356F61AD99517003FC87E /* Debug */ = {
1267 | isa = XCBuildConfiguration;
1268 | buildSettings = {
1269 | BUNDLE_LOADER = "$(TEST_HOST)";
1270 | GCC_PREPROCESSOR_DEFINITIONS = (
1271 | "DEBUG=1",
1272 | "$(inherited)",
1273 | );
1274 | INFOPLIST_FILE = frontendTests/Info.plist;
1275 | IPHONEOS_DEPLOYMENT_TARGET = 9.0;
1276 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
1277 | OTHER_LDFLAGS = (
1278 | "-ObjC",
1279 | "-lc++",
1280 | );
1281 | PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)";
1282 | PRODUCT_NAME = "$(TARGET_NAME)";
1283 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/frontend.app/frontend";
1284 | };
1285 | name = Debug;
1286 | };
1287 | 00E356F71AD99517003FC87E /* Release */ = {
1288 | isa = XCBuildConfiguration;
1289 | buildSettings = {
1290 | BUNDLE_LOADER = "$(TEST_HOST)";
1291 | COPY_PHASE_STRIP = NO;
1292 | INFOPLIST_FILE = frontendTests/Info.plist;
1293 | IPHONEOS_DEPLOYMENT_TARGET = 9.0;
1294 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
1295 | OTHER_LDFLAGS = (
1296 | "-ObjC",
1297 | "-lc++",
1298 | );
1299 | PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)";
1300 | PRODUCT_NAME = "$(TARGET_NAME)";
1301 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/frontend.app/frontend";
1302 | };
1303 | name = Release;
1304 | };
1305 | 13B07F941A680F5B00A75B9A /* Debug */ = {
1306 | isa = XCBuildConfiguration;
1307 | buildSettings = {
1308 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
1309 | CURRENT_PROJECT_VERSION = 1;
1310 | DEAD_CODE_STRIPPING = NO;
1311 | INFOPLIST_FILE = frontend/Info.plist;
1312 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
1313 | OTHER_LDFLAGS = (
1314 | "$(inherited)",
1315 | "-ObjC",
1316 | "-lc++",
1317 | );
1318 | PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)";
1319 | PRODUCT_NAME = frontend;
1320 | VERSIONING_SYSTEM = "apple-generic";
1321 | };
1322 | name = Debug;
1323 | };
1324 | 13B07F951A680F5B00A75B9A /* Release */ = {
1325 | isa = XCBuildConfiguration;
1326 | buildSettings = {
1327 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
1328 | CURRENT_PROJECT_VERSION = 1;
1329 | INFOPLIST_FILE = frontend/Info.plist;
1330 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
1331 | OTHER_LDFLAGS = (
1332 | "$(inherited)",
1333 | "-ObjC",
1334 | "-lc++",
1335 | );
1336 | PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)";
1337 | PRODUCT_NAME = frontend;
1338 | VERSIONING_SYSTEM = "apple-generic";
1339 | };
1340 | name = Release;
1341 | };
1342 | 2D02E4971E0B4A5E006451C7 /* Debug */ = {
1343 | isa = XCBuildConfiguration;
1344 | buildSettings = {
1345 | ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image";
1346 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
1347 | CLANG_ANALYZER_NONNULL = YES;
1348 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
1349 | CLANG_WARN_INFINITE_RECURSION = YES;
1350 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
1351 | DEBUG_INFORMATION_FORMAT = dwarf;
1352 | ENABLE_TESTABILITY = YES;
1353 | GCC_NO_COMMON_BLOCKS = YES;
1354 | INFOPLIST_FILE = "frontend-tvOS/Info.plist";
1355 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
1356 | OTHER_LDFLAGS = (
1357 | "-ObjC",
1358 | "-lc++",
1359 | );
1360 | PRODUCT_BUNDLE_IDENTIFIER = "com.facebook.REACT.frontend-tvOS";
1361 | PRODUCT_NAME = "$(TARGET_NAME)";
1362 | SDKROOT = appletvos;
1363 | TARGETED_DEVICE_FAMILY = 3;
1364 | TVOS_DEPLOYMENT_TARGET = 9.2;
1365 | };
1366 | name = Debug;
1367 | };
1368 | 2D02E4981E0B4A5E006451C7 /* Release */ = {
1369 | isa = XCBuildConfiguration;
1370 | buildSettings = {
1371 | ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image";
1372 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
1373 | CLANG_ANALYZER_NONNULL = YES;
1374 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
1375 | CLANG_WARN_INFINITE_RECURSION = YES;
1376 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
1377 | COPY_PHASE_STRIP = NO;
1378 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
1379 | GCC_NO_COMMON_BLOCKS = YES;
1380 | INFOPLIST_FILE = "frontend-tvOS/Info.plist";
1381 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
1382 | OTHER_LDFLAGS = (
1383 | "-ObjC",
1384 | "-lc++",
1385 | );
1386 | PRODUCT_BUNDLE_IDENTIFIER = "com.facebook.REACT.frontend-tvOS";
1387 | PRODUCT_NAME = "$(TARGET_NAME)";
1388 | SDKROOT = appletvos;
1389 | TARGETED_DEVICE_FAMILY = 3;
1390 | TVOS_DEPLOYMENT_TARGET = 9.2;
1391 | };
1392 | name = Release;
1393 | };
1394 | 2D02E4991E0B4A5E006451C7 /* Debug */ = {
1395 | isa = XCBuildConfiguration;
1396 | buildSettings = {
1397 | BUNDLE_LOADER = "$(TEST_HOST)";
1398 | CLANG_ANALYZER_NONNULL = YES;
1399 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
1400 | CLANG_WARN_INFINITE_RECURSION = YES;
1401 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
1402 | DEBUG_INFORMATION_FORMAT = dwarf;
1403 | ENABLE_TESTABILITY = YES;
1404 | GCC_NO_COMMON_BLOCKS = YES;
1405 | INFOPLIST_FILE = "frontend-tvOSTests/Info.plist";
1406 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
1407 | OTHER_LDFLAGS = (
1408 | "-ObjC",
1409 | "-lc++",
1410 | );
1411 | PRODUCT_BUNDLE_IDENTIFIER = "com.facebook.REACT.frontend-tvOSTests";
1412 | PRODUCT_NAME = "$(TARGET_NAME)";
1413 | SDKROOT = appletvos;
1414 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/frontend-tvOS.app/frontend-tvOS";
1415 | TVOS_DEPLOYMENT_TARGET = 10.1;
1416 | };
1417 | name = Debug;
1418 | };
1419 | 2D02E49A1E0B4A5E006451C7 /* Release */ = {
1420 | isa = XCBuildConfiguration;
1421 | buildSettings = {
1422 | BUNDLE_LOADER = "$(TEST_HOST)";
1423 | CLANG_ANALYZER_NONNULL = YES;
1424 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
1425 | CLANG_WARN_INFINITE_RECURSION = YES;
1426 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
1427 | COPY_PHASE_STRIP = NO;
1428 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
1429 | GCC_NO_COMMON_BLOCKS = YES;
1430 | INFOPLIST_FILE = "frontend-tvOSTests/Info.plist";
1431 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
1432 | OTHER_LDFLAGS = (
1433 | "-ObjC",
1434 | "-lc++",
1435 | );
1436 | PRODUCT_BUNDLE_IDENTIFIER = "com.facebook.REACT.frontend-tvOSTests";
1437 | PRODUCT_NAME = "$(TARGET_NAME)";
1438 | SDKROOT = appletvos;
1439 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/frontend-tvOS.app/frontend-tvOS";
1440 | TVOS_DEPLOYMENT_TARGET = 10.1;
1441 | };
1442 | name = Release;
1443 | };
1444 | 83CBBA201A601CBA00E9B192 /* Debug */ = {
1445 | isa = XCBuildConfiguration;
1446 | buildSettings = {
1447 | ALWAYS_SEARCH_USER_PATHS = NO;
1448 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
1449 | CLANG_CXX_LIBRARY = "libc++";
1450 | CLANG_ENABLE_MODULES = YES;
1451 | CLANG_ENABLE_OBJC_ARC = YES;
1452 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
1453 | CLANG_WARN_BOOL_CONVERSION = YES;
1454 | CLANG_WARN_COMMA = YES;
1455 | CLANG_WARN_CONSTANT_CONVERSION = YES;
1456 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
1457 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
1458 | CLANG_WARN_EMPTY_BODY = YES;
1459 | CLANG_WARN_ENUM_CONVERSION = YES;
1460 | CLANG_WARN_INFINITE_RECURSION = YES;
1461 | CLANG_WARN_INT_CONVERSION = YES;
1462 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
1463 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
1464 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
1465 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
1466 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
1467 | CLANG_WARN_STRICT_PROTOTYPES = YES;
1468 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
1469 | CLANG_WARN_UNREACHABLE_CODE = YES;
1470 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
1471 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
1472 | COPY_PHASE_STRIP = NO;
1473 | ENABLE_STRICT_OBJC_MSGSEND = YES;
1474 | ENABLE_TESTABILITY = YES;
1475 | GCC_C_LANGUAGE_STANDARD = gnu99;
1476 | GCC_DYNAMIC_NO_PIC = NO;
1477 | GCC_NO_COMMON_BLOCKS = YES;
1478 | GCC_OPTIMIZATION_LEVEL = 0;
1479 | GCC_PREPROCESSOR_DEFINITIONS = (
1480 | "DEBUG=1",
1481 | "$(inherited)",
1482 | );
1483 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
1484 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
1485 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
1486 | GCC_WARN_UNDECLARED_SELECTOR = YES;
1487 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
1488 | GCC_WARN_UNUSED_FUNCTION = YES;
1489 | GCC_WARN_UNUSED_VARIABLE = YES;
1490 | IPHONEOS_DEPLOYMENT_TARGET = 9.0;
1491 | MTL_ENABLE_DEBUG_INFO = YES;
1492 | ONLY_ACTIVE_ARCH = YES;
1493 | SDKROOT = iphoneos;
1494 | };
1495 | name = Debug;
1496 | };
1497 | 83CBBA211A601CBA00E9B192 /* Release */ = {
1498 | isa = XCBuildConfiguration;
1499 | buildSettings = {
1500 | ALWAYS_SEARCH_USER_PATHS = NO;
1501 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
1502 | CLANG_CXX_LIBRARY = "libc++";
1503 | CLANG_ENABLE_MODULES = YES;
1504 | CLANG_ENABLE_OBJC_ARC = YES;
1505 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
1506 | CLANG_WARN_BOOL_CONVERSION = YES;
1507 | CLANG_WARN_COMMA = YES;
1508 | CLANG_WARN_CONSTANT_CONVERSION = YES;
1509 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
1510 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
1511 | CLANG_WARN_EMPTY_BODY = YES;
1512 | CLANG_WARN_ENUM_CONVERSION = YES;
1513 | CLANG_WARN_INFINITE_RECURSION = YES;
1514 | CLANG_WARN_INT_CONVERSION = YES;
1515 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
1516 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
1517 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
1518 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
1519 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
1520 | CLANG_WARN_STRICT_PROTOTYPES = YES;
1521 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
1522 | CLANG_WARN_UNREACHABLE_CODE = YES;
1523 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
1524 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
1525 | COPY_PHASE_STRIP = YES;
1526 | ENABLE_NS_ASSERTIONS = NO;
1527 | ENABLE_STRICT_OBJC_MSGSEND = YES;
1528 | GCC_C_LANGUAGE_STANDARD = gnu99;
1529 | GCC_NO_COMMON_BLOCKS = YES;
1530 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
1531 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
1532 | GCC_WARN_UNDECLARED_SELECTOR = YES;
1533 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
1534 | GCC_WARN_UNUSED_FUNCTION = YES;
1535 | GCC_WARN_UNUSED_VARIABLE = YES;
1536 | IPHONEOS_DEPLOYMENT_TARGET = 9.0;
1537 | MTL_ENABLE_DEBUG_INFO = NO;
1538 | SDKROOT = iphoneos;
1539 | VALIDATE_PRODUCT = YES;
1540 | };
1541 | name = Release;
1542 | };
1543 | /* End XCBuildConfiguration section */
1544 |
1545 | /* Begin XCConfigurationList section */
1546 | 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "frontendTests" */ = {
1547 | isa = XCConfigurationList;
1548 | buildConfigurations = (
1549 | 00E356F61AD99517003FC87E /* Debug */,
1550 | 00E356F71AD99517003FC87E /* Release */,
1551 | );
1552 | defaultConfigurationIsVisible = 0;
1553 | defaultConfigurationName = Release;
1554 | };
1555 | 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "frontend" */ = {
1556 | isa = XCConfigurationList;
1557 | buildConfigurations = (
1558 | 13B07F941A680F5B00A75B9A /* Debug */,
1559 | 13B07F951A680F5B00A75B9A /* Release */,
1560 | );
1561 | defaultConfigurationIsVisible = 0;
1562 | defaultConfigurationName = Release;
1563 | };
1564 | 2D02E4BA1E0B4A5E006451C7 /* Build configuration list for PBXNativeTarget "frontend-tvOS" */ = {
1565 | isa = XCConfigurationList;
1566 | buildConfigurations = (
1567 | 2D02E4971E0B4A5E006451C7 /* Debug */,
1568 | 2D02E4981E0B4A5E006451C7 /* Release */,
1569 | );
1570 | defaultConfigurationIsVisible = 0;
1571 | defaultConfigurationName = Release;
1572 | };
1573 | 2D02E4BB1E0B4A5E006451C7 /* Build configuration list for PBXNativeTarget "frontend-tvOSTests" */ = {
1574 | isa = XCConfigurationList;
1575 | buildConfigurations = (
1576 | 2D02E4991E0B4A5E006451C7 /* Debug */,
1577 | 2D02E49A1E0B4A5E006451C7 /* Release */,
1578 | );
1579 | defaultConfigurationIsVisible = 0;
1580 | defaultConfigurationName = Release;
1581 | };
1582 | 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "frontend" */ = {
1583 | isa = XCConfigurationList;
1584 | buildConfigurations = (
1585 | 83CBBA201A601CBA00E9B192 /* Debug */,
1586 | 83CBBA211A601CBA00E9B192 /* Release */,
1587 | );
1588 | defaultConfigurationIsVisible = 0;
1589 | defaultConfigurationName = Release;
1590 | };
1591 | /* End XCConfigurationList section */
1592 | };
1593 | rootObject = 83CBB9F71A601CBA00E9B192 /* Project object */;
1594 | }
1595 |
--------------------------------------------------------------------------------
/frontend/ios/frontend.xcodeproj/xcshareddata/xcschemes/frontend-tvOS.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 |
--------------------------------------------------------------------------------
/frontend/ios/frontend.xcodeproj/xcshareddata/xcschemes/frontend.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 |
--------------------------------------------------------------------------------
/frontend/ios/frontend/AppDelegate.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2015-present, Facebook, Inc.
3 | *
4 | * This source code is licensed under the MIT license found in the
5 | * LICENSE file in the root directory of this source tree.
6 | */
7 |
8 | #import
9 |
10 | @interface AppDelegate : UIResponder
11 |
12 | @property (nonatomic, strong) UIWindow *window;
13 |
14 | @end
15 |
--------------------------------------------------------------------------------
/frontend/ios/frontend/AppDelegate.m:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2015-present, Facebook, Inc.
3 | *
4 | * This source code is licensed under the MIT license found in the
5 | * LICENSE file in the root directory of this source tree.
6 | */
7 |
8 | #import "AppDelegate.h"
9 |
10 | #import
11 | #import
12 |
13 | @implementation AppDelegate
14 |
15 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
16 | {
17 | NSURL *jsCodeLocation;
18 |
19 | jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
20 |
21 | RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
22 | moduleName:@"frontend"
23 | initialProperties:nil
24 | launchOptions:launchOptions];
25 | rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1];
26 |
27 | self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
28 | UIViewController *rootViewController = [UIViewController new];
29 | rootViewController.view = rootView;
30 | self.window.rootViewController = rootViewController;
31 | [self.window makeKeyAndVisible];
32 | return YES;
33 | }
34 |
35 | @end
36 |
--------------------------------------------------------------------------------
/frontend/ios/frontend/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 |
--------------------------------------------------------------------------------
/frontend/ios/frontend/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | }
33 | ],
34 | "info" : {
35 | "version" : 1,
36 | "author" : "xcode"
37 | }
38 | }
--------------------------------------------------------------------------------
/frontend/ios/frontend/Images.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/frontend/ios/frontend/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | frontend
9 | CFBundleExecutable
10 | $(EXECUTABLE_NAME)
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | 1
25 | LSRequiresIPhoneOS
26 |
27 | NSLocationWhenInUseUsageDescription
28 |
29 | UILaunchStoryboardName
30 | LaunchScreen
31 | UIRequiredDeviceCapabilities
32 |
33 | armv7
34 |
35 | UISupportedInterfaceOrientations
36 |
37 | UIInterfaceOrientationPortrait
38 | UIInterfaceOrientationLandscapeLeft
39 | UIInterfaceOrientationLandscapeRight
40 |
41 | UIViewControllerBasedStatusBarAppearance
42 |
43 | UIAppFonts
44 |
45 | Spectral-BoldItalic.ttf
46 | Spectral-Bold.ttf
47 | Spectral-Italic.ttf
48 | Spectral-Regular.ttf
49 | CrimsonText-Bold.ttf
50 | CrimsonText-BoldItalic.ttf
51 | CrimsonText-Italic.ttf
52 | CrimsonText-Regular.ttf
53 | Spectral-Medium.ttf
54 | Spectral-MediumItalic.ttf
55 | Spectral-SemiBold.ttf
56 | Spectral-SemiBoldItalic.ttf
57 | Nunito-Bold.ttf
58 | Nunito-BoldItalic.ttf
59 | Nunito-ExtraBold.ttf
60 | Nunito-ExtraBoldItalic.ttf
61 | Nunito-Italic.ttf
62 | Nunito-Light.ttf
63 | Nunito-LightItalic.ttf
64 | Nunito-Regular.ttf
65 | Nunito-SemiBold.ttf
66 | Nunito-SemiBoldItalic.ttf
67 |
68 | NSAppTransportSecurity
69 |
70 | NSAllowsArbitraryLoads
71 |
72 | NSExceptionDomains
73 |
74 | localhost
75 |
76 | NSExceptionAllowsInsecureHTTPLoads
77 |
78 |
79 |
80 |
81 |
82 |
83 |
--------------------------------------------------------------------------------
/frontend/ios/frontend/main.m:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2015-present, Facebook, Inc.
3 | *
4 | * This source code is licensed under the MIT license found in the
5 | * LICENSE file in the root directory of this source tree.
6 | */
7 |
8 | #import
9 |
10 | #import "AppDelegate.h"
11 |
12 | int main(int argc, char * argv[]) {
13 | @autoreleasepool {
14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/frontend/ios/frontendTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/frontend/ios/frontendTests/frontendTests.m:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2015-present, Facebook, Inc.
3 | *
4 | * This source code is licensed under the MIT license found in the
5 | * LICENSE file in the root directory of this source tree.
6 | */
7 |
8 | #import
9 | #import
10 |
11 | #import
12 | #import
13 |
14 | #define TIMEOUT_SECONDS 600
15 | #define TEXT_TO_LOOK_FOR @"Welcome to React Native!"
16 |
17 | @interface frontendTests : XCTestCase
18 |
19 | @end
20 |
21 | @implementation frontendTests
22 |
23 | - (BOOL)findSubviewInView:(UIView *)view matching:(BOOL(^)(UIView *view))test
24 | {
25 | if (test(view)) {
26 | return YES;
27 | }
28 | for (UIView *subview in [view subviews]) {
29 | if ([self findSubviewInView:subview matching:test]) {
30 | return YES;
31 | }
32 | }
33 | return NO;
34 | }
35 |
36 | - (void)testRendersWelcomeScreen
37 | {
38 | UIViewController *vc = [[[RCTSharedApplication() delegate] window] rootViewController];
39 | NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS];
40 | BOOL foundElement = NO;
41 |
42 | __block NSString *redboxError = nil;
43 | RCTSetLogFunction(^(RCTLogLevel level, RCTLogSource source, NSString *fileName, NSNumber *lineNumber, NSString *message) {
44 | if (level >= RCTLogLevelError) {
45 | redboxError = message;
46 | }
47 | });
48 |
49 | while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) {
50 | [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
51 | [[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
52 |
53 | foundElement = [self findSubviewInView:vc.view matching:^BOOL(UIView *view) {
54 | if ([view.accessibilityLabel isEqualToString:TEXT_TO_LOOK_FOR]) {
55 | return YES;
56 | }
57 | return NO;
58 | }];
59 | }
60 |
61 | RCTSetLogFunction(RCTDefaultLogFunction);
62 |
63 | XCTAssertNil(redboxError, @"RedBox error: %@", redboxError);
64 | XCTAssertTrue(foundElement, @"Couldn't find element with text '%@' in %d seconds", TEXT_TO_LOOK_FOR, TIMEOUT_SECONDS);
65 | }
66 |
67 |
68 | @end
69 |
--------------------------------------------------------------------------------
/frontend/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | preset: "react-native",
3 | roots: ["/test"],
4 | transform: {
5 | "^.+\\.js$": "/node_modules/babel-jest",
6 | ".(ts|tsx)": "/node_modules/ts-jest/preprocessor.js"
7 | },
8 | testRegex: "(/__tests__/.*|(\\.|/)(test|spec))\\.tsx?$",
9 | moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json", "node"],
10 | cacheDirectory: ".jest/cache",
11 | clearMocks: true,
12 | watchman: true
13 | };
14 |
--------------------------------------------------------------------------------
/frontend/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "frontend",
3 | "version": "0.0.1",
4 | "private": true,
5 | "description": "Become a Foton developer",
6 | "license": "MIT",
7 | "author": {
8 | "name": "Raphael Thomazella",
9 | "email": "thomazella9@gmail.com",
10 | "url": "https://github.com/thomazella"
11 | },
12 | "scripts": {
13 | "start": "node node_modules/react-native/local-cli/cli.js start",
14 | "cli": "node node_modules/react-native/local-cli/cli.js",
15 | "test": "jest",
16 | "type-check": "tsc --noEmit",
17 | "lint": "eslint . --ext js,ts,tsx"
18 | },
19 | "dependencies": {
20 | "@babel/runtime": "^7.0.0",
21 | "apollo-cache-inmemory": "^1.2.10",
22 | "apollo-client": "^2.4.2",
23 | "apollo-link-context": "^1.0.9",
24 | "apollo-link-http": "^1.5.5",
25 | "babel-core": "7.0.0-bridge.0",
26 | "enzyme": "^3.4.4",
27 | "graphql": "^14.0.2",
28 | "graphql-tag": "^2.9.2",
29 | "react": "16.5.0",
30 | "react-apollo": "^2.2.2",
31 | "react-icons": "^3.0.5",
32 | "react-native": "0.57.1",
33 | "react-navigation": "^2.16.0",
34 | "react-powerplug": "^1.0.0-rc.1",
35 | "styled-components": "^3.4.9"
36 | },
37 | "devDependencies": {
38 | "@babel/cli": "^7.1.0",
39 | "@babel/core": "^7.1.0",
40 | "@babel/plugin-proposal-class-properties": "^7.0.0",
41 | "@babel/plugin-proposal-export-namespace-from": "^7.0.0",
42 | "@babel/plugin-proposal-json-strings": "^7.0.0",
43 | "@babel/plugin-proposal-throw-expressions": "^7.0.0",
44 | "@babel/plugin-syntax-dynamic-import": "^7.0.0",
45 | "@babel/plugin-syntax-import-meta": "^7.0.0",
46 | "@babel/plugin-transform-flow-strip-types": "^7.0.0",
47 | "@babel/plugin-transform-runtime": "^7.1.0",
48 | "@babel/preset-env": "^7.0.0",
49 | "@babel/preset-react": "^7.0.0",
50 | "@babel/preset-stage-2": "^7.0.0",
51 | "@babel/preset-typescript": "^7.1.0",
52 | "@types/graphql": "^14.0.1",
53 | "@types/jest": "^23.3.2",
54 | "@types/react": "^16.4.14",
55 | "@types/react-native": "^0.57.0",
56 | "@types/react-navigation": "^2.0.22",
57 | "@types/react-test-renderer": "^16.0.2",
58 | "@types/styled-components": "^3.0.1",
59 | "babel-eslint": "^9.0.0",
60 | "babel-jest": "^23.6.0",
61 | "eslint": "^5.6.0",
62 | "eslint-config-airbnb": "^16.1.0",
63 | "eslint-config-prettier": "^2.9.0",
64 | "eslint-import-resolver-typescript": "^1.0.2",
65 | "eslint-plugin-import": "^2.12.0",
66 | "eslint-plugin-jsx-a11y": "^6.0.3",
67 | "eslint-plugin-prettier": "^2.6.0",
68 | "eslint-plugin-react": "^7.9.1",
69 | "eslint-plugin-typescript": "^0.12.0",
70 | "jest": "23.6.0",
71 | "metro-react-native-babel-preset": "0.46.0",
72 | "prettier": "^1.14.3",
73 | "react-native-typescript-transformer": "^1.2.10",
74 | "react-test-renderer": "16.5.0",
75 | "ts-jest": "^23.10.2",
76 | "typescript": "~3.0.1",
77 | "typescript-eslint-parser": "^19.0.1",
78 | "typescript-styled-plugin": "^0.11.0"
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/frontend/post/one.md:
--------------------------------------------------------------------------------
1 | ## iOS emphasis
2 |
3 | We'll be focusing on getting the ins and outs of iOS apps because that's what we do better.
4 |
5 | ## Styling
6 |
7 | #### Styling
8 |
9 | React native supports styling natively through an export called `StyleSheet`
10 |
11 | ```jsx
12 | import { StyleSheet } from "react-native";
13 | ```
14 |
15 | It's used like this
16 |
17 | ```jsx
18 | const styles = StyleSheet({
19 | heading: {
20 | marginBottom: 15,
21 | color: "pink"
22 | },
23 | footer: {
24 | padding: 25
25 | }
26 | })
27 |
28 | // later on...
29 |
30 | React Native!
31 | ```
32 |
33 | - Rn uses style objects, like React prop styles.
34 | - The styles need to be wrapped in a property, like `heading` or `footer`, not doing so crashes.
35 | - Wrong css values crash the app, like `textAlign: "flex-start"`
36 |
37 | #### Styling is less developed in React native. :(
38 |
39 | Keep that in mind.
40 | Animations and transitions require a lot of manual work to get done.
41 | Some units like `vh` or `vw` don't work.
42 | Some RN exports, like `Button` on iOS, will not accept any styling.
43 |
44 | ### Styled components
45 |
46 | If you're already used to styled components this will make your RN experience a lot smoother.
47 | If you're not, no problem.
48 |
49 | ## The simulator
50 |
51 | The simulator is the development tool we use to simulate an iPhone.
52 |
53 | ### What you should know:
54 |
55 | - `cmd+d` will invoke a toolbox with several options
56 | - `cmd+r` will reload the Simulator (we do this *very* often)
57 |
58 | ### Enable `hot reloading.`
59 |
60 | Avoid `live reloading.`
61 | It's a poor man's hot reload.
62 | It'll reload the whole app and reset your route to the beginning of the stack, so you'll need to click the UI to get back to the screen you were.
63 |
64 | ### Enable `Debug JS remotely.`
65 |
66 | It'll launch a chrome tab.
67 | Right click it and choose `inspector`.
68 | When inspector is open, a `debugger;` statement in the source code will pause the runtime, but if the inspector is closed, it WILL NOT PAUSE.
69 |
70 | #### Inspector will close randomly, you'll need to re-open it.
71 | #### When inspector pauses, it'll grab your desktop focus, even if it is in another desktop.
72 |
73 | This can be a little annoying.
74 |
75 | #### Debugging causes Simulator to crash with the message `Runtime is not ready for debugging.`
76 |
77 | If you get that, it's most likely because you restarted Metro or something else.
78 | Restarting metro will throw this error all the time.
79 | If metro is running in a terminal tab, hit `cmd+r` in simulator and look at the metro tab.
80 | If you see loading activity, wait a bit.
81 | Then reload again.
82 | Also try closing chrome or temporarily disabling `debug JS remotely`, but it shouldn't be needed.
83 |
84 | ### Run Metro using `react-native start --reset-cache`
85 |
86 | This method is very safe, if you don't mind waiting a bit more (10 seconds).
87 | If you install npm packages or modify node_modules, it's likely you could crash the app with some random error.
88 | Also renaming files will crash the app and crash Metro.
89 | Keep calm and kill Metro with `ctrl+c`, then restart it again using the `--reset-cache` flag.
90 |
91 | ### Alias `react-native` to `rn`
92 |
93 | `alias rn='react-native'`
94 | This one is awesome.
95 | If you ever have problems, `alias` will dump all aliases currently active to stdin.
96 | `alias | grep foo` will search aliases for `'foo'` and print matches.
97 | `unalias rn` will undo the alias.
98 | Under bash the shell will read `~/.bash_profile` and `~/.bashrc` on every startup, so it's a good place to put aliases.
99 |
100 | ### Build on Xcode
101 |
102 | Xcode builds give you more control over errors.
103 | Avoid `react-native run-ios`.
104 | Nothing wrong with it though, it's just a recommendation.
105 | To build on Xcode, open the xcode project.
106 | Normally `open ios/${APPNAME}.xcodeproj` from the project root, where APPNAME is your app's name.
107 |
108 | ### Cocoa pods
109 |
110 | Try to avoid.
111 | But if you're using it anyway, DON'T open the `*.xcodeproj` file.
112 | It won't build no matter how much you beg it.
113 | Open the `*.xcworkspace` file.
114 |
115 | ### Xcode caches
116 |
117 | Soft clean: `cmd+k`
118 | Hard clean: `shift+cmd+k`
119 |
120 | This is often a good troubleshooting step.
121 | When facing a random error, clean it.
122 |
123 | ### Clicking the stack trace in simulator
124 |
125 | If you click the stack trace, one of the entries actually, it will jump your text editor to the file where the crash happened.
126 | Most of the time it helps to understand better what is going on.
127 |
--------------------------------------------------------------------------------
/frontend/rn-cli.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | getTransformModulePath() {
3 | return require.resolve("react-native-typescript-transformer");
4 | },
5 | getSourceExts() {
6 | return ["ts", "tsx"];
7 | }
8 | };
9 |
--------------------------------------------------------------------------------
/frontend/src/App.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "frontend",
3 | "displayName": "frontend"
4 | }
--------------------------------------------------------------------------------
/frontend/src/App.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 | import { createStackNavigator } from "react-navigation";
3 | import { ThemeProvider } from "styled-components";
4 | import { ApolloProvider } from "react-apollo";
5 | import { Create, Detail, Login, Register, List } from "./pages";
6 | import client from "./services/graphql";
7 | import theme from "./theme";
8 |
9 | const NavigationWrapper = createStackNavigator(
10 | {
11 | Create: { screen: Create },
12 | Detail: { screen: Detail },
13 | List: { screen: List },
14 | Login: { screen: Login },
15 | Register: { screen: Register }
16 | },
17 | { initialRouteName: "Login" }
18 | );
19 |
20 | const App = () => (
21 |
22 |
23 |
24 |
25 |
26 | );
27 |
28 | export default App;
29 |
--------------------------------------------------------------------------------
/frontend/src/components/BookFlatList.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 | import { FlatList, StyleSheet, FlatListProps } from "react-native";
3 | import styled from "styled-components/native";
4 | import { Touchable, Strong } from ".";
5 | import Sans from "./Sans";
6 |
7 | // development hack
8 | const random = () => Math.floor(Math.random() * 3)
9 | const color = ["complement", "primary", "secondary"]
10 | const randomColor = (props: any) => {
11 | const name = color[random()];
12 | const value = props.theme[name][random()]
13 | return value
14 | }
15 |
16 | const Book = styled(Touchable)`
17 | border-color: ${props => props.theme.gray[0]};
18 | border-radius: 10px;
19 | border-style: solid;
20 | align-items: flex-start;
21 | margin-bottom: 10px;
22 | box-shadow: 10px 3px 4px ${props => props.theme.gray[2]};
23 | background-color: ${props => randomColor(props)};
24 | `;
25 |
26 | const Author = styled(Sans)`
27 | color: ${props => props.theme.colors.white};
28 | font-style: italic;
29 | `;
30 |
31 | const BookTitle = styled(Strong)`
32 | color: ${props => props.theme.colors.white};
33 | font-weight: 700;
34 | font-size: 25px;
35 | text-transform: capitalize;
36 | margin-bottom: 13px;
37 | `;
38 |
39 | export type Author = {
40 | name: string;
41 | age: number;
42 | };
43 | export type Book = {
44 | id: number;
45 | author: Author;
46 | title: string;
47 | };
48 | export type Navigate = (...args: any[]) => void;
49 | export type BookFlatListProps = {
50 | user: string;
51 | navigate: Navigate;
52 | } & Partial>;
53 |
54 | class BookFlatList extends React.Component<
55 | BookFlatListProps
56 | > {
57 | bookStyle = StyleSheet.create({
58 | book: {
59 | marginTop: 20,
60 | flex: 1,
61 | padding: 20
62 | }
63 | });
64 |
65 | extractKey = (book: B) => String(book.id);
66 |
67 | renderItem = ({ item: book }: { item: B }) => {
68 | const { navigate, user } = this.props;
69 |
70 | return (
71 | navigate("Detail", { book, user })}>
72 | {`${book.title}`}
73 | {`${book.author && book.author.name}`}
74 |
75 | );
76 | };
77 |
78 | render() {
79 | return (
80 | // @ts-ignore
81 |
89 | );
90 | }
91 | }
92 |
93 | export default BookFlatList;
94 |
--------------------------------------------------------------------------------
/frontend/src/components/Button.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 | import styled from "styled-components/native";
3 | import { TouchableOpacity } from "react-native";
4 |
5 | const Touchable = (props: any) => {
6 | const { children, ...other } = props;
7 |
8 | return (
9 |
13 | {children}
14 |
15 | );
16 | };
17 |
18 | const Button = styled(Touchable)`
19 | background-color: ${props => props.theme.secondary[0]};
20 | border-radius: ${props => props.theme.border.radius};
21 | padding: 5px;
22 | align-items: center;
23 | font-size: 8px;
24 | min-width: 80px;
25 | min-height: 45px;
26 | margin: 8px;
27 | justify-content: center;
28 | `;
29 |
30 | export default Button;
31 |
--------------------------------------------------------------------------------
/frontend/src/components/ErrorText.ts:
--------------------------------------------------------------------------------
1 | import styled from "styled-components/native";
2 | import { Strong } from ".";
3 |
4 | const ErrorText = styled(Strong)`
5 | color: red;
6 | `;
7 |
8 | export default ErrorText;
9 |
--------------------------------------------------------------------------------
/frontend/src/components/Filter.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 | import { Value } from "react-powerplug";
3 | import styled from "styled-components/native";
4 | import TextInput from "./TextInput";
5 |
6 | const Input = styled(TextInput)`
7 | font-size: 17px;
8 | margin-bottom: 10px;
9 | text-align: left;
10 | width: 100%;
11 | `;
12 |
13 | const Filter = (props: any) => {
14 | const { onChangeText, ...others } = props;
15 |
16 | return (
17 |
18 | {({ value: text, set }) => (
19 | {
23 | set(input);
24 | return onChangeText(input);
25 | }}
26 | {...others}
27 | />
28 | )}
29 |
30 | );
31 | };
32 |
33 | export default Filter;
34 |
--------------------------------------------------------------------------------
/frontend/src/components/Heading.ts:
--------------------------------------------------------------------------------
1 | import styled from "styled-components/native";
2 | import { Strong } from ".";
3 |
4 | const Heading = styled(Strong)`
5 | font-size: 28;
6 | font-weight: 800;
7 | color: ${props => props.theme.colors.black};
8 | text-transform: capitalize;
9 | `;
10 |
11 | export default Heading;
12 |
--------------------------------------------------------------------------------
/frontend/src/components/Sans.tsx:
--------------------------------------------------------------------------------
1 | import styled from "styled-components/native";
2 |
3 | const Sans = styled.Text`
4 | font-family: "Nunito";
5 | font-size: 15;
6 | font-weight: 600;
7 | color: ${props => props.theme.colors.white};
8 | `;
9 |
10 | export default Sans;
11 |
--------------------------------------------------------------------------------
/frontend/src/components/Strong.ts:
--------------------------------------------------------------------------------
1 | import styled from "styled-components/native";
2 | import Sans from "./Sans";
3 |
4 | const Strong = styled(Sans)`
5 | font-weight: 700;
6 | font-size: 16;
7 | `;
8 |
9 | export default Strong;
10 |
--------------------------------------------------------------------------------
/frontend/src/components/Text.ts:
--------------------------------------------------------------------------------
1 | import styled from "styled-components/native";
2 |
3 | const Text = styled.Text`
4 | font-family: Spectral;
5 | font-size: 16;
6 | font-weight: 500;
7 | color: rgba(33, 0, 0, 1);
8 | `;
9 |
10 | export default Text;
11 |
--------------------------------------------------------------------------------
/frontend/src/components/TextInput.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 | import styled from "styled-components/native";
3 |
4 | const TextInput = styled.TextInput`
5 | font-family: "Nunito";
6 | font-weight: 400;
7 | font-size: 17;
8 | min-width: 120px;
9 | min-height: 30px;
10 | border-style: solid;
11 | padding: 7px;
12 | width: 180px;
13 | border-width: 2px;
14 | border-color: ${props => props.theme.gray[0]};
15 | border-radius: ${props => props.theme.border.radius};
16 | color: ${props => props.theme.colors.black};
17 | `;
18 |
19 | export default (props: any) => (
20 |
25 | );
26 |
--------------------------------------------------------------------------------
/frontend/src/components/Touchable.ts:
--------------------------------------------------------------------------------
1 | import styled from "styled-components/native";
2 |
3 | const Touchable = styled.TouchableOpacity`
4 | padding: 15px;
5 | align-items: center;
6 | font-size: 18px;
7 | width: 100%;
8 | `;
9 |
10 | export default Touchable;
11 |
--------------------------------------------------------------------------------
/frontend/src/components/Wrapper.ts:
--------------------------------------------------------------------------------
1 | import styled from "styled-components/native";
2 |
3 | const Wrapper = styled.View`
4 | flex: 1;
5 | justify-content: center;
6 | align-items: center;
7 | background-color: transparent;
8 | `;
9 |
10 | export default Wrapper;
11 |
--------------------------------------------------------------------------------
/frontend/src/components/dText.ts:
--------------------------------------------------------------------------------
1 | import styled from "styled-components/native";
2 |
3 | const Text = styled.Text`
4 | font-family: Spectral;
5 | font-size: 16;
6 | font-weight: 500;
7 | color: rgba(33, 0, 0, 1);
8 | `;
9 |
10 | export default Text;
11 |
--------------------------------------------------------------------------------
/frontend/src/components/index.ts:
--------------------------------------------------------------------------------
1 | export { default as Touchable } from "./Touchable";
2 | export * from "./Touchable";
3 |
4 | export { default as Wrapper } from "./Wrapper";
5 | export * from "./Wrapper";
6 |
7 | export { default as Button } from "./Button";
8 | export * from "./Button";
9 |
10 | export { default as Filter } from "./Filter";
11 | export * from "./Filter";
12 |
13 | export { default as Text } from "./Text";
14 | export * from "./Text";
15 |
16 | export { default as TextInput } from "./TextInput";
17 | export * from "./TextInput";
18 |
19 | export { default as Strong } from "./Strong";
20 | export * from "./Strong";
21 |
22 | export { default as ErrorText } from "./ErrorText";
23 | export * from "./ErrorText";
24 |
25 | export { default as BookFlatList } from "./BookFlatList";
26 | export * from "./BookFlatList";
27 |
28 | export { default as Heading } from "./Heading";
29 | export * from "./Heading";
30 |
31 | export { default as Sans } from "./Sans";
32 | export * from "./Sans";
33 |
--------------------------------------------------------------------------------
/frontend/src/layouts/DefaultLayout.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 | import styled from "styled-components/native";
3 | import { capitalize } from "../utils";
4 | import { Strong } from "../components";
5 |
6 | const OuterBackground = styled.ImageBackground`
7 | padding: 15px 15px 15px 15px;
8 | height: 100%;
9 | width: 100%;
10 | background-color: ${props => props.theme.colors.white};
11 | `;
12 |
13 | const InnerBackground = styled.View`
14 | flex: 1;
15 | justify-content: center;
16 | align-items: center;
17 | height: 100%;
18 | width: 100%;
19 | background-color: rgba(255,255,255,0.95);
20 | `;
21 |
22 | const Header = styled(Strong)`
23 | font-size: 16px;
24 | margin-bottom: 10px;
25 | text-align: left;
26 | width: 100%;
27 | color: white;
28 | `;
29 |
30 | const Layout = (props: any) => {
31 | const { children, user, ...otherProps } = props;
32 |
33 | return (
34 |
38 | {user && Welcome {capitalize(user)}!}
39 | {children}
40 |
41 | );
42 | };
43 |
44 | export default Layout;
45 |
--------------------------------------------------------------------------------
/frontend/src/layouts/index.ts:
--------------------------------------------------------------------------------
1 | export { default as Layout } from "./DefaultLayout";
2 | export * from "./DefaultLayout";
3 |
--------------------------------------------------------------------------------
/frontend/src/pages/Create.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 | import { View, ActivityIndicator } from "react-native";
3 | import styled from "styled-components/native";
4 | import gql from "graphql-tag";
5 | import { Mutation, MutationFn } from "react-apollo";
6 | import { log, getNavParams, formatMessage, NavigatableProps } from "../utils";
7 | import Layout from "../layouts/DefaultLayout";
8 | import {
9 | Button,
10 | Wrapper,
11 | Book,
12 | TextInput,
13 | Sans,
14 | ErrorText,
15 | Heading
16 | } from "../components";
17 |
18 | const Title = styled(Heading)`
19 | margin-bottom: 70;
20 | `;
21 |
22 | const Text = styled(Sans)`
23 | font-weight: 400;
24 | font-size: 16px;
25 | margin-bottom: 7px;
26 | `;
27 |
28 | const Field = styled.View``;
29 |
30 | const Feedback = styled.View`
31 | align-items: center;
32 | height: 30px;
33 | `;
34 |
35 | const Buttons = styled.View`
36 | margin-top: 70px;
37 | flex-direction: row;
38 | `;
39 |
40 | type addBookData = { data: Book };
41 |
42 | const mutationAddBook = gql`
43 | mutation($title: String!, $name: String!, $age: Int!) {
44 | addBook(title: $title, author: { name: $name, age: $age }) {
45 | title
46 | author {
47 | name
48 | age
49 | }
50 | }
51 | }
52 | `;
53 |
54 | type CreateState = Readonly<{
55 | name: string;
56 | age?: string;
57 | title: string;
58 | error?: Error;
59 | }>;
60 |
61 | class Create extends React.Component {
62 | initialState: Readonly = {
63 | name: "",
64 | title: "",
65 | age: undefined
66 | };
67 |
68 | state = this.initialState;
69 |
70 | resetState = () => this.setState({ ...this.initialState });
71 |
72 | validate = (input: string) => {
73 | const invalidNumber = Number.isNaN(Number(input));
74 | if (invalidNumber) return;
75 | return this.setState({ age: input });
76 | };
77 |
78 | handleAddBook = (doAddBook: MutationFn) => {
79 | const user = getNavParams(this.props, "user");
80 | const { age, name, title } = this.state;
81 | const { navigate } = this.props.navigation;
82 |
83 | if (!age || !name || !title) {
84 | console.log("not all book fields filled");
85 | return this.setState({
86 | error: Error("Null input: Please fill in all fields")
87 | });
88 | }
89 | doAddBook({
90 | variables: { name, title, age: Number(age) }
91 | })
92 | .then(() => navigate("List", { user }))
93 | .catch(e => log(e));
94 | };
95 |
96 | render() {
97 | const { navigate } = this.props.navigation;
98 | const user = getNavParams(this.props, "user");
99 |
100 | return (
101 |
102 |
103 | Create a book
104 |
105 | Enter book title
106 | this.setState({ title: input })}
110 | />
111 |
112 |
113 | Enter author name
114 | this.setState({ name: input })}
118 | />
119 |
120 |
121 | How old is the author?
122 | this.validate(text)}
126 | />
127 |
128 |
129 | {(addBook, { data, loading }) => (
130 |
131 |
132 | {!data &&
133 | this.state.error && (
134 |
135 | {formatMessage(this.state.error.message)}
136 |
137 | )}
138 | {loading && }
139 |
140 |
141 |
144 |
147 |
150 |
151 |
152 | )}
153 |
154 |
155 |
156 | );
157 | }
158 | }
159 |
160 | export default Create;
161 |
--------------------------------------------------------------------------------
/frontend/src/pages/Detail.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 | import styled from "styled-components/native";
3 | import Layout from "../layouts/DefaultLayout";
4 | import { getNavParams } from "../utils";
5 | import { Button, Sans, Heading } from "../components";
6 |
7 | const Title = styled(Heading)`
8 | font-size: 35px;
9 | margin-bottom: 40px;
10 | text-align: center;
11 | text-transform: capitalize;
12 | `;
13 |
14 | const Cover = styled.Image`
15 | width: 220px;
16 | height: 220px;
17 | border-radius: 10px;
18 | margin: 25px;
19 | margin-bottom: 40px;
20 | border-color: ${props => props.theme.colors.black};
21 | border-style: solid;
22 | `;
23 |
24 | const Wrapper = styled.View`
25 | flex: 1;
26 | justify-content: flex-start;
27 | align-items: center;
28 | padding: 25px;
29 | `;
30 |
31 | const Description = styled(Sans)`
32 | color: ${props => props.theme.colors.black};
33 | font-size: 17px;
34 | margin-top: 25px;
35 | margin-bottom: 25px;
36 | text-align: left;
37 | `;
38 |
39 | const Detail = (props: any) => {
40 | const { navigate } = props.navigation;
41 | const params = getNavParams(props);
42 | if (!params) {
43 | return null;
44 | }
45 | const { user, book } = params;
46 |
47 | return (
48 |
49 |
50 | {book.title}
51 |
56 |
57 | By {book.author.name}, {book.author.age} years old.
58 |
59 |
62 |
63 |
64 | );
65 | };
66 |
67 | export default Detail;
68 |
--------------------------------------------------------------------------------
/frontend/src/pages/List.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 | import { ActivityIndicator } from "react-native";
3 | import gql from "graphql-tag";
4 | import styled from "styled-components/native";
5 | import { ApolloConsumer } from "react-apollo";
6 | import { ApolloQueryResult, ApolloClient } from "apollo-client";
7 | import {
8 | getNumericId,
9 | getNavParams,
10 | lowerCase,
11 | NavigatableProps
12 | } from "../utils";
13 | import { Layout } from "../layouts";
14 | import { BookFlatList, Book, Filter } from "../components";
15 |
16 | const Wrapper = styled.View`
17 | margin-top: 20px;
18 | flex: 1;
19 | width: 100%;
20 | `;
21 |
22 | const View = styled.View`
23 | flex: 1;
24 | `;
25 |
26 | const FilterView = styled.View`
27 | margin: 10px 15px 0px 15px;
28 | `;
29 |
30 | const query = gql`
31 | query($skip: Int, $limit: Int) {
32 | books(skip: $skip, limit: $limit) {
33 | title
34 | author {
35 | name
36 | age
37 | }
38 | }
39 | }
40 | `;
41 |
42 | type ListData = { books: Book[] };
43 | type ListState = {
44 | books: any[];
45 | filtered: any[];
46 | fetchedAll: boolean;
47 | };
48 |
49 | class List extends React.Component {
50 | state: Readonly = {
51 | filtered: [],
52 | books: [],
53 | fetchedAll: false
54 | };
55 |
56 | showAll = () => this.setState(({ books }) => ({ filtered: books }));
57 |
58 | filterByTitle = (sections: any[], query: string) =>
59 | sections.filter(section => {
60 | const title = lowerCase(section.title);
61 | return title.includes(query);
62 | });
63 |
64 | filterBooks = (text: string) => {
65 | if (!text) {
66 | return this.showAll();
67 | }
68 | return this.setState(({ books }) => ({
69 | filtered: this.filterByTitle(books, lowerCase(text))
70 | }));
71 | };
72 |
73 | unpack = (ApolloRes: ApolloQueryResult) => {
74 | const { books } = ApolloRes.data;
75 | const booksWithId = books.map(book => ({
76 | ...book,
77 | id: getNumericId()
78 | }));
79 | return booksWithId;
80 | };
81 |
82 | fetch = (client: ApolloClient) =>
83 | client
84 | .query({ query })
85 | .then(packedData => {
86 | const data = this.unpack(packedData);
87 | console.log("Books", data);
88 | return this.setState({
89 | books: data,
90 | filtered: data
91 | });
92 | })
93 | .catch(e => {
94 | e && console.log(e);
95 | });
96 |
97 | fetchMore = (
98 | { distanceFromEnd }: { distanceFromEnd: number },
99 | client: ApolloClient
100 | ) => {
101 | console.log("fetchmore", distanceFromEnd)
102 | const { filtered, books, fetchedAll } = this.state;
103 | const skip = books.length;
104 | if (
105 | Math.floor(distanceFromEnd) <= 0 || // pagination event is positive
106 | fetchedAll ||
107 | String(filtered) !== String(books) // filtering blocks pagination
108 | ) {
109 | return;
110 | }
111 | return client
112 | .query({
113 | query,
114 | variables: { skip },
115 | fetchPolicy: "network-only"
116 | })
117 | .then(packedData => {
118 | const newBooks = this.unpack(packedData);
119 | console.log("newBooks", newBooks);
120 | if (!newBooks.length) {
121 | return this.setState({ fetchedAll: true });
122 | }
123 | return this.setState(state => ({
124 | books: [...state.books, ...newBooks],
125 | filtered: [...state.books, ...newBooks]
126 | }));
127 | })
128 | .catch(e => {
129 | e && console.log(e);
130 | });
131 | };
132 |
133 | render() {
134 | const user = getNavParams(this.props, "user");
135 | const { navigate } = this.props.navigation;
136 | const { books, filtered } = this.state;
137 | return (
138 |
139 |
140 |
141 | {client => {
142 | if (!books.length) {
143 | this.fetch(client);
144 | return ;
145 | }
146 | return (
147 |
148 |
149 |
150 |
151 |
152 | data={filtered}
153 | navigate={navigate}
154 | user={user}
155 | onEndReached={e => this.fetchMore(e, client)}
156 | />
157 |
158 | );
159 | }}
160 |
161 |
162 |
163 | );
164 | }
165 | }
166 |
167 | export default List;
168 |
--------------------------------------------------------------------------------
/frontend/src/pages/Login.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 | import { AsyncStorage, ActivityIndicator, View } from "react-native";
3 | import styled from "styled-components/native";
4 | import gql from "graphql-tag";
5 | import { Mutation, MutationFn } from "react-apollo";
6 | import { log, NavigatableProps } from "../utils";
7 | import Layout from "../layouts/DefaultLayout";
8 | import {
9 | Button,
10 | Wrapper,
11 | TextInput,
12 | Sans,
13 | ErrorText,
14 | Heading
15 | } from "../components";
16 |
17 | export const LoginContainer = styled.View`
18 | justify-content: center;
19 | align-items: center;
20 | `;
21 |
22 | export const InputContainer = styled.View`
23 | justify-content: space-between;
24 | align-items: center;
25 | height: 65%;
26 | `;
27 |
28 | export const Feedback = styled.View`
29 | height: 30px;
30 | `;
31 |
32 | export const Buttons = styled.View`
33 | margin-top: 30px;
34 | flex-direction: row;
35 | justify-content: space-evenly;
36 | width: 70%;
37 | `;
38 |
39 | export const Title = styled(Heading)`
40 | margin-top: 60px;
41 | margin-bottom: 20px;
42 | `;
43 |
44 | export const Input = styled(TextInput)`
45 | font-size: 17px;
46 | margin-bottom: 25px;
47 | text-align: left;
48 | `;
49 |
50 | type loginData = { data: { addUser: { token: string } } };
51 |
52 | const loginMutation = gql`
53 | mutation($name: String!, $password: String!, $noAuth: Boolean) {
54 | login(name: $name, password: $password, noAuth: $noAuth) {
55 | token
56 | }
57 | }
58 | `;
59 |
60 | type LoginState = {
61 | name: string;
62 | password: string;
63 | token?: string;
64 | error?: Error;
65 | };
66 |
67 | class Login extends React.Component {
68 | state: Readonly = {
69 | name: "",
70 | password: ""
71 | };
72 |
73 | handleLogin = (doLogin: MutationFn) => {
74 | const { navigate } = this.props.navigation;
75 | const { name, password } = this.state;
76 |
77 | if (!name || !password) {
78 | console.log("no user or password");
79 | return this.setState({
80 | error: Error("Please fill in all fields")
81 | });
82 | }
83 |
84 | return this.setState({ token: undefined }, () => {
85 | doLogin({
86 | variables: { name, password, noAuth: true }
87 | })
88 | // @ts-ignore
89 | .then(({ data, errors }) => {
90 | if (errors) {
91 | const [error] = errors;
92 | return this.setState({ error });
93 | }
94 | return AsyncStorage.setItem("token", data.login.token).then(() =>
95 | navigate("Create", { user: this.state.name })
96 | );
97 | })
98 | .catch((error: Error) => {
99 | console.log(error);
100 | this.setState({ error });
101 | });
102 | });
103 | };
104 |
105 | render() {
106 | const { navigate } = this.props.navigation;
107 | console.log(this.props);
108 |
109 | return (
110 |
111 |
112 | Welcome back
113 |
114 | {(login, { data, loading }) => {
115 | if (data) log("data", data);
116 | return (
117 |
118 |
119 |
120 | this.setState({ name })}
124 | />
125 |
130 | this.setState({ password })
131 | }
132 | />
133 |
134 |
135 | {!data &&
136 | this.state.error && (
137 |
138 | {this.state.error.message}
139 |
140 | )}
141 | {loading && }
142 |
143 |
144 |
147 |
150 |
151 |
152 |
153 | );
154 | }}
155 |
156 |
157 |
158 | );
159 | }
160 | }
161 |
162 | export default Login;
163 |
--------------------------------------------------------------------------------
/frontend/src/pages/Register.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 | import { AsyncStorage, ActivityIndicator } from "react-native";
3 | import gql from "graphql-tag";
4 | import styled from "styled-components/native";
5 | import { Mutation, MutationFn } from "react-apollo";
6 | import Layout from "../layouts/DefaultLayout";
7 | import { formatMessage, getNavParams, NavigatableProps } from "../utils";
8 | import { Wrapper, Button, Sans, ErrorText } from "../components";
9 | import { LoginContainer, Title, Input, Buttons } from "./Login";
10 |
11 | const Feedback = styled.View`
12 | height: 30;
13 | align-items: center;
14 | `;
15 |
16 | const Inputs = styled.View`
17 | align-items: center;
18 | `;
19 |
20 | const InputContainer = styled.View`
21 | flex: 1;
22 | justify-content: space-evenly;
23 | max-height: 70%;
24 | `;
25 |
26 | type addUserData = { data: { addUser: { token: string } } };
27 |
28 | const mutationAddUser = gql`
29 | mutation($name: String!, $password: String!, $noAuth: Boolean) {
30 | addUser(name: $name, password: $password, noAuth: $noAuth) {
31 | token
32 | }
33 | }
34 | `;
35 |
36 | type RegisterState = {
37 | name: string;
38 | password: string;
39 | error?: Error;
40 | };
41 |
42 | class Register extends React.Component {
43 | state: Readonly = {
44 | name: "",
45 | password: ""
46 | };
47 |
48 | handleRegister = (addUser: MutationFn) => {
49 | const { navigate } = this.props.navigation;
50 | const { name, password } = this.state;
51 |
52 | if (!name || !password) {
53 | console.log("no user or password");
54 | return this.setState({
55 | error: Error("Null input: Please fill in all fields")
56 | });
57 | }
58 |
59 | addUser({
60 | variables: {
61 | name: this.state.name,
62 | password: this.state.password,
63 | noAuth: true
64 | }
65 | })
66 | // @ts-ignore
67 | .then(({ data, errors }) => {
68 | console.log("data and errors ->,", data, errors);
69 | if (errors) {
70 | const [error] = errors;
71 | return this.setState({ error });
72 | }
73 | navigate("Create", { user: this.state.name });
74 | return AsyncStorage.setItem("token", data.addUser.token);
75 | })
76 | .catch(error => this.setState({ error }));
77 | };
78 |
79 | render() {
80 | const user = getNavParams(this.props, "user");
81 |
82 | return (
83 |
84 |
85 | Welcome to the club
86 |
87 | {(addUser, { data, loading }) => (
88 |
89 |
90 |
91 | this.setState({ name })}
95 | />
96 |
101 | this.setState({ password })
102 | }
103 | />
104 |
105 |
106 | {!data &&
107 | this.state.error && (
108 |
109 | {formatMessage(this.state.error.message)}
110 |
111 | )}
112 | {loading && }
113 |
114 |
115 |
118 |
119 |
120 |
121 | )}
122 |
123 |
124 |
125 | );
126 | }
127 | }
128 |
129 | export default Register;
130 |
--------------------------------------------------------------------------------
/frontend/src/pages/index.ts:
--------------------------------------------------------------------------------
1 | export { default as Create } from "./Create";
2 | export { default as Detail } from "./Detail";
3 | export { default as Login } from "./Login";
4 | export { default as Register } from "./Register";
5 | export { default as List } from "./List";
6 |
--------------------------------------------------------------------------------
/frontend/src/services/graphql.ts:
--------------------------------------------------------------------------------
1 | import { ApolloClient } from "apollo-client";
2 | import { HttpLink } from "apollo-link-http";
3 | import { setContext } from "apollo-link-context";
4 | import { InMemoryCache } from "apollo-cache-inmemory";
5 | import { AsyncStorage } from "react-native";
6 |
7 | const addressMap = {
8 | production: "https://nicelooking.client.domain.com",
9 | development: "http://localhost:4000/graphql"
10 | };
11 | const uri = addressMap.development;
12 | const connectToDevTools = true;
13 | const dataIdFromObject = (object: any) => object.key
14 | const cache = new InMemoryCache({ dataIdFromObject });
15 |
16 | const authLink = setContext(async (_, { headers }) => {
17 | let token;
18 | try {
19 | token = await AsyncStorage.getItem("token");
20 | } catch (e) {
21 | console.log("client setup token error:", e);
22 | }
23 | return { headers: { ...headers, token } };
24 | });
25 |
26 | const defaultOptions = {
27 | watchQuery: {
28 | fetchPolicy: "cache-and-network",
29 | errorPolicy: "ignore"
30 | },
31 | query: {
32 | fetchPolicy: "cache-first",
33 | errorPolicy: "all"
34 | },
35 | mutate: {
36 | errorPolicy: "all"
37 | }
38 | };
39 |
40 | const link = authLink.concat(new HttpLink({ uri }));
41 | //@ts-ignore
42 | const client = new ApolloClient({
43 | cache,
44 | link,
45 | connectToDevTools,
46 | defaultOptions
47 | });
48 |
49 | export default client;
50 |
--------------------------------------------------------------------------------
/frontend/src/theme.ts:
--------------------------------------------------------------------------------
1 | const theme = {
2 | colors: {
3 | white: "white",
4 | black: "black"
5 | },
6 | border: {
7 | radius: 22
8 | },
9 | gray: ["rgba(245,245,245,1)", "rgba(230,230,230,1)", "rgba(200,200,200,1)"],
10 | primary: [
11 | "rgba( 7,103,160,1)",
12 | "rgba( 70,159,212,1)",
13 | "rgba( 59,128,169,1)",
14 | "rgba( 40, 85,111,1)",
15 | "rgba( 22, 55, 75,1)",
16 | ],
17 | secondary: [
18 | "rgba(228, 80,144,1)",
19 | "rgba(144, 48, 90,1)",
20 | "rgba(190, 64,119,1)",
21 | "rgba( 99, 32, 61,1)",
22 | "rgba( 55, 17, 33,1)"
23 | ],
24 | tertiary: [
25 | "rgba(170,162, 57,1)",
26 | "rgba(255,244, 89,1)",
27 | "rgba(224,214, 76,1)",
28 | "rgba(117,112, 38,1)",
29 | "rgba( 64, 61, 20,1)"
30 | ],
31 | complement: [
32 | "rgba(251,138, 0,1)",
33 | "rgba(255,173, 73,1)",
34 | "rgba(255,176, 79,1)",
35 | "rgba(174,121, 56,1)",
36 | "rgba(118, 78, 30,1)",
37 | ]
38 | };
39 |
40 | export default theme;
41 |
--------------------------------------------------------------------------------
/frontend/src/utils.ts:
--------------------------------------------------------------------------------
1 | export const log = (...x: any[]) => console.log(...x);
2 |
3 | let id = -1;
4 | /**
5 | * Produces unique number each call, starting from 0. E.g. 2.
6 | * @param prefix Lodash-like prefix for the id. E.g. "art".
7 | * @returns Number "2" or String "art2".
8 | */
9 | export const getNumericId = (prefix?: string) => {
10 | id += 1;
11 | return prefix ? `${prefix}${id}` : id;
12 | };
13 |
14 | /**
15 | * Discards the first two words of an error message.
16 | * @param message Error.message
17 | * @returns sliced message.
18 | */
19 | export const formatMessage = (message: string) =>
20 | message
21 | .split(" ")
22 | .slice(2)
23 | .join(" ");
24 |
25 | /**
26 | * Safely get params from navigation.state
27 | * @param props Component props.
28 | * @param key Property to access in navigation state
29 | */
30 | export const getNavParams = (props: any, key?: string) => {
31 | const params =
32 | props &&
33 | props.navigation &&
34 | props.navigation.state &&
35 | props.navigation.state.params;
36 |
37 | if (params == undefined) return undefined;
38 | if (!key) return params;
39 |
40 | const result = params[key];
41 | if (result == undefined) return undefined;
42 | return result.length ? result : undefined;
43 | };
44 |
45 | export const capitalize = (x: string) => x[0].toUpperCase() + x.slice(1);
46 |
47 | export const lowerCase = (input: string) =>
48 | String.prototype.toLowerCase.call(input);
49 |
50 | export type NavigatableProps = { navigation: any };
51 |
--------------------------------------------------------------------------------
/frontend/test/test.test.ts:
--------------------------------------------------------------------------------
1 | test("test", () => {
2 | expect(2).toBe(2);
3 | })
4 |
--------------------------------------------------------------------------------
/frontend/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | /* Basic Options */
4 | "target": "esnext" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */,
5 | "module": "esnext" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */,
6 | // "lib": [], /* Specify library files to be included in the compilation. */
7 | // "allowJs": true, /* Allow javascript files to be compiled. */
8 | // "checkJs": true, /* Report errors in .js files. */
9 | "jsx": "react" /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */,
10 | "declaration": true, /* Generates corresponding '.d.ts' file. */
11 | // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
12 | // "sourceMap": true, /* Generates corresponding '.map' file. */
13 | // "outFile": "./", /* Concatenate and emit output to single file. */
14 | // "outDir": "./", /* Redirect output structure to the directory. */
15 | // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
16 | // "composite": true, /* Enable project compilation */
17 | // "removeComments": true, /* Do not emit comments to output. */
18 | // "noEmit": true, /* Do not emit outputs. */
19 | // "importHelpers": true, /* Import emit helpers from 'tslib'. */
20 | // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
21 | // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
22 |
23 | /* Strict Type-Checking Options */
24 | "strict": true /* Enable all strict type-checking options. */,
25 | // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
26 | // "strictNullChecks": true, /* Enable strict null checks. */
27 | // "strictFunctionTypes": true, /* Enable strict checking of function types. */
28 | // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
29 | // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
30 | // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
31 |
32 | /* Additional Checks */
33 | "noUnusedLocals": true, /* Report errors on unused locals. */
34 | "noUnusedParameters": true, /* Report errors on unused parameters. */
35 | "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
36 | "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
37 |
38 | /* Module Resolution Options */
39 | "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
40 | // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
41 | // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
42 | // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
43 | // "typeRoots": [], /* List of folders to include type definitions from. */
44 | // "types": [], /* Type declaration files to be included in compilation. */
45 | "allowSyntheticDefaultImports": true /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */,
46 | "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */,
47 | // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
48 |
49 | /* Source Map Options */
50 | // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
51 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
52 | // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
53 | // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
54 |
55 | /* Experimental Options */
56 | // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
57 | // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
58 | "stripInternal": true,
59 | "plugins": [
60 | {
61 | "name": "typescript-styled-plugin"
62 | }
63 | ]
64 | },
65 | "include": [
66 | "src"
67 | ]
68 | }
69 |
--------------------------------------------------------------------------------
/server/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["env"],
3 | "plugins": [["transform-object-rest-spread"], ["transform-runtime"]]
4 | }
5 |
--------------------------------------------------------------------------------
/server/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig helps developers define and maintain consistent
2 | # coding styles between different editors and IDEs
3 | # editorconfig.org
4 |
5 | root = true
6 |
7 | [*]
8 |
9 | # Change these settings to your own preference
10 | indent_style = space
11 | indent_size = 2
12 |
13 | # We recommend you to keep these unchanged
14 | end_of_line = lf
15 | charset = utf-8
16 | trim_trailing_whitespace = true
17 | insert_final_newline = true
18 |
19 | [*.md]
20 | trim_trailing_whitespace = false
--------------------------------------------------------------------------------
/server/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "es6": true,
4 | "jest": true
5 | },
6 | "extends": [
7 | "eslint:recommended",
8 | "prettier",
9 | "airbnb",
10 | "plugin:prettier/recommended"
11 | ],
12 | "parserOptions": {
13 | "sourceType": "module"
14 | },
15 | "rules": {
16 | "linebreak-style": ["error", "unix"],
17 | "react/jsx-filename-extension": "off",
18 | "no-underscore-dangle": "off",
19 | "arrow-body-style": "off"
20 | },
21 | "parser": "babel-eslint"
22 | }
23 |
--------------------------------------------------------------------------------
/server/index.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-console */
2 | import express from "express";
3 | import { ApolloServer } from "apollo-server-express";
4 | import { validateToken } from "./src/modules/user/UserLoader";
5 | import "./src/services/database";
6 |
7 | import * as BookType from "./src/modules/book/BookType";
8 | import * as AuthorType from "./src/modules/author/AuthorType";
9 | import * as UserType from "./src/modules/user/UserType";
10 | import * as DateType from "./src/modules/date/DateType";
11 |
12 | const SchemaDefinition = `
13 | schema {
14 | query: Query
15 | mutation: Mutation
16 | }
17 | type Query {
18 | books(skip: Int, limit: Int): [Book]
19 | dev_books(skip: Int, limit: Int): [Book]
20 | dev_users: [User]
21 | }
22 | type Mutation {
23 | login(name: String, password: String, noAuth: Boolean): Token!
24 | addBook(title: String, author: AuthorInput): Book
25 | addUser(name: String, password: String, noAuth: Boolean): Token!
26 | dev_addBook(title: String, author: AuthorInput): Book
27 | }
28 | `;
29 |
30 | const typeDefs = [
31 | BookType.typeDefs,
32 | AuthorType.typeDefs,
33 | UserType.typeDefs,
34 | DateType.typeDefs
35 | ];
36 |
37 | const resolvers = {
38 | Query: {
39 | ...BookType.resolvers,
40 | ...UserType.resolvers
41 | },
42 | Mutation: {
43 | ...BookType.mutations,
44 | ...UserType.mutations
45 | },
46 | ...DateType.resolvers
47 | };
48 |
49 | const server = new ApolloServer({
50 | typeDefs: [SchemaDefinition, ...typeDefs],
51 | resolvers,
52 | context: validateToken
53 | });
54 |
55 | const app = express();
56 | server.applyMiddleware({ app });
57 |
58 | app.listen({ port: 4000 }, () =>
59 | console.log(`🚀 Server ready at http://localhost:4000${server.graphqlPath}`)
60 | );
61 |
--------------------------------------------------------------------------------
/server/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "scripts": {
3 | "start": "babel-watch index.js",
4 | "lint": "eslint src"
5 | },
6 | "license": "MIT",
7 | "dependencies": {
8 | "apollo-server": "^2.1.0",
9 | "apollo-server-express": "^2.1.0",
10 | "babel-cli": "^6.26.0",
11 | "babel-preset-env": "^1.7.0",
12 | "bcrypt": "^3.0.1",
13 | "express": "^4.16.3",
14 | "graphql": "^14.0.2",
15 | "graphql-tools": "^4.0.0",
16 | "jsonwebtoken": "^8.3.0",
17 | "mongoose": "^5.3.1"
18 | },
19 | "devDependencies": {
20 | "babel-eslint": "^9.0.0",
21 | "babel-plugin-transform-object-rest-spread": "^6.26.0",
22 | "babel-plugin-transform-runtime": "^6.23.0",
23 | "babel-watch": "^2.0.7",
24 | "eslint": "^5.6.0",
25 | "eslint-config-airbnb": "^16.1.0",
26 | "eslint-config-prettier": "^2.9.0",
27 | "eslint-import-resolver-typescript": "^1.0.2",
28 | "eslint-plugin-import": "^2.12.0",
29 | "eslint-plugin-jsx-a11y": "^6.0.3",
30 | "eslint-plugin-prettier": "^2.6.0",
31 | "eslint-plugin-react": "^7.9.1",
32 | "eslint-plugin-typescript": "^0.12.0",
33 | "prettier": "^1.14.3"
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/server/src/modules/author/AuthorLoader.js:
--------------------------------------------------------------------------------
1 | import mongoose from "mongoose";
2 | import AuthorModel from "./AuthorModel";
3 |
4 | const { ObjectId } = mongoose.Types;
5 |
6 | const addAuthor = ({ name, age }) => {
7 | const _id = new ObjectId();
8 | const author = new AuthorModel({ name, age, _id });
9 | return author.save();
10 | };
11 |
12 | export default addAuthor;
13 |
--------------------------------------------------------------------------------
/server/src/modules/author/AuthorModel.js:
--------------------------------------------------------------------------------
1 | import mongoose, { Schema } from "mongoose";
2 |
3 | const authorSchema = new Schema({
4 | _id: Schema.Types.ObjectId,
5 | name: String,
6 | age: Number
7 | });
8 |
9 | export default mongoose.model("Author", authorSchema);
10 |
--------------------------------------------------------------------------------
/server/src/modules/author/AuthorType.js:
--------------------------------------------------------------------------------
1 | import * as AuthorLoader from "./AuthorLoader";
2 |
3 | export const typeDefs = `
4 | type Author {
5 | id: ID!
6 | name: String!
7 | age: Int!
8 | }
9 | input AuthorInput {
10 | name: String!
11 | age: Int!
12 | }
13 | `;
14 |
15 | export const resolvers = {
16 | authors: () => AuthorLoader.loadAllAuthors()
17 | };
18 |
--------------------------------------------------------------------------------
/server/src/modules/book/BookLoader.js:
--------------------------------------------------------------------------------
1 | import mongoose from "mongoose";
2 | import BookModel from "./BookModel";
3 | import addAuthor from "../author/AuthorLoader";
4 |
5 | const { ObjectId } = mongoose.Types;
6 |
7 | export const addBook = ({ title, author: bookAuthor }) => {
8 | return addAuthor({ ...bookAuthor }).then(author => {
9 | const _id = new ObjectId();
10 | const timestamp = new Date();
11 | const book = new BookModel({ title, author, _id, timestamp });
12 | return book.save();
13 | });
14 | };
15 |
16 | export const loadAllBooks = ({ skip, limit = 6 }) => {
17 | return BookModel.find({}, null, { skip, limit })
18 | .sort({ timestamp: "descending" })
19 | .populate("author")
20 | .then(result => {
21 | return result;
22 | });
23 | };
24 |
--------------------------------------------------------------------------------
/server/src/modules/book/BookModel.js:
--------------------------------------------------------------------------------
1 | import mongoose, { Schema } from "mongoose";
2 |
3 | const bookSchema = new Schema({
4 | _id: Schema.Types.ObjectId,
5 | title: String,
6 | author: { type: Schema.Types.ObjectId, ref: "Author" },
7 | timestamp: Date
8 | });
9 |
10 | export default mongoose.model("Book", bookSchema);
11 |
--------------------------------------------------------------------------------
/server/src/modules/book/BookType.js:
--------------------------------------------------------------------------------
1 | import { AuthenticationError } from "apollo-server-express";
2 | import { loadAllBooks, addBook } from "./BookLoader";
3 |
4 | export const typeDefs = `
5 | type Book {
6 | id: ID!
7 | title: String!
8 | author: Author!
9 | timestamp: Date!
10 | }
11 | `;
12 |
13 | export const resolvers = {
14 | books: (root, args, { auth }) => {
15 | if (auth) {
16 | return loadAllBooks(args);
17 | }
18 | throw AuthenticationError("Please signing again.");
19 | },
20 | dev_books: (root, args) => loadAllBooks(args)
21 | };
22 |
23 | export const mutations = {
24 | addBook: (root, args, { auth }) => {
25 | if (auth) {
26 | return addBook(args);
27 | }
28 | throw new AuthenticationError("Please signing again.");
29 | },
30 | dev_addBook: (root, args) => addBook(args)
31 | };
32 |
--------------------------------------------------------------------------------
/server/src/modules/date/DateType.js:
--------------------------------------------------------------------------------
1 | import { GraphQLScalarType } from "graphql";
2 | import { Kind } from "graphql/language";
3 |
4 | export const typeDefs = `
5 | scalar Date
6 | `;
7 |
8 | export const resolvers = {
9 | Date: new GraphQLScalarType({
10 | name: "Date",
11 | description: "Date custom scalar type",
12 | parseValue(value) {
13 | return new Date(value); // value from the client
14 | },
15 | serialize(value) {
16 | return value.getTime(); // value sent to the client
17 | },
18 | parseLiteral(ast) {
19 | if (ast.kind === Kind.INT) {
20 | return new Date(ast.value); // ast value is always in string format
21 | }
22 | return null;
23 | }
24 | })
25 | };
26 |
--------------------------------------------------------------------------------
/server/src/modules/user/UserLoader.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-console */
2 | import jwt from "jsonwebtoken";
3 | import mongoose from "mongoose";
4 | import bcrypt from "bcrypt";
5 | import { AuthenticationError } from "apollo-server-express";
6 | import UserModel from "./UserModel";
7 |
8 | const { ObjectId } = mongoose.Types;
9 | const secret = "ABB15D42-3BCD-498B-9095-416F24C4E821";
10 |
11 | export const lowerCase = input => String.prototype.toLowerCase.call(input);
12 |
13 | export const loadAllUsers = () => {
14 | return UserModel.find({}).then(result => {
15 | return result;
16 | });
17 | };
18 |
19 | /**
20 | * Verify token in request is not expired.
21 | * @param req Request.
22 | * @returns {Promise} Promise to be fulfilled with { auth: String }.
23 | */
24 | export const validateToken = ({ req }) => {
25 | const { token } = req.headers;
26 | const { noAuth } = req.body.variables;
27 |
28 | if (!token || noAuth) {
29 | return Promise.resolve();
30 | }
31 |
32 | return new Promise((res, rej) => {
33 | jwt.verify(token, secret, e => {
34 | if (e) {
35 | rej(new AuthenticationError("Please sign in again"));
36 | }
37 | res({ auth: token });
38 | });
39 | }).catch(e => {
40 | throw e;
41 | });
42 | };
43 |
44 | /**
45 | * Get a new JWT token.
46 | * @param {User} user object to get token for.
47 | * @returns {String} Token.
48 | */
49 | export const newToken = user =>
50 | jwt.sign(user, secret, {
51 | expiresIn: "99999s"
52 | });
53 |
54 | /**
55 | * Checks if a provided password matches a user's hash.
56 | * @param {String} password Plain text string to be validated.
57 | * @param {User} user User object to validate against.
58 | * @returns {Promise} Promise to be fulfilled with bool true.
59 | */
60 | export const validatePassword = (password, user) =>
61 | new Promise((res, rej) => {
62 | bcrypt
63 | .compare(password, user.hash)
64 | .then(success => {
65 | if (!success) {
66 | return rej(Error("Incorrect password"));
67 | }
68 | return res(true);
69 | })
70 | .catch(e => rej(Error(`Server Error: ${JSON.stringify(e)}`)));
71 | });
72 |
73 | export const addUser = ({ name: inputName, password }) => {
74 | const name = lowerCase(inputName);
75 | return UserModel.find({ name }).then(found => {
76 | if (found.length) {
77 | throw Error("User already registered.");
78 | }
79 | const hash = bcrypt.hashSync(password, 4);
80 | const _id = new ObjectId();
81 | const user = new UserModel({ name, hash, _id });
82 | user.save();
83 | const token = newToken({ name });
84 | return { token };
85 | });
86 | };
87 |
--------------------------------------------------------------------------------
/server/src/modules/user/UserModel.js:
--------------------------------------------------------------------------------
1 | import mongoose, { Schema } from "mongoose";
2 |
3 | const userSchema = new Schema({
4 | _id: Schema.Types.ObjectId,
5 | name: String,
6 | hash: String
7 | });
8 |
9 | export default mongoose.model("User", userSchema);
10 |
--------------------------------------------------------------------------------
/server/src/modules/user/UserType.js:
--------------------------------------------------------------------------------
1 | import * as UserLoader from "./UserLoader";
2 | import UserModel from "./UserModel";
3 |
4 | const {
5 | addUser,
6 | loadAllUsers,
7 | newToken,
8 | validatePassword,
9 | lowerCase
10 | } = UserLoader;
11 |
12 | export const typeDefs = `
13 | type User {
14 | id: ID!
15 | name: String!
16 | hash: String!
17 | }
18 | type Token {
19 | id: ID!
20 | token: String!
21 | }
22 | `;
23 |
24 | export const resolvers = {
25 | dev_users: () => loadAllUsers()
26 | };
27 |
28 | export const mutations = {
29 | addUser: (root, args) => addUser(args),
30 | login: (root, { name: inputName, password }) => {
31 | const name = lowerCase(inputName);
32 | return UserModel.find({ name }).then(result => {
33 | if (!result.length) {
34 | throw Error("User doesn't exist. Please register.");
35 | }
36 |
37 | const [user] = result;
38 | return validatePassword(password, user)
39 | .then(res => {
40 | if (res) {
41 | const token = newToken({ name });
42 | return { token };
43 | }
44 | throw Error("Server Error");
45 | })
46 | .catch(e => {
47 | throw e;
48 | });
49 | });
50 | }
51 | };
52 |
--------------------------------------------------------------------------------
/server/src/services/database.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-console */
2 | import mongoose from "mongoose";
3 |
4 | const dbAddress = {
5 | production:
6 | "mongodb+srv://user:bEHp24AVrfijnMbw@rtr-cluster-pgojw.mongodb.net/main?retryWrites=true",
7 | development: "mongodb://localhost:27017/test2"
8 | };
9 |
10 | mongoose.connect(
11 | dbAddress.production,
12 | { useNewUrlParser: true }
13 | );
14 | mongoose.connection.on("error", () => {
15 | console.log("database connection error");
16 | });
17 |
--------------------------------------------------------------------------------
/yarn.lock:
--------------------------------------------------------------------------------
1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2 | # yarn lockfile v1
3 |
4 |
5 |
--------------------------------------------------------------------------------