├── .buckconfig
├── .bundle
└── config
├── .eslintrc.js
├── .gitignore
├── .node-version
├── .prettierrc.js
├── .ruby-version
├── .watchmanconfig
├── Gemfile
├── LICENSE
├── README.md
├── __tests__
└── App-test.tsx
├── android
├── app
│ ├── _BUCK
│ ├── build.gradle
│ ├── build_defs.bzl
│ ├── debug.keystore
│ ├── proguard-rules.pro
│ └── src
│ │ ├── debug
│ │ ├── AndroidManifest.xml
│ │ └── java
│ │ │ └── com
│ │ │ └── rnzustandboilerplate
│ │ │ └── ReactNativeFlipper.java
│ │ └── main
│ │ ├── AndroidManifest.xml
│ │ ├── java
│ │ └── com
│ │ │ └── rnzustandboilerplate
│ │ │ ├── MainActivity.java
│ │ │ ├── MainApplication.java
│ │ │ └── newarchitecture
│ │ │ ├── MainApplicationReactNativeHost.java
│ │ │ ├── components
│ │ │ └── MainComponentsRegistry.java
│ │ │ └── modules
│ │ │ └── MainApplicationTurboModuleManagerDelegate.java
│ │ ├── jni
│ │ ├── CMakeLists.txt
│ │ ├── MainApplicationModuleProvider.cpp
│ │ ├── MainApplicationModuleProvider.h
│ │ ├── MainApplicationTurboModuleManagerDelegate.cpp
│ │ ├── MainApplicationTurboModuleManagerDelegate.h
│ │ ├── MainComponentsRegistry.cpp
│ │ ├── MainComponentsRegistry.h
│ │ └── OnLoad.cpp
│ │ └── res
│ │ ├── drawable
│ │ └── rn_edit_text_material.xml
│ │ ├── mipmap-hdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-mdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxxhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ └── values
│ │ ├── strings.xml
│ │ └── styles.xml
├── build.gradle
├── gradle.properties
├── gradle
│ └── wrapper
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
├── app.json
├── app
├── Entrypoint.tsx
├── assets
│ └── react-native.png
├── components
│ ├── ThemeController.tsx
│ └── index.ts
├── config
│ ├── api-config.ts
│ ├── images.ts
│ ├── metrics.ts
│ ├── styles.ts
│ └── theme-config.ts
├── lib
│ └── index.ts
├── models
│ └── api
│ │ ├── character.ts
│ │ └── login.ts
├── navigation
│ ├── NavigationService.tsx
│ ├── NavigationStack.tsx
│ └── index.tsx
├── screens
│ ├── ForgotPassword
│ │ ├── index.tsx
│ │ └── styles.ts
│ ├── Home
│ │ ├── index.tsx
│ │ └── styles.ts
│ └── Login
│ │ ├── index.tsx
│ │ └── styles.ts
├── services
│ ├── ApiService.ts
│ ├── client.ts
│ └── react-query
│ │ ├── queries
│ │ └── user.ts
│ │ └── query-client.ts
├── store
│ ├── createLoginSlice.ts
│ ├── createThemeSlice.ts
│ └── index.ts
└── utils
│ └── stringUtils.ts
├── babel.config.js
├── index.js
├── ios
├── .xcode.env
├── MaterialCommunityIcons.ttf
├── MaterialIcons.ttf
├── Podfile
├── Podfile.lock
├── RNZustandBoilerPlate.xcodeproj
│ ├── project.pbxproj
│ └── xcshareddata
│ │ └── xcschemes
│ │ └── RNZustandBoilerPlate.xcscheme
├── RNZustandBoilerPlate.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
├── RNZustandBoilerPlate
│ ├── AppDelegate.h
│ ├── AppDelegate.mm
│ ├── Images.xcassets
│ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ └── Contents.json
│ ├── Info.plist
│ ├── LaunchScreen.storyboard
│ └── main.m
└── RNZustandBoilerPlateTests
│ ├── Info.plist
│ └── RNZustandBoilerPlateTests.m
├── metro.config.js
├── package-lock.json
├── package.json
├── tsconfig.json
└── 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 |
--------------------------------------------------------------------------------
/.bundle/config:
--------------------------------------------------------------------------------
1 | BUNDLE_PATH: "vendor/bundle"
2 | BUNDLE_FORCE_RUBY_PLATFORM: 1
3 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | extends: '@react-native-community',
4 | parser: '@typescript-eslint/parser',
5 | plugins: ['@typescript-eslint'],
6 | overrides: [
7 | {
8 | files: ['*.ts', '*.tsx'],
9 | rules: {
10 | '@typescript-eslint/no-shadow': ['error'],
11 | 'no-shadow': 'off',
12 | 'no-undef': 'off',
13 | },
14 | },
15 | ],
16 | };
17 |
--------------------------------------------------------------------------------
/.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 | ios/.xcode.env.local
24 |
25 | # Android/IntelliJ
26 | #
27 | build/
28 | .idea
29 | .gradle
30 | local.properties
31 | *.iml
32 | *.hprof
33 | .cxx/
34 |
35 | # node.js
36 | #
37 | node_modules/
38 | npm-debug.log
39 | yarn-error.log
40 |
41 | # BUCK
42 | buck-out/
43 | \.buckd/
44 | *.keystore
45 | !debug.keystore
46 |
47 | # fastlane
48 | #
49 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
50 | # screenshots whenever they are needed.
51 | # For more information about the recommended setup visit:
52 | # https://docs.fastlane.tools/best-practices/source-control/
53 |
54 | **/fastlane/report.xml
55 | **/fastlane/Preview.html
56 | **/fastlane/screenshots
57 | **/fastlane/test_output
58 |
59 | # Bundle artifact
60 | *.jsbundle
61 |
62 | # Ruby / CocoaPods
63 | /ios/Pods/
64 | /vendor/bundle/
65 |
--------------------------------------------------------------------------------
/.node-version:
--------------------------------------------------------------------------------
1 | 16
2 |
--------------------------------------------------------------------------------
/.prettierrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | arrowParens: 'avoid',
3 | bracketSameLine: true,
4 | bracketSpacing: true,
5 | singleQuote: true,
6 | trailingComma: 'all',
7 | };
8 |
--------------------------------------------------------------------------------
/.ruby-version:
--------------------------------------------------------------------------------
1 | 2.7.5
2 |
--------------------------------------------------------------------------------
/.watchmanconfig:
--------------------------------------------------------------------------------
1 | {}
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | source 'https://rubygems.org'
2 |
3 | # You may use http://rbenv.org/ or https://rvm.io/ to install and use this version
4 | ruby '2.7.5'
5 |
6 | gem 'cocoapods', '~> 1.11', '>= 1.11.2'
7 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 Victor K Varghese
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 all
13 | 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 THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 🚀 React Native Query Boilerplate with Zustand (RN / Expo)
2 |
3 | [](https://facebook.github.io/react-native/)
4 | [](https://reactnavigation.org/)
5 |
6 | ## Built using
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | ## Features
23 | - [Expo](https://docs.expo.dev/) support. Check expo branch.
24 | - [Typescript](https://www.typescriptlang.org/) support.
25 | - [React Hooks](https://reactjs.org/docs/hooks-intro.html)
26 | - [React Query](https://react-query.tanstack.com)
27 | - [Zustand](https://github.com/pmndrs/zustand)
28 | - [React Navigation](https://reactnavigation.org/) with [Authentication flow](https://reactnavigation.org/docs/auth-flow) baked in & theming support.
29 | - [React Native Gesture Handler](https://github.com/kmagiera/react-native-gesture-handler)
30 | - [React Native Paper](https://callstack.github.io/react-native-paper/)- with theming support
31 | - [React Native Vector Icons](https://github.com/oblador/react-native-vector-icons)
32 | - [Jest](https://facebook.github.io/jest/)
33 | - [Eslint](http://eslint.org/) ([Airbnb config](https://github.com/airbnb/javascript/tree/master/packages/eslint-config-airbnb))
34 |
35 |
36 | ## How this looks
37 |
38 |
39 | ## Prerequisites
40 |
41 | - [Node](https://nodejs.org) v10 (it is recommended to install it via [NVM](https://github.com/creationix/nvm))
42 | - [Yarn](https://yarnpkg.com/)
43 | - A development machine set up for React Native by following [these instructions](https://facebook.github.io/react-native/docs/getting-started.html)
44 |
45 | ## Getting Started
46 |
47 | 1. Clone this repo, `git clone https://github.com/victorkvarghese/react-native-zustand-boilerplate.git `
48 | 2. Go to project's root directory, `cd `
49 | 3. Remove `.git` folder, `rm -rf .git`
50 | 4. Use [React Native Rename](https://github.com/junedomingo/react-native-rename) to update project name `$ npx react-native-rename `
51 | 5. Run `yarn` to install dependencies
52 |
53 | 6. Start the packager with `yarn start`
54 | 7. Connect a mobile device to your development machine
55 | 8. Run the test application:
56 |
57 | - On Android:
58 | - Run `react-native run-android` or Use Android Studio (Recommended)
59 | - On iOS:
60 | - Open `ios/YourReactProject.xcworkspace` in Xcode
61 | - Hit `Run` after selecting the desired device
62 |
63 | 9. Enjoy!!!
64 |
65 | ## Contributing
66 |
67 | PRs are welcome
68 |
--------------------------------------------------------------------------------
/__tests__/App-test.tsx:
--------------------------------------------------------------------------------
1 | /**
2 | * @format
3 | */
4 |
5 | import 'react-native';
6 | import React from 'react';
7 | import App from '../App';
8 |
9 | // Note: test renderer must be required after react-native.
10 | import renderer from 'react-test-renderer';
11 |
12 | it('renders correctly', () => {
13 | renderer.create();
14 | });
15 |
--------------------------------------------------------------------------------
/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.rnzustandboilerplate",
39 | )
40 |
41 | android_resource(
42 | name = "res",
43 | package = "com.rnzustandboilerplate",
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 |
--------------------------------------------------------------------------------
/android/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: "com.android.application"
2 |
3 | import com.android.build.OutputFile
4 | import org.apache.tools.ant.taskdefs.condition.Os
5 |
6 | /**
7 | * The react.gradle file registers a task for each build variant (e.g. bundleDebugJsAndAssets
8 | * and bundleReleaseJsAndAssets).
9 | * These basically call `react-native bundle` with the correct arguments during the Android build
10 | * cycle. By default, bundleDebugJsAndAssets is skipped, as in debug/dev mode we prefer to load the
11 | * bundle directly from the development server. Below you can see all the possible configurations
12 | * and their defaults. If you decide to add a configuration block, make sure to add it before the
13 | * `apply from: "../../node_modules/react-native/react.gradle"` line.
14 | *
15 | * project.ext.react = [
16 | * // the name of the generated asset file containing your JS bundle
17 | * bundleAssetName: "index.android.bundle",
18 | *
19 | * // the entry file for bundle generation. If none specified and
20 | * // "index.android.js" exists, it will be used. Otherwise "index.js" is
21 | * // default. Can be overridden with ENTRY_FILE environment variable.
22 | * entryFile: "index.android.js",
23 | *
24 | * // https://reactnative.dev/docs/performance#enable-the-ram-format
25 | * bundleCommand: "ram-bundle",
26 | *
27 | * // whether to bundle JS and assets in debug mode
28 | * bundleInDebug: false,
29 | *
30 | * // whether to bundle JS and assets in release mode
31 | * bundleInRelease: true,
32 | *
33 | * // whether to bundle JS and assets in another build variant (if configured).
34 | * // See http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Build-Variants
35 | * // The configuration property can be in the following formats
36 | * // 'bundleIn${productFlavor}${buildType}'
37 | * // 'bundleIn${buildType}'
38 | * // bundleInFreeDebug: true,
39 | * // bundleInPaidRelease: true,
40 | * // bundleInBeta: true,
41 | *
42 | * // whether to disable dev mode in custom build variants (by default only disabled in release)
43 | * // for example: to disable dev mode in the staging build type (if configured)
44 | * devDisabledInStaging: true,
45 | * // The configuration property can be in the following formats
46 | * // 'devDisabledIn${productFlavor}${buildType}'
47 | * // 'devDisabledIn${buildType}'
48 | *
49 | * // the root of your project, i.e. where "package.json" lives
50 | * root: "../../",
51 | *
52 | * // where to put the JS bundle asset in debug mode
53 | * jsBundleDirDebug: "$buildDir/intermediates/assets/debug",
54 | *
55 | * // where to put the JS bundle asset in release mode
56 | * jsBundleDirRelease: "$buildDir/intermediates/assets/release",
57 | *
58 | * // where to put drawable resources / React Native assets, e.g. the ones you use via
59 | * // require('./image.png')), in debug mode
60 | * resourcesDirDebug: "$buildDir/intermediates/res/merged/debug",
61 | *
62 | * // where to put drawable resources / React Native assets, e.g. the ones you use via
63 | * // require('./image.png')), in release mode
64 | * resourcesDirRelease: "$buildDir/intermediates/res/merged/release",
65 | *
66 | * // by default the gradle tasks are skipped if none of the JS files or assets change; this means
67 | * // that we don't look at files in android/ or ios/ to determine whether the tasks are up to
68 | * // date; if you have any other folders that you want to ignore for performance reasons (gradle
69 | * // indexes the entire tree), add them here. Alternatively, if you have JS files in android/
70 | * // for example, you might want to remove it from here.
71 | * inputExcludes: ["android/**", "ios/**"],
72 | *
73 | * // override which node gets called and with what additional arguments
74 | * nodeExecutableAndArgs: ["node"],
75 | *
76 | * // supply additional arguments to the packager
77 | * extraPackagerArgs: []
78 | * ]
79 | */
80 |
81 | project.ext.react = [
82 | enableHermes: true, // clean and rebuild if changing
83 | ]
84 |
85 | apply from: "../../node_modules/react-native/react.gradle"
86 |
87 | /**
88 | * Set this to true to create two separate APKs instead of one:
89 | * - An APK that only works on ARM devices
90 | * - An APK that only works on x86 devices
91 | * The advantage is the size of the APK is reduced by about 4MB.
92 | * Upload all the APKs to the Play Store and people will download
93 | * the correct one based on the CPU architecture of their device.
94 | */
95 | def enableSeparateBuildPerCPUArchitecture = false
96 |
97 | /**
98 | * Run Proguard to shrink the Java bytecode in release builds.
99 | */
100 | def enableProguardInReleaseBuilds = false
101 |
102 | /**
103 | * The preferred build flavor of JavaScriptCore.
104 | *
105 | * For example, to use the international variant, you can use:
106 | * `def jscFlavor = 'org.webkit:android-jsc-intl:+'`
107 | *
108 | * The international variant includes ICU i18n library and necessary data
109 | * allowing to use e.g. `Date.toLocaleString` and `String.localeCompare` that
110 | * give correct results when using with locales other than en-US. Note that
111 | * this variant is about 6MiB larger per architecture than default.
112 | */
113 | def jscFlavor = 'org.webkit:android-jsc:+'
114 |
115 | /**
116 | * Whether to enable the Hermes VM.
117 | *
118 | * This should be set on project.ext.react and that value will be read here. If it is not set
119 | * on project.ext.react, JavaScript will not be compiled to Hermes Bytecode
120 | * and the benefits of using Hermes will therefore be sharply reduced.
121 | */
122 | def enableHermes = project.ext.react.get("enableHermes", false);
123 |
124 | project.ext.vectoricons = [
125 | iconFontNames: [ 'MaterialIcons.ttf', 'MaterialCommunityIcons.ttf' ] // Name of the font files you want to copy
126 | ]
127 | apply from: "../../node_modules/react-native-vector-icons/fonts.gradle"
128 |
129 | /**
130 | * Architectures to build native code for.
131 | */
132 | def reactNativeArchitectures() {
133 | def value = project.getProperties().get("reactNativeArchitectures")
134 | return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"]
135 | }
136 |
137 | android {
138 | ndkVersion rootProject.ext.ndkVersion
139 |
140 | compileSdkVersion rootProject.ext.compileSdkVersion
141 |
142 | defaultConfig {
143 | applicationId "com.rnzustandboilerplate"
144 | minSdkVersion rootProject.ext.minSdkVersion
145 | targetSdkVersion rootProject.ext.targetSdkVersion
146 | versionCode 1
147 | versionName "1.0"
148 | buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
149 |
150 | if (isNewArchitectureEnabled()) {
151 | // We configure the CMake build only if you decide to opt-in for the New Architecture.
152 | externalNativeBuild {
153 | cmake {
154 | arguments "-DPROJECT_BUILD_DIR=$buildDir",
155 | "-DREACT_ANDROID_DIR=$rootDir/../node_modules/react-native/ReactAndroid",
156 | "-DREACT_ANDROID_BUILD_DIR=$rootDir/../node_modules/react-native/ReactAndroid/build",
157 | "-DNODE_MODULES_DIR=$rootDir/../node_modules",
158 | "-DANDROID_STL=c++_shared"
159 | }
160 | }
161 | if (!enableSeparateBuildPerCPUArchitecture) {
162 | ndk {
163 | abiFilters (*reactNativeArchitectures())
164 | }
165 | }
166 | }
167 | }
168 |
169 | if (isNewArchitectureEnabled()) {
170 | // We configure the NDK build only if you decide to opt-in for the New Architecture.
171 | externalNativeBuild {
172 | cmake {
173 | path "$projectDir/src/main/jni/CMakeLists.txt"
174 | }
175 | }
176 | def reactAndroidProjectDir = project(':ReactAndroid').projectDir
177 | def packageReactNdkDebugLibs = tasks.register("packageReactNdkDebugLibs", Copy) {
178 | dependsOn(":ReactAndroid:packageReactNdkDebugLibsForBuck")
179 | from("$reactAndroidProjectDir/src/main/jni/prebuilt/lib")
180 | into("$buildDir/react-ndk/exported")
181 | }
182 | def packageReactNdkReleaseLibs = tasks.register("packageReactNdkReleaseLibs", Copy) {
183 | dependsOn(":ReactAndroid:packageReactNdkReleaseLibsForBuck")
184 | from("$reactAndroidProjectDir/src/main/jni/prebuilt/lib")
185 | into("$buildDir/react-ndk/exported")
186 | }
187 | afterEvaluate {
188 | // If you wish to add a custom TurboModule or component locally,
189 | // you should uncomment this line.
190 | // preBuild.dependsOn("generateCodegenArtifactsFromSchema")
191 | preDebugBuild.dependsOn(packageReactNdkDebugLibs)
192 | preReleaseBuild.dependsOn(packageReactNdkReleaseLibs)
193 |
194 | // Due to a bug inside AGP, we have to explicitly set a dependency
195 | // between configureCMakeDebug* tasks and the preBuild tasks.
196 | // This can be removed once this is solved: https://issuetracker.google.com/issues/207403732
197 | configureCMakeRelWithDebInfo.dependsOn(preReleaseBuild)
198 | configureCMakeDebug.dependsOn(preDebugBuild)
199 | reactNativeArchitectures().each { architecture ->
200 | tasks.findByName("configureCMakeDebug[${architecture}]")?.configure {
201 | dependsOn("preDebugBuild")
202 | }
203 | tasks.findByName("configureCMakeRelWithDebInfo[${architecture}]")?.configure {
204 | dependsOn("preReleaseBuild")
205 | }
206 | }
207 | }
208 | }
209 |
210 | splits {
211 | abi {
212 | reset()
213 | enable enableSeparateBuildPerCPUArchitecture
214 | universalApk false // If true, also generate a universal APK
215 | include (*reactNativeArchitectures())
216 | }
217 | }
218 | signingConfigs {
219 | debug {
220 | storeFile file('debug.keystore')
221 | storePassword 'android'
222 | keyAlias 'androiddebugkey'
223 | keyPassword 'android'
224 | }
225 | }
226 | buildTypes {
227 | debug {
228 | signingConfig signingConfigs.debug
229 | }
230 | release {
231 | // Caution! In production, you need to generate your own keystore file.
232 | // see https://reactnative.dev/docs/signed-apk-android.
233 | signingConfig signingConfigs.debug
234 | minifyEnabled enableProguardInReleaseBuilds
235 | proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
236 | }
237 | }
238 |
239 | // applicationVariants are e.g. debug, release
240 | applicationVariants.all { variant ->
241 | variant.outputs.each { output ->
242 | // For each separate APK per architecture, set a unique version code as described here:
243 | // https://developer.android.com/studio/build/configure-apk-splits.html
244 | // Example: versionCode 1 will generate 1001 for armeabi-v7a, 1002 for x86, etc.
245 | def versionCodes = ["armeabi-v7a": 1, "x86": 2, "arm64-v8a": 3, "x86_64": 4]
246 | def abi = output.getFilter(OutputFile.ABI)
247 | if (abi != null) { // null for the universal-debug, universal-release variants
248 | output.versionCodeOverride =
249 | defaultConfig.versionCode * 1000 + versionCodes.get(abi)
250 | }
251 |
252 | }
253 | }
254 | }
255 |
256 | dependencies {
257 | implementation fileTree(dir: "libs", include: ["*.jar"])
258 |
259 | //noinspection GradleDynamicVersion
260 | implementation "com.facebook.react:react-native:+" // From node_modules
261 |
262 | implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.0.0"
263 |
264 | debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") {
265 | exclude group:'com.facebook.fbjni'
266 | }
267 |
268 | debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") {
269 | exclude group:'com.facebook.flipper'
270 | exclude group:'com.squareup.okhttp3', module:'okhttp'
271 | }
272 |
273 | debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}") {
274 | exclude group:'com.facebook.flipper'
275 | }
276 |
277 | if (enableHermes) {
278 | //noinspection GradleDynamicVersion
279 | implementation("com.facebook.react:hermes-engine:+") { // From node_modules
280 | exclude group:'com.facebook.fbjni'
281 | }
282 | } else {
283 | implementation jscFlavor
284 | }
285 | }
286 |
287 | if (isNewArchitectureEnabled()) {
288 | // If new architecture is enabled, we let you build RN from source
289 | // Otherwise we fallback to a prebuilt .aar bundled in the NPM package.
290 | // This will be applied to all the imported transtitive dependency.
291 | configurations.all {
292 | resolutionStrategy.dependencySubstitution {
293 | substitute(module("com.facebook.react:react-native"))
294 | .using(project(":ReactAndroid"))
295 | .because("On New Architecture we're building React Native from source")
296 | substitute(module("com.facebook.react:hermes-engine"))
297 | .using(project(":ReactAndroid:hermes-engine"))
298 | .because("On New Architecture we're building Hermes from source")
299 | }
300 | }
301 | }
302 |
303 | // Run this once to be able to run the application with BUCK
304 | // puts all compile dependencies into folder libs for BUCK to use
305 | task copyDownloadableDepsToLibs(type: Copy) {
306 | from configurations.implementation
307 | into 'libs'
308 | }
309 |
310 | apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
311 |
312 | def isNewArchitectureEnabled() {
313 | // To opt-in for the New Architecture, you can either:
314 | // - Set `newArchEnabled` to true inside the `gradle.properties` file
315 | // - Invoke gradle with `-newArchEnabled=true`
316 | // - Set an environment variable `ORG_GRADLE_PROJECT_newArchEnabled=true`
317 | return project.hasProperty("newArchEnabled") && project.newArchEnabled == "true"
318 | }
319 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/android/app/debug.keystore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/victorkvarghese/react-native-query-boilerplate/22f95fa286082a284a2dbd0ecf7433c487b7925d/android/app/debug.keystore
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/android/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/android/app/src/debug/java/com/rnzustandboilerplate/ReactNativeFlipper.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) Meta Platforms, Inc. and 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.rnzustandboilerplate;
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.ReactInstanceEventListener;
23 | import com.facebook.react.ReactInstanceManager;
24 | import com.facebook.react.bridge.ReactContext;
25 | import com.facebook.react.modules.network.NetworkingModule;
26 | import okhttp3.OkHttpClient;
27 |
28 | public class ReactNativeFlipper {
29 | public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) {
30 | if (FlipperUtils.shouldEnableFlipper(context)) {
31 | final FlipperClient client = AndroidFlipperClient.getInstance(context);
32 |
33 | client.addPlugin(new InspectorFlipperPlugin(context, DescriptorMapping.withDefaults()));
34 | client.addPlugin(new ReactFlipperPlugin());
35 | client.addPlugin(new DatabasesFlipperPlugin(context));
36 | client.addPlugin(new SharedPreferencesFlipperPlugin(context));
37 | client.addPlugin(CrashReporterPlugin.getInstance());
38 |
39 | NetworkFlipperPlugin networkFlipperPlugin = new NetworkFlipperPlugin();
40 | NetworkingModule.setCustomClientBuilder(
41 | new NetworkingModule.CustomClientBuilder() {
42 | @Override
43 | public void apply(OkHttpClient.Builder builder) {
44 | builder.addNetworkInterceptor(new FlipperOkhttpInterceptor(networkFlipperPlugin));
45 | }
46 | });
47 | client.addPlugin(networkFlipperPlugin);
48 | client.start();
49 |
50 | // Fresco Plugin needs to ensure that ImagePipelineFactory is initialized
51 | // Hence we run if after all native modules have been initialized
52 | ReactContext reactContext = reactInstanceManager.getCurrentReactContext();
53 | if (reactContext == null) {
54 | reactInstanceManager.addReactInstanceEventListener(
55 | new ReactInstanceEventListener() {
56 | @Override
57 | public void onReactContextInitialized(ReactContext reactContext) {
58 | reactInstanceManager.removeReactInstanceEventListener(this);
59 | reactContext.runOnNativeModulesQueueThread(
60 | new Runnable() {
61 | @Override
62 | public void run() {
63 | client.addPlugin(new FrescoFlipperPlugin());
64 | }
65 | });
66 | }
67 | });
68 | } else {
69 | client.addPlugin(new FrescoFlipperPlugin());
70 | }
71 | }
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
13 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/android/app/src/main/java/com/rnzustandboilerplate/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.rnzustandboilerplate;
2 |
3 | import com.facebook.react.ReactActivity;
4 | import com.facebook.react.ReactActivityDelegate;
5 | import com.facebook.react.ReactRootView;
6 | import android.os.Bundle;
7 |
8 | public class MainActivity extends ReactActivity {
9 |
10 | /**
11 | * Returns the name of the main component registered from JavaScript. This is used to schedule
12 | * rendering of the component.
13 | */
14 | @Override
15 | protected String getMainComponentName() {
16 | return "RNZustandBoilerPlate";
17 | }
18 |
19 | /**
20 | * Returns the instance of the {@link ReactActivityDelegate}. There the RootView is created and
21 | * you can specify the renderer you wish to use - the new renderer (Fabric) or the old renderer
22 | * (Paper).
23 | */
24 | @Override
25 | protected ReactActivityDelegate createReactActivityDelegate() {
26 | return new MainActivityDelegate(this, getMainComponentName());
27 | }
28 |
29 | public static class MainActivityDelegate extends ReactActivityDelegate {
30 | public MainActivityDelegate(ReactActivity activity, String mainComponentName) {
31 | super(activity, mainComponentName);
32 | }
33 |
34 | @Override
35 | protected ReactRootView createRootView() {
36 | ReactRootView reactRootView = new ReactRootView(getContext());
37 | // If you opted-in for the New Architecture, we enable the Fabric Renderer.
38 | reactRootView.setIsFabric(BuildConfig.IS_NEW_ARCHITECTURE_ENABLED);
39 | return reactRootView;
40 | }
41 |
42 | @Override
43 | protected boolean isConcurrentRootEnabled() {
44 | // If you opted-in for the New Architecture, we enable Concurrent Root (i.e. React 18).
45 | // More on this on https://reactjs.org/blog/2022/03/29/react-v18.html
46 | return BuildConfig.IS_NEW_ARCHITECTURE_ENABLED;
47 | }
48 |
49 | @Override
50 | protected void onCreate(Bundle savedInstanceState) {
51 | super.onCreate(null);
52 | }
53 |
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/android/app/src/main/java/com/rnzustandboilerplate/MainApplication.java:
--------------------------------------------------------------------------------
1 | package com.rnzustandboilerplate;
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.react.config.ReactFeatureFlags;
11 | import com.facebook.soloader.SoLoader;
12 | import com.rnzustandboilerplate.newarchitecture.MainApplicationReactNativeHost;
13 | import java.lang.reflect.InvocationTargetException;
14 | import java.util.List;
15 |
16 | public class MainApplication extends Application implements ReactApplication {
17 |
18 | private final ReactNativeHost mReactNativeHost =
19 | new ReactNativeHost(this) {
20 | @Override
21 | public boolean getUseDeveloperSupport() {
22 | return BuildConfig.DEBUG;
23 | }
24 |
25 | @Override
26 | protected List getPackages() {
27 | @SuppressWarnings("UnnecessaryLocalVariable")
28 | List packages = new PackageList(this).getPackages();
29 | // Packages that cannot be autolinked yet can be added manually here, for example:
30 | // packages.add(new MyReactNativePackage());
31 | return packages;
32 | }
33 |
34 | @Override
35 | protected String getJSMainModuleName() {
36 | return "index";
37 | }
38 | };
39 |
40 | private final ReactNativeHost mNewArchitectureNativeHost =
41 | new MainApplicationReactNativeHost(this);
42 |
43 | @Override
44 | public ReactNativeHost getReactNativeHost() {
45 | if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
46 | return mNewArchitectureNativeHost;
47 | } else {
48 | return mReactNativeHost;
49 | }
50 | }
51 |
52 | @Override
53 | public void onCreate() {
54 | super.onCreate();
55 | // If you opted-in for the New Architecture, we enable the TurboModule system
56 | ReactFeatureFlags.useTurboModules = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED;
57 | SoLoader.init(this, /* native exopackage */ false);
58 | initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
59 | }
60 |
61 | /**
62 | * Loads Flipper in React Native templates. Call this in the onCreate method with something like
63 | * initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
64 | *
65 | * @param context
66 | * @param reactInstanceManager
67 | */
68 | private static void initializeFlipper(
69 | Context context, ReactInstanceManager reactInstanceManager) {
70 | if (BuildConfig.DEBUG) {
71 | try {
72 | /*
73 | We use reflection here to pick up the class that initializes Flipper,
74 | since Flipper library is not available in release mode
75 | */
76 | Class> aClass = Class.forName("com.rnzustandboilerplate.ReactNativeFlipper");
77 | aClass
78 | .getMethod("initializeFlipper", Context.class, ReactInstanceManager.class)
79 | .invoke(null, context, reactInstanceManager);
80 | } catch (ClassNotFoundException e) {
81 | e.printStackTrace();
82 | } catch (NoSuchMethodException e) {
83 | e.printStackTrace();
84 | } catch (IllegalAccessException e) {
85 | e.printStackTrace();
86 | } catch (InvocationTargetException e) {
87 | e.printStackTrace();
88 | }
89 | }
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/android/app/src/main/java/com/rnzustandboilerplate/newarchitecture/MainApplicationReactNativeHost.java:
--------------------------------------------------------------------------------
1 | package com.rnzustandboilerplate.newarchitecture;
2 |
3 | import android.app.Application;
4 | import androidx.annotation.NonNull;
5 | import com.facebook.react.PackageList;
6 | import com.facebook.react.ReactInstanceManager;
7 | import com.facebook.react.ReactNativeHost;
8 | import com.facebook.react.ReactPackage;
9 | import com.facebook.react.ReactPackageTurboModuleManagerDelegate;
10 | import com.facebook.react.bridge.JSIModulePackage;
11 | import com.facebook.react.bridge.JSIModuleProvider;
12 | import com.facebook.react.bridge.JSIModuleSpec;
13 | import com.facebook.react.bridge.JSIModuleType;
14 | import com.facebook.react.bridge.JavaScriptContextHolder;
15 | import com.facebook.react.bridge.ReactApplicationContext;
16 | import com.facebook.react.bridge.UIManager;
17 | import com.facebook.react.fabric.ComponentFactory;
18 | import com.facebook.react.fabric.CoreComponentsRegistry;
19 | import com.facebook.react.fabric.FabricJSIModuleProvider;
20 | import com.facebook.react.fabric.ReactNativeConfig;
21 | import com.facebook.react.uimanager.ViewManagerRegistry;
22 | import com.rnzustandboilerplate.BuildConfig;
23 | import com.rnzustandboilerplate.newarchitecture.components.MainComponentsRegistry;
24 | import com.rnzustandboilerplate.newarchitecture.modules.MainApplicationTurboModuleManagerDelegate;
25 | import java.util.ArrayList;
26 | import java.util.List;
27 |
28 | /**
29 | * A {@link ReactNativeHost} that helps you load everything needed for the New Architecture, both
30 | * TurboModule delegates and the Fabric Renderer.
31 | *
32 | *
Please note that this class is used ONLY if you opt-in for the New Architecture (see the
33 | * `newArchEnabled` property). Is ignored otherwise.
34 | */
35 | public class MainApplicationReactNativeHost extends ReactNativeHost {
36 | public MainApplicationReactNativeHost(Application application) {
37 | super(application);
38 | }
39 |
40 | @Override
41 | public boolean getUseDeveloperSupport() {
42 | return BuildConfig.DEBUG;
43 | }
44 |
45 | @Override
46 | protected List getPackages() {
47 | List packages = new PackageList(this).getPackages();
48 | // Packages that cannot be autolinked yet can be added manually here, for example:
49 | // packages.add(new MyReactNativePackage());
50 | // TurboModules must also be loaded here providing a valid TurboReactPackage implementation:
51 | // packages.add(new TurboReactPackage() { ... });
52 | // If you have custom Fabric Components, their ViewManagers should also be loaded here
53 | // inside a ReactPackage.
54 | return packages;
55 | }
56 |
57 | @Override
58 | protected String getJSMainModuleName() {
59 | return "index";
60 | }
61 |
62 | @NonNull
63 | @Override
64 | protected ReactPackageTurboModuleManagerDelegate.Builder
65 | getReactPackageTurboModuleManagerDelegateBuilder() {
66 | // Here we provide the ReactPackageTurboModuleManagerDelegate Builder. This is necessary
67 | // for the new architecture and to use TurboModules correctly.
68 | return new MainApplicationTurboModuleManagerDelegate.Builder();
69 | }
70 |
71 | @Override
72 | protected JSIModulePackage getJSIModulePackage() {
73 | return new JSIModulePackage() {
74 | @Override
75 | public List getJSIModules(
76 | final ReactApplicationContext reactApplicationContext,
77 | final JavaScriptContextHolder jsContext) {
78 | final List specs = new ArrayList<>();
79 |
80 | // Here we provide a new JSIModuleSpec that will be responsible of providing the
81 | // custom Fabric Components.
82 | specs.add(
83 | new JSIModuleSpec() {
84 | @Override
85 | public JSIModuleType getJSIModuleType() {
86 | return JSIModuleType.UIManager;
87 | }
88 |
89 | @Override
90 | public JSIModuleProvider getJSIModuleProvider() {
91 | final ComponentFactory componentFactory = new ComponentFactory();
92 | CoreComponentsRegistry.register(componentFactory);
93 |
94 | // Here we register a Components Registry.
95 | // The one that is generated with the template contains no components
96 | // and just provides you the one from React Native core.
97 | MainComponentsRegistry.register(componentFactory);
98 |
99 | final ReactInstanceManager reactInstanceManager = getReactInstanceManager();
100 |
101 | ViewManagerRegistry viewManagerRegistry =
102 | new ViewManagerRegistry(
103 | reactInstanceManager.getOrCreateViewManagers(reactApplicationContext));
104 |
105 | return new FabricJSIModuleProvider(
106 | reactApplicationContext,
107 | componentFactory,
108 | ReactNativeConfig.DEFAULT_CONFIG,
109 | viewManagerRegistry);
110 | }
111 | });
112 | return specs;
113 | }
114 | };
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/android/app/src/main/java/com/rnzustandboilerplate/newarchitecture/components/MainComponentsRegistry.java:
--------------------------------------------------------------------------------
1 | package com.rnzustandboilerplate.newarchitecture.components;
2 |
3 | import com.facebook.jni.HybridData;
4 | import com.facebook.proguard.annotations.DoNotStrip;
5 | import com.facebook.react.fabric.ComponentFactory;
6 | import com.facebook.soloader.SoLoader;
7 |
8 | /**
9 | * Class responsible to load the custom Fabric Components. This class has native methods and needs a
10 | * corresponding C++ implementation/header file to work correctly (already placed inside the jni/
11 | * folder for you).
12 | *
13 | *
Please note that this class is used ONLY if you opt-in for the New Architecture (see the
14 | * `newArchEnabled` property). Is ignored otherwise.
15 | */
16 | @DoNotStrip
17 | public class MainComponentsRegistry {
18 | static {
19 | SoLoader.loadLibrary("fabricjni");
20 | }
21 |
22 | @DoNotStrip private final HybridData mHybridData;
23 |
24 | @DoNotStrip
25 | private native HybridData initHybrid(ComponentFactory componentFactory);
26 |
27 | @DoNotStrip
28 | private MainComponentsRegistry(ComponentFactory componentFactory) {
29 | mHybridData = initHybrid(componentFactory);
30 | }
31 |
32 | @DoNotStrip
33 | public static MainComponentsRegistry register(ComponentFactory componentFactory) {
34 | return new MainComponentsRegistry(componentFactory);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/android/app/src/main/java/com/rnzustandboilerplate/newarchitecture/modules/MainApplicationTurboModuleManagerDelegate.java:
--------------------------------------------------------------------------------
1 | package com.rnzustandboilerplate.newarchitecture.modules;
2 |
3 | import com.facebook.jni.HybridData;
4 | import com.facebook.react.ReactPackage;
5 | import com.facebook.react.ReactPackageTurboModuleManagerDelegate;
6 | import com.facebook.react.bridge.ReactApplicationContext;
7 | import com.facebook.soloader.SoLoader;
8 | import java.util.List;
9 |
10 | /**
11 | * Class responsible to load the TurboModules. This class has native methods and needs a
12 | * corresponding C++ implementation/header file to work correctly (already placed inside the jni/
13 | * folder for you).
14 | *
15 | *