├── .buckconfig ├── .eslintignore ├── .eslintrc ├── .flowconfig ├── .gitattributes ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md └── workflows │ └── documentation.yml ├── .gitignore ├── .gitlab-ci.yml ├── .npmignore ├── .prettierignore ├── .prettierrc ├── .watchmanconfig ├── LICENSE ├── README.md ├── documentation ├── .eslintrc.js ├── .gitignore ├── .prettierignore ├── .prettierrc ├── .stylelintrc.js ├── README.md ├── babel.config.js ├── docs │ ├── 1_Introduction │ │ └── 1_1_RNBoilerplate.md │ ├── 2_Getting Started │ │ ├── 2_1_Installation.md │ │ └── 2_2_Configuration.md │ ├── 3_Guides │ │ ├── 3_1_Theme.md │ │ ├── 3_2_SplashScreenLoadingData.md │ │ ├── 3_3_ReduxStore.md │ │ ├── 3_4_AddALangTranslation.md │ │ ├── 3_5_UsingFlipper.md │ │ └── BetaBuild.md │ └── assets │ │ ├── Flipper.png │ │ ├── TOM-Legend.png │ │ ├── TOM.png │ │ └── Theme │ │ ├── Layout │ │ ├── Column │ │ │ ├── C1.png │ │ │ ├── C2.png │ │ │ ├── C3.png │ │ │ ├── C4.png │ │ │ └── C5.png │ │ └── Row │ │ │ ├── R1.png │ │ │ ├── R2.png │ │ │ ├── R3.png │ │ │ ├── R4.png │ │ │ └── R5.png │ │ └── Text │ │ ├── textCenter.png │ │ ├── textJustify.png │ │ ├── textLarge.png │ │ ├── textLeft.png │ │ ├── textRegular.png │ │ ├── textRight.png │ │ ├── textSmall.png │ │ ├── titleLarge.png │ │ ├── titleRegular.png │ │ └── titleSmall.png ├── docusaurus.config.js ├── package.json ├── sidebars.js ├── src │ ├── css │ │ └── custom.css │ └── pages │ │ ├── index.js │ │ └── styles.module.css ├── static │ ├── .nojekyll │ └── img │ │ ├── TOM-Legend.png │ │ ├── TOM-small.png │ │ ├── TOM.png │ │ ├── favicon.png │ │ └── oss_logo.png └── yarn.lock ├── package.json ├── post-init.script.js ├── template.config.js └── template ├── __tests__ └── App-test.tsx ├── _buckconfig ├── _eslintrc.js ├── _flowconfig ├── _gitattributes ├── _gitignore ├── _prettierrc.js ├── _watchmanconfig ├── android ├── .gitignore ├── app │ ├── BUCK │ ├── build.gradle │ ├── build_defs.bzl │ ├── debug.keystore │ ├── proguard-rules.pro │ └── src │ │ ├── debug │ │ ├── AndroidManifest.xml │ │ └── java │ │ │ └── com │ │ │ └── boilerplate │ │ │ └── ReactNativeFlipper.java │ │ └── main │ │ ├── AndroidManifest.xml │ │ ├── ic_launcher-playstore.png │ │ ├── java │ │ └── com │ │ │ └── boilerplate │ │ │ ├── MainActivity.java │ │ │ └── MainApplication.java │ │ └── res │ │ ├── drawable │ │ ├── splash_icon.png │ │ └── splash_screen.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ ├── ic_launcher_foreground.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-ldpi │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ ├── ic_launcher_foreground.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ ├── ic_launcher_foreground.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ ├── ic_launcher_foreground.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ ├── ic_launcher_foreground.png │ │ └── ic_launcher_round.png │ │ └── values │ │ ├── colors.xml │ │ ├── ic_launcher_background.xml │ │ ├── strings.xml │ │ └── styles.xml ├── build.gradle ├── gradle.properties ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle ├── app.json ├── babel.config.js ├── index.js ├── ios ├── .gitignore ├── Boilerplate-tvOS │ └── Info.plist ├── Boilerplate-tvOSTests │ └── Info.plist ├── Boilerplate.xcodeproj │ ├── project.pbxproj │ └── xcshareddata │ │ └── xcschemes │ │ ├── Boilerplate-tvOS.xcscheme │ │ └── Boilerplate.xcscheme ├── Boilerplate.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcshareddata │ │ └── IDEWorkspaceChecks.plist │ └── xcuserdata │ │ └── ozanmanav.xcuserdatad │ │ └── UserInterfaceState.xcuserstate ├── Boilerplate │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Images.xcassets │ │ ├── AppIcon.appiconset │ │ │ ├── Contents.json │ │ │ ├── Icon-App-20x20@1x.png │ │ │ ├── Icon-App-20x20@2x.png │ │ │ ├── Icon-App-20x20@3x.png │ │ │ ├── Icon-App-29x29@1x.png │ │ │ ├── Icon-App-29x29@2x.png │ │ │ ├── Icon-App-29x29@3x.png │ │ │ ├── Icon-App-40x40@1x.png │ │ │ ├── Icon-App-40x40@2x.png │ │ │ ├── Icon-App-40x40@3x.png │ │ │ ├── Icon-App-60x60@2x.png │ │ │ ├── Icon-App-60x60@3x.png │ │ │ ├── Icon-App-76x76@1x.png │ │ │ ├── Icon-App-76x76@2x.png │ │ │ ├── Icon-App-83.5x83.5@2x.png │ │ │ └── ItunesArtwork@2x.png │ │ ├── Contents.json │ │ └── SplashIcon.imageset │ │ │ ├── Contents.json │ │ │ ├── Splash_icon@1x.png │ │ │ ├── Splash_icon@2x.png │ │ │ └── Splash_icon@3x.png │ ├── Info.plist │ ├── LaunchScreen.storyboard │ └── main.m ├── BoilerplateTests │ ├── BoilerplateTests.m │ └── Info.plist ├── Podfile └── Podfile.lock ├── jest.config.js ├── jest.setup.js ├── metro.config.js ├── package.json ├── src ├── App.tsx ├── Assets │ └── Images │ │ └── TOM.png ├── Components │ ├── Brand.tsx │ └── index.tsx ├── Config │ ├── .gitignore │ └── index.example.ts ├── Containers │ ├── Example │ │ └── Index.tsx │ ├── Startup │ │ └── Index.tsx │ └── index.ts ├── Navigators │ ├── Application.tsx │ ├── Main.tsx │ ├── Root.tsx │ └── index.ts ├── Services │ ├── User │ │ ├── FetchOne.ts │ │ └── index.ts │ └── index.ts ├── Store │ ├── Startup │ │ ├── Init.ts │ │ └── index.ts │ ├── User │ │ ├── FetchOne.ts │ │ └── index.ts │ └── index.ts ├── Theme │ ├── Common.ts │ ├── Fonts.ts │ ├── Gutters.ts │ ├── Images.ts │ ├── Layout.ts │ ├── Variables.ts │ └── index.ts └── Translations │ ├── index.ts │ └── resources │ ├── en.ts │ └── index.ts ├── tsconfig.json ├── types.d.ts └── yarn.lock /.buckconfig: -------------------------------------------------------------------------------- 1 | 2 | [android] 3 | target = Google Inc.:Google APIs:23 4 | 5 | [maven_repositories] 6 | central = https://repo1.maven.org/maven2 7 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules/** 2 | android/** 3 | ios/** 4 | __tests__/** -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": [ 3 | "react", 4 | "react-native", 5 | "prettier" 6 | ], 7 | "parserOptions": { 8 | "ecmaVersion": 2018, 9 | "ecmaFeatures": { 10 | "jsx": true, 11 | "modules": true 12 | }, 13 | "sourceType": "module", 14 | "useJSXTextNode": false 15 | }, 16 | "env": { 17 | "react-native/react-native": true 18 | }, 19 | "extends": [ 20 | "standard", 21 | "plugin:react/recommended", 22 | "plugin:react-native/all", 23 | "plugin:prettier/recommended" 24 | ], 25 | "settings": { 26 | "react": { 27 | "version": "detect", 28 | }, 29 | }, 30 | "rules": { 31 | "react-native/no-raw-text": 0 // Avoid false positive, wait for fix 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /.flowconfig: -------------------------------------------------------------------------------- 1 | [ignore] 2 | ; We fork some components by platform 3 | .*/*[.]android.js 4 | 5 | ; Ignore "BUCK" generated dirs 6 | /\.buckd/ 7 | 8 | ; Ignore unexpected extra "@providesModule" 9 | .*/node_modules/.*/node_modules/fbjs/.* 10 | 11 | ; Ignore duplicate module providers 12 | ; For RN Apps installed via npm, "Libraries" folder is inside 13 | ; "node_modules/react-native" but in the source repo it is in the root 14 | node_modules/react-native/Libraries/react-native/React.js 15 | 16 | ; Ignore polyfills 17 | node_modules/react-native/Libraries/polyfills/.* 18 | 19 | ; These should not be required directly 20 | ; require from fbjs/lib instead: require('fbjs/lib/warning') 21 | node_modules/warning/.* 22 | 23 | ; Flow doesn't support platforms 24 | .*/Libraries/Utilities/HMRLoadingView.js 25 | 26 | [untyped] 27 | .*/node_modules/@react-native-community/cli/.*/.* 28 | 29 | [include] 30 | 31 | [libs] 32 | node_modules/react-native/Libraries/react-native/react-native-interface.js 33 | node_modules/react-native/flow/ 34 | 35 | [options] 36 | emoji=true 37 | 38 | esproposal.optional_chaining=enable 39 | esproposal.nullish_coalescing=enable 40 | 41 | module.file_ext=.js 42 | module.file_ext=.json 43 | module.file_ext=.ios.js 44 | 45 | module.system=haste 46 | module.system.haste.use_name_reducers=true 47 | # get basename 48 | module.system.haste.name_reducers='^.*/\([a-zA-Z0-9$_.-]+\.js\(\.flow\)?\)$' -> '\1' 49 | # strip .js or .js.flow suffix 50 | module.system.haste.name_reducers='^\(.*\)\.js\(\.flow\)?$' -> '\1' 51 | # strip .ios suffix 52 | module.system.haste.name_reducers='^\(.*\)\.ios$' -> '\1' 53 | module.system.haste.name_reducers='^\(.*\)\.android$' -> '\1' 54 | module.system.haste.name_reducers='^\(.*\)\.native$' -> '\1' 55 | module.system.haste.paths.blacklist=.*/__tests__/.* 56 | module.system.haste.paths.blacklist=.*/__mocks__/.* 57 | module.system.haste.paths.whitelist=/node_modules/react-native/Libraries/.* 58 | module.system.haste.paths.whitelist=/node_modules/react-native/RNTester/.* 59 | module.system.haste.paths.whitelist=/node_modules/react-native/IntegrationTests/.* 60 | module.system.haste.paths.blacklist=/node_modules/react-native/Libraries/react-native/react-native-implementation.js 61 | module.system.haste.paths.blacklist=/node_modules/react-native/Libraries/Animated/src/polyfills/.* 62 | 63 | munge_underscores=true 64 | 65 | module.name_mapper='^[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> 'RelativeImageStub' 66 | 67 | suppress_type=$FlowIssue 68 | suppress_type=$FlowFixMe 69 | suppress_type=$FlowFixMeProps 70 | suppress_type=$FlowFixMeState 71 | 72 | suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(\\)? *\\(site=[a-z,_]*react_native\\(_ios\\)?_\\(oss\\|fb\\)[a-z,_]*\\)?)\\) 73 | suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(\\)? *\\(site=[a-z,_]*react_native\\(_ios\\)?_\\(oss\\|fb\\)[a-z,_]*\\)?)\\)?:? #[0-9]+ 74 | suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError 75 | 76 | [lints] 77 | sketchy-null-number=warn 78 | sketchy-null-mixed=warn 79 | sketchy-number=warn 80 | untyped-type-import=warn 81 | nonstrict-import=warn 82 | deprecated-type=warn 83 | unsafe-getters-setters=warn 84 | inexact-spread=warn 85 | unnecessary-invariant=warn 86 | signature-verification-failure=warn 87 | deprecated-utility=error 88 | 89 | [strict] 90 | deprecated-type 91 | nonstrict-import 92 | sketchy-null 93 | unclear-type 94 | unsafe-getters-setters 95 | untyped-import 96 | untyped-type-import 97 | 98 | [version] 99 | ^0.98.0 -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.pbxproj -text 2 | * text=auto 3 | 4 | # Force the following filetypes to have unix eols, so Windows does not break them 5 | **/*.* text eol=lf 6 | 7 | # Windows forced line-endings 8 | /.idea/* text eol=crlf 9 | 10 | # 11 | ## These files are binary and should be left untouched 12 | # 13 | 14 | # (binary is a macro for -text -diff) 15 | *.png binary 16 | *.jpg binary 17 | *.jpeg binary 18 | *.gif binary 19 | *.ico binary 20 | *.mov binary 21 | *.mp4 binary 22 | *.mp3 binary 23 | *.flv binary 24 | *.fla binary 25 | *.swf binary 26 | *.gz binary 27 | *.zip binary 28 | *.7z binary 29 | *.ttf binary 30 | *.eot binary 31 | *.woff binary 32 | *.woff2 binary 33 | *.pyc binary 34 | *.pdf binary 35 | *.ez binary 36 | *.bz2 binary 37 | *.swp binary 38 | *.swp binary 39 | *.ipa binary 40 | *.apk binary 41 | *.jar binary 42 | *gradlew binary 43 | *BUCK binary 44 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Smartphone (please complete the following information):** 27 | - Device: [e.g. iPhone6] 28 | - OS: [e.g. iOS8.1] 29 | - Version [e.g. 22] 30 | 31 | **Additional context** 32 | Add any other context about the problem here. 33 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/workflows/documentation.yml: -------------------------------------------------------------------------------- 1 | name: documentation 2 | 3 | on: 4 | pull_request: 5 | branches: [master] 6 | push: 7 | branches: [master] 8 | 9 | jobs: 10 | checks: 11 | if: github.event_name != 'push' 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/checkout@v1 15 | - uses: actions/setup-node@v1 16 | with: 17 | node-version: '12.x' 18 | - name: Test Build 19 | run: | 20 | cd documentation 21 | yarn install --frozen-lockfile 22 | npm run build 23 | gh-release: 24 | if: github.event_name != 'pull_request' 25 | runs-on: ubuntu-latest 26 | steps: 27 | - uses: actions/checkout@v1 28 | - uses: actions/setup-node@v1 29 | with: 30 | node-version: '12.x' 31 | - name: Add key to allow access to repository 32 | env: 33 | SSH_AUTH_SOCK: /tmp/ssh_agent.sock 34 | run: | 35 | mkdir -p ~/.ssh 36 | ssh-keyscan github.com >> ~/.ssh/known_hosts 37 | echo "${{ secrets.GH_PAGES_DEPLOY }}" > ~/.ssh/id_rsa 38 | chmod 600 ~/.ssh/id_rsa 39 | cat <> ~/.ssh/config 40 | Host github.com 41 | HostName github.com 42 | IdentityFile ~/.ssh/id_rsa 43 | EOT 44 | - name: Release to GitHub Pages 45 | env: 46 | USE_SSH: true 47 | GIT_USER: git 48 | DEPLOYMENT_BRANCH: gh-pages 49 | run: | 50 | git config --global user.email "actions@gihub.com" 51 | git config --global user.name "gh-actions" 52 | cd documentation 53 | yarn install --frozen-lockfile 54 | yarn deploy -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # Android/IntelliJ 6 | # 7 | build/ 8 | .idea 9 | .gradle 10 | local.properties 11 | *.iml 12 | 13 | # node.js 14 | # 15 | npm-debug.log 16 | yarn-error.log 17 | 18 | # Ignore specific files copying by RN CLI 19 | template/.gitignore 20 | template/.gitattributes 21 | template/.eslintrc.js 22 | template/.flowconfig 23 | template/.buckconfig 24 | template/.prettierrc.js 25 | template/.watchmanconfig 26 | -------------------------------------------------------------------------------- /.gitlab-ci.yml: -------------------------------------------------------------------------------- 1 | image: node:8.10.0 2 | 3 | cache: 4 | paths: 5 | - node_modules 6 | 7 | before_script: 8 | - yarn 9 | 10 | prettier: 11 | script: 12 | - npm run prettier-check 13 | 14 | eslint: 15 | script: 16 | - npm run lint-check 17 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | templates/node_modules 3 | templates/ios/Pods 4 | documentation 5 | .idea 6 | .github 7 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | node_modules/** 2 | android/** 3 | ios/** 4 | __tests__/** -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | printWidth : 100, 3 | tabWidth : 2, 4 | useTabs : false, 5 | semi : false, 6 | singleQuote : true, 7 | trailingComma : "es5", 8 | bracketSpacing : true, 9 | jsxBracketSameLine : false, 10 | arrowParens : "always", 11 | rangeStart : 0, 12 | parser : "babel", 13 | requirePragma : false, 14 | insertPragma : false, 15 | proseWrap : "preserve" 16 | } 17 | -------------------------------------------------------------------------------- /.watchmanconfig: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2018 The Coding Machine 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # This is a Typescript powered fork repo. I constantly update this repo with the original repo. The last update date is 06.12.2020. 2 | 3 |
4 | Logo 5 |
6 | 7 | ![GitHub Release Date](https://img.shields.io/github/release-date/ozanmanav/react-native-boilerplate-ts) 8 | ![GitHub last commit](https://img.shields.io/github/last-commit/ozanmanav/react-native-boilerplate-ts) 9 | ![GitHub commit activity](https://img.shields.io/github/commit-activity/m/ozanmanav/react-native-boilerplate-ts) 10 | ![GitHub commits since latest release](https://img.shields.io/github/commits-since/ozanmanav/react-native-boilerplate-ts/latest) 11 | ![GitHub top language](https://img.shields.io/github/languages/top/ozanmanav/react-native-boilerplate-ts) 12 | 13 | # TheCodingMachine React Native boilerplate 14 | 15 | This project is a [React Native](https://facebook.github.io/react-native/) boilerplate that can be used to kickstart a mobile application. 16 | 17 | The boilerplate provides **an optimized architecture for building solid cross-platform mobile applications** through separation of concerns between the UI and business logic. It is fully documented so that each piece of code that lands in your application can be understood and used. 18 | 19 | ``` 20 | If you love this boilerplate, give us a star, you will be a ray of sunshine in our lives :) 21 | ``` 22 | 23 | 24 | ## Requirements 25 | 26 | Node 10 or greater is required. Development for iOS requires a Mac and Xcode 9.4 or up, and will target iOS 9 and up. 27 | 28 | You also need to install the dependencies required by React Native. 29 | Go to the [React Native environment setup](https://reactnative.dev/docs/environment-setup), then select `React Native CLI Quickstart` tab. 30 | Follow instructions for your given `development OS` and `target OS`. 31 | 32 | ## Quick start 33 | 34 | To create a new project using the boilerplate simply run : 35 | 36 | ``` 37 | npx --ignore-existing react-native init MyApp --template @ozanmanav/react-native-boilerplate-ts 38 | ``` 39 | 40 | Assuming you have all the requirements installed, you can setup and run the project by running: 41 | 42 | - `yarn install` to install the dependencies 43 | - run the following steps for your platform 44 | 45 | ### Android 46 | 47 | - only the first time you run the project, you need to generate a `debug key` with: 48 | - `cd android/app` 49 | - `keytool -genkey -v -keystore debug.keystore -storepass android -alias androiddebugkey -keypass android -keyalg RSA -keysize 2048 -validity 10000` 50 | - `cd ../..` to come back to the root folder 51 | - `yarn start` to start the metro bundler, in a dedicated terminal 52 | - `yarn android` to run the Android application (remember to start a simulator or connect an Android phone) 53 | 54 | ### iOS 55 | 56 | - `cd ios` 57 | - `pod install` to install pod dependencies 58 | - `cd ..` to come back to the root folder 59 | - `yarn start` to start the metro bundler, in a dedicated terminal 60 | - `yarn ios` to run the iOS application (remember to start a simulator or connect an iPhone phone) 61 | 62 | ## Digging Deeper 63 | 64 | To learn more about this boilerplate, go to [full documentation](https://thecodingmachine.github.io/react-native-boilerplate) 65 | 66 | ## License 67 | 68 | This project is released under the [MIT License](LICENSE). 69 | 70 | ## About us 71 | 72 | [TheCodingMachine](https://www.thecodingmachine.com/) is a web and mobile agency based in Paris and Lyon, France. We are [constantly looking for new developers and team leaders](https://www.thecodingmachine.com/nous-rejoindre/) and we love [working with freelancers](https://coders.thecodingmachine.com/). You'll find [an overview of all our open source projects on our website](https://thecodingmachine.io/open-source) and on [Github](https://github.com/thecodingmachine). 73 | -------------------------------------------------------------------------------- /documentation/.eslintrc.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 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 | * @format 8 | */ 9 | 10 | const OFF = 0; 11 | const WARNING = 1; 12 | const ERROR = 2; 13 | 14 | module.exports = { 15 | root: true, 16 | env: { 17 | browser: true, 18 | commonjs: true, 19 | jest: true, 20 | node: true, 21 | }, 22 | parser: 'babel-eslint', 23 | parserOptions: { 24 | allowImportExportEverywhere: true, 25 | }, 26 | extends: ['airbnb', 'prettier', 'prettier/react'], 27 | plugins: ['react-hooks', 'header'], 28 | rules: { 29 | // Ignore certain webpack alias because it can't be resolved 30 | 'import/no-unresolved': [ 31 | ERROR, 32 | {ignore: ['^@theme', '^@docusaurus', '^@generated']}, 33 | ], 34 | 'import/extensions': OFF, 35 | 'header/header': [ 36 | ERROR, 37 | 'block', 38 | 39 | [ 40 | '*', 41 | ' * Copyright (c) Facebook, Inc. and its affiliates.', 42 | ' *', 43 | ' * This source code is licensed under the MIT license found in the', 44 | ' * LICENSE file in the root directory of this source tree.', 45 | ' *', 46 | // Unfortunately eslint-plugin-header doesn't support optional lines. 47 | // If you want to enforce your website JS files to have @flow or @format, 48 | // modify these lines accordingly. 49 | { 50 | pattern: '.* @format', 51 | }, 52 | ' ', 53 | ], 54 | ], 55 | 'react/jsx-closing-bracket-location': OFF, // Conflicts with Prettier. 56 | 'react/jsx-filename-extension': OFF, 57 | 'react-hooks/rules-of-hooks': ERROR, 58 | 'react/prop-types': OFF, // PropTypes aren't used much these days. 59 | }, 60 | }; 61 | -------------------------------------------------------------------------------- /documentation/.gitignore: -------------------------------------------------------------------------------- 1 | # Dependencies 2 | /node_modules 3 | 4 | # Production 5 | /build 6 | 7 | # Generated files 8 | .docusaurus 9 | .cache-loader 10 | 11 | # Misc 12 | .DS_Store 13 | .env.local 14 | .env.development.local 15 | .env.test.local 16 | .env.production.local 17 | 18 | npm-debug.log* 19 | yarn-debug.log* 20 | yarn-error.log* 21 | 22 | # ESLint 23 | .eslintcache 24 | -------------------------------------------------------------------------------- /documentation/.prettierignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | build 3 | .docusaurus 4 | -------------------------------------------------------------------------------- /documentation/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "arrowParens": "always", 3 | "bracketSpacing": false, 4 | "jsxBracketSameLine": true, 5 | "printWidth": 80, 6 | "proseWrap": "never", 7 | "singleQuote": true, 8 | "trailingComma": "all" 9 | } 10 | -------------------------------------------------------------------------------- /documentation/.stylelintrc.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 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 | module.exports = { 9 | plugins: ['stylelint-copyright'], 10 | rules: { 11 | 'docusaurus/copyright-header': true, 12 | }, 13 | }; 14 | -------------------------------------------------------------------------------- /documentation/README.md: -------------------------------------------------------------------------------- 1 | # Website 2 | 3 | This website is built using [Docusaurus 2](https://v2.docusaurus.io/), a modern static website generator. 4 | 5 | ### Installation 6 | 7 | ``` 8 | $ yarn 9 | ``` 10 | 11 | ### Local Development 12 | 13 | ``` 14 | $ yarn start 15 | ``` 16 | 17 | This command starts a local development server and open up a browser window. Most changes are reflected live without having to restart the server. 18 | 19 | ### Build 20 | 21 | ``` 22 | $ yarn build 23 | ``` 24 | 25 | This command generates static content into the `build` directory and can be served using any static contents hosting service. 26 | 27 | ### Deployment 28 | 29 | ``` 30 | $ GIT_USER= USE_SSH=true yarn deploy 31 | ``` 32 | 33 | 34 | If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch. 35 | 36 | ### Continuous Integration 37 | 38 | Some common defaults for linting/formatting have been set for you. If you integrate your project with an open source Continuous Integration system (e.g. Travis CI, CircleCI), you may check for issues using the following command. 39 | 40 | ``` 41 | $ yarn ci 42 | ``` 43 | -------------------------------------------------------------------------------- /documentation/babel.config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 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 | * @format 8 | */ 9 | 10 | module.exports = { 11 | presets: [require.resolve('@docusaurus/core/lib/babel/preset')], 12 | }; 13 | -------------------------------------------------------------------------------- /documentation/docs/1_Introduction/1_1_RNBoilerplate.md: -------------------------------------------------------------------------------- 1 | --- 2 | slug: /Introduction 3 | title: React Native Boilerplate 4 | --- 5 | 6 |
7 | 8 |
9 | 10 | This project is a [React Native](https://facebook.github.io/react-native/) boilerplate that can be used to kick-start a mobile application. 11 | 12 | The boilerplate provides **an architecture optimized for building solid cross-platform mobile applications** through separation of concerns between the UI and business logic. 13 | We made this full documentation so that each piece of code that lands in your application can be understood and used. 14 | 15 | 16 | :::tip Don't forget !! 17 | If you love this boilerplate, give us a star, you will be a ray of sunshine in our lives 🌈 ☀️ 18 | ::: 19 | 20 | ## Architecture 21 | 22 | The driving goal of the architecture of the boilerplate is separation of concerns and using React Native at its best. 23 | 24 | - **Using modern Javascript** 25 | So many javascript features are indispensable now like hooks, functional component and really cool dependencies. 26 | 27 | - **Presentational components are separated from containers**. 28 | 29 | Presentational components are small components that are concerned with *how things look*. 30 | Containers usually define whole application screens and are concerned with *how things work*: they include presentational components and wire everything together. 31 | 32 | If you are interested you can [read more about it here](https://medium.com/@dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0). 33 | 34 | - **State is managed using global [Redux](https://redux.js.org/) stores**. 35 | 36 | When applications grow, sharing state and its changes can become very hard. Questions like "How can I access this data?" or "When did this change?" are common, just like passing data around components just to be able to use it in nested components. 37 | 38 | With Redux, state is shared using global *stores*, and changes are predictable: *actions* are applied by *reducers* to the state. While the pattern can be a bit much for small projects, the clear separation of responsibilities and predictability helps with bigger applications. 39 | 40 | If you are interested you can [read more about it here](https://redux.js.org/introduction/motivation). 41 | 42 | ## Content 43 | 44 | The boilerplate contains: 45 | 46 | - a [React Native](https://facebook.github.io/react-native/) (v**0.63.3**) application (in "[ejected](https://github.com/react-community/create-react-native-app/blob/master/EJECTING.md)" mode to allow using dependencies that rely on native code) 47 | - a [clear directory layout](#directory-layout) to provide a base architecture for your application 48 | - [Redux](https://redux.js.org/) (v**4.0.5**) to help manage state 49 | - [Redux Persist](https://github.com/rt2zz/redux-persist) (v**6.0.0**) to persist the Redux state 50 | - [React Navigation](https://reactnavigation.org/) (v**5**) to handle routing and navigation in the app, with a splash screen setup by default 51 | - [redux toolkit](https://github.com/infinitered/reduxsauce) (v**1.4.0**) to make redux easier 52 | - [axios](https://github.com/axios/axios) (v**0.20.0**) to make API calls 53 | - [prettier](https://prettier.io/) and [eslint](https://eslint.org/) preconfigured for React Native 54 | - [react-native-flipper](https://fbflipper.com/) (v**0.62.0**) to debug react-native and [redux-flipper](https://github.com/jk-gan/redux-flipper) (v**1.3.2**) to debug redux 55 | 56 | The boilerplate includes an example (displaying fake user data) from UI components to the business logic. The example is easy to remove so that it doesn't get in the way. 57 | 58 | ## Directory layout 59 | 60 | - `src/Assets`: assets (image, audio files, ...) used by the application 61 | - `src/Components`: presentational components 62 | - `src/Config`: configuration of the application 63 | - `src/Containers`: container components, i.e. the application's screens 64 | - `src/Navigators`: react navigation navigators 65 | - `src/Services`: application services, e.g. API clients 66 | - `src/Stores`: redux [actions, reducers and stores](https://redux.js.org/basics) 67 | - `src/Translations`: application strings, you can add languages files and be able to translate your app strings 68 | - `src/Theme`: base styles for the application 69 | 70 | ## Updates 71 | 72 | The boilerplate will follow new React-Native releases as soon as libraries and tools used here are compatible. 73 | -------------------------------------------------------------------------------- /documentation/docs/2_Getting Started/2_1_Installation.md: -------------------------------------------------------------------------------- 1 | --- 2 | slug: /Installation 3 | title: Installation 4 | --- 5 | 6 | ## Requirements 7 | 8 | Node 10 or greater is required. Development for iOS requires a Mac and Xcode 9.4 or up, and will target iOS 9 and up. 9 | 10 | You also need to install the dependencies required by React Native: 11 | 12 | - for [Android development](https://facebook.github.io/react-native/docs/getting-started.html#installing-dependencies-3) 13 | - for [iOS development](https://facebook.github.io/react-native/docs/getting-started.html#installing-dependencies) 14 | 15 | ## Using the boilerplate 16 | 17 | To create a new project using the boilerplate simply run : 18 | 19 | ``` 20 | npx react-native init MyApp --template @ozanmanav/react-native-boilerplate-ts 21 | ``` 22 | 23 | ## Running the project 24 | 25 | Assuming you have all the requirements installed, you can setup and run the project by running: 26 | 27 | - `yarn install` to install the dependencies 28 | - run the following steps for your platform 29 | 30 | ### Android 31 | 32 | - only the first time you run the project, you need to generate a debug key with: 33 | - `cd android/app` 34 | - `keytool -genkey -v -keystore debug.keystore -storepass android -alias androiddebugkey -keypass android -keyalg RSA -keysize 2048 -validity 10000` 35 | - `cd ../..` to come back to the root folder 36 | - `yarn start` to start the metro bundler, in a dedicated terminal 37 | - `yarn android` to run the Android application (remember to start a simulator or connect an Android phone) 38 | 39 | ### iOS 40 | 41 | - `cd ios` 42 | - `pod install` to install pod dependencies 43 | - `cd ..` to come back to the root folder 44 | - `yarn start` to start the metro bundler, in a dedicated terminal 45 | - `yarn ios` to run the iOS application (remember to start a simulator or connect an iPhone phone) 46 | -------------------------------------------------------------------------------- /documentation/docs/2_Getting Started/2_2_Configuration.md: -------------------------------------------------------------------------------- 1 | --- 2 | slug: /Configuration 3 | title: Configuration 4 | --- 5 | 6 | ## Change the appicon 7 | To help generate appicons, you can use an online tool like [appicon](https://appicon.co/) to generate for both iOS and Android all icons and image sets. 8 | 9 | ### iOS 10 | To change the appicon of the iOS application, you need to replace all the content of 11 | ``` 12 | src > ios > *name_of_your_app* > Images.xcassets > AppIcon.appiconset 13 | ``` 14 | with your appicons generated with [appicon](https://appicon.co/) for example. 15 | 16 | ### Android 17 | To change the appicon of the Android application, you need to replace all the content of 18 | ``` 19 | src > android > app > src > res 20 | ``` 21 | with your appicons generated with [appicon](https://appicon.co/) for example. 22 | 23 | --- 24 | 25 | ## Change the splash screen icon 26 | 27 | ### iOS 28 | You can use the same tool ([appicon](https://appicon.co/)) to generate image sets (@1x, @2x, @3x). 29 | Then you just have to replace : `Splash_icon@1x.png`, `Splash_icon@2x.png`, `Splash_icon@3x.png` with yours in : 30 | ``` 31 | src > ios > *name_of_your_app* > Images.xcassets > SplashIcon.imageset 32 | ``` 33 | 34 | ### Android 35 | You just have to replace the splash_icon.png located at : 36 | ``` 37 | src > android > app > src > res > drawable 38 | ``` -------------------------------------------------------------------------------- /documentation/docs/3_Guides/3_1_Theme.md: -------------------------------------------------------------------------------- 1 | --- 2 | slug: /Theme 3 | title: Theme 4 | --- 5 | 6 | The Theme folder, at the root of project, includes a nice kit for building and maintaining the UI of application. 7 | It helps with variables and reusable classes to create harmony between application screens. 8 | 9 | --- 10 | 11 | ## Variables 12 | The first file is the variables one. It contains 3 groups of variables : 13 | - 🎨 **Colors** : defines global colors of the graphical charter, 14 | ```javascript 15 | export const Colors = { 16 | transparent: 'rgba(0,0,0,0)', 17 | primary: '#007bff', 18 | white: '#ffffff', 19 | text: '#212529', 20 | success: '#28a745', 21 | error: '#dc3545', 22 | } 23 | ``` 24 | 25 | - 🔠 **FontSize** : defines sizes for your text guidelines. These variables are used in the file [Font](#font-) described down below. 26 | ```javascript 27 | export const FontSize = { 28 | small: 12, 29 | regular: 14, 30 | large: 18, 31 | } 32 | ``` 33 | 34 | - ✂️ **MetricsSizes** : defines metrics sizes of your guidelines. These variables are used by [Gutters](#gutters-%EF%B8%8F) to create generic spaces for all your application, 35 | ```javascript 36 | const tiny = 5 // 10 37 | const small = tiny * 2 // 10 38 | const regular = tiny * 3 // 15 39 | const large = regular * 2 // 30 40 | export const MetricsSizes = { 41 | tiny, 42 | small, 43 | regular, 44 | large, 45 | } 46 | ``` 47 | 48 | --- 49 | 50 | ## Common 51 | The `Common` defines global style. It helps keeping the style at one place and avoid stylesheets everywhere in the code. 52 | For example you can defines style for buttons, inputs, background like this : 53 | ```javascript 54 | export default StyleSheet.create({ 55 | button: { 56 | backgroundColor: Colors.primary, 57 | }, 58 | backgroundReset: { 59 | backgroundColor: Colors.transparent, 60 | }, 61 | }) 62 | ``` 63 | 64 | --- 65 | 66 | ## Font 🔤 67 | The `Font` presets some text classes using the [FontSize](#variables) variables. 68 | It provides these classes: 69 | 70 | ### textSmall 71 | It applies a `fontSize: FontSize.small` on the element. 72 |
73 | 74 |
75 | 76 | ### textRegular 77 | It applies a `fontSize: FontSize.regular` on the element. 78 |
79 | 80 |
81 | 82 | ### textLarge 83 | It applies a `fontSize: FontSize.large` on the element. 84 |
85 | 86 |
87 | 88 | ### titleSmall 89 | It applies a `fontSize: FontSize.small * 2` and `fontWeight: 'bold'` on the element. 90 |
91 | 92 |
93 | 94 | ### titleRegular 95 | It applies a `fontSize: FontSize.regular * 2` and `fontWeight: 'bold'` on the element. 96 |
97 | 98 |
99 | 100 | ### titleLarge 101 | It applies a `fontSize: FontSize.large * 2` and `fontWeight: 'bold'` on the element. 102 |
103 | 104 |
105 | 106 | ### textCenter 107 | Centers a text horizontally. 108 |
109 | 110 |
111 | 112 | ### textJustify 113 | Justifies a paragraph. 114 |
115 | 116 |
117 | 118 | ### textLeft 119 | Aligns text on the left side of his parent. 120 |
121 | 122 |
123 | 124 | ### textRight 125 | Align text on the right side of his parent. 126 |
127 | 128 |
129 | 130 | --- 131 | 132 | ## Gutters ✂️ 133 | Gutters is a classes generator. It builds from [MetricsSizes](#variables) variables all associated gutters. 134 | It generates, for each MetricsSize variables, classes like this : 135 | ``` 136 | [size][direction][op]: { 137 | [op][direction]: [value] 138 | } 139 | ``` 140 | 141 | Where : 142 | * `[size]`: is the key of the variable included in MetricsSizes ('small' for example) 143 | * `[direction]`: can be ['Bottom','Top','Right','Left','Horizontal','Vertical'] 144 | * `[op]`: can be ['Margin', 'Padding'] 145 | * `[value]`: is the value of the [size] 146 | 147 | For example, for the metricsSize `small`, the `Gutters` file provides these classes : 148 | ``` 149 | smallBottomMargin, smallTopMargin, smallRightMargin, smallLeftMargin, smallVerticalMargin, smallHorizontalMargin 150 | ``` 151 | and 152 | ``` 153 | smallBottomPadding, smallTopPadding, smallRightPadding, smallLeftPadding, smallVerticalPadding, smallHorizontalPadding 154 | ``` 155 | 156 | --- 157 | 158 | ## Images 🖼 159 | This files includes all images used in the application. 160 | To use it, you only have to import the image like below 161 | 162 | ```javascript 163 | export default { 164 | logo: require('@/Assets/Images/TOM.png'), 165 | } 166 | ``` 167 | 168 | Then you can use your image like this : 169 | 170 | ```javascript 171 | import { Images } from '@/Theme' 172 | ... 173 | 174 | ``` 175 | 176 | --- 177 | 178 | ## Layout 179 | The `Layout` file gives basic stylesheets classes to create layout and align elements. 180 | 181 | ### Column layout ⬇️ 182 | All stylesheet classes below help building a Column layout 183 | 184 | #### column 185 | Apply a top to bottom direction's column to an element. So all direct children will be stacked as following: 186 |
187 | 188 |
189 | 190 | #### columnReverse 191 | Apply a bottom to top direction's column to an element. So all direct children will be stacked as following: 192 |
193 | 194 |
195 | 196 | #### colCenter 197 | Apply a top to bottom direction's column and center all direct children as following: 198 |
199 | 200 |
201 | 202 | #### colVCenter 203 | Apply a top to bottom direction's column and center vertically all direct children as following: 204 |
205 | 206 |
207 | 208 | #### colHCenter 209 | Apply a top to bottom direction's column and center horizontally all direct children as following: 210 |
211 | 212 |
213 | 214 | ### Row layout ➡️ 215 | All stylesheet classes below help building a Row layout 216 | 217 | #### row 218 | Apply the row direction to an element left to right. So all direct children will be stacked as following: 219 |
220 | 221 |
222 | 223 | #### rowReverse 224 | Apply the column direction to an element right to left. So all direct children will be stacked as following: 225 |
226 | 227 |
228 | 229 | #### rowCenter 230 | Apply the column direction to an element left to right. So all direct children will be stacked as following: 231 |
232 | 233 |
234 | 235 | #### rowVCenter 236 | Apply the column direction to an element left to right. So all direct children will be stacked as following: 237 |
238 | 239 |
240 | 241 | #### rowHCenter 242 | Apply the column direction to an element left to right. So all direct children will be stacked as following: 243 |
244 | 245 |
246 | 247 | ### Default layout 🃏 248 | #### center 249 | center horizontally and vertically an element 250 | 251 | #### alignItemsCenter 252 | Align children of a container in the center of the container's cross axis. 253 | 254 | #### alignItemsStart 255 | Align children of a container to the start of the container's cross axis. 256 | 257 | #### alignItemsStretch 258 | Stretch children of a container to match the height of the container's cross axis. 259 | 260 | #### justifyContentCenter 261 | Align children of a container in the center of the container's main axis. 262 | 263 | #### justifyContentAround 264 | Evenly space off children across the container's main axis, distributing the remaining space around the children. Compared to space-between, using space-around will result in space being distributed to the beginning of the first child and end of the last child. 265 | 266 | #### justifyContentBetween 267 | Evenly space off children across the container's main axis, distributing the remaining space between the children. 268 | 269 | #### scrollSpaceAround 270 | make a space around on scroll view 271 | 272 | #### scrollSpaceBetween 273 | make a space between on scroll view 274 | 275 | #### selfStretch 276 | same has alignItemsStretch but it affect the children directly 277 | 278 | ### Size layout 📏 279 | #### fill 280 | Apply a `flex: 1` 281 | 282 | #### fullSize 283 | Make an element fit his height and width's parent 284 | 285 | #### fullWidth 286 | make the element fit his width's parent 287 | 288 | #### fullHeight 289 | make the element fit his height's parent 290 | 291 | ### Operation layout 🧮 292 | #### mirror 293 | make an element flip around the X axis 294 | 295 | #### rotate90 296 | rotate an element by 90° clockwise 297 | 298 | #### rotate90Inverse 299 | rotate an element by 90° counterclockwise 300 | 301 | :::note 302 | In all these groups you can add, remove or edit variables/classes with the values you want 303 | ::: -------------------------------------------------------------------------------- /documentation/docs/3_Guides/3_2_SplashScreenLoadingData.md: -------------------------------------------------------------------------------- 1 | --- 2 | slug: /SplashScreenLoadingData 3 | title: Splash screen & loading data 4 | --- 5 | 6 | In many applications, you need to load data from API before displaying any content. 7 | To do that, we built a solid navigation based on a splash screen to load data before the content shows, and [inline require](https://reactnative.dev/docs/ram-bundles-inline-requires#inline-requires) to improve performance. 8 | 9 | --- 10 | 11 | ## How the navigation is build ❓ 12 | The answer is : 13 | 14 | > Like it's recommended in the React Navigation V5 documentation 🤓 15 | 16 | Like everywhere else, the entry point of the navigation is in the root file `src/App.js` : 17 | 18 | ```jsx 19 | const App = () => ( 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | ) 31 | ``` 32 | 33 | What is new here is into the `ApplicationNavigator` component : 34 | 35 | ```jsx 36 | const Stack = createStackNavigator() 37 | 38 | let MainNavigator 39 | 40 | // @refresh reset 41 | const ApplicationNavigator = () => { 42 | const [isApplicationLoaded, setIsApplicationLoaded] = useState(false) 43 | 44 | const applicationIsLoading = useSelector((state) => state.startup.loading) 45 | 46 | useEffect(() => { 47 | if (MainNavigator == null && !applicationIsLoading) { 48 | MainNavigator = require('@/Navigators/Main').default 49 | setIsApplicationLoaded(true) 50 | } 51 | }, [applicationIsLoading]) 52 | 53 | return ( 54 | 55 | 56 | {isApplicationLoaded && ( 57 | 58 | )} 59 | 60 | ) 61 | } 62 | ``` 63 | 64 | So the root navigator is a stack with two screens : 65 | - the splash screen (`IndexStartupContainer`), 66 | - a second navigator (`MainNavigator`). 67 | 68 | The main goal of the `ApplicationNavigator` is to only have one screen (the `IndexStartupContainer`) to load. 69 | And, when the application finish loading, then fetch and display the `MainNavigator`. 70 | In other words, when `ApplicationNavigator` is mounted, it only can display the `IndexStartupContainer` because the `MainNavigator` isn't loaded and imported yet. 71 | In the `StartupContainer`, the redux action which is used to load data on init application is trigger and when the action is finish, the state `state.startup.initialize.loading` turns `true`. 72 | when this state is true, in the useEffect the `MainNavigator` navigator is imported , the navigation navigate and reset to a screen of the `MainNavigator`. 73 | 74 | To conclude, all new screens have to be added to `MainNavigator`. The `ApplicationNavigator` increase startup performance thanks to inline require and provides a splash screen to load your data. 75 | 76 | ## How to load data before app open ❓ 77 | 78 | To have a great separation of concerns, all API call are make into Services. In the above section, it said that in `IndexStartupContainer`, a redux action is triggered. This action is `InitializeStartupAction` : 79 | 80 | ```javascript 81 | useEffect(() => { 82 | dispatch(InitStartup.action()) 83 | }, [dispatch]) 84 | ``` 85 | 86 | In redux, triggering an action lead to an associated reducer and in most cases the action pass trough a middleware. 87 | All the logic can be found at `Stores/Startup/Init.js`. 88 | 89 | ```javascript 90 | import { buildAction, buildReducers } from '@/Store/builder' 91 | import FetchOne from '@/Store/User/FetchOne' 92 | 93 | export default { 94 | initialState: { loading: false, error: null }, 95 | action: buildAction('startup/init', async (args, { dispatch }) => { 96 | // Here we load the user 1 for example, but you can for example load the connected user 97 | await dispatch(FetchOne.action(1)) 98 | }), 99 | reducers: buildReducers({ itemKey: null }), // We do not want to modify some item by default 100 | } 101 | ``` 102 | 103 | All stores are based on redux-toolkit to simplify the process of API calls by using the `createAsyncThunk` function (hidden by the `buildAction` action which is a store builder function). 104 | So, to load data on splash screen you just have to add dispatched action in the buildAction. 105 | -------------------------------------------------------------------------------- /documentation/docs/3_Guides/3_3_ReduxStore.md: -------------------------------------------------------------------------------- 1 | --- 2 | slug: /ReduxStore 3 | title: Redux store 4 | --- 5 | 6 | 🚧 It's a Work In Progress section 🚧 7 | 8 | ## Architecture 9 | The root file include configuration of redux. The two main constants are `reducers` and `persistConfig` 10 | 11 | ```javascript 12 | const reducers = combineReducers({ 13 | startup, 14 | user, 15 | }) 16 | 17 | const persistConfig = { 18 | key: 'root', 19 | storage: AsyncStorage, 20 | whitelist: [], 21 | } 22 | ``` 23 | 24 | - `whitelist` includes state to persist (with `redux-persist`) 25 | - `reducers` includes all `reducer modules` 26 | 27 | ## Slices 28 | 29 | A slice is a group of actions, states and reducers for a same module. For example, in this boilerplate, there are two slices : `Startup` and `User`. 30 | In each slice, an `index.js` file which combines each store's feature (`fetchOne.js` for the `User` slice example). 31 | We've decided to separate each feature in one file in order to avoid very large incomprehensible files. 32 | So each feature includes its scoped state, actions and related reducers. 33 | 34 | ```javascript 35 | export default { 36 | initialState: { 37 | // Optionally, you can scope variables 38 | fetchOne: { loading: false, error: null }, 39 | }, 40 | action: buildAction('user/fetchOne', fetchOneUserService), 41 | reducers: buildReducers({ 42 | errorKey: 'fetchOne.error', // Optionally, if you scoped variables, you can use a key with dot notation 43 | loadingKey: 'fetchOne.loading', 44 | }), 45 | } 46 | ``` 47 | 48 | In the `index.js` file, all features are merged in a slice where states, actions, and reducers are merged and placed in a slice. 49 | 50 | ```javascript 51 | const moduleInitialState = { 52 | item: {}, 53 | } 54 | 55 | export default buildSlice('user', [FetchOne], moduleInitialState).reducer 56 | ``` 57 | 58 | For the `User` example, the below state will be created : 59 | ``` 60 | { 61 | user: { 62 | item: {}, 63 | fetchOne: { 64 | loading: false, 65 | error: null, 66 | } 67 | } 68 | } 69 | ``` 70 | `Actions` will be : `user/fetchOne/pending`, `user/fetchOne/fulfilled`, `user/fetchOne/rejected`. 71 | For each action, a reducer is associated. 72 | 73 | ## Redux-toolkit-wrapper 74 | The boilerplate includes a [wrapper of redux-toolkit](https://github.com/thecodingmachine/redux-toolkit-wrapper) to make it easier to use. It provides three helpers. 75 | If your are not familiar with redux-toolkit, please have a look at their [documentation](https://redux-toolkit.js.org/api/configureStore). 76 | 77 | ### buildAction 78 | `buildAction` is a wrapper of [`createAsyncThunk`](https://redux-toolkit.js.org/api/createAsyncThunk). 79 | 80 | | Parameters | Description | Type | Default | 81 | | :-------------------- | :------------------------------------------ | :-------- | :--------- | 82 | | actionName | the name of the action | string | undefined | 83 | | action | function to launch and await | function | () => {} | 84 | 85 | ### buildReducers 86 | `buildReducers` create default reducers based on CRUD logic. It creates three functions : pending, fulfilled and rejected. 87 | - `pending` set the `loadingKey` to `true` and the `errorKey` to `null`. 88 | - `fulfilled` replaces `itemKey` with the payload (if `itemKey` is not `null`) and the `loadingKey` to `false` 89 | - `pending` set the `loadingKey` to `false` and the `errorKey` to payload. 90 | 91 | 92 | | Parameters | Description | Type | Default | 93 | | :------------- | :----------------------------- | :-------- | :-------- | 94 | | itemKey | the key of the item state | string | 'item' | 95 | | loadingKey | the key of the loading state | string | 'loading' | 96 | | errorKey | the key of the error state | string | 'error' | 97 | 98 | ### buildSlice 99 | `buildSlice` is a wrapper of [`createSlice`](https://redux-toolkit.js.org/api/createSlice). 100 | 101 | 102 | | Parameters | Description | Type | Default | 103 | | :-------------------- | :-------------------------------------------- | :-------- | :-------- | 104 | | name | the name of the slice | string | undefined | 105 | | modules | array of all modules | array | [] | 106 | | moduleInitialState | initial state for all modules of the slice | object | {} | 107 | -------------------------------------------------------------------------------- /documentation/docs/3_Guides/3_4_AddALangTranslation.md: -------------------------------------------------------------------------------- 1 | --- 2 | slug: /AddALangTranslation 3 | title: Add a lang translation 4 | --- 5 | 6 | The boilerplate includes an i18n feature to store and translate String data. 7 | The package used is [i18next](https://www.i18next.com/) you can use their documentation for not included functionnalities. 8 | 9 | --- 10 | 11 | ## Add a new language 12 | All languages files are located in `src/Translations/resources`. By default, there is the `en.js` file. 13 | To add a new language just `cp en.js fr.js` and export it in : `src/Translations/resources/index` 14 | 15 | ```jsx 16 | export { default as en } from './en' 17 | export { default as fr } from './fr' 18 | ``` 19 | 20 | Now you can translate all keys of the `fr.js` file : 21 | ```jsx 22 | export default { 23 | welcome: 'Bienvenue sur le React Native Boilerplate de TheCodingMachine', 24 | actions: { 25 | continue: 'Continuer', 26 | }, 27 | example: { 28 | helloUser: 'Je suis un faux utilisateur, mon nom est {{name}}', 29 | labels: { 30 | userId: "Entrer un id d'utilisateur", 31 | }, 32 | }, 33 | } 34 | ``` 35 | 36 | That's it ! Now you can change the language with `i18n.changeLanguage('fr')` 37 | 38 | -------------------------------------------------------------------------------- /documentation/docs/3_Guides/3_5_UsingFlipper.md: -------------------------------------------------------------------------------- 1 | --- 2 | slug: /UsingFlipper 3 | title: Using Flipper 4 | --- 5 | 6 | Flipper is a debugger for React native and, with a plugin, for redux too. 7 | All you have to do is download [Flipper](https://fbflipper.com/). Afterinstalling it, in Flipper desktop client do: 8 | 9 | ``` 10 | Manage Plugins > Install Plugins > search "redux-debugger" > Install 11 | ``` 12 | 13 | That'is ! 14 |
15 | 16 |
-------------------------------------------------------------------------------- /documentation/docs/3_Guides/BetaBuild.md: -------------------------------------------------------------------------------- 1 | --- 2 | slug: /BetaBuild 3 | title: Beta build 4 | --- 5 | 6 | 🚧 It's a Work In Progress section 🚧 7 | 8 | # Distributing beta builds 9 | 10 | Developers love writing React Native code but no one likes deploying React Native app or distributing beta builds. 11 | 12 | All your headaches will disappear with this documentation and the amazing [Fastlane](https://fastlane.tools/) tool :) 13 | 14 | ## Before you start 15 | 16 | You need a Mac. I'm sorry, but if you are a Windows user, you can stop reading right now. 17 | Fastlane will not work on Windows PC. But in all cases, if you need to deploy your app on IOS, you must have a Mac. 18 | 19 | Let's explain which tools we are using to distribute beta builds: 20 | 21 | - [Fastlane](https://fastlane.tools/), the easiest way to automate beta deployments and releases for your iOS and Android apps. It handles all tedious tasks like generating screenshots, dealing with code signing and releasing your application. 22 | - [TestFlight](https://developer.apple.com/testflight/), part of App Store Connect, let you build your iOS app and invite internal or external users to test it 23 | - [Google Play](https://support.google.com/googleplay/android-developer/answer/3131213?hl=fr), which does the same job as TestFlight for Android apps 24 | 25 | ``` 26 | If you love this documentation, give us a star, you will be a ray of sunshine in our lives :) 27 | ``` 28 | 29 | _This documentation is a part of a React Native project template for building solid applications through separation of concerns between the UI, state management and business logic._ _Just navigate to the [project home page](https://github.com/ozanmanav/react-native-boilerplate-ts) if you want to see more._ 30 | 31 | ## Installing Fastlane 32 | 33 | First you need to install Fastlane on your Mac. Follow these steps: 34 | 35 | 1. Install the latest Xcode command line tools: 36 | 37 | ``` 38 | $ xcode-select --install 39 | ``` 40 | 41 | 2. Install Ruby using [Homebrew](https://brew.sh/): 42 | 43 | ``` 44 | $ brew install ruby 45 | ``` 46 | 47 | 3. Install Fastlane with RubyGems: 48 | 49 | ``` 50 | $ sudo gem install fastlane -NV 51 | ``` 52 | 53 | You are now ready to set up Fastlane for iOS and Android :rocket: 54 | 55 | ## iOS 56 | 57 | ### Prerequisites 58 | 59 | Before continuing make sure you have: 60 | 61 | - [ ] Install all [required dependencies](https://facebook.github.io/react-native/docs/getting-started.html#installing-dependencies), with Xcode 9 or higher 62 | - [ ] Choose the [bundle identifier](https://cocoacasts.com/what-are-app-ids-and-bundle-identifiers/) of your app (for example `com.tcm.boilerplate`) 63 | - [ ] An Apple ID with an admin user, with its username (email, for example `dev-team@yourcompany.com`) and password 64 | - [ ] Your app name, if not already created on the Developer Portal (for example `TCM React Native Boilerplate`). Fastlane can create applications in the Developer Portal and App Store Connect, so it's recommended to let Fastlane do the job for you. 65 | - [ ] Use the right [.gitignore](https://github.com/ozanmanav/react-native-boilerplate-ts/blob/master/template/ios/.gitignore) file inside the `ios` directory 66 | - [ ] You also need to create an App Icon to use Fastlane or you will get an error on running `fastlane beta`. You can simply create one using the website [MakeAppIcon](https://makeappicon.com/) 67 | 68 | Open your Xcode project and modify some information: 69 | 70 | - [ ] In the `General` tab, `Identity` section, change the `Bundle Identifier` to your identifier (useful for Fastlane) 71 | - [ ] In the `Signing & Capabilities` tab, `Signing` section, disable `Automatically manage signing` 72 | - [ ] In the `Build Settings` tab, set view filter on top to `All` and `Combined`, then go to the `Signing` section and into `Code Signing Identity`, set `Don't Code Sign` for the `debug` line (including `Any iOS SDK` also) and set `iOS Distribution` for the `release` line (including `Any iOS SDK` also). 73 | 74 | Like this: 75 | 76 | | Code Signing Identity | < Multiple values > | 77 | | --------------------- | ------------------- | 78 | | Debug | Don't Code Sign | 79 | | Any iOS SDK | Don't Code Sign | 80 | | Release | iOS Distribution | 81 | | Any iOS SDK | iOS Distribution | 82 | 83 | ### Setting up 84 | 85 | First you need to set up Fastlane for your iOS project: 86 | 87 | ``` 88 | $ cd my-project/ios 89 | $ fastlane init 90 | ``` 91 | 92 | _Note: If you have an error on this step, please see the `issues` section._ 93 | 94 | Fastlane will automatically detect your project and ask for any missing information. 95 | 96 | The following questions will be asked: 97 | 98 | - `What would you like to use fastlane for?` 99 | - For this tutorial a good answer is `2 - Automate beta distribution to TestFlight` 100 | - `Select Scheme:` 101 | - Here we will select the scheme without `-tvOS` suffix 102 | - `Apple ID Username:` 103 | - If you don't know, you didn't read the "Prerequisites" step :) 104 | Our answer is `dev-team@yourcompany.com` 105 | - `Password (for Apple ID Username):` 106 | 107 | - If you don't know, you didn't read the "Prerequisites" step :) 108 | Our answer is `keep it secret` 109 | 110 | - If your account has multiple teams in the App Store Connect, you may have this question: `Multiple App Store Connect teams found, please enter the number of the team you want to use:` 111 | - Select the right team 112 | - If your account has multiple teams in the Developer Portal, you may have this question: `Multiple teams found on the Developer Portal, please enter the number of the team you want to use:` 113 | - Select the right team 114 | - If you haven't already created the App on the Developer Portal or App Store Connect, Fastlane can do it for you! (else you must have a message `Your app 'com.tcm.boilerplate' is available in your Apple Developer Portal / App Store Connect`) 115 | - It will ask `Do you want fastlane to create the App ID for you on the Apple Developer Portal / App Store Connect? (y/n)` 116 | - Type `y` 117 | - `App Name`: 118 | - `TCM React Native Boilerplate` 119 | 120 | Fastlane will then give you some information about git, the files it will create, etc. Just type `enter` to continue. 121 | 122 | **Congrats!** Fastlane has created some files. 123 | 124 | If you are using Git, commit all generated files. 125 | 126 | Once the setup has finished you can see a new folder inside the `ios` folder: 127 | 128 | ``` 129 | - fastlane/ 130 | - Appfile 131 | - Fastfile 132 | ``` 133 | 134 | It's not finish, you need to follow `Code Signing` part to setting up a provisioning profile. 135 | 136 | For information: 137 | 138 | `Appfile` contains identifiers used to connect to the Developer Portal and App Store Connect. You can read more about this file [here](https://docs.fastlane.tools/advanced/#appfile). 139 | 140 | `Fastfile` contains all actions you can launch. You can read more about this file [here](https://docs.fastlane.tools/actions). Because we previously chose `Automate beta distribution to TestFlight` on set up, a `beta` [lane](https://docs.fastlane.tools/advanced/lanes/) is available by default. This `lane` contains 3 actions: 141 | 142 | - increment the build number of your app 143 | - build your app 144 | - upload to TestFlight 145 | 146 | ### Code signing 147 | 148 | Signing your app assures users that it is from a known source and the app hasn’t been modified since it was last signed. Before your app can integrate app services, be installed on a device, or be submitted to the App Store, it must be signed with a certificate issued by Apple. 149 | 150 | A full guide is available on the fastlane doc, describing the best approaches for your [code signing process](https://docs.fastlane.tools/codesigning/getting-started/). 151 | 152 | Using `match` is probably [the best solution](https://codesigning.guide/). 153 | Because we don't want to revoke our existing certificates, but still want an automated setup, we will use [cert and sigh](https://docs.fastlane.tools/codesigning/getting-started/#using-cert-and-sigh). 154 | 155 | Add the following lines to your `Fastfile`, just after the `increment_build_number` function and before `build_app` (Note that you will need to replace some information): 156 | 157 | ``` 158 | get_certificates( # Create or get certificate, and install it 159 | output_path: "./builds" # Download certificate in the build folder (you don't need to create the folder) 160 | ) 161 | get_provisioning_profile( # Create or get provisioning profile 162 | output_path: "./builds", # Download provisioning profile in the build folder 163 | filename: "provisioning.mobileprovision" # Rename the local provisioning profile 164 | ) 165 | update_project_provisioning( # Set the project provisioning profile (related in Xcode to the General > Signing Release section) 166 | xcodeproj: "Boilerplate.xcodeproj", 167 | target_filter: "Boilerplate", # Name of your project 168 | profile: "./builds/provisioning.mobileprovision", 169 | build_configuration: "Release" 170 | ) 171 | update_project_team( # Set the right team on your project 172 | teamid: CredentialsManager::AppfileConfig.try_fetch_value(:team_id) 173 | ) 174 | ``` 175 | 176 | Then, we need to configure the provisioning profile for the build step. 177 | 178 | Add the following lines to your `Fastfile`, inside the `build_app` function, just after the `scheme` parameter (Make sure you add a `,` after the `scheme` parameter): 179 | 180 | ``` 181 | clean: true, 182 | export_method: "app-store", 183 | export_options: { 184 | provisioningProfiles: { 185 | CredentialsManager::AppfileConfig.try_fetch_value(:app_identifier) => CredentialsManager::AppfileConfig.try_fetch_value(:app_identifier) + " AppStore" # Value of this parameter is the name of the Provisioning Profile. By default, it will be "{bundleId} AppStore" 186 | } 187 | }, 188 | build_path: "./builds", 189 | output_directory: "./builds" 190 | ``` 191 | 192 | Thanks to this the Certificates and Provisioning Profile will be automatically created when you will create a beta build! 193 | :rocket: You are now ready to create your first beta build. 194 | 195 | ### Creating a beta build 196 | 197 | Creating a beta build and uploading it on TestFlight is now really easy. 198 | Just type the following: 199 | 200 | ``` 201 | $ cd my-project/ios 202 | $ fastlane beta 203 | ``` 204 | 205 | ## Android 206 | 207 | ### Prerequisites 208 | 209 | Before continuing make sure you have: 210 | 211 | - [ ] A Google Play Console _admin_ account and its username (email, for example `dev-team@yourcompany.com`) and password 212 | - [ ] Create your application in the Google Play Console (unlike for iOS Fastlane cannot do that for you) 213 | - [ ] Use the right [.gitignore](https://github.com/ozanmanav/react-native-boilerplate-ts/blob/master/template/android/.gitignore) file inside the `android` directory (if you are using this boilerplate you are good to go) 214 | - [ ] [Collect your Google Credentials](https://docs.fastlane.tools/getting-started/android/setup/#collect-your-google-credentials) 215 | :warning: In the Google Play Console, add the parameter `&hl=en` at the end of the URL (before any #) to switch to English. In some languages, the "Create Service Account" will not be available. Download the JSON key file, and copy it into `my-project/android/key.json` 216 | - [ ] Install [all dependencies](https://facebook.github.io/react-native/docs/getting-started.html#installing-dependencies-1) for macOS and Android 217 | 218 | ### Setting up 219 | 220 | First you need to set up Fastlane for your android project: 221 | 222 | ``` 223 | $ cd my-project/android 224 | $ fastlane init 225 | ``` 226 | 227 | Fastlane will automatically detect your project and ask for any missing information. 228 | 229 | The following questions will be asked: 230 | 231 | - `Package Name (com.krausefx.app)` 232 | - Our answer is `com.tcm.boilerplate` 233 | - `Path to the json secret file` 234 | - Type `key.json` (path to the file previously created in the Prerequisites step) 235 | - Download existing metadata and setup metadata management? 236 | - `y` 237 | 238 | Fastlane will then give you some information about git, the files it will create, etc. Just type `enter` to continue. 239 | 240 | Congrats! Fastlane has created some files. 241 | If you are using Git, commit all generated files. 242 | 243 | Once the setup has finished you can see a new folder inside the `android` folder: 244 | 245 | ``` 246 | - fastlane/ 247 | - Appfile 248 | - Fastfile 249 | ``` 250 | 251 | `Appfile` contains identifiers used to connect to the Google Play Console and the link to the `key.json` file. 252 | You can read more about this file [here](https://docs.fastlane.tools/advanced/#appfile). 253 | 254 | `Fastfile` contains all actions you can launch. You can read more about this file [here](https://docs.fastlane.tools/actions). 255 | A `beta [lane](https://docs.fastlane.tools/advanced/lanes/)`, a `deploy lane` and a `test lane` are available by default. 256 | 257 | You can remove the `deploy lane` to avoid some mistakes, and replace the `beta` lane by the following: 258 | 259 | ``` 260 | desc "Submit a new Beta Build to Play Store" 261 | lane :beta do 262 | store_password = prompt(text: "Signing Store Password: ", secure_text: true) 263 | key_password = prompt(text: "Alias Key Password: ", secure_text: true) 264 | releaseFilePath = File.join(Dir.pwd, "..", "my-release-key.keystore") 265 | gradle(task: 'clean') 266 | gradle( 267 | task: 'assemble', 268 | build_type: 'Release', 269 | print_command: false, 270 | properties: { 271 | "android.injected.signing.store.file" => releaseFilePath, 272 | "android.injected.signing.store.password" => store_password, 273 | "android.injected.signing.key.alias" => "my-key-alias", 274 | "android.injected.signing.key.password" => key_password, 275 | } 276 | ) 277 | upload_to_play_store( 278 | track: 'internal' 279 | ) 280 | ``` 281 | 282 | As you can see, we need to sign our APK with a signing key. Don't worry, we will generate it in a moment, let's just explain what the lane do. 283 | 284 | First, script ask the user two values : signing store and alias key passwords, with the [`prompt`](https://docs.fastlane.tools/actions/prompt/) fastlane plugin. Asking the user those passwords ensure that no secret keys are stored into your app. 285 | Then, this lane clean your project, assemble the application, automatically injecting signing configuration at runtime, before uploading it in the Google Play Store. 286 | Upload is made `internally`, that means only internal testers will be allowed to download the app. You can learn more about different test types [here](https://support.google.com/googleplay/android-developer/answer/3131213). 287 | 288 | #### Generating a signing key 289 | 290 | [Official documentation](https://facebook.github.io/react-native/docs/signed-apk-android#generating-a-signing-key) well explained how to generate a signing key. 291 | 292 | You simply need to run the following : 293 | 294 | ```bash 295 | keytool -genkey -v -keystore my-release-key.keystore -alias my-key-alias -keyalg RSA -keysize 2048 -validity 10000 296 | ``` 297 | 298 | This command prompts you for passwords for the keystore and key and for the Distinguished Name fields for your key. 299 | It then generates the keystore as a file called `my-release-key.keystore` 300 | 301 | Note: Remember to keep your keystore file private and never commit it to version control. 302 | 303 | Copy the generated `my-release-key.keystore` file into the root of `android` folder. 304 | 305 | You're now good to build and deploy ! 306 | 307 | ### Creating a beta build 308 | 309 | :warning: The first time you deploy your application, you MUST upload it into Google Play Console `manually`. Google don't allow to use theirs APIs for the first upload. 310 | To do this, comment the three last lines of the `Fastfile` 311 | 312 | ``` 313 | #upload_to_play_store( 314 | # track: 'internal' 315 | # ) 316 | ``` 317 | 318 | or create a new lane without those lines. 319 | 320 | :exclamation: There is no official plugin to automatically upgrade android version code (unlike the iOS lane). 321 | Before each deployment, be sure to `manually` upgrade the `versionCode` value inside `android/app/build.gradle`. 322 | We are working on an automatic way to do this. 323 | 324 | Creating a beta build and uploading it on Google Play is now really easy. 325 | Just type the following: 326 | 327 | ``` 328 | $ cd my-project/android 329 | $ fastlane beta 330 | ``` 331 | 332 | ## Troubleshooting 333 | 334 | ### Stuck at `bundle install` or `bundle update` running `fastlane init` 335 | 336 | If the `fastlane init` process is stuck when running `bundle install` or `bundle update` it may mean that `bundle` command is asking for root permissions. 337 | You can stop the process and retry again with `sudo fastlane init`, however you will need to change back ownership of the generated files to your user when it finishes by running this command: 338 | 339 | ``` 340 | $ sudo chown 341 | ``` 342 | 343 | ### Permission denied running android beta lane 344 | 345 | If you have a `Permission denied` issue on an android beta build, please run: 346 | 347 | ``` 348 | $ chmod a+x /my-project/android/gradlew 349 | ``` 350 | 351 | ### Fastlane init failed 352 | 353 | ``` 354 | fastlane init failed 355 | ["The request could not be completed because:", "Could not receive latest API key from App Store Connect, this might be a server issue."] 356 | Something failed while running `fastlane init` 357 | Tried using Apple ID with email 'dev-team@yourcompany.com' 358 | You can either retry, or fallback to manual setup which will create a basic Fastfile 359 | Would you like to fallback to a manual Fastfile? (y/n) 360 | ``` 361 | 362 | Answer `n`, and retry previous steps with a correct Apple ID and password. 363 | Make sure you are connected to internet. 364 | 365 | --- 366 | 367 | If you need more informations, don't hesitate to read the [fastlane documentation](https://docs.fastlane.tools/) 368 | -------------------------------------------------------------------------------- /documentation/docs/assets/Flipper.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozanmanav/react-native-boilerplate-ts/8a60dc96ecb304a4dc87a12d8bc393f6ccae3811/documentation/docs/assets/Flipper.png -------------------------------------------------------------------------------- /documentation/docs/assets/TOM-Legend.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozanmanav/react-native-boilerplate-ts/8a60dc96ecb304a4dc87a12d8bc393f6ccae3811/documentation/docs/assets/TOM-Legend.png -------------------------------------------------------------------------------- /documentation/docs/assets/TOM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozanmanav/react-native-boilerplate-ts/8a60dc96ecb304a4dc87a12d8bc393f6ccae3811/documentation/docs/assets/TOM.png -------------------------------------------------------------------------------- /documentation/docs/assets/Theme/Layout/Column/C1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozanmanav/react-native-boilerplate-ts/8a60dc96ecb304a4dc87a12d8bc393f6ccae3811/documentation/docs/assets/Theme/Layout/Column/C1.png -------------------------------------------------------------------------------- /documentation/docs/assets/Theme/Layout/Column/C2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozanmanav/react-native-boilerplate-ts/8a60dc96ecb304a4dc87a12d8bc393f6ccae3811/documentation/docs/assets/Theme/Layout/Column/C2.png -------------------------------------------------------------------------------- /documentation/docs/assets/Theme/Layout/Column/C3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozanmanav/react-native-boilerplate-ts/8a60dc96ecb304a4dc87a12d8bc393f6ccae3811/documentation/docs/assets/Theme/Layout/Column/C3.png -------------------------------------------------------------------------------- /documentation/docs/assets/Theme/Layout/Column/C4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozanmanav/react-native-boilerplate-ts/8a60dc96ecb304a4dc87a12d8bc393f6ccae3811/documentation/docs/assets/Theme/Layout/Column/C4.png -------------------------------------------------------------------------------- /documentation/docs/assets/Theme/Layout/Column/C5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozanmanav/react-native-boilerplate-ts/8a60dc96ecb304a4dc87a12d8bc393f6ccae3811/documentation/docs/assets/Theme/Layout/Column/C5.png -------------------------------------------------------------------------------- /documentation/docs/assets/Theme/Layout/Row/R1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozanmanav/react-native-boilerplate-ts/8a60dc96ecb304a4dc87a12d8bc393f6ccae3811/documentation/docs/assets/Theme/Layout/Row/R1.png -------------------------------------------------------------------------------- /documentation/docs/assets/Theme/Layout/Row/R2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozanmanav/react-native-boilerplate-ts/8a60dc96ecb304a4dc87a12d8bc393f6ccae3811/documentation/docs/assets/Theme/Layout/Row/R2.png -------------------------------------------------------------------------------- /documentation/docs/assets/Theme/Layout/Row/R3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozanmanav/react-native-boilerplate-ts/8a60dc96ecb304a4dc87a12d8bc393f6ccae3811/documentation/docs/assets/Theme/Layout/Row/R3.png -------------------------------------------------------------------------------- /documentation/docs/assets/Theme/Layout/Row/R4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozanmanav/react-native-boilerplate-ts/8a60dc96ecb304a4dc87a12d8bc393f6ccae3811/documentation/docs/assets/Theme/Layout/Row/R4.png -------------------------------------------------------------------------------- /documentation/docs/assets/Theme/Layout/Row/R5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozanmanav/react-native-boilerplate-ts/8a60dc96ecb304a4dc87a12d8bc393f6ccae3811/documentation/docs/assets/Theme/Layout/Row/R5.png -------------------------------------------------------------------------------- /documentation/docs/assets/Theme/Text/textCenter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozanmanav/react-native-boilerplate-ts/8a60dc96ecb304a4dc87a12d8bc393f6ccae3811/documentation/docs/assets/Theme/Text/textCenter.png -------------------------------------------------------------------------------- /documentation/docs/assets/Theme/Text/textJustify.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozanmanav/react-native-boilerplate-ts/8a60dc96ecb304a4dc87a12d8bc393f6ccae3811/documentation/docs/assets/Theme/Text/textJustify.png -------------------------------------------------------------------------------- /documentation/docs/assets/Theme/Text/textLarge.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozanmanav/react-native-boilerplate-ts/8a60dc96ecb304a4dc87a12d8bc393f6ccae3811/documentation/docs/assets/Theme/Text/textLarge.png -------------------------------------------------------------------------------- /documentation/docs/assets/Theme/Text/textLeft.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozanmanav/react-native-boilerplate-ts/8a60dc96ecb304a4dc87a12d8bc393f6ccae3811/documentation/docs/assets/Theme/Text/textLeft.png -------------------------------------------------------------------------------- /documentation/docs/assets/Theme/Text/textRegular.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozanmanav/react-native-boilerplate-ts/8a60dc96ecb304a4dc87a12d8bc393f6ccae3811/documentation/docs/assets/Theme/Text/textRegular.png -------------------------------------------------------------------------------- /documentation/docs/assets/Theme/Text/textRight.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozanmanav/react-native-boilerplate-ts/8a60dc96ecb304a4dc87a12d8bc393f6ccae3811/documentation/docs/assets/Theme/Text/textRight.png -------------------------------------------------------------------------------- /documentation/docs/assets/Theme/Text/textSmall.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozanmanav/react-native-boilerplate-ts/8a60dc96ecb304a4dc87a12d8bc393f6ccae3811/documentation/docs/assets/Theme/Text/textSmall.png -------------------------------------------------------------------------------- /documentation/docs/assets/Theme/Text/titleLarge.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozanmanav/react-native-boilerplate-ts/8a60dc96ecb304a4dc87a12d8bc393f6ccae3811/documentation/docs/assets/Theme/Text/titleLarge.png -------------------------------------------------------------------------------- /documentation/docs/assets/Theme/Text/titleRegular.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozanmanav/react-native-boilerplate-ts/8a60dc96ecb304a4dc87a12d8bc393f6ccae3811/documentation/docs/assets/Theme/Text/titleRegular.png -------------------------------------------------------------------------------- /documentation/docs/assets/Theme/Text/titleSmall.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozanmanav/react-native-boilerplate-ts/8a60dc96ecb304a4dc87a12d8bc393f6ccae3811/documentation/docs/assets/Theme/Text/titleSmall.png -------------------------------------------------------------------------------- /documentation/docusaurus.config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 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 | * @format 8 | */ 9 | 10 | module.exports = { 11 | title: 'React Native Boilerplate', 12 | tagline: 13 | 'Ready to use react native architecture based on Separation of Concerns.', 14 | url: 'https://thecodingmachine.github.io', 15 | baseUrl: '/react-native-boilerplate/', 16 | onBrokenLinks: 'warn', 17 | favicon: 'img/favicon.png', 18 | organizationName: 'thecodingmachine', 19 | projectName: 'react-native-boilerplate', 20 | themeConfig: { 21 | navbar: { 22 | title: 'RNBoilerplate', 23 | logo: { 24 | alt: 'React Native Boilerplate', 25 | src: 'img/TOM-small.png', 26 | }, 27 | items: [ 28 | { 29 | to: 'docs/Introduction', 30 | activeBasePath: 'docs', 31 | label: 'Docs', 32 | position: 'left', 33 | }, 34 | { 35 | href: 'https://github.com/ozanmanav/react-native-boilerplate-ts', 36 | label: 'GitHub', 37 | position: 'right', 38 | }, 39 | ], 40 | }, 41 | footer: { 42 | style: 'dark', 43 | logo: { 44 | alt: 'Facebook Open Source Logo', 45 | src: 'img/TOM.png', 46 | }, 47 | copyright: `Copyright © ${new Date().getFullYear()} TheCodingMachine, Inc. Built with Docusaurus.`, 48 | }, 49 | }, 50 | presets: [ 51 | [ 52 | '@docusaurus/preset-classic', 53 | { 54 | docs: { 55 | sidebarPath: require.resolve('./sidebars.js'), 56 | editUrl: 57 | 'https://github.com/ozanmanav/react-native-boilerplate-ts/edit/master/website-documentation/docs', 58 | }, 59 | theme: { 60 | customCss: require.resolve('./src/css/custom.css'), 61 | }, 62 | }, 63 | ], 64 | ], 65 | }; 66 | -------------------------------------------------------------------------------- /documentation/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "documentation", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "docusaurus": "docusaurus", 7 | "start": "docusaurus start", 8 | "build": "docusaurus build", 9 | "swizzle": "docusaurus swizzle", 10 | "deploy": "docusaurus deploy", 11 | "serve": "docusaurus serve", 12 | "ci": "yarn lint && yarn prettier:diff", 13 | "lint": "eslint --cache \"**/*.js\" && stylelint \"**/*.css\"", 14 | "prettier": "prettier --config .prettierrc --write \"**/*.{js,md}\"", 15 | "prettier:diff": "prettier --config .prettierrc --list-different \"**/*.{js,md}\"" 16 | }, 17 | "dependencies": { 18 | "@docusaurus/core": "2.0.0-alpha.64", 19 | "@docusaurus/preset-classic": "2.0.0-alpha.64", 20 | "@mdx-js/react": "^1.5.8", 21 | "clsx": "^1.1.1", 22 | "react": "^16.8.4", 23 | "react-dom": "^16.8.4" 24 | }, 25 | "devDependencies": { 26 | "babel-eslint": "^10.0.3", 27 | "eslint": "^6.7.1", 28 | "eslint-config-airbnb": "^18.0.1", 29 | "eslint-config-prettier": "^6.7.0", 30 | "eslint-plugin-header": "^3.0.0", 31 | "eslint-plugin-import": "^2.21.2", 32 | "eslint-plugin-jsx-a11y": "^6.2.3", 33 | "eslint-plugin-react": "^7.20.0", 34 | "eslint-plugin-react-hooks": "^4.0.4", 35 | "prettier": "^2.0.2", 36 | "stylelint": "^13.2.1" 37 | }, 38 | "browserslist": { 39 | "production": [ 40 | ">0.2%", 41 | "not dead", 42 | "not op_mini all" 43 | ], 44 | "development": [ 45 | "last 1 chrome version", 46 | "last 1 firefox version", 47 | "last 1 safari version" 48 | ] 49 | } 50 | } -------------------------------------------------------------------------------- /documentation/sidebars.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 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 | * @format 8 | */ 9 | const fs = require('fs') 10 | 11 | const autoGenerated = (root = 'docs', path = root) => fs.readdirSync(path).filter(x => x !== 'assets').reduce((acc, item) => { 12 | if (fs.lstatSync(`${path}/${item}`).isDirectory()) { 13 | const listOfFilesInDirectory = autoGenerated(root, `${path}/${item}`) 14 | return { 15 | ...acc, 16 | ...listOfFilesInDirectory || {} 17 | } 18 | } 19 | 20 | const actualPath = path.split(`${root}/`)[1] || 'others' 21 | const olderValues = actualPath !== 'others' ? (acc[path.split(`${root}/`)[1]] || []) : (acc.others || []) 22 | 23 | return { 24 | ...acc, 25 | [actualPath]: [ 26 | ...olderValues, 27 | `${path.split(`${root}/`).slice(1)}/${item}`.replace(/\.[^.]*$/, ''), 28 | ] 29 | } 30 | }, {}) 31 | 32 | module.exports = { 33 | docs: Object.entries(autoGenerated()).reduce((acc, [key, value]) => { 34 | if (key !== 'others') { 35 | return [ 36 | ...acc, 37 | { 38 | type: 'category', 39 | label: key.replace(/^[^_]*_/, ''), 40 | items: value, 41 | }, 42 | ] 43 | } 44 | return [ 45 | ...acc, 46 | ...value.map(item=> ({type: 'doc', id: item.split('/').pop()})) 47 | ] 48 | }, []) 49 | }; 50 | -------------------------------------------------------------------------------- /documentation/src/css/custom.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 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 | * @format 8 | */ 9 | 10 | /** 11 | * Any CSS included here will be global. The classic template 12 | * bundles Infima by default. Infima is a CSS framework designed to 13 | * work well for content-centric websites. 14 | */ 15 | 16 | /* You can override the default Infima variables here. */ 17 | :root { 18 | --ifm-color-primary: #25c2a0; 19 | --ifm-color-primary-dark: rgb(33, 175, 144); 20 | --ifm-color-primary-darker: rgb(31, 165, 136); 21 | --ifm-color-primary-darkest: rgb(26, 136, 112); 22 | --ifm-color-primary-light: rgb(70, 203, 174); 23 | --ifm-color-primary-lighter: rgb(102, 212, 189); 24 | --ifm-color-primary-lightest: rgb(146, 224, 208); 25 | --ifm-code-font-size: 95%; 26 | } 27 | 28 | .docusaurus-highlight-code-line { 29 | background-color: rgb(72, 77, 91); 30 | display: block; 31 | margin: 0 calc(-1 * var(--ifm-pre-padding)); 32 | padding: 0 var(--ifm-pre-padding); 33 | } 34 | -------------------------------------------------------------------------------- /documentation/src/pages/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 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 | * @format 8 | */ 9 | 10 | import React from 'react'; 11 | import clsx from 'clsx'; 12 | import Layout from '@theme/Layout'; 13 | import Link from '@docusaurus/Link'; 14 | import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; 15 | import useBaseUrl from '@docusaurus/useBaseUrl'; 16 | import styles from './styles.module.css'; 17 | 18 | const features = [ 19 | { 20 | title: 'Easy to Use 👌', 21 | // imageUrl: 'img/undraw_docusaurus_mountain.svg', 22 | description: ( 23 | <> 24 | A simple starter kit with basic and well known dependencies. 25 | We provide an easy to understand example 26 | 27 | ), 28 | }, 29 | { 30 | title: 'Small to Big 📱', 31 | // imageUrl: 'img/undraw_docusaurus_tree.svg', 32 | description: ( 33 | <> 34 | A light Starterkit with solid bases to build small and large application. 35 | We decided to use only necessary dependencies but strong ones. 36 | 37 | ), 38 | }, 39 | { 40 | title: 'Powered by RN Lovers 💙', 41 | // imageUrl: 'img/undraw_docusaurus_react.svg', 42 | description: ( 43 | <> 44 | We love working on React Native ! Join the adventure 😉 45 | 46 | ), 47 | }, 48 | ]; 49 | 50 | function Feature({imageUrl, title, description}) { 51 | const imgUrl = useBaseUrl(imageUrl); 52 | return ( 53 |
54 | {imgUrl && ( 55 |
56 | {title} 57 |
58 | )} 59 |

{title}

60 |

{description}

61 |
62 | ); 63 | } 64 | 65 | function Home() { 66 | const context = useDocusaurusContext(); 67 | const {siteConfig = {}} = context; 68 | return ( 69 | 72 |
73 |
74 |

{siteConfig.title}

75 |

{siteConfig.tagline}

76 |
77 | 83 | Get Started 84 | 85 |
86 |
87 |
88 |
89 | {features && features.length > 0 && ( 90 |
91 |
92 |
93 | {features.map(({title, imageUrl, description}) => ( 94 | 100 | ))} 101 |
102 |
103 |
104 | )} 105 |
106 |
107 | ); 108 | } 109 | 110 | export default Home; 111 | -------------------------------------------------------------------------------- /documentation/src/pages/styles.module.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 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 | * @format 8 | */ 9 | 10 | /** 11 | * CSS files with the .module.css suffix will be treated as CSS modules 12 | * and scoped locally. 13 | */ 14 | 15 | .heroBanner { 16 | padding: 4rem 0; 17 | text-align: center; 18 | position: relative; 19 | overflow: hidden; 20 | } 21 | 22 | @media screen and (max-width: 966px) { 23 | .heroBanner { 24 | padding: 2rem; 25 | } 26 | } 27 | 28 | .buttons { 29 | display: flex; 30 | align-items: center; 31 | justify-content: center; 32 | } 33 | 34 | .features { 35 | display: flex; 36 | align-items: center; 37 | padding: 2rem 0; 38 | width: 100%; 39 | } 40 | 41 | .featureImage { 42 | height: 200px; 43 | width: 200px; 44 | } 45 | -------------------------------------------------------------------------------- /documentation/static/.nojekyll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozanmanav/react-native-boilerplate-ts/8a60dc96ecb304a4dc87a12d8bc393f6ccae3811/documentation/static/.nojekyll -------------------------------------------------------------------------------- /documentation/static/img/TOM-Legend.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozanmanav/react-native-boilerplate-ts/8a60dc96ecb304a4dc87a12d8bc393f6ccae3811/documentation/static/img/TOM-Legend.png -------------------------------------------------------------------------------- /documentation/static/img/TOM-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozanmanav/react-native-boilerplate-ts/8a60dc96ecb304a4dc87a12d8bc393f6ccae3811/documentation/static/img/TOM-small.png -------------------------------------------------------------------------------- /documentation/static/img/TOM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozanmanav/react-native-boilerplate-ts/8a60dc96ecb304a4dc87a12d8bc393f6ccae3811/documentation/static/img/TOM.png -------------------------------------------------------------------------------- /documentation/static/img/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozanmanav/react-native-boilerplate-ts/8a60dc96ecb304a4dc87a12d8bc393f6ccae3811/documentation/static/img/favicon.png -------------------------------------------------------------------------------- /documentation/static/img/oss_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozanmanav/react-native-boilerplate-ts/8a60dc96ecb304a4dc87a12d8bc393f6ccae3811/documentation/static/img/oss_logo.png -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@ozanmanav/react-native-boilerplate-ts", 3 | "version": "2.1.4", 4 | "description": "TheCodingMachine React Native Boilerplate With Typescript", 5 | "repository": { 6 | "type": "git", 7 | "url": "https://github.com/ozanmanav/react-native-boilerplate-ts.git" 8 | }, 9 | "author": "Ozan Manav ", 10 | "license": "MIT", 11 | "bugs": { 12 | "url": "https://github.com/ozanmanav/react-native-boilerplate-ts/issues" 13 | }, 14 | "homepage": "https://github.com/ozanmanav/react-native-boilerplate-ts#readme", 15 | "main": "post-init.script.js", 16 | "scripts": { 17 | "test": "echo \"Error: no test specified\" && exit 1" 18 | }, 19 | "keywords": [ 20 | "react", 21 | "native", 22 | "boilerplate", 23 | "thecodingmachine", 24 | "react-native", 25 | "starter-kit" 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /post-init.script.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const fs = require('fs') 4 | fs.copyFile('src/Config/index.example.ts', 'src/Config/index.ts', (err) => { 5 | if (err) throw err 6 | console.log('src/Config/index.example.ts was copied to src/Config/index.ts') 7 | }) 8 | 9 | console.log('TheCodingMachine React-Native Boilerplate initialized with success !') 10 | console.log( 11 | '' + 12 | ' .-` `:: \n' + 13 | ' `///////////// `/shhhy+- ://. /sy/ /ss/ :NMN: \n' + 14 | ' `sssssyhhhyhhy:` `yMMMMNNMMMd. osss: `hMMMh- .-` `+ss: +MMm/. \n' + 15 | ' :MMM+----. `mMMm+:-`.oo/` osssyo` `dMMMMh- ohhh- `oyy+- sMMd/. \n' + 16 | ' :MMM+` oMMN/- osssyhs`.mMMMMMh- -hds` .syy+- `hMMh:` \n' + 17 | ' :MMM+` hMMd: oss-ohhhMMMhdMMh- `. +NNm/. .dMMy:` \n' + 18 | ' :MMM+` oMMN/ oss-`shdMMd:dMMh- :-` sMMd/. -NMMo- \n' + 19 | ' :MMM+` `mMMm/` `/+:. oss- `sdMd:.hMMh- hMys- `hMMh:` -hdy-` \n' + 20 | ' :MMM+` `yMMMMdssss+ oss. `oh/- hMMh- -hyo: dMMs:` -ss+` \n' + 21 | ' .oys:` .+yhyo/- -::` `` -syo- ..` +mo- `// \n' + 22 | ' `` ``` `` `. ' 23 | ) 24 | 25 | console.log( 26 | '- If you need to read more about this boilerplate : https://thecodingmachine.github.io/react-native-boilerplate/' 27 | ) 28 | console.log( 29 | '- If you have some troubles : https://github.com/ozanmanav/react-native-boilerplate-ts/issues' 30 | ) 31 | console.log( 32 | '- If you love this boilerplate, give us a star, you will be a ray of sunshine in our lives :) https://github.com/ozanmanav/react-native-boilerplate-ts' 33 | ) 34 | -------------------------------------------------------------------------------- /template.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | // Placeholder name that will be replaced in package.json, index.json, android/, ios/ for a project name. 3 | placeholderName: 'Boilerplate', 4 | 5 | // Placeholder title that will be replaced in values.xml and Info.plist with title provided by the user. 6 | // We default this value to 'Hello App Display Name', which is default placeholder in react-native template. 7 | titlePlaceholder: 'TheCodingMachine React Native Boilerplate', 8 | 9 | // Directory with the template which will be copied and processed by React Native CLI. Template directory should have package.json with all dependencies specified, including `react-native`. 10 | templateDir: './template', 11 | 12 | // Path to script, which will be executed after initialization process, but before installing all the dependencies specified in the template. 13 | // This script runs as a shell script but you can change that (e.g. to Node) by using a shebang (see example custom template). 14 | postInitScript: './post-init.script.js', 15 | } 16 | -------------------------------------------------------------------------------- /template/__tests__/App-test.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * @format 3 | */ 4 | import 'react-native' 5 | import React from 'react' 6 | import App from '../src/App' 7 | 8 | // Note: test renderer must be required after react-native. 9 | import renderer from 'react-test-renderer' 10 | 11 | it('renders correctly', () => { 12 | renderer.create() 13 | }) 14 | -------------------------------------------------------------------------------- /template/_buckconfig: -------------------------------------------------------------------------------- 1 | 2 | [android] 3 | target = Google Inc.:Google APIs:23 4 | 5 | [maven_repositories] 6 | central = https://repo1.maven.org/maven2 7 | -------------------------------------------------------------------------------- /template/_eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | extends: ['@react-native-community'], 4 | rules: { 5 | semi: ['error', 'never'], 6 | 'object-curly-spacing': ['error', 'always'], 7 | 'array-bracket-spacing': ['error', 'never'], 8 | }, 9 | settings: { 10 | 'import/resolver': { 11 | 'babel-module': {}, 12 | }, 13 | }, 14 | } 15 | -------------------------------------------------------------------------------- /template/_flowconfig: -------------------------------------------------------------------------------- 1 | [ignore] 2 | ; We fork some components by platform 3 | .*/*[.]android.js 4 | 5 | ; Ignore "BUCK" generated dirs 6 | /\.buckd/ 7 | 8 | ; Ignore polyfills 9 | node_modules/react-native/Libraries/polyfills/.* 10 | 11 | ; These should not be required directly 12 | ; require from fbjs/lib instead: require('fbjs/lib/warning') 13 | node_modules/warning/.* 14 | 15 | ; Flow doesn't support platforms 16 | .*/Libraries/Utilities/LoadingView.js 17 | 18 | [untyped] 19 | .*/node_modules/@react-native-community/cli/.*/.* 20 | 21 | [include] 22 | 23 | [libs] 24 | node_modules/react-native/interface.js 25 | node_modules/react-native/flow/ 26 | 27 | [options] 28 | emoji=true 29 | 30 | esproposal.optional_chaining=enable 31 | esproposal.nullish_coalescing=enable 32 | 33 | module.file_ext=.js 34 | module.file_ext=.json 35 | module.file_ext=.ios.js 36 | 37 | munge_underscores=true 38 | 39 | module.name_mapper='^react-native/\(.*\)$' -> '/node_modules/react-native/\1' 40 | module.name_mapper='^@?[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> '/node_modules/react-native/Libraries/Image/RelativeImageStub' 41 | 42 | suppress_type=$FlowIssue 43 | suppress_type=$FlowFixMe 44 | suppress_type=$FlowFixMeProps 45 | suppress_type=$FlowFixMeState 46 | 47 | suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(\\)? *\\(site=[a-z,_]*react_native\\(_ios\\)?_\\(oss\\|fb\\)[a-z,_]*\\)?)\\) 48 | suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(\\)? *\\(site=[a-z,_]*react_native\\(_ios\\)?_\\(oss\\|fb\\)[a-z,_]*\\)?)\\)?:? #[0-9]+ 49 | suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError 50 | 51 | [lints] 52 | sketchy-null-number=warn 53 | sketchy-null-mixed=warn 54 | sketchy-number=warn 55 | untyped-type-import=warn 56 | nonstrict-import=warn 57 | deprecated-type=warn 58 | unsafe-getters-setters=warn 59 | unnecessary-invariant=warn 60 | signature-verification-failure=warn 61 | deprecated-utility=error 62 | 63 | [strict] 64 | deprecated-type 65 | nonstrict-import 66 | sketchy-null 67 | unclear-type 68 | unsafe-getters-setters 69 | untyped-import 70 | untyped-type-import 71 | 72 | [version] 73 | ^0.122.0 74 | -------------------------------------------------------------------------------- /template/_gitattributes: -------------------------------------------------------------------------------- 1 | *.pbxproj -text 2 | -------------------------------------------------------------------------------- /template/_gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # Xcode 6 | # 7 | build/ 8 | *.pbxuser 9 | !default.pbxuser 10 | *.mode1v3 11 | !default.mode1v3 12 | *.mode2v3 13 | !default.mode2v3 14 | *.perspectivev3 15 | !default.perspectivev3 16 | xcuserdata 17 | *.xccheckout 18 | *.moved-aside 19 | DerivedData 20 | *.hmap 21 | *.ipa 22 | *.xcuserstate 23 | 24 | # Android/IntelliJ 25 | # 26 | build/ 27 | .idea 28 | .gradle 29 | local.properties 30 | *.iml 31 | 32 | # node.js 33 | # 34 | node_modules/ 35 | npm-debug.log 36 | yarn-error.log 37 | 38 | # BUCK 39 | buck-out/ 40 | \.buckd/ 41 | *.keystore 42 | !debug.keystore 43 | 44 | # fastlane 45 | # 46 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 47 | # screenshots whenever they are needed. 48 | # For more information about the recommended setup visit: 49 | # https://docs.fastlane.tools/best-practices/source-control/ 50 | 51 | */fastlane/report.xml 52 | */fastlane/Preview.html 53 | */fastlane/screenshots 54 | 55 | # Bundle artifact 56 | *.jsbundle 57 | 58 | # CocoaPods 59 | /ios/Pods/ 60 | -------------------------------------------------------------------------------- /template/_prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | jsxBracketSameLine: false, 3 | singleQuote: true, 4 | trailingComma: 'all', 5 | semi: false, 6 | } 7 | -------------------------------------------------------------------------------- /template/_watchmanconfig: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /template/android/.gitignore: -------------------------------------------------------------------------------- 1 | # fastlane specific 2 | fastlane/report.xml 3 | 4 | # deliver temporary files 5 | fastlane/Preview.html 6 | 7 | # snapshot generated screenshots 8 | fastlane/screenshots 9 | 10 | # scan temporary files 11 | fastlane/test_output 12 | 13 | # Fastlane builds 14 | builds/* -------------------------------------------------------------------------------- /template/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 | load(":build_defs.bzl", "create_aar_targets", "create_jar_targets") 12 | 13 | lib_deps = [] 14 | 15 | create_aar_targets(glob(["libs/*.aar"])) 16 | 17 | create_jar_targets(glob(["libs/*.jar"])) 18 | 19 | android_library( 20 | name = "all-libs", 21 | exported_deps = lib_deps, 22 | ) 23 | 24 | android_library( 25 | name = "app-code", 26 | srcs = glob([ 27 | "src/main/java/**/*.java", 28 | ]), 29 | deps = [ 30 | ":all-libs", 31 | ":build_config", 32 | ":res", 33 | ], 34 | ) 35 | 36 | android_build_config( 37 | name = "build_config", 38 | package = "com.boilerplate", 39 | ) 40 | 41 | android_resource( 42 | name = "res", 43 | package = "com.boilerplate", 44 | res = "src/main/res", 45 | ) 46 | 47 | android_binary( 48 | name = "app", 49 | keystore = "//android/keystores:debug", 50 | manifest = "src/main/AndroidManifest.xml", 51 | package_type = "debug", 52 | deps = [ 53 | ":app-code", 54 | ], 55 | ) 56 | -------------------------------------------------------------------------------- /template/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. If none specified and 19 | * // "index.android.js" exists, it will be used. Otherwise "index.js" is 20 | * // default. Can be overridden with ENTRY_FILE environment variable. 21 | * entryFile: "index.android.js", 22 | * 23 | * // https://reactnative.dev/docs/performance#enable-the-ram-format 24 | * bundleCommand: "ram-bundle", 25 | * 26 | * // whether to bundle JS and assets in debug mode 27 | * bundleInDebug: false, 28 | * 29 | * // whether to bundle JS and assets in release mode 30 | * bundleInRelease: true, 31 | * 32 | * // whether to bundle JS and assets in another build variant (if configured). 33 | * // See http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Build-Variants 34 | * // The configuration property can be in the following formats 35 | * // 'bundleIn${productFlavor}${buildType}' 36 | * // 'bundleIn${buildType}' 37 | * // bundleInFreeDebug: true, 38 | * // bundleInPaidRelease: true, 39 | * // bundleInBeta: true, 40 | * 41 | * // whether to disable dev mode in custom build variants (by default only disabled in release) 42 | * // for example: to disable dev mode in the staging build type (if configured) 43 | * devDisabledInStaging: true, 44 | * // The configuration property can be in the following formats 45 | * // 'devDisabledIn${productFlavor}${buildType}' 46 | * // 'devDisabledIn${buildType}' 47 | * 48 | * // the root of your project, i.e. where "package.json" lives 49 | * root: "../../", 50 | * 51 | * // where to put the JS bundle asset in debug mode 52 | * jsBundleDirDebug: "$buildDir/intermediates/assets/debug", 53 | * 54 | * // where to put the JS bundle asset in release mode 55 | * jsBundleDirRelease: "$buildDir/intermediates/assets/release", 56 | * 57 | * // where to put drawable resources / React Native assets, e.g. the ones you use via 58 | * // require('./image.png')), in debug mode 59 | * resourcesDirDebug: "$buildDir/intermediates/res/merged/debug", 60 | * 61 | * // where to put drawable resources / React Native assets, e.g. the ones you use via 62 | * // require('./image.png')), in release mode 63 | * resourcesDirRelease: "$buildDir/intermediates/res/merged/release", 64 | * 65 | * // by default the gradle tasks are skipped if none of the JS files or assets change; this means 66 | * // that we don't look at files in android/ or ios/ to determine whether the tasks are up to 67 | * // date; if you have any other folders that you want to ignore for performance reasons (gradle 68 | * // indexes the entire tree), add them here. Alternatively, if you have JS files in android/ 69 | * // for example, you might want to remove it from here. 70 | * inputExcludes: ["android/**", "ios/**"], 71 | * 72 | * // override which node gets called and with what additional arguments 73 | * nodeExecutableAndArgs: ["node"], 74 | * 75 | * // supply additional arguments to the packager 76 | * extraPackagerArgs: [] 77 | * ] 78 | */ 79 | 80 | project.ext.react = [ 81 | enableHermes: false, // clean and rebuild if changing 82 | ] 83 | 84 | apply from: "../../node_modules/react-native/react.gradle" 85 | 86 | /** 87 | * Set this to true to create two separate APKs instead of one: 88 | * - An APK that only works on ARM devices 89 | * - An APK that only works on x86 devices 90 | * The advantage is the size of the APK is reduced by about 4MB. 91 | * Upload all the APKs to the Play Store and people will download 92 | * the correct one based on the CPU architecture of their device. 93 | */ 94 | def enableSeparateBuildPerCPUArchitecture = false 95 | 96 | /** 97 | * Run Proguard to shrink the Java bytecode in release builds. 98 | */ 99 | def enableProguardInReleaseBuilds = false 100 | 101 | /** 102 | * The preferred build flavor of JavaScriptCore. 103 | * 104 | * For example, to use the international variant, you can use: 105 | * `def jscFlavor = 'org.webkit:android-jsc-intl:+'` 106 | * 107 | * The international variant includes ICU i18n library and necessary data 108 | * allowing to use e.g. `Date.toLocaleString` and `String.localeCompare` that 109 | * give correct results when using with locales other than en-US. Note that 110 | * this variant is about 6MiB larger per architecture than default. 111 | */ 112 | def jscFlavor = 'org.webkit:android-jsc:+' 113 | 114 | /** 115 | * Whether to enable the Hermes VM. 116 | * 117 | * This should be set on project.ext.react and mirrored here. If it is not set 118 | * on project.ext.react, JavaScript will not be compiled to Hermes Bytecode 119 | * and the benefits of using Hermes will therefore be sharply reduced. 120 | */ 121 | def enableHermes = project.ext.react.get("enableHermes", false); 122 | 123 | android { 124 | compileSdkVersion rootProject.ext.compileSdkVersion 125 | 126 | compileOptions { 127 | sourceCompatibility JavaVersion.VERSION_1_8 128 | targetCompatibility JavaVersion.VERSION_1_8 129 | } 130 | 131 | defaultConfig { 132 | applicationId "com.boilerplate" 133 | minSdkVersion rootProject.ext.minSdkVersion 134 | targetSdkVersion rootProject.ext.targetSdkVersion 135 | versionCode 1 136 | versionName "1.0" 137 | } 138 | splits { 139 | abi { 140 | reset() 141 | enable enableSeparateBuildPerCPUArchitecture 142 | universalApk false // If true, also generate a universal APK 143 | include "armeabi-v7a", "x86", "arm64-v8a", "x86_64" 144 | } 145 | } 146 | signingConfigs { 147 | debug { 148 | storeFile file('debug.keystore') 149 | storePassword 'android' 150 | keyAlias 'androiddebugkey' 151 | keyPassword 'android' 152 | } 153 | } 154 | buildTypes { 155 | debug { 156 | signingConfig signingConfigs.debug 157 | } 158 | release { 159 | // Caution! In production, you need to generate your own keystore file. 160 | // see https://reactnative.dev/docs/signed-apk-android. 161 | signingConfig signingConfigs.debug 162 | minifyEnabled enableProguardInReleaseBuilds 163 | proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" 164 | } 165 | } 166 | 167 | // applicationVariants are e.g. debug, release 168 | applicationVariants.all { variant -> 169 | variant.outputs.each { output -> 170 | // For each separate APK per architecture, set a unique version code as described here: 171 | // https://developer.android.com/studio/build/configure-apk-splits.html 172 | def versionCodes = ["armeabi-v7a": 1, "x86": 2, "arm64-v8a": 3, "x86_64": 4] 173 | def abi = output.getFilter(OutputFile.ABI) 174 | if (abi != null) { // null for the universal-debug, universal-release variants 175 | output.versionCodeOverride = 176 | versionCodes.get(abi) * 1048576 + defaultConfig.versionCode 177 | } 178 | 179 | } 180 | } 181 | } 182 | 183 | dependencies { 184 | implementation fileTree(dir: "libs", include: ["*.jar"]) 185 | //noinspection GradleDynamicVersion 186 | implementation "com.facebook.react:react-native:+" // From node_modules 187 | 188 | implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.0.0" 189 | 190 | debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") { 191 | exclude group:'com.facebook.fbjni' 192 | } 193 | 194 | debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") { 195 | exclude group:'com.facebook.flipper' 196 | exclude group:'com.squareup.okhttp3', module:'okhttp' 197 | } 198 | 199 | debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}") { 200 | exclude group:'com.facebook.flipper' 201 | } 202 | 203 | if (enableHermes) { 204 | def hermesPath = "../../node_modules/hermes-engine/android/"; 205 | debugImplementation files(hermesPath + "hermes-debug.aar") 206 | releaseImplementation files(hermesPath + "hermes-release.aar") 207 | } else { 208 | implementation jscFlavor 209 | } 210 | } 211 | 212 | // Run this once to be able to run the application with BUCK 213 | // puts all compile dependencies into folder libs for BUCK to use 214 | task copyDownloadableDepsToLibs(type: Copy) { 215 | from configurations.compile 216 | into 'libs' 217 | } 218 | 219 | apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project) 220 | -------------------------------------------------------------------------------- /template/android/app/build_defs.bzl: -------------------------------------------------------------------------------- 1 | """Helper definitions to glob .aar and .jar targets""" 2 | 3 | def create_aar_targets(aarfiles): 4 | for aarfile in aarfiles: 5 | name = "aars__" + aarfile[aarfile.rindex("/") + 1:aarfile.rindex(".aar")] 6 | lib_deps.append(":" + name) 7 | android_prebuilt_aar( 8 | name = name, 9 | aar = aarfile, 10 | ) 11 | 12 | def create_jar_targets(jarfiles): 13 | for jarfile in jarfiles: 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 | -------------------------------------------------------------------------------- /template/android/app/debug.keystore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozanmanav/react-native-boilerplate-ts/8a60dc96ecb304a4dc87a12d8bc393f6ccae3811/template/android/app/debug.keystore -------------------------------------------------------------------------------- /template/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 | -------------------------------------------------------------------------------- /template/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /template/android/app/src/debug/java/com/boilerplate/ReactNativeFlipper.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | *

This source code is licensed under the MIT license found in the LICENSE file in the root 5 | * directory of this source tree. 6 | */ 7 | package com.boilerplate; 8 | 9 | import android.content.Context; 10 | import com.facebook.flipper.android.AndroidFlipperClient; 11 | import com.facebook.flipper.android.utils.FlipperUtils; 12 | import com.facebook.flipper.core.FlipperClient; 13 | import com.facebook.flipper.plugins.crashreporter.CrashReporterPlugin; 14 | import com.facebook.flipper.plugins.databases.DatabasesFlipperPlugin; 15 | import com.facebook.flipper.plugins.fresco.FrescoFlipperPlugin; 16 | import com.facebook.flipper.plugins.inspector.DescriptorMapping; 17 | import com.facebook.flipper.plugins.inspector.InspectorFlipperPlugin; 18 | import com.facebook.flipper.plugins.network.FlipperOkhttpInterceptor; 19 | import com.facebook.flipper.plugins.network.NetworkFlipperPlugin; 20 | import com.facebook.flipper.plugins.react.ReactFlipperPlugin; 21 | import com.facebook.flipper.plugins.sharedpreferences.SharedPreferencesFlipperPlugin; 22 | import com.facebook.react.ReactInstanceManager; 23 | import com.facebook.react.bridge.ReactContext; 24 | import com.facebook.react.modules.network.NetworkingModule; 25 | import okhttp3.OkHttpClient; 26 | 27 | public class ReactNativeFlipper { 28 | public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) { 29 | if (FlipperUtils.shouldEnableFlipper(context)) { 30 | final FlipperClient client = AndroidFlipperClient.getInstance(context); 31 | 32 | client.addPlugin(new InspectorFlipperPlugin(context, DescriptorMapping.withDefaults())); 33 | client.addPlugin(new ReactFlipperPlugin()); 34 | client.addPlugin(new DatabasesFlipperPlugin(context)); 35 | client.addPlugin(new SharedPreferencesFlipperPlugin(context)); 36 | client.addPlugin(CrashReporterPlugin.getInstance()); 37 | 38 | NetworkFlipperPlugin networkFlipperPlugin = new NetworkFlipperPlugin(); 39 | NetworkingModule.setCustomClientBuilder( 40 | new NetworkingModule.CustomClientBuilder() { 41 | @Override 42 | public void apply(OkHttpClient.Builder builder) { 43 | builder.addNetworkInterceptor(new FlipperOkhttpInterceptor(networkFlipperPlugin)); 44 | } 45 | }); 46 | client.addPlugin(networkFlipperPlugin); 47 | client.start(); 48 | 49 | // Fresco Plugin needs to ensure that ImagePipelineFactory is initialized 50 | // Hence we run if after all native modules have been initialized 51 | ReactContext reactContext = reactInstanceManager.getCurrentReactContext(); 52 | if (reactContext == null) { 53 | reactInstanceManager.addReactInstanceEventListener( 54 | new ReactInstanceManager.ReactInstanceEventListener() { 55 | @Override 56 | public void onReactContextInitialized(ReactContext reactContext) { 57 | reactInstanceManager.removeReactInstanceEventListener(this); 58 | reactContext.runOnNativeModulesQueueThread( 59 | new Runnable() { 60 | @Override 61 | public void run() { 62 | client.addPlugin(new FrescoFlipperPlugin()); 63 | } 64 | }); 65 | } 66 | }); 67 | } else { 68 | client.addPlugin(new FrescoFlipperPlugin()); 69 | } 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /template/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 13 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /template/android/app/src/main/ic_launcher-playstore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozanmanav/react-native-boilerplate-ts/8a60dc96ecb304a4dc87a12d8bc393f6ccae3811/template/android/app/src/main/ic_launcher-playstore.png -------------------------------------------------------------------------------- /template/android/app/src/main/java/com/boilerplate/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.boilerplate; 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. This is used to schedule 9 | * rendering of the component. 10 | */ 11 | @Override 12 | protected String getMainComponentName() { 13 | return "Boilerplate"; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /template/android/app/src/main/java/com/boilerplate/MainApplication.java: -------------------------------------------------------------------------------- 1 | package com.boilerplate; 2 | 3 | import android.app.Application; 4 | import android.content.Context; 5 | import com.facebook.react.PackageList; 6 | import com.facebook.react.ReactApplication; 7 | import com.facebook.react.ReactInstanceManager; 8 | import com.facebook.react.ReactNativeHost; 9 | import com.facebook.react.ReactPackage; 10 | import com.facebook.soloader.SoLoader; 11 | import java.lang.reflect.InvocationTargetException; 12 | import java.util.List; 13 | 14 | public class MainApplication extends Application implements ReactApplication { 15 | 16 | private final ReactNativeHost mReactNativeHost = 17 | new ReactNativeHost(this) { 18 | @Override 19 | public boolean getUseDeveloperSupport() { 20 | return BuildConfig.DEBUG; 21 | } 22 | 23 | @Override 24 | protected List getPackages() { 25 | @SuppressWarnings("UnnecessaryLocalVariable") 26 | List packages = new PackageList(this).getPackages(); 27 | // Packages that cannot be autolinked yet can be added manually here, for example: 28 | // packages.add(new MyReactNativePackage()); 29 | return packages; 30 | } 31 | 32 | @Override 33 | protected String getJSMainModuleName() { 34 | return "index"; 35 | } 36 | }; 37 | 38 | @Override 39 | public ReactNativeHost getReactNativeHost() { 40 | return mReactNativeHost; 41 | } 42 | 43 | @Override 44 | public void onCreate() { 45 | super.onCreate(); 46 | SoLoader.init(this, /* native exopackage */ false); 47 | initializeFlipper(this, getReactNativeHost().getReactInstanceManager()); 48 | } 49 | 50 | /** 51 | * Loads Flipper in React Native templates. Call this in the onCreate method with something like 52 | * initializeFlipper(this, getReactNativeHost().getReactInstanceManager()); 53 | * 54 | * @param context 55 | * @param reactInstanceManager 56 | */ 57 | private static void initializeFlipper( 58 | Context context, ReactInstanceManager reactInstanceManager) { 59 | if (BuildConfig.DEBUG) { 60 | try { 61 | /* 62 | We use reflection here to pick up the class that initializes Flipper, 63 | since Flipper library is not available in release mode 64 | */ 65 | Class aClass = Class.forName("com.boilerplate.ReactNativeFlipper"); 66 | aClass 67 | .getMethod("initializeFlipper", Context.class, ReactInstanceManager.class) 68 | .invoke(null, context, reactInstanceManager); 69 | } catch (ClassNotFoundException e) { 70 | e.printStackTrace(); 71 | } catch (NoSuchMethodException e) { 72 | e.printStackTrace(); 73 | } catch (IllegalAccessException e) { 74 | e.printStackTrace(); 75 | } catch (InvocationTargetException e) { 76 | e.printStackTrace(); 77 | } 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /template/android/app/src/main/res/drawable/splash_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozanmanav/react-native-boilerplate-ts/8a60dc96ecb304a4dc87a12d8bc393f6ccae3811/template/android/app/src/main/res/drawable/splash_icon.png -------------------------------------------------------------------------------- /template/android/app/src/main/res/drawable/splash_screen.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /template/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /template/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /template/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozanmanav/react-native-boilerplate-ts/8a60dc96ecb304a4dc87a12d8bc393f6ccae3811/template/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /template/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozanmanav/react-native-boilerplate-ts/8a60dc96ecb304a4dc87a12d8bc393f6ccae3811/template/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /template/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozanmanav/react-native-boilerplate-ts/8a60dc96ecb304a4dc87a12d8bc393f6ccae3811/template/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /template/android/app/src/main/res/mipmap-ldpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozanmanav/react-native-boilerplate-ts/8a60dc96ecb304a4dc87a12d8bc393f6ccae3811/template/android/app/src/main/res/mipmap-ldpi/ic_launcher.png -------------------------------------------------------------------------------- /template/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozanmanav/react-native-boilerplate-ts/8a60dc96ecb304a4dc87a12d8bc393f6ccae3811/template/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /template/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozanmanav/react-native-boilerplate-ts/8a60dc96ecb304a4dc87a12d8bc393f6ccae3811/template/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /template/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozanmanav/react-native-boilerplate-ts/8a60dc96ecb304a4dc87a12d8bc393f6ccae3811/template/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /template/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozanmanav/react-native-boilerplate-ts/8a60dc96ecb304a4dc87a12d8bc393f6ccae3811/template/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /template/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozanmanav/react-native-boilerplate-ts/8a60dc96ecb304a4dc87a12d8bc393f6ccae3811/template/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /template/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozanmanav/react-native-boilerplate-ts/8a60dc96ecb304a4dc87a12d8bc393f6ccae3811/template/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /template/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozanmanav/react-native-boilerplate-ts/8a60dc96ecb304a4dc87a12d8bc393f6ccae3811/template/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /template/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozanmanav/react-native-boilerplate-ts/8a60dc96ecb304a4dc87a12d8bc393f6ccae3811/template/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /template/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozanmanav/react-native-boilerplate-ts/8a60dc96ecb304a4dc87a12d8bc393f6ccae3811/template/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /template/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozanmanav/react-native-boilerplate-ts/8a60dc96ecb304a4dc87a12d8bc393f6ccae3811/template/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /template/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozanmanav/react-native-boilerplate-ts/8a60dc96ecb304a4dc87a12d8bc393f6ccae3811/template/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /template/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozanmanav/react-native-boilerplate-ts/8a60dc96ecb304a4dc87a12d8bc393f6ccae3811/template/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /template/android/app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #FFFFFF 4 | 5 | -------------------------------------------------------------------------------- /template/android/app/src/main/res/values/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #FFFFFF 4 | -------------------------------------------------------------------------------- /template/android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Boilerplate 3 | 4 | -------------------------------------------------------------------------------- /template/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 12 | 13 | -------------------------------------------------------------------------------- /template/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 = "29.0.2" 6 | minSdkVersion = 16 7 | compileSdkVersion = 29 8 | targetSdkVersion = 29 9 | } 10 | repositories { 11 | google() 12 | jcenter() 13 | } 14 | dependencies { 15 | classpath("com.android.tools.build:gradle:3.5.3") 16 | // NOTE: Do not place your application dependencies here; they belong 17 | // in the individual module build.gradle files 18 | } 19 | } 20 | 21 | allprojects { 22 | repositories { 23 | mavenLocal() 24 | maven { 25 | // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm 26 | url("$rootDir/../node_modules/react-native/android") 27 | } 28 | maven { 29 | // Android JSC is installed from npm 30 | url("$rootDir/../node_modules/jsc-android/dist") 31 | } 32 | 33 | google() 34 | jcenter() 35 | maven { url 'https://www.jitpack.io' } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /template/android/gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m 13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 14 | 15 | # When configured, Gradle will run in incubating parallel mode. 16 | # This option should only be used with decoupled projects. More details, visit 17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 18 | # org.gradle.parallel=true 19 | 20 | # AndroidX package structure to make it clearer which packages are bundled with the 21 | # Android operating system, and which are packaged with your app's APK 22 | # https://developer.android.com/topic/libraries/support-library/androidx-rn 23 | android.useAndroidX=true 24 | # Automatically convert third-party libraries to use AndroidX 25 | android.enableJetifier=true 26 | 27 | # Version of flipper SDK to use with React Native 28 | FLIPPER_VERSION=0.54.0 29 | -------------------------------------------------------------------------------- /template/android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozanmanav/react-native-boilerplate-ts/8a60dc96ecb304a4dc87a12d8bc393f6ccae3811/template/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /template/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.2-all.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /template/android/gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # 4 | # Copyright 2015 the original author or authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | ## 21 | ## Gradle start up script for UN*X 22 | ## 23 | ############################################################################## 24 | 25 | # Attempt to set APP_HOME 26 | # Resolve links: $0 may be a link 27 | PRG="$0" 28 | # Need this for relative symlinks. 29 | while [ -h "$PRG" ] ; do 30 | ls=`ls -ld "$PRG"` 31 | link=`expr "$ls" : '.*-> \(.*\)$'` 32 | if expr "$link" : '/.*' > /dev/null; then 33 | PRG="$link" 34 | else 35 | PRG=`dirname "$PRG"`"/$link" 36 | fi 37 | done 38 | SAVED="`pwd`" 39 | cd "`dirname \"$PRG\"`/" >/dev/null 40 | APP_HOME="`pwd -P`" 41 | cd "$SAVED" >/dev/null 42 | 43 | APP_NAME="Gradle" 44 | APP_BASE_NAME=`basename "$0"` 45 | 46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 48 | 49 | # Use the maximum available, or set MAX_FD != -1 to use that value. 50 | MAX_FD="maximum" 51 | 52 | warn () { 53 | echo "$*" 54 | } 55 | 56 | die () { 57 | echo 58 | echo "$*" 59 | echo 60 | exit 1 61 | } 62 | 63 | # OS specific support (must be 'true' or 'false'). 64 | cygwin=false 65 | msys=false 66 | darwin=false 67 | nonstop=false 68 | case "`uname`" in 69 | CYGWIN* ) 70 | cygwin=true 71 | ;; 72 | Darwin* ) 73 | darwin=true 74 | ;; 75 | MINGW* ) 76 | msys=true 77 | ;; 78 | NONSTOP* ) 79 | nonstop=true 80 | ;; 81 | esac 82 | 83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 84 | 85 | # Determine the Java command to use to start the JVM. 86 | if [ -n "$JAVA_HOME" ] ; then 87 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 88 | # IBM's JDK on AIX uses strange locations for the executables 89 | JAVACMD="$JAVA_HOME/jre/sh/java" 90 | else 91 | JAVACMD="$JAVA_HOME/bin/java" 92 | fi 93 | if [ ! -x "$JAVACMD" ] ; then 94 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 95 | 96 | Please set the JAVA_HOME variable in your environment to match the 97 | location of your Java installation." 98 | fi 99 | else 100 | JAVACMD="java" 101 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 102 | 103 | Please set the JAVA_HOME variable in your environment to match the 104 | location of your Java installation." 105 | fi 106 | 107 | # Increase the maximum file descriptors if we can. 108 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 109 | MAX_FD_LIMIT=`ulimit -H -n` 110 | if [ $? -eq 0 ] ; then 111 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 112 | MAX_FD="$MAX_FD_LIMIT" 113 | fi 114 | ulimit -n $MAX_FD 115 | if [ $? -ne 0 ] ; then 116 | warn "Could not set maximum file descriptor limit: $MAX_FD" 117 | fi 118 | else 119 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 120 | fi 121 | fi 122 | 123 | # For Darwin, add options to specify how the application appears in the dock 124 | if $darwin; then 125 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 126 | fi 127 | 128 | # For Cygwin or MSYS, switch paths to Windows format before running java 129 | if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then 130 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 131 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 132 | JAVACMD=`cygpath --unix "$JAVACMD"` 133 | 134 | # We build the pattern for arguments to be converted via cygpath 135 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 136 | SEP="" 137 | for dir in $ROOTDIRSRAW ; do 138 | ROOTDIRS="$ROOTDIRS$SEP$dir" 139 | SEP="|" 140 | done 141 | OURCYGPATTERN="(^($ROOTDIRS))" 142 | # Add a user-defined pattern to the cygpath arguments 143 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 144 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 145 | fi 146 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 147 | i=0 148 | for arg in "$@" ; do 149 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 150 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 151 | 152 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 153 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 154 | else 155 | eval `echo args$i`="\"$arg\"" 156 | fi 157 | i=`expr $i + 1` 158 | done 159 | case $i in 160 | 0) set -- ;; 161 | 1) set -- "$args0" ;; 162 | 2) set -- "$args0" "$args1" ;; 163 | 3) set -- "$args0" "$args1" "$args2" ;; 164 | 4) set -- "$args0" "$args1" "$args2" "$args3" ;; 165 | 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 166 | 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 167 | 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 168 | 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 169 | 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 170 | esac 171 | fi 172 | 173 | # Escape application args 174 | save () { 175 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 176 | echo " " 177 | } 178 | APP_ARGS=`save "$@"` 179 | 180 | # Collect all arguments for the java command, following the shell quoting and substitution rules 181 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 182 | 183 | exec "$JAVACMD" "$@" 184 | -------------------------------------------------------------------------------- /template/android/gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto init 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto init 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :init 68 | @rem Get command-line arguments, handling Windows variants 69 | 70 | if not "%OS%" == "Windows_NT" goto win9xME_args 71 | 72 | :win9xME_args 73 | @rem Slurp the command line arguments. 74 | set CMD_LINE_ARGS= 75 | set _SKIP=2 76 | 77 | :win9xME_args_slurp 78 | if "x%~1" == "x" goto execute 79 | 80 | set CMD_LINE_ARGS=%* 81 | 82 | :execute 83 | @rem Setup the command line 84 | 85 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 86 | 87 | @rem Execute Gradle 88 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 89 | 90 | :end 91 | @rem End local scope for the variables with windows NT shell 92 | if "%ERRORLEVEL%"=="0" goto mainEnd 93 | 94 | :fail 95 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 96 | rem the _cmd.exe /c_ return code! 97 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 98 | exit /b 1 99 | 100 | :mainEnd 101 | if "%OS%"=="Windows_NT" endlocal 102 | 103 | :omega 104 | -------------------------------------------------------------------------------- /template/android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'Boilerplate' 2 | apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings) 3 | include ':app' 4 | -------------------------------------------------------------------------------- /template/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Boilerplate", 3 | "displayName": "Boilerplate" 4 | } -------------------------------------------------------------------------------- /template/babel.config.js: -------------------------------------------------------------------------------- 1 | const presets = ['module:metro-react-native-babel-preset'] 2 | const plugins = [] 3 | 4 | plugins.push([ 5 | 'module-resolver', 6 | { 7 | root: ['./src'], 8 | extensions: ['.js', '.ts', '.tsx', '.json'], 9 | alias: { 10 | '@': './src', 11 | }, 12 | }, 13 | ]) 14 | 15 | module.exports = { 16 | presets, 17 | plugins, 18 | } 19 | -------------------------------------------------------------------------------- /template/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @format 3 | */ 4 | 5 | import { AppRegistry } from 'react-native' 6 | import App from './src/App' 7 | import { name as appName } from './app.json' 8 | 9 | AppRegistry.registerComponent(appName, () => App) 10 | -------------------------------------------------------------------------------- /template/ios/.gitignore: -------------------------------------------------------------------------------- 1 | # fastlane specific 2 | fastlane/report.xml 3 | 4 | # deliver temporary files 5 | fastlane/Preview.html 6 | 7 | # snapshot generated screenshots 8 | fastlane/screenshots 9 | 10 | # scan temporary files 11 | fastlane/test_output 12 | 13 | # fastlane builds 14 | builds/* 15 | *.xcarchive -------------------------------------------------------------------------------- /template/ios/Boilerplate-tvOS/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | NSAppTransportSecurity 26 | 27 | NSExceptionDomains 28 | 29 | localhost 30 | 31 | NSExceptionAllowsInsecureHTTPLoads 32 | 33 | 34 | 35 | 36 | NSLocationWhenInUseUsageDescription 37 | 38 | UILaunchStoryboardName 39 | LaunchScreen 40 | UIRequiredDeviceCapabilities 41 | 42 | armv7 43 | 44 | UISupportedInterfaceOrientations 45 | 46 | UIInterfaceOrientationPortrait 47 | UIInterfaceOrientationLandscapeLeft 48 | UIInterfaceOrientationLandscapeRight 49 | 50 | UIViewControllerBasedStatusBarAppearance 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /template/ios/Boilerplate-tvOSTests/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 | -------------------------------------------------------------------------------- /template/ios/Boilerplate.xcodeproj/xcshareddata/xcschemes/Boilerplate-tvOS.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 53 | 55 | 61 | 62 | 63 | 64 | 70 | 72 | 78 | 79 | 80 | 81 | 83 | 84 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /template/ios/Boilerplate.xcodeproj/xcshareddata/xcschemes/Boilerplate.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 53 | 55 | 61 | 62 | 63 | 64 | 70 | 72 | 78 | 79 | 80 | 81 | 83 | 84 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /template/ios/Boilerplate.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /template/ios/Boilerplate.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /template/ios/Boilerplate.xcworkspace/xcuserdata/ozanmanav.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozanmanav/react-native-boilerplate-ts/8a60dc96ecb304a4dc87a12d8bc393f6ccae3811/template/ios/Boilerplate.xcworkspace/xcuserdata/ozanmanav.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /template/ios/Boilerplate/AppDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @interface AppDelegate : UIResponder 5 | 6 | @property (nonatomic, strong) UIWindow *window; 7 | 8 | @end 9 | -------------------------------------------------------------------------------- /template/ios/Boilerplate/AppDelegate.m: -------------------------------------------------------------------------------- 1 | #import "AppDelegate.h" 2 | 3 | #import 4 | #import 5 | #import 6 | 7 | #ifdef FB_SONARKIT_ENABLED 8 | #import 9 | #import 10 | #import 11 | #import 12 | #import 13 | #import 14 | 15 | static void InitializeFlipper(UIApplication *application) { 16 | FlipperClient *client = [FlipperClient sharedClient]; 17 | SKDescriptorMapper *layoutDescriptorMapper = [[SKDescriptorMapper alloc] initWithDefaults]; 18 | [client addPlugin:[[FlipperKitLayoutPlugin alloc] initWithRootNode:application withDescriptorMapper:layoutDescriptorMapper]]; 19 | [client addPlugin:[[FKUserDefaultsPlugin alloc] initWithSuiteName:nil]]; 20 | [client addPlugin:[FlipperKitReactPlugin new]]; 21 | [client addPlugin:[[FlipperKitNetworkPlugin alloc] initWithNetworkAdapter:[SKIOSNetworkAdapter new]]]; 22 | [client start]; 23 | } 24 | #endif 25 | 26 | @implementation AppDelegate 27 | 28 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 29 | { 30 | #ifdef FB_SONARKIT_ENABLED 31 | InitializeFlipper(application); 32 | #endif 33 | 34 | RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions]; 35 | RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge 36 | moduleName:@"Boilerplate" 37 | initialProperties:nil]; 38 | 39 | rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1]; 40 | 41 | self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; 42 | UIViewController *rootViewController = [UIViewController new]; 43 | rootViewController.view = rootView; 44 | self.window.rootViewController = rootViewController; 45 | [self.window makeKeyAndVisible]; 46 | return YES; 47 | } 48 | 49 | - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge 50 | { 51 | #if DEBUG 52 | return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil]; 53 | #else 54 | return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; 55 | #endif 56 | } 57 | 58 | @end 59 | -------------------------------------------------------------------------------- /template/ios/Boilerplate/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "Icon-App-20x20@2x.png", 5 | "idiom" : "iphone", 6 | "scale" : "2x", 7 | "size" : "20x20" 8 | }, 9 | { 10 | "filename" : "Icon-App-20x20@3x.png", 11 | "idiom" : "iphone", 12 | "scale" : "3x", 13 | "size" : "20x20" 14 | }, 15 | { 16 | "filename" : "Icon-App-29x29@1x.png", 17 | "idiom" : "iphone", 18 | "scale" : "1x", 19 | "size" : "29x29" 20 | }, 21 | { 22 | "filename" : "Icon-App-29x29@2x.png", 23 | "idiom" : "iphone", 24 | "scale" : "2x", 25 | "size" : "29x29" 26 | }, 27 | { 28 | "filename" : "Icon-App-29x29@3x.png", 29 | "idiom" : "iphone", 30 | "scale" : "3x", 31 | "size" : "29x29" 32 | }, 33 | { 34 | "filename" : "Icon-App-40x40@2x.png", 35 | "idiom" : "iphone", 36 | "scale" : "2x", 37 | "size" : "40x40" 38 | }, 39 | { 40 | "filename" : "Icon-App-40x40@3x.png", 41 | "idiom" : "iphone", 42 | "scale" : "3x", 43 | "size" : "40x40" 44 | }, 45 | { 46 | "filename" : "Icon-App-60x60@2x.png", 47 | "idiom" : "iphone", 48 | "scale" : "2x", 49 | "size" : "60x60" 50 | }, 51 | { 52 | "filename" : "Icon-App-60x60@3x.png", 53 | "idiom" : "iphone", 54 | "scale" : "3x", 55 | "size" : "60x60" 56 | }, 57 | { 58 | "filename" : "Icon-App-20x20@1x.png", 59 | "idiom" : "ipad", 60 | "scale" : "1x", 61 | "size" : "20x20" 62 | }, 63 | { 64 | "filename" : "Icon-App-20x20@2x.png", 65 | "idiom" : "ipad", 66 | "scale" : "2x", 67 | "size" : "20x20" 68 | }, 69 | { 70 | "filename" : "Icon-App-29x29@1x.png", 71 | "idiom" : "ipad", 72 | "scale" : "1x", 73 | "size" : "29x29" 74 | }, 75 | { 76 | "filename" : "Icon-App-29x29@2x.png", 77 | "idiom" : "ipad", 78 | "scale" : "2x", 79 | "size" : "29x29" 80 | }, 81 | { 82 | "filename" : "Icon-App-40x40@1x.png", 83 | "idiom" : "ipad", 84 | "scale" : "1x", 85 | "size" : "40x40" 86 | }, 87 | { 88 | "filename" : "Icon-App-40x40@2x.png", 89 | "idiom" : "ipad", 90 | "scale" : "2x", 91 | "size" : "40x40" 92 | }, 93 | { 94 | "filename" : "Icon-App-76x76@1x.png", 95 | "idiom" : "ipad", 96 | "scale" : "1x", 97 | "size" : "76x76" 98 | }, 99 | { 100 | "filename" : "Icon-App-76x76@2x.png", 101 | "idiom" : "ipad", 102 | "scale" : "2x", 103 | "size" : "76x76" 104 | }, 105 | { 106 | "filename" : "Icon-App-83.5x83.5@2x.png", 107 | "idiom" : "ipad", 108 | "scale" : "2x", 109 | "size" : "83.5x83.5" 110 | }, 111 | { 112 | "filename" : "ItunesArtwork@2x.png", 113 | "idiom" : "ios-marketing", 114 | "scale" : "1x", 115 | "size" : "1024x1024" 116 | } 117 | ], 118 | "info" : { 119 | "author" : "xcode", 120 | "version" : 1 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /template/ios/Boilerplate/Images.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozanmanav/react-native-boilerplate-ts/8a60dc96ecb304a4dc87a12d8bc393f6ccae3811/template/ios/Boilerplate/Images.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /template/ios/Boilerplate/Images.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozanmanav/react-native-boilerplate-ts/8a60dc96ecb304a4dc87a12d8bc393f6ccae3811/template/ios/Boilerplate/Images.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /template/ios/Boilerplate/Images.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozanmanav/react-native-boilerplate-ts/8a60dc96ecb304a4dc87a12d8bc393f6ccae3811/template/ios/Boilerplate/Images.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /template/ios/Boilerplate/Images.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozanmanav/react-native-boilerplate-ts/8a60dc96ecb304a4dc87a12d8bc393f6ccae3811/template/ios/Boilerplate/Images.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /template/ios/Boilerplate/Images.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozanmanav/react-native-boilerplate-ts/8a60dc96ecb304a4dc87a12d8bc393f6ccae3811/template/ios/Boilerplate/Images.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /template/ios/Boilerplate/Images.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozanmanav/react-native-boilerplate-ts/8a60dc96ecb304a4dc87a12d8bc393f6ccae3811/template/ios/Boilerplate/Images.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /template/ios/Boilerplate/Images.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozanmanav/react-native-boilerplate-ts/8a60dc96ecb304a4dc87a12d8bc393f6ccae3811/template/ios/Boilerplate/Images.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /template/ios/Boilerplate/Images.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozanmanav/react-native-boilerplate-ts/8a60dc96ecb304a4dc87a12d8bc393f6ccae3811/template/ios/Boilerplate/Images.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /template/ios/Boilerplate/Images.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozanmanav/react-native-boilerplate-ts/8a60dc96ecb304a4dc87a12d8bc393f6ccae3811/template/ios/Boilerplate/Images.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /template/ios/Boilerplate/Images.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozanmanav/react-native-boilerplate-ts/8a60dc96ecb304a4dc87a12d8bc393f6ccae3811/template/ios/Boilerplate/Images.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /template/ios/Boilerplate/Images.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozanmanav/react-native-boilerplate-ts/8a60dc96ecb304a4dc87a12d8bc393f6ccae3811/template/ios/Boilerplate/Images.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /template/ios/Boilerplate/Images.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozanmanav/react-native-boilerplate-ts/8a60dc96ecb304a4dc87a12d8bc393f6ccae3811/template/ios/Boilerplate/Images.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /template/ios/Boilerplate/Images.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozanmanav/react-native-boilerplate-ts/8a60dc96ecb304a4dc87a12d8bc393f6ccae3811/template/ios/Boilerplate/Images.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /template/ios/Boilerplate/Images.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozanmanav/react-native-boilerplate-ts/8a60dc96ecb304a4dc87a12d8bc393f6ccae3811/template/ios/Boilerplate/Images.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /template/ios/Boilerplate/Images.xcassets/AppIcon.appiconset/ItunesArtwork@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozanmanav/react-native-boilerplate-ts/8a60dc96ecb304a4dc87a12d8bc393f6ccae3811/template/ios/Boilerplate/Images.xcassets/AppIcon.appiconset/ItunesArtwork@2x.png -------------------------------------------------------------------------------- /template/ios/Boilerplate/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /template/ios/Boilerplate/Images.xcassets/SplashIcon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "Webp.net-resizeimage (2).png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "Webp.net-resizeimage (1).png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "Webp.net-resizeimage.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /template/ios/Boilerplate/Images.xcassets/SplashIcon.imageset/Splash_icon@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozanmanav/react-native-boilerplate-ts/8a60dc96ecb304a4dc87a12d8bc393f6ccae3811/template/ios/Boilerplate/Images.xcassets/SplashIcon.imageset/Splash_icon@1x.png -------------------------------------------------------------------------------- /template/ios/Boilerplate/Images.xcassets/SplashIcon.imageset/Splash_icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozanmanav/react-native-boilerplate-ts/8a60dc96ecb304a4dc87a12d8bc393f6ccae3811/template/ios/Boilerplate/Images.xcassets/SplashIcon.imageset/Splash_icon@2x.png -------------------------------------------------------------------------------- /template/ios/Boilerplate/Images.xcassets/SplashIcon.imageset/Splash_icon@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozanmanav/react-native-boilerplate-ts/8a60dc96ecb304a4dc87a12d8bc393f6ccae3811/template/ios/Boilerplate/Images.xcassets/SplashIcon.imageset/Splash_icon@3x.png -------------------------------------------------------------------------------- /template/ios/Boilerplate/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | Boilerplate 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 | NSAppTransportSecurity 28 | 29 | NSAllowsArbitraryLoads 30 | 31 | NSExceptionDomains 32 | 33 | localhost 34 | 35 | NSExceptionAllowsInsecureHTTPLoads 36 | 37 | 38 | 39 | 40 | NSLocationWhenInUseUsageDescription 41 | 42 | UILaunchStoryboardName 43 | LaunchScreen 44 | UIRequiredDeviceCapabilities 45 | 46 | armv7 47 | 48 | UISupportedInterfaceOrientations 49 | 50 | UIInterfaceOrientationPortrait 51 | UIInterfaceOrientationLandscapeLeft 52 | UIInterfaceOrientationLandscapeRight 53 | 54 | UIViewControllerBasedStatusBarAppearance 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /template/ios/Boilerplate/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /template/ios/Boilerplate/main.m: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | #import "AppDelegate.h" 4 | 5 | int main(int argc, char * argv[]) { 6 | @autoreleasepool { 7 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /template/ios/BoilerplateTests/BoilerplateTests.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | #import 5 | #import 6 | 7 | #define TIMEOUT_SECONDS 600 8 | #define TEXT_TO_LOOK_FOR @"Welcome to React" 9 | 10 | @interface BoilerplateTests : XCTestCase 11 | 12 | @end 13 | 14 | @implementation BoilerplateTests 15 | 16 | - (BOOL)findSubviewInView:(UIView *)view matching:(BOOL(^)(UIView *view))test 17 | { 18 | if (test(view)) { 19 | return YES; 20 | } 21 | for (UIView *subview in [view subviews]) { 22 | if ([self findSubviewInView:subview matching:test]) { 23 | return YES; 24 | } 25 | } 26 | return NO; 27 | } 28 | 29 | - (void)testRendersWelcomeScreen 30 | { 31 | UIViewController *vc = [[[RCTSharedApplication() delegate] window] rootViewController]; 32 | NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS]; 33 | BOOL foundElement = NO; 34 | 35 | __block NSString *redboxError = nil; 36 | #ifdef DEBUG 37 | RCTSetLogFunction(^(RCTLogLevel level, RCTLogSource source, NSString *fileName, NSNumber *lineNumber, NSString *message) { 38 | if (level >= RCTLogLevelError) { 39 | redboxError = message; 40 | } 41 | }); 42 | #endif 43 | 44 | while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) { 45 | [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; 46 | [[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; 47 | 48 | foundElement = [self findSubviewInView:vc.view matching:^BOOL(UIView *view) { 49 | if ([view.accessibilityLabel isEqualToString:TEXT_TO_LOOK_FOR]) { 50 | return YES; 51 | } 52 | return NO; 53 | }]; 54 | } 55 | 56 | #ifdef DEBUG 57 | RCTSetLogFunction(RCTDefaultLogFunction); 58 | #endif 59 | 60 | XCTAssertNil(redboxError, @"RedBox error: %@", redboxError); 61 | XCTAssertTrue(foundElement, @"Couldn't find element with text '%@' in %d seconds", TEXT_TO_LOOK_FOR, TIMEOUT_SECONDS); 62 | } 63 | 64 | 65 | @end 66 | -------------------------------------------------------------------------------- /template/ios/BoilerplateTests/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 | -------------------------------------------------------------------------------- /template/ios/Podfile: -------------------------------------------------------------------------------- 1 | require_relative '../node_modules/react-native/scripts/react_native_pods' 2 | require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules' 3 | 4 | platform :ios, '10.0' 5 | 6 | target 'Boilerplate' do 7 | config = use_native_modules! 8 | 9 | use_react_native!(:path => config["reactNativePath"]) 10 | 11 | target 'BoilerplateTests' do 12 | inherit! :complete 13 | # Pods for testing 14 | end 15 | 16 | # Enables Flipper. 17 | # 18 | # Note that if you have use_frameworks! enabled, Flipper will not work and 19 | # you should disable these next few lines. 20 | use_flipper! 21 | post_install do |installer| 22 | flipper_post_install(installer) 23 | end 24 | end 25 | 26 | target 'Boilerplate-tvOS' do 27 | # Pods for Boilerplate-tvOS 28 | 29 | target 'Boilerplate-tvOSTests' do 30 | inherit! :search_paths 31 | # Pods for testing 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /template/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | preset: 'react-native', 3 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'], 4 | } 5 | -------------------------------------------------------------------------------- /template/jest.setup.js: -------------------------------------------------------------------------------- 1 | import mockAsyncStorage from '@react-native-async-storage/async-storage/jest/async-storage-mock' 2 | 3 | jest.mock('@react-native-async-storage/async-storage', () => mockAsyncStorage) 4 | -------------------------------------------------------------------------------- /template/metro.config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Metro configuration for React Native 3 | * https://github.com/facebook/react-native 4 | * 5 | * @format 6 | */ 7 | 8 | module.exports = { 9 | transformer: { 10 | getTransformOptions: async () => ({ 11 | transform: { 12 | experimentalImportSupport: false, 13 | inlineRequires: false, 14 | }, 15 | }), 16 | }, 17 | } 18 | -------------------------------------------------------------------------------- /template/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "boilerplate", 3 | "version": "2.1.4", 4 | "private": true, 5 | "scripts": { 6 | "android": "react-native run-android", 7 | "ios": "react-native run-ios", 8 | "start": "react-native start", 9 | "test": "jest", 10 | "lint": "eslint ." 11 | }, 12 | "dependencies": { 13 | "@react-native-async-storage/async-storage": "^1.13.2", 14 | "@react-native-community/masked-view": "^0.1.10", 15 | "@react-navigation/bottom-tabs": "^5.11.1", 16 | "@react-navigation/native": "^5.8.9", 17 | "@react-navigation/stack": "^5.12.6", 18 | "@reduxjs/toolkit": "^1.4.0", 19 | "@thecodingmachine/redux-toolkit-wrapper": "^1.2.0", 20 | "@types/react-redux": "^7.1.11", 21 | "axios": "^0.21.0", 22 | "i18next": "^19.8.2", 23 | "react": "16.13.1", 24 | "react-i18next": "^11.7.3", 25 | "react-native": "0.63.3", 26 | "react-native-flipper": "^0.64.0", 27 | "react-native-gesture-handler": "^1.8.0", 28 | "react-native-reanimated": "^1.13.0", 29 | "react-native-safe-area-context": "^3.1.9", 30 | "react-native-screens": "^2.14.0", 31 | "react-redux": "^7.2.1", 32 | "redux": "^4.0.5", 33 | "redux-flipper": "^1.4.2", 34 | "redux-persist": "^6.0.0" 35 | }, 36 | "devDependencies": { 37 | "@babel/core": "^7.11.6", 38 | "@babel/runtime": "^7.12.5", 39 | "@react-native-community/eslint-config": "^2.0.0", 40 | "@types/jest": "^26.0.16", 41 | "@types/react": "^17.0.0", 42 | "@types/react-native": "^0.63.37", 43 | "@types/react-test-renderer": "^17.0.0", 44 | "babel-jest": "^26.6.3", 45 | "babel-plugin-module-resolver": "^4.0.0", 46 | "eslint": "^7.13.0", 47 | "eslint-import-resolver-babel-module": "^5.1.2", 48 | "eslint-plugin-import": "^2.22.0", 49 | "identity-obj-proxy": "^3.0.0", 50 | "jest": "^26.6.3", 51 | "metro-react-native-babel-preset": "^0.64.0", 52 | "react-test-renderer": "17.0.1", 53 | "typescript": "^4.1.2" 54 | }, 55 | "jest": { 56 | "preset": "react-native", 57 | "moduleFileExtensions": [ 58 | "ts", 59 | "tsx", 60 | "js", 61 | "jsx", 62 | "json", 63 | "node" 64 | ], 65 | "moduleNameMapper": { 66 | ".+\\.(css|styl|less|sass|scss|png|jpg|ttf|woff|woff2)$": "identity-obj-proxy" 67 | }, 68 | "setupFiles": [ 69 | "./jest.setup.js", 70 | "./node_modules/react-native-gesture-handler/jestSetup.js" 71 | ], 72 | "timers": "fake", 73 | "testEnvironment": "jsdom" 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /template/src/App.tsx: -------------------------------------------------------------------------------- 1 | import 'react-native-gesture-handler' 2 | import React from 'react' 3 | import { Provider } from 'react-redux' 4 | import { PersistGate } from 'redux-persist/lib/integration/react' 5 | import { store, persistor } from '@/Store' 6 | import { SafeAreaView, StatusBar } from 'react-native' 7 | import { NavigationContainer } from '@react-navigation/native' 8 | import { ApplicationNavigator } from '@/Navigators' 9 | import { navigationRef } from '@/Navigators/Root' 10 | import { Layout } from '@/Theme' 11 | import './Translations' 12 | 13 | const App = () => ( 14 | 15 | {/** 16 | * PersistGate delays the rendering of the app's UI until the persisted state has been retrieved 17 | * and saved to redux. 18 | * The `loading` prop can be `null` or any react instance to show during loading (e.g. a splash screen), 19 | * for example `loading={}`. 20 | * @see https://github.com/rt2zz/redux-persist/blob/master/docs/PersistGate.md 21 | */} 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | ) 32 | 33 | export default App 34 | -------------------------------------------------------------------------------- /template/src/Assets/Images/TOM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozanmanav/react-native-boilerplate-ts/8a60dc96ecb304a4dc87a12d8bc393f6ccae3811/template/src/Assets/Images/TOM.png -------------------------------------------------------------------------------- /template/src/Components/Brand.tsx: -------------------------------------------------------------------------------- 1 | import React, { FunctionComponent } from 'react' 2 | import { View, Image } from 'react-native' 3 | import { Layout, Images } from '@/Theme' 4 | 5 | type BrandProps = { 6 | height?: number, 7 | width?: number, 8 | mode?: 'contain' | 'center' | 'stretch' | 'cover' | 'repeat' | undefined, 9 | } 10 | 11 | const Brand: FunctionComponent = ({ height = 200, width = 200, mode = 'contain' }) => ( 12 | 13 | 14 | 15 | ) 16 | 17 | export default Brand 18 | -------------------------------------------------------------------------------- /template/src/Components/index.tsx: -------------------------------------------------------------------------------- 1 | export { default as Brand } from './Brand' 2 | -------------------------------------------------------------------------------- /template/src/Config/.gitignore: -------------------------------------------------------------------------------- 1 | index.js -------------------------------------------------------------------------------- /template/src/Config/index.example.ts: -------------------------------------------------------------------------------- 1 | export const Config = { 2 | API_URL: 'https://jsonplaceholder.typicode.com/', 3 | } 4 | -------------------------------------------------------------------------------- /template/src/Containers/Example/Index.tsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react' 2 | import { useDispatch } from 'react-redux' 3 | import { View, ActivityIndicator, Text, TextInput } from 'react-native' 4 | 5 | import { Brand } from '@/Components' 6 | import { Common, Fonts, Gutters, Layout } from '@/Theme' 7 | import FetchOne from '@/Store/User/FetchOne' 8 | import { useSelector } from '@/Store' 9 | import { useTranslation } from 'react-i18next' 10 | 11 | const IndexExampleContainer = () => { 12 | const { t } = useTranslation() 13 | 14 | const dispatch = useDispatch() 15 | 16 | const user = useSelector((state) => state.user.item) 17 | const fetchOneUserLoading = useSelector((state) => state.user.fetchOne.loading) 18 | const fetchOneUserError = useSelector((state) => state.user.fetchOne.error) 19 | 20 | const [userId, setUserId] = useState('1') 21 | 22 | const fetch = (id: string) => { 23 | setUserId(id) 24 | dispatch(FetchOne.action(id)) 25 | } 26 | 27 | return ( 28 | 29 | 30 | 31 | {fetchOneUserLoading && } 32 | {fetchOneUserError ? ( 33 | {fetchOneUserError.message} 34 | ) : ( 35 | {t('example.helloUser', { name: user.name })} 36 | )} 37 | 38 | 47 | {t('example.labels.userId')} 48 | fetch(text)} 50 | editable={!fetchOneUserLoading} 51 | keyboardType={'number-pad'} 52 | maxLength={1} 53 | value={userId} 54 | selectTextOnFocus 55 | style={[Layout.fill, Common.textInput]} 56 | /> 57 | 58 | 59 | ) 60 | } 61 | 62 | export default IndexExampleContainer 63 | -------------------------------------------------------------------------------- /template/src/Containers/Startup/Index.tsx: -------------------------------------------------------------------------------- 1 | import React, { FunctionComponent, useEffect } from 'react' 2 | import { ActivityIndicator, View, Text } from 'react-native' 3 | import { Layout, Fonts, Gutters } from '@/Theme' 4 | import { useDispatch } from 'react-redux' 5 | import InitStartup from '@/Store/Startup/Init' 6 | import { useTranslation } from 'react-i18next' 7 | import { Brand } from '@/Components' 8 | import { StackNavigationProp } from '@react-navigation/stack' 9 | 10 | const IndexStartupContainer: FunctionComponent<{ navigation: StackNavigationProp<{}> }> = ({ 11 | navigation, 12 | }) => { 13 | const { t } = useTranslation() 14 | 15 | const dispatch = useDispatch() 16 | 17 | useEffect(() => { 18 | dispatch(InitStartup.action()) 19 | }, [dispatch]) 20 | 21 | return ( 22 | 23 | 24 | 25 | {t('welcome')} 26 | 27 | ) 28 | } 29 | 30 | export default IndexStartupContainer 31 | -------------------------------------------------------------------------------- /template/src/Containers/index.ts: -------------------------------------------------------------------------------- 1 | export { default as IndexExampleContainer } from './Example/Index' 2 | export { default as IndexStartupContainer } from './Startup/Index' 3 | -------------------------------------------------------------------------------- /template/src/Navigators/Application.tsx: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from 'react' 2 | import { createStackNavigator } from '@react-navigation/stack' 3 | import { IndexStartupContainer } from '@/Containers' 4 | import { useSelector } from '@/Store' 5 | 6 | const Stack = createStackNavigator() 7 | 8 | let MainNavigator: any 9 | 10 | // @refresh reset 11 | const ApplicationNavigator = () => { 12 | const [isApplicationLoaded, setIsApplicationLoaded] = useState(false) 13 | 14 | const applicationIsLoading = useSelector((state) => state.startup.loading) 15 | 16 | useEffect(() => { 17 | if (MainNavigator == null && !applicationIsLoading) { 18 | MainNavigator = require('@/Navigators/Main').default 19 | setIsApplicationLoaded(true) 20 | } 21 | }, [applicationIsLoading]) 22 | 23 | return ( 24 | 25 | 26 | {isApplicationLoaded && ( 27 | 34 | )} 35 | 36 | ) 37 | } 38 | 39 | export default ApplicationNavigator 40 | -------------------------------------------------------------------------------- /template/src/Navigators/Main.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { createBottomTabNavigator } from '@react-navigation/bottom-tabs' 3 | import { IndexExampleContainer } from '@/Containers' 4 | 5 | const Tab = createBottomTabNavigator() 6 | 7 | // @refresh reset 8 | const MainNavigator = () => { 9 | return ( 10 | 11 | 12 | 13 | ) 14 | } 15 | 16 | export default MainNavigator 17 | -------------------------------------------------------------------------------- /template/src/Navigators/Root.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Used to navigating without the navigation prop 3 | * @see https://reactnavigation.org/docs/navigating-without-navigation-prop/ 4 | * 5 | * You can add other navigation functions that you need and export them 6 | */ 7 | import * as React from 'react' 8 | import { CommonActions, NavigationContainerRef, ParamListBase } from '@react-navigation/native' 9 | 10 | export const navigationRef = React.createRef(); 11 | 12 | export function navigate(name: string, params: ParamListBase) { 13 | navigationRef.current?.navigate(name, params) 14 | } 15 | 16 | export function navigateAndReset(routes = [], index = 0) { 17 | navigationRef.current?.dispatch( 18 | CommonActions.reset({ 19 | index, 20 | routes, 21 | }) 22 | ) 23 | } 24 | 25 | export function navigateAndSimpleReset(name: string, index = 0) { 26 | navigationRef.current?.dispatch( 27 | CommonActions.reset({ 28 | index, 29 | routes: [{ name }], 30 | }) 31 | ) 32 | } 33 | -------------------------------------------------------------------------------- /template/src/Navigators/index.ts: -------------------------------------------------------------------------------- 1 | export { default as ApplicationNavigator } from './Application' 2 | export { default as MainNavigator } from './Main' 3 | -------------------------------------------------------------------------------- /template/src/Services/User/FetchOne.ts: -------------------------------------------------------------------------------- 1 | import api, { handleError } from '@/Services' 2 | 3 | export default async (userId: string) => { 4 | if (!userId) { 5 | return handleError({ message: 'User ID is required' }) 6 | } 7 | const response = await api.get(`users/${userId}`) 8 | return response.data 9 | } 10 | -------------------------------------------------------------------------------- /template/src/Services/User/index.ts: -------------------------------------------------------------------------------- 1 | export { default as FetchOneUserService } from './FetchOne' 2 | -------------------------------------------------------------------------------- /template/src/Services/index.ts: -------------------------------------------------------------------------------- 1 | import axios from 'axios' 2 | import { Config } from '@/Config' 3 | 4 | const instance = axios.create({ 5 | baseURL: Config.API_URL, 6 | headers: { 7 | Accept: 'application/json', 8 | 'Content-Type': 'application/json', 9 | }, 10 | timeout: 3000, 11 | }) 12 | 13 | type HandleErrorProps = { 14 | message: string, 15 | data?: any, 16 | status?: string, 17 | } 18 | 19 | export const handleError = ({ message, data, status }: HandleErrorProps) => { 20 | return Promise.reject({ message, data, status }) 21 | } 22 | 23 | instance.interceptors.response.use( 24 | (response) => response, 25 | ({ message, response: { data, status } }) => { 26 | return handleError({ message, data, status }) 27 | } 28 | ) 29 | 30 | export default instance 31 | -------------------------------------------------------------------------------- /template/src/Store/Startup/Init.ts: -------------------------------------------------------------------------------- 1 | import { 2 | buildAsyncState, 3 | buildAsyncActions, 4 | buildAsyncReducers, 5 | } from '@thecodingmachine/redux-toolkit-wrapper' 6 | import FetchOne from '@/Store/User/FetchOne' 7 | import { navigateAndSimpleReset } from '@/Navigators/Root' 8 | 9 | export default { 10 | initialState: buildAsyncState(), 11 | action: buildAsyncActions('startup/init', async (args: any, { dispatch }: any) => { 12 | // Timeout to fake waiting some process 13 | // Remove it, or keep it if you want display a beautiful splash screen ;) 14 | await new Promise((resolve) => setTimeout(resolve, 1000)) 15 | // Here we load the user 1 for example, but you can for example load the connected user 16 | await dispatch(FetchOne.action(1)) 17 | // Navigate and reset to the main navigator 18 | navigateAndSimpleReset('Main') 19 | }), 20 | reducers: buildAsyncReducers({ itemKey: null }), // We do not want to modify some item by default 21 | } 22 | -------------------------------------------------------------------------------- /template/src/Store/Startup/index.ts: -------------------------------------------------------------------------------- 1 | import { buildSlice } from '@thecodingmachine/redux-toolkit-wrapper' 2 | import InitStartup from './Init' 3 | 4 | export default buildSlice('startup', [InitStartup]).reducer 5 | -------------------------------------------------------------------------------- /template/src/Store/User/FetchOne.ts: -------------------------------------------------------------------------------- 1 | import { 2 | buildAsyncState, 3 | buildAsyncReducers, 4 | buildAsyncActions, 5 | } from '@thecodingmachine/redux-toolkit-wrapper' 6 | import fetchOneUserService from '@/Services/User/FetchOne' 7 | 8 | export default { 9 | initialState: buildAsyncState('fetchOne'), 10 | action: buildAsyncActions('user/fetchOne', fetchOneUserService), 11 | reducers: buildAsyncReducers({ 12 | errorKey: 'fetchOne.error', // Optionally, if you scoped variables, you can use a key with dot notation 13 | loadingKey: 'fetchOne.loading', 14 | }), 15 | } 16 | -------------------------------------------------------------------------------- /template/src/Store/User/index.ts: -------------------------------------------------------------------------------- 1 | import { buildSlice } from '@thecodingmachine/redux-toolkit-wrapper' 2 | import FetchOne from './FetchOne' 3 | 4 | // This state is common to all the "user" module, and can be modified by any "user" reducers 5 | const sliceInitialState = { 6 | item: {}, 7 | } 8 | 9 | export default buildSlice('user', [FetchOne], sliceInitialState).reducer 10 | -------------------------------------------------------------------------------- /template/src/Store/index.ts: -------------------------------------------------------------------------------- 1 | import AsyncStorage from '@react-native-async-storage/async-storage' 2 | import { combineReducers } from 'redux' 3 | import { 4 | persistReducer, 5 | persistStore, 6 | FLUSH, 7 | REHYDRATE, 8 | PAUSE, 9 | PERSIST, 10 | PURGE, 11 | REGISTER, 12 | } from 'redux-persist' 13 | import { configureStore } from '@reduxjs/toolkit' 14 | import { createSelectorHook } from 'react-redux' 15 | 16 | type RootStateType = { 17 | user:any; 18 | startup: any; 19 | } 20 | 21 | export const useSelector = createSelectorHook() 22 | 23 | import startup from './Startup' 24 | import user from './User' 25 | 26 | 27 | const reducers = combineReducers({ 28 | startup, 29 | user, 30 | }) 31 | 32 | const persistConfig = { 33 | key: 'root', 34 | storage: AsyncStorage, 35 | whitelist: [], 36 | } 37 | 38 | const persistedReducer = persistReducer(persistConfig, reducers) 39 | 40 | const store = configureStore({ 41 | reducer: persistedReducer, 42 | middleware: (getDefaultMiddleware) => { 43 | const middlewares = getDefaultMiddleware({ 44 | serializableCheck: { 45 | ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER], 46 | }, 47 | }) 48 | 49 | if (__DEV__ && !process.env.JEST_WORKER_ID) { 50 | const createDebugger = require('redux-flipper').default 51 | middlewares.push(createDebugger()) 52 | } 53 | 54 | return middlewares 55 | }, 56 | }) 57 | 58 | const persistor = persistStore(store) 59 | 60 | export { store, persistor } 61 | -------------------------------------------------------------------------------- /template/src/Theme/Common.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file defines the base application styles. 3 | * 4 | * Use it to define generic component styles (e.g. the default text styles, default button styles...). 5 | */ 6 | import { Colors } from './Variables' 7 | import { StyleSheet } from 'react-native' 8 | 9 | export default StyleSheet.create({ 10 | button: { 11 | backgroundColor: Colors.primary, 12 | }, 13 | backgroundPrimary: { 14 | backgroundColor: Colors.primary, 15 | }, 16 | backgroundReset: { 17 | backgroundColor: Colors.transparent, 18 | }, 19 | textInput: { 20 | borderWidth: 1, 21 | borderColor: Colors.text, 22 | backgroundColor: Colors.white, 23 | color: Colors.text, 24 | minHeight: 50, 25 | textAlign: 'center', 26 | marginTop: 10, 27 | marginBottom: 10, 28 | }, 29 | }) 30 | -------------------------------------------------------------------------------- /template/src/Theme/Fonts.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file contains all application's style relative to fonts 3 | */ 4 | import { StyleSheet } from 'react-native' 5 | import { FontSize } from './Variables' 6 | 7 | export default StyleSheet.create({ 8 | textSmall: { 9 | fontSize: FontSize.small, 10 | }, 11 | textRegular: { 12 | fontSize: FontSize.regular, 13 | }, 14 | textLarge: { 15 | fontSize: FontSize.large, 16 | }, 17 | titleSmall: { 18 | fontSize: FontSize.small * 2, 19 | fontWeight: 'bold', 20 | }, 21 | titleRegular: { 22 | fontSize: FontSize.regular * 2, 23 | fontWeight: 'bold', 24 | }, 25 | titleLarge: { 26 | fontSize: FontSize.large * 2, 27 | fontWeight: 'bold', 28 | }, 29 | textCenter: { 30 | textAlign: 'center', 31 | }, 32 | textJustify: { 33 | textAlign: 'justify', 34 | }, 35 | textLeft: { 36 | textAlign: 'left', 37 | }, 38 | textRight: { 39 | textAlign: 'right', 40 | }, 41 | }) 42 | -------------------------------------------------------------------------------- /template/src/Theme/Gutters.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file contains metric styles that are global to the application. 3 | */ 4 | import { MetricsSizes } from './Variables' 5 | import { StyleSheet } from 'react-native' 6 | 7 | /** 8 | * Generate Styles depending on MetricsSizes vars availabled at ./Theme/Variables 9 | * Styles are like : 10 | * : { 11 | * : 12 | * } 13 | * where: 14 | * : is the key of the variable included in MetricsSizes 15 | * : can be ['Bottom','Top','Right','Left','Horizontal','Vertical'] 16 | * : can be ['Margin', 'Padding'] 17 | * : is the value of the 18 | */ 19 | export default StyleSheet.create({ 20 | ...Object.entries(MetricsSizes).reduce( 21 | (acc, [key, value]) => ({ 22 | ...acc, 23 | /* Margins */ 24 | [`${key}BMargin`]: { 25 | marginBottom: value, 26 | }, 27 | [`${key}TMargin`]: { 28 | marginTop: value, 29 | }, 30 | [`${key}RMargin`]: { 31 | marginRight: value, 32 | }, 33 | [`${key}LMargin`]: { 34 | marginLeft: value, 35 | }, 36 | [`${key}VMargin`]: { 37 | marginVertical: value, 38 | }, 39 | [`${key}HMargin`]: { 40 | marginHorizontal: value, 41 | }, 42 | /* Paddings */ 43 | [`${key}BPadding`]: { 44 | paddingBottom: value, 45 | }, 46 | [`${key}TPadding`]: { 47 | paddingTop: value, 48 | }, 49 | [`${key}RPadding`]: { 50 | paddingRight: value, 51 | }, 52 | [`${key}LPadding`]: { 53 | paddingLeft: value, 54 | }, 55 | [`${key}VPadding`]: { 56 | paddingVertical: value, 57 | }, 58 | [`${key}HPadding`]: { 59 | paddingHorizontal: value, 60 | }, 61 | }), 62 | {} 63 | ), 64 | }) as { 65 | [key: string]: any, 66 | } 67 | -------------------------------------------------------------------------------- /template/src/Theme/Images.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Images should be stored in the `App/Images` directory and referenced using variables defined here. 3 | */ 4 | 5 | export default { 6 | logo: require('@/Assets/Images/TOM.png'), 7 | } 8 | -------------------------------------------------------------------------------- /template/src/Theme/Layout.ts: -------------------------------------------------------------------------------- 1 | import { StyleSheet } from 'react-native' 2 | 3 | export default StyleSheet.create({ 4 | /* Column Layouts */ 5 | column: { 6 | flexDirection: 'column', 7 | }, 8 | columnReverse: { 9 | flexDirection: 'column-reverse', 10 | }, 11 | colCenter: { 12 | flexDirection: 'column', 13 | alignItems: 'center', 14 | justifyContent: 'center', 15 | }, 16 | colVCenter: { 17 | flexDirection: 'column', 18 | alignItems: 'center', 19 | }, 20 | colHCenter: { 21 | flexDirection: 'column', 22 | justifyContent: 'center', 23 | }, 24 | /* Row Layouts */ 25 | row: { 26 | flexDirection: 'row', 27 | }, 28 | rowReverse: { 29 | flexDirection: 'row-reverse', 30 | }, 31 | rowCenter: { 32 | flexDirection: 'row', 33 | alignItems: 'center', 34 | justifyContent: 'center', 35 | }, 36 | rowVCenter: { 37 | flexDirection: 'row', 38 | justifyContent: 'center', 39 | }, 40 | rowHCenter: { 41 | flexDirection: 'row', 42 | alignItems: 'center', 43 | }, 44 | /* Default Layouts */ 45 | center: { 46 | alignItems: 'center', 47 | justifyContent: 'center', 48 | }, 49 | alignItemsCenter: { 50 | alignItems: 'center', 51 | }, 52 | alignItemsStart: { 53 | alignItems: 'flex-start', 54 | }, 55 | alignItemsStretch: { 56 | alignItems: 'stretch', 57 | }, 58 | justifyContentCenter: { 59 | justifyContent: 'center', 60 | }, 61 | justifyContentAround: { 62 | justifyContent: 'space-around', 63 | }, 64 | justifyContentBetween: { 65 | justifyContent: 'space-between', 66 | }, 67 | scrollSpaceAround: { 68 | flexGrow: 1, 69 | justifyContent: 'space-around', 70 | }, 71 | scrollSpaceBetween: { 72 | flexGrow: 1, 73 | justifyContent: 'space-between', 74 | }, 75 | selfStretch: { 76 | alignSelf: 'stretch', 77 | }, 78 | /* Sizes Layouts */ 79 | fill: { 80 | flex: 1, 81 | }, 82 | fullSize: { 83 | height: '100%', 84 | width: '100%', 85 | }, 86 | fullWidth: { 87 | width: '100%', 88 | }, 89 | fullHeight: { 90 | height: '100%', 91 | }, 92 | /* Operation Layout */ 93 | mirror: { 94 | transform: [{ scaleX: -1 }], 95 | }, 96 | rotate90: { 97 | transform: [{ rotate: '90deg' }], 98 | }, 99 | rotate90Inverse: { 100 | transform: [{ rotate: '-90deg' }], 101 | }, 102 | }) 103 | -------------------------------------------------------------------------------- /template/src/Theme/Variables.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file contains the application's variables. 3 | * 4 | * Define color, sizes, etc. here instead of duplicating them throughout the components. 5 | * That allows to change them more easily later on. 6 | */ 7 | 8 | /** 9 | * Colors 10 | */ 11 | export const Colors = { 12 | transparent: 'rgba(0,0,0,0)', 13 | // Example colors: 14 | white: '#ffffff', 15 | text: '#212529', 16 | primary: '#E14032', 17 | success: '#28a745', 18 | error: '#dc3545', 19 | } 20 | 21 | /** 22 | * FontSize 23 | */ 24 | export const FontSize = { 25 | small: 12, 26 | regular: 14, 27 | large: 18, 28 | } 29 | 30 | /** 31 | * Metrics Sizes 32 | */ 33 | const tiny = 5 // 10 34 | const small = tiny * 2 // 10 35 | const regular = tiny * 3 // 15 36 | const large = regular * 2 // 30 37 | export const MetricsSizes = { 38 | tiny, 39 | small, 40 | regular, 41 | large, 42 | } 43 | -------------------------------------------------------------------------------- /template/src/Theme/index.ts: -------------------------------------------------------------------------------- 1 | export { default as Fonts } from './Fonts' 2 | export { default as Gutters } from './Gutters' 3 | export { default as Images } from './Images' 4 | export { default as Layout } from './Layout' 5 | export { default as Common } from './Common' 6 | export { Colors, FontSize } from './Variables' 7 | -------------------------------------------------------------------------------- /template/src/Translations/index.ts: -------------------------------------------------------------------------------- 1 | import i18n from 'i18next' 2 | import { initReactI18next } from 'react-i18next' 3 | import * as resources from './resources' 4 | 5 | i18n.use(initReactI18next).init({ 6 | resources: { 7 | ...Object.entries(resources).reduce( 8 | (acc, [key, value]) => ({ 9 | ...acc, 10 | [key]: { 11 | translation: value, 12 | }, 13 | }), 14 | {}, 15 | ), 16 | }, 17 | lng: 'en', 18 | }) 19 | 20 | export default i18n 21 | -------------------------------------------------------------------------------- /template/src/Translations/resources/en.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | welcome: 'Welcome to React Native Boilerplate by TheCodingMachine', 3 | actions: { 4 | continue: 'Continue', 5 | }, 6 | example: { 7 | helloUser: 'I am a fake user, my name is {{name}}', 8 | labels: { 9 | userId: 'Enter a user id', 10 | }, 11 | }, 12 | } 13 | -------------------------------------------------------------------------------- /template/src/Translations/resources/index.ts: -------------------------------------------------------------------------------- 1 | export { default as en } from './en' 2 | -------------------------------------------------------------------------------- /template/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowJs": true, 4 | "allowSyntheticDefaultImports": true, 5 | "esModuleInterop": true, 6 | "isolatedModules": true, 7 | "jsx": "react", 8 | "lib": ["es6"], 9 | "moduleResolution": "node", 10 | "noEmit": true, 11 | "strict": true, 12 | "target": "esnext", 13 | "baseUrl": ".", 14 | "paths": { 15 | "@/*": ["./src/*"] 16 | } 17 | }, 18 | "exclude": [ 19 | "node_modules", 20 | "babel.config.js", 21 | "metro.config.js", 22 | "jest.config.js" 23 | ] 24 | } -------------------------------------------------------------------------------- /template/types.d.ts: -------------------------------------------------------------------------------- 1 | declare module '@thecodingmachine/redux-toolkit-wrapper'; --------------------------------------------------------------------------------