├── .buckconfig ├── .eslintrc.js ├── .flowconfig ├── .gitattributes ├── .gitignore ├── .prettierrc.js ├── .watchmanconfig ├── README.md ├── __tests__ └── App-test.js ├── _editorconfig ├── android ├── app │ ├── _BUCK │ ├── build.gradle │ ├── build_defs.bzl │ ├── debug.keystore │ ├── proguard-rules.pro │ └── src │ │ ├── debug │ │ ├── AndroidManifest.xml │ │ └── java │ │ │ └── com │ │ │ └── magentoreactnativecommunity │ │ │ └── ReactNativeFlipper.java │ │ └── main │ │ ├── AndroidManifest.xml │ │ ├── assets │ │ └── fonts │ │ │ ├── AntDesign.ttf │ │ │ ├── Entypo.ttf │ │ │ ├── EvilIcons.ttf │ │ │ ├── Feather.ttf │ │ │ ├── FontAwesome.ttf │ │ │ ├── FontAwesome5_Brands.ttf │ │ │ ├── FontAwesome5_Regular.ttf │ │ │ ├── FontAwesome5_Solid.ttf │ │ │ ├── Fontisto.ttf │ │ │ ├── Foundation.ttf │ │ │ ├── Ionicons.ttf │ │ │ ├── MaterialCommunityIcons.ttf │ │ │ ├── MaterialIcons.ttf │ │ │ ├── Octicons.ttf │ │ │ ├── SimpleLineIcons.ttf │ │ │ ├── SourceSansPro-Black.ttf │ │ │ ├── SourceSansPro-BlackItalic.ttf │ │ │ ├── SourceSansPro-Bold.ttf │ │ │ ├── SourceSansPro-BoldItalic.ttf │ │ │ ├── SourceSansPro-ExtraLight.ttf │ │ │ ├── SourceSansPro-ExtraLightItalic.ttf │ │ │ ├── SourceSansPro-Italic.ttf │ │ │ ├── SourceSansPro-Light.ttf │ │ │ ├── SourceSansPro-LightItalic.ttf │ │ │ ├── SourceSansPro-Regular.ttf │ │ │ ├── SourceSansPro-SemiBold.ttf │ │ │ ├── SourceSansPro-SemiBoldItalic.ttf │ │ │ └── Zocial.ttf │ │ ├── ic_launcher-playstore.png │ │ ├── java │ │ └── com │ │ │ └── magentoreactnativecommunity │ │ │ ├── MainActivity.java │ │ │ ├── MainApplication.java │ │ │ └── SplashActivity.java │ │ └── res │ │ ├── drawable │ │ ├── background_splash.xml │ │ └── splash.png │ │ ├── layout │ │ └── launch_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-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-v21 │ │ └── styles.xml │ │ └── 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 ├── assets └── fonts │ └── Source_Sans_Pro │ ├── OFL.txt │ ├── SourceSansPro-Black.ttf │ ├── SourceSansPro-BlackItalic.ttf │ ├── SourceSansPro-Bold.ttf │ ├── SourceSansPro-BoldItalic.ttf │ ├── SourceSansPro-ExtraLight.ttf │ ├── SourceSansPro-ExtraLightItalic.ttf │ ├── SourceSansPro-Italic.ttf │ ├── SourceSansPro-Light.ttf │ ├── SourceSansPro-LightItalic.ttf │ ├── SourceSansPro-Regular.ttf │ ├── SourceSansPro-SemiBold.ttf │ └── SourceSansPro-SemiBoldItalic.ttf ├── babel.config.js ├── docs └── demo.gif ├── index.js ├── ios ├── MagentoReactNativeCommunity.xcodeproj │ ├── project.pbxproj │ └── xcshareddata │ │ └── xcschemes │ │ ├── MagentoReactNativeCommunity-tvOS.xcscheme │ │ └── MagentoReactNativeCommunity.xcscheme ├── MagentoReactNativeCommunity.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── MagentoReactNativeCommunity │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Images.xcassets │ │ ├── AppIcon.appiconset │ │ │ ├── 100.png │ │ │ ├── 1024.png │ │ │ ├── 114.png │ │ │ ├── 120.png │ │ │ ├── 128.png │ │ │ ├── 144.png │ │ │ ├── 152.png │ │ │ ├── 16.png │ │ │ ├── 167.png │ │ │ ├── 172.png │ │ │ ├── 180.png │ │ │ ├── 196.png │ │ │ ├── 20.png │ │ │ ├── 216.png │ │ │ ├── 256.png │ │ │ ├── 29.png │ │ │ ├── 32.png │ │ │ ├── 40.png │ │ │ ├── 48.png │ │ │ ├── 50.png │ │ │ ├── 512.png │ │ │ ├── 55.png │ │ │ ├── 57.png │ │ │ ├── 58.png │ │ │ ├── 60.png │ │ │ ├── 64.png │ │ │ ├── 72.png │ │ │ ├── 76.png │ │ │ ├── 80.png │ │ │ ├── 87.png │ │ │ ├── 88.png │ │ │ └── Contents.json │ │ ├── Contents.json │ │ └── splash.imageset │ │ │ ├── Contents.json │ │ │ └── mrn-bold.png │ ├── Info.plist │ ├── LaunchScreen.storyboard │ └── main.m ├── MagentoReactNativeCommunityTests │ ├── Info.plist │ └── MagentoReactNativeCommunityTests.m ├── Podfile └── Podfile.lock ├── jest.config.js ├── magento.config.js ├── metro.config.js ├── package.json ├── react-native.config.js ├── scripts └── generatePossibleTypes.js ├── src ├── App.tsx ├── apollo │ ├── client.ts │ ├── data │ │ └── possibleTypes.json │ ├── mutations │ │ ├── addProductsToCart.ts │ │ ├── createCart.ts │ │ └── removeItemFromCart.ts │ └── queries │ │ ├── cartItemsFragment.ts │ │ ├── getCartDetails.ts │ │ ├── getCategory.ts │ │ ├── getCategoryProducts.ts │ │ ├── getProductDetails.ts │ │ ├── mediaGalleryFragment.ts │ │ └── productPriceFragment.ts ├── components │ ├── cart │ │ ├── CartDetailsListItem.tsx │ │ ├── CartDetailsScreen.tsx │ │ └── HeaderCartButton.tsx │ ├── categories │ │ ├── CategoriesScreen.tsx │ │ └── CategoryListItem.tsx │ ├── checkout │ │ └── CheckoutScreen.tsx │ ├── common │ │ ├── AnimatedAppearance.tsx │ │ ├── MediaGallery.tsx │ │ ├── TouchableRipple.tsx │ │ ├── TouchableScale.tsx │ │ └── util │ │ │ └── Transitions.ts │ └── products │ │ ├── ProductDetailsScreen.tsx │ │ ├── ProductListItem.tsx │ │ ├── ProductListScreen.tsx │ │ └── options │ │ ├── ConfigurableOptionValues.tsx │ │ └── ConfigurableProductOptions.tsx ├── logic │ ├── cart │ │ ├── useCart.ts │ │ └── useCartDetails.ts │ ├── categories │ │ ├── useCategories.ts │ │ └── useCategoryColors.ts │ ├── products │ │ ├── useCategoryProducts.ts │ │ └── useProductDetails.ts │ └── util │ │ └── price.ts ├── navigation │ ├── Navigation.tsx │ └── routes.ts ├── redux │ ├── cart.ts │ ├── reducers.ts │ └── store.ts └── theme │ ├── colors.ts │ ├── fonts.ts │ ├── index.ts │ └── shadows.ts ├── 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 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | extends: '@react-native-community', 4 | rules: { 5 | 'object-curly-spacing': ['error', 'always'], 6 | '@typescript-eslint/no-unused-vars': 1, 7 | }, 8 | }; 9 | -------------------------------------------------------------------------------- /.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 | ; Flow doesn't support platforms 12 | .*/Libraries/Utilities/LoadingView.js 13 | 14 | [untyped] 15 | .*/node_modules/@react-native-community/cli/.*/.* 16 | 17 | [include] 18 | 19 | [libs] 20 | node_modules/react-native/interface.js 21 | node_modules/react-native/flow/ 22 | 23 | [options] 24 | emoji=true 25 | 26 | esproposal.optional_chaining=enable 27 | esproposal.nullish_coalescing=enable 28 | 29 | exact_by_default=true 30 | 31 | module.file_ext=.js 32 | module.file_ext=.json 33 | module.file_ext=.ios.js 34 | 35 | munge_underscores=true 36 | 37 | module.name_mapper='^react-native/\(.*\)$' -> '/node_modules/react-native/\1' 38 | 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' 39 | 40 | suppress_type=$FlowIssue 41 | suppress_type=$FlowFixMe 42 | suppress_type=$FlowFixMeProps 43 | suppress_type=$FlowFixMeState 44 | 45 | [lints] 46 | sketchy-null-number=warn 47 | sketchy-null-mixed=warn 48 | sketchy-number=warn 49 | untyped-type-import=warn 50 | nonstrict-import=warn 51 | deprecated-type=warn 52 | unsafe-getters-setters=warn 53 | unnecessary-invariant=warn 54 | signature-verification-failure=warn 55 | 56 | [strict] 57 | deprecated-type 58 | nonstrict-import 59 | sketchy-null 60 | unclear-type 61 | unsafe-getters-setters 62 | untyped-import 63 | untyped-type-import 64 | 65 | [version] 66 | ^0.137.0 67 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Windows files should use crlf line endings 2 | # https://help.github.com/articles/dealing-with-line-endings/ 3 | *.bat text eol=crlf 4 | -------------------------------------------------------------------------------- /.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 | 61 | # VSCode 62 | .vscode -------------------------------------------------------------------------------- /.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | bracketSpacing: true, 3 | jsxBracketSameLine: true, 4 | singleQuote: true, 5 | trailingComma: 'all', 6 | printWidth: 100, 7 | arrowParens: 'avoid', 8 | }; 9 | -------------------------------------------------------------------------------- /.watchmanconfig: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 |
3 | Magento React Native logo 4 |

5 | 6 | 7 |
8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 |
24 | 25 | # Magento React Native Community 26 | New version of the https://github.com/troublediehard/magento-react-native based on GraphQL api. 27 | Which will be covered with YouTube tutorials https://www.youtube.com/playlist?list=PL97fL9DAn9QyNAWAh-X-mFJdXKm96AqVM. 28 | 29 | ## 🎬 Demo 30 | ![Demo](docs/demo.gif) 31 | -------------------------------------------------------------------------------- /__tests__/App-test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @format 3 | */ 4 | 5 | import 'react-native'; 6 | import React from 'react'; 7 | import App from '../src/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 | -------------------------------------------------------------------------------- /_editorconfig: -------------------------------------------------------------------------------- 1 | # Windows files 2 | [*.bat] 3 | end_of_line = crlf 4 | -------------------------------------------------------------------------------- /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.magentoreactnativecommunity", 39 | ) 40 | 41 | android_resource( 42 | name = "res", 43 | package = "com.magentoreactnativecommunity", 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 | 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: true, // 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 | ndkVersion rootProject.ext.ndkVersion 125 | 126 | compileSdkVersion rootProject.ext.compileSdkVersion 127 | 128 | compileOptions { 129 | sourceCompatibility JavaVersion.VERSION_1_8 130 | targetCompatibility JavaVersion.VERSION_1_8 131 | } 132 | 133 | defaultConfig { 134 | applicationId "com.magentoreactnativecommunity" 135 | minSdkVersion rootProject.ext.minSdkVersion 136 | targetSdkVersion rootProject.ext.targetSdkVersion 137 | versionCode 1 138 | versionName "1.0" 139 | } 140 | splits { 141 | abi { 142 | reset() 143 | enable enableSeparateBuildPerCPUArchitecture 144 | universalApk false // If true, also generate a universal APK 145 | include "armeabi-v7a", "x86", "arm64-v8a", "x86_64" 146 | } 147 | } 148 | signingConfigs { 149 | debug { 150 | storeFile file('debug.keystore') 151 | storePassword 'android' 152 | keyAlias 'androiddebugkey' 153 | keyPassword 'android' 154 | } 155 | } 156 | buildTypes { 157 | debug { 158 | signingConfig signingConfigs.debug 159 | } 160 | release { 161 | // Caution! In production, you need to generate your own keystore file. 162 | // see https://reactnative.dev/docs/signed-apk-android. 163 | signingConfig signingConfigs.debug 164 | minifyEnabled enableProguardInReleaseBuilds 165 | proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" 166 | } 167 | } 168 | 169 | // applicationVariants are e.g. debug, release 170 | applicationVariants.all { variant -> 171 | variant.outputs.each { output -> 172 | // For each separate APK per architecture, set a unique version code as described here: 173 | // https://developer.android.com/studio/build/configure-apk-splits.html 174 | // Example: versionCode 1 will generate 1001 for armeabi-v7a, 1002 for x86, etc. 175 | def versionCodes = ["armeabi-v7a": 1, "x86": 2, "arm64-v8a": 3, "x86_64": 4] 176 | def abi = output.getFilter(OutputFile.ABI) 177 | if (abi != null) { // null for the universal-debug, universal-release variants 178 | output.versionCodeOverride = 179 | defaultConfig.versionCode * 1000 + versionCodes.get(abi) 180 | } 181 | 182 | } 183 | } 184 | } 185 | 186 | dependencies { 187 | implementation fileTree(dir: "libs", include: ["*.jar"]) 188 | //noinspection GradleDynamicVersion 189 | implementation "com.facebook.react:react-native:+" // From node_modules 190 | 191 | implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.0.0" 192 | 193 | debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") { 194 | exclude group:'com.facebook.fbjni' 195 | } 196 | 197 | debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") { 198 | exclude group:'com.facebook.flipper' 199 | exclude group:'com.squareup.okhttp3', module:'okhttp' 200 | } 201 | 202 | debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}") { 203 | exclude group:'com.facebook.flipper' 204 | } 205 | 206 | if (enableHermes) { 207 | def hermesPath = "../../node_modules/hermes-engine/android/"; 208 | debugImplementation files(hermesPath + "hermes-debug.aar") 209 | releaseImplementation files(hermesPath + "hermes-release.aar") 210 | } else { 211 | implementation jscFlavor 212 | } 213 | } 214 | 215 | // Run this once to be able to run the application with BUCK 216 | // puts all compile dependencies into folder libs for BUCK to use 217 | task copyDownloadableDepsToLibs(type: Copy) { 218 | from configurations.compile 219 | into 'libs' 220 | } 221 | 222 | apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project) 223 | -------------------------------------------------------------------------------- /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/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/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 | -keep class com.facebook.react.turbomodule.** { *; } 12 | -------------------------------------------------------------------------------- /android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /android/app/src/debug/java/com/magentoreactnativecommunity/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.magentoreactnativecommunity; 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 | -------------------------------------------------------------------------------- /android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 13 | 17 | 18 | 19 | 20 | 21 | 22 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /android/app/src/main/assets/fonts/AntDesign.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/android/app/src/main/assets/fonts/AntDesign.ttf -------------------------------------------------------------------------------- /android/app/src/main/assets/fonts/Entypo.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/android/app/src/main/assets/fonts/Entypo.ttf -------------------------------------------------------------------------------- /android/app/src/main/assets/fonts/EvilIcons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/android/app/src/main/assets/fonts/EvilIcons.ttf -------------------------------------------------------------------------------- /android/app/src/main/assets/fonts/Feather.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/android/app/src/main/assets/fonts/Feather.ttf -------------------------------------------------------------------------------- /android/app/src/main/assets/fonts/FontAwesome.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/android/app/src/main/assets/fonts/FontAwesome.ttf -------------------------------------------------------------------------------- /android/app/src/main/assets/fonts/FontAwesome5_Brands.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/android/app/src/main/assets/fonts/FontAwesome5_Brands.ttf -------------------------------------------------------------------------------- /android/app/src/main/assets/fonts/FontAwesome5_Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/android/app/src/main/assets/fonts/FontAwesome5_Regular.ttf -------------------------------------------------------------------------------- /android/app/src/main/assets/fonts/FontAwesome5_Solid.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/android/app/src/main/assets/fonts/FontAwesome5_Solid.ttf -------------------------------------------------------------------------------- /android/app/src/main/assets/fonts/Fontisto.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/android/app/src/main/assets/fonts/Fontisto.ttf -------------------------------------------------------------------------------- /android/app/src/main/assets/fonts/Foundation.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/android/app/src/main/assets/fonts/Foundation.ttf -------------------------------------------------------------------------------- /android/app/src/main/assets/fonts/Ionicons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/android/app/src/main/assets/fonts/Ionicons.ttf -------------------------------------------------------------------------------- /android/app/src/main/assets/fonts/MaterialCommunityIcons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/android/app/src/main/assets/fonts/MaterialCommunityIcons.ttf -------------------------------------------------------------------------------- /android/app/src/main/assets/fonts/MaterialIcons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/android/app/src/main/assets/fonts/MaterialIcons.ttf -------------------------------------------------------------------------------- /android/app/src/main/assets/fonts/Octicons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/android/app/src/main/assets/fonts/Octicons.ttf -------------------------------------------------------------------------------- /android/app/src/main/assets/fonts/SimpleLineIcons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/android/app/src/main/assets/fonts/SimpleLineIcons.ttf -------------------------------------------------------------------------------- /android/app/src/main/assets/fonts/SourceSansPro-Black.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/android/app/src/main/assets/fonts/SourceSansPro-Black.ttf -------------------------------------------------------------------------------- /android/app/src/main/assets/fonts/SourceSansPro-BlackItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/android/app/src/main/assets/fonts/SourceSansPro-BlackItalic.ttf -------------------------------------------------------------------------------- /android/app/src/main/assets/fonts/SourceSansPro-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/android/app/src/main/assets/fonts/SourceSansPro-Bold.ttf -------------------------------------------------------------------------------- /android/app/src/main/assets/fonts/SourceSansPro-BoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/android/app/src/main/assets/fonts/SourceSansPro-BoldItalic.ttf -------------------------------------------------------------------------------- /android/app/src/main/assets/fonts/SourceSansPro-ExtraLight.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/android/app/src/main/assets/fonts/SourceSansPro-ExtraLight.ttf -------------------------------------------------------------------------------- /android/app/src/main/assets/fonts/SourceSansPro-ExtraLightItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/android/app/src/main/assets/fonts/SourceSansPro-ExtraLightItalic.ttf -------------------------------------------------------------------------------- /android/app/src/main/assets/fonts/SourceSansPro-Italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/android/app/src/main/assets/fonts/SourceSansPro-Italic.ttf -------------------------------------------------------------------------------- /android/app/src/main/assets/fonts/SourceSansPro-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/android/app/src/main/assets/fonts/SourceSansPro-Light.ttf -------------------------------------------------------------------------------- /android/app/src/main/assets/fonts/SourceSansPro-LightItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/android/app/src/main/assets/fonts/SourceSansPro-LightItalic.ttf -------------------------------------------------------------------------------- /android/app/src/main/assets/fonts/SourceSansPro-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/android/app/src/main/assets/fonts/SourceSansPro-Regular.ttf -------------------------------------------------------------------------------- /android/app/src/main/assets/fonts/SourceSansPro-SemiBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/android/app/src/main/assets/fonts/SourceSansPro-SemiBold.ttf -------------------------------------------------------------------------------- /android/app/src/main/assets/fonts/SourceSansPro-SemiBoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/android/app/src/main/assets/fonts/SourceSansPro-SemiBoldItalic.ttf -------------------------------------------------------------------------------- /android/app/src/main/assets/fonts/Zocial.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/android/app/src/main/assets/fonts/Zocial.ttf -------------------------------------------------------------------------------- /android/app/src/main/ic_launcher-playstore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/android/app/src/main/ic_launcher-playstore.png -------------------------------------------------------------------------------- /android/app/src/main/java/com/magentoreactnativecommunity/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.magentoreactnativecommunity; 2 | 3 | import android.os.Bundle; 4 | 5 | import com.facebook.react.ReactActivity; 6 | 7 | import org.devio.rn.splashscreen.SplashScreen; 8 | 9 | public class MainActivity extends ReactActivity { 10 | 11 | @Override 12 | protected void onCreate(Bundle savedInstanceState) { 13 | SplashScreen.show(this, R.style.SplashStatusBarTheme); 14 | super.onCreate(savedInstanceState); 15 | } 16 | 17 | /** 18 | * Returns the name of the main component registered from JavaScript. This is used to schedule 19 | * rendering of the component. 20 | */ 21 | @Override 22 | protected String getMainComponentName() { 23 | return "MagentoReactNativeCommunity"; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /android/app/src/main/java/com/magentoreactnativecommunity/MainApplication.java: -------------------------------------------------------------------------------- 1 | package com.magentoreactnativecommunity; 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 | import com.facebook.react.bridge.JSIModulePackage; // <- add 15 | import com.swmansion.reanimated.ReanimatedJSIModulePackage; // <- add 16 | 17 | public class MainApplication extends Application implements ReactApplication { 18 | 19 | private final ReactNativeHost mReactNativeHost = 20 | new ReactNativeHost(this) { 21 | @Override 22 | public boolean getUseDeveloperSupport() { 23 | return BuildConfig.DEBUG; 24 | } 25 | 26 | @Override 27 | protected List getPackages() { 28 | @SuppressWarnings("UnnecessaryLocalVariable") 29 | List packages = new PackageList(this).getPackages(); 30 | // Packages that cannot be autolinked yet can be added manually here, for example: 31 | // packages.add(new MyReactNativePackage()); 32 | return packages; 33 | } 34 | 35 | @Override 36 | protected String getJSMainModuleName() { 37 | return "index"; 38 | } 39 | 40 | @Override 41 | protected JSIModulePackage getJSIModulePackage() { 42 | return new ReanimatedJSIModulePackage(); // <- add 43 | } 44 | }; 45 | 46 | @Override 47 | public ReactNativeHost getReactNativeHost() { 48 | return mReactNativeHost; 49 | } 50 | 51 | @Override 52 | public void onCreate() { 53 | super.onCreate(); 54 | SoLoader.init(this, /* native exopackage */ false); 55 | initializeFlipper(this, getReactNativeHost().getReactInstanceManager()); 56 | } 57 | 58 | /** 59 | * Loads Flipper in React Native templates. Call this in the onCreate method with something like 60 | * initializeFlipper(this, getReactNativeHost().getReactInstanceManager()); 61 | * 62 | * @param context 63 | * @param reactInstanceManager 64 | */ 65 | private static void initializeFlipper( 66 | Context context, ReactInstanceManager reactInstanceManager) { 67 | if (BuildConfig.DEBUG) { 68 | try { 69 | /* 70 | We use reflection here to pick up the class that initializes Flipper, 71 | since Flipper library is not available in release mode 72 | */ 73 | Class aClass = Class.forName("com.magentoreactnativecommunity.ReactNativeFlipper"); 74 | aClass 75 | .getMethod("initializeFlipper", Context.class, ReactInstanceManager.class) 76 | .invoke(null, context, reactInstanceManager); 77 | } catch (ClassNotFoundException e) { 78 | e.printStackTrace(); 79 | } catch (NoSuchMethodException e) { 80 | e.printStackTrace(); 81 | } catch (IllegalAccessException e) { 82 | e.printStackTrace(); 83 | } catch (InvocationTargetException e) { 84 | e.printStackTrace(); 85 | } 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /android/app/src/main/java/com/magentoreactnativecommunity/SplashActivity.java: -------------------------------------------------------------------------------- 1 | package com.magentoreactnativecommunity; 2 | 3 | import android.content.Intent; 4 | import android.os.Bundle; 5 | 6 | import androidx.appcompat.app.AppCompatActivity; 7 | 8 | public class SplashActivity extends AppCompatActivity { 9 | @Override 10 | protected void onCreate(Bundle savedInstanceState) { 11 | super.onCreate(savedInstanceState); 12 | 13 | Intent intent = new Intent(this, MainActivity.class); 14 | startActivity(intent); 15 | finish(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/background_splash.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 12 | 13 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/android/app/src/main/res/drawable/splash.png -------------------------------------------------------------------------------- /android/app/src/main/res/layout/launch_screen.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/values-v21/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 12 | 13 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #000000 4 | #000 5 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #000000 4 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | MagentoReactNativeCommunity 3 | 4 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /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.3" 6 | minSdkVersion = 21 7 | compileSdkVersion = 29 8 | targetSdkVersion = 29 9 | ndkVersion = "20.1.5948944" 10 | } 11 | repositories { 12 | google() 13 | jcenter() 14 | } 15 | dependencies { 16 | classpath("com.android.tools.build:gradle:4.1.0") 17 | // NOTE: Do not place your application dependencies here; they belong 18 | // in the individual module build.gradle files 19 | } 20 | } 21 | 22 | allprojects { 23 | repositories { 24 | mavenLocal() 25 | maven { 26 | // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm 27 | url("$rootDir/../node_modules/react-native/android") 28 | } 29 | maven { 30 | // Android JSC is installed from npm 31 | url("$rootDir/../node_modules/jsc-android/dist") 32 | } 33 | 34 | google() 35 | jcenter() 36 | maven { url 'https://www.jitpack.io' } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /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.75.1 29 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /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 | 86 | # Determine the Java command to use to start the JVM. 87 | if [ -n "$JAVA_HOME" ] ; then 88 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 89 | # IBM's JDK on AIX uses strange locations for the executables 90 | JAVACMD="$JAVA_HOME/jre/sh/java" 91 | else 92 | JAVACMD="$JAVA_HOME/bin/java" 93 | fi 94 | if [ ! -x "$JAVACMD" ] ; then 95 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 96 | 97 | Please set the JAVA_HOME variable in your environment to match the 98 | location of your Java installation." 99 | fi 100 | else 101 | JAVACMD="java" 102 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 103 | 104 | Please set the JAVA_HOME variable in your environment to match the 105 | location of your Java installation." 106 | fi 107 | 108 | # Increase the maximum file descriptors if we can. 109 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 110 | MAX_FD_LIMIT=`ulimit -H -n` 111 | if [ $? -eq 0 ] ; then 112 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 113 | MAX_FD="$MAX_FD_LIMIT" 114 | fi 115 | ulimit -n $MAX_FD 116 | if [ $? -ne 0 ] ; then 117 | warn "Could not set maximum file descriptor limit: $MAX_FD" 118 | fi 119 | else 120 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 121 | fi 122 | fi 123 | 124 | # For Darwin, add options to specify how the application appears in the dock 125 | if $darwin; then 126 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 127 | fi 128 | 129 | # For Cygwin or MSYS, switch paths to Windows format before running java 130 | if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then 131 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 132 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 133 | 134 | JAVACMD=`cygpath --unix "$JAVACMD"` 135 | 136 | # We build the pattern for arguments to be converted via cygpath 137 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 138 | SEP="" 139 | for dir in $ROOTDIRSRAW ; do 140 | ROOTDIRS="$ROOTDIRS$SEP$dir" 141 | SEP="|" 142 | done 143 | OURCYGPATTERN="(^($ROOTDIRS))" 144 | # Add a user-defined pattern to the cygpath arguments 145 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 146 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 147 | fi 148 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 149 | i=0 150 | for arg in "$@" ; do 151 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 152 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 153 | 154 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 155 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 156 | else 157 | eval `echo args$i`="\"$arg\"" 158 | fi 159 | i=`expr $i + 1` 160 | done 161 | case $i in 162 | 0) set -- ;; 163 | 1) set -- "$args0" ;; 164 | 2) set -- "$args0" "$args1" ;; 165 | 3) set -- "$args0" "$args1" "$args2" ;; 166 | 4) set -- "$args0" "$args1" "$args2" "$args3" ;; 167 | 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 168 | 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 169 | 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 170 | 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 171 | 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 172 | esac 173 | fi 174 | 175 | # Escape application args 176 | save () { 177 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 178 | echo " " 179 | } 180 | APP_ARGS=`save "$@"` 181 | 182 | # Collect all arguments for the java command, following the shell quoting and substitution rules 183 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 184 | 185 | exec "$JAVACMD" "$@" 186 | -------------------------------------------------------------------------------- /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 execute 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 execute 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 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'MagentoReactNativeCommunity' 2 | apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings) 3 | include ':app' 4 | -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "MagentoReactNativeCommunity", 3 | "displayName": "MagentoReactNativeCommunity" 4 | } -------------------------------------------------------------------------------- /assets/fonts/Source_Sans_Pro/OFL.txt: -------------------------------------------------------------------------------- 1 | Copyright 2010, 2012, 2014 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name ‘Source’. 2 | 3 | This Font Software is licensed under the SIL Open Font License, Version 1.1. 4 | This license is copied below, and is also available with a FAQ at: 5 | http://scripts.sil.org/OFL 6 | 7 | 8 | ----------------------------------------------------------- 9 | SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 10 | ----------------------------------------------------------- 11 | 12 | PREAMBLE 13 | The goals of the Open Font License (OFL) are to stimulate worldwide 14 | development of collaborative font projects, to support the font creation 15 | efforts of academic and linguistic communities, and to provide a free and 16 | open framework in which fonts may be shared and improved in partnership 17 | with others. 18 | 19 | The OFL allows the licensed fonts to be used, studied, modified and 20 | redistributed freely as long as they are not sold by themselves. The 21 | fonts, including any derivative works, can be bundled, embedded, 22 | redistributed and/or sold with any software provided that any reserved 23 | names are not used by derivative works. The fonts and derivatives, 24 | however, cannot be released under any other type of license. The 25 | requirement for fonts to remain under this license does not apply 26 | to any document created using the fonts or their derivatives. 27 | 28 | DEFINITIONS 29 | "Font Software" refers to the set of files released by the Copyright 30 | Holder(s) under this license and clearly marked as such. This may 31 | include source files, build scripts and documentation. 32 | 33 | "Reserved Font Name" refers to any names specified as such after the 34 | copyright statement(s). 35 | 36 | "Original Version" refers to the collection of Font Software components as 37 | distributed by the Copyright Holder(s). 38 | 39 | "Modified Version" refers to any derivative made by adding to, deleting, 40 | or substituting -- in part or in whole -- any of the components of the 41 | Original Version, by changing formats or by porting the Font Software to a 42 | new environment. 43 | 44 | "Author" refers to any designer, engineer, programmer, technical 45 | writer or other person who contributed to the Font Software. 46 | 47 | PERMISSION & CONDITIONS 48 | Permission is hereby granted, free of charge, to any person obtaining 49 | a copy of the Font Software, to use, study, copy, merge, embed, modify, 50 | redistribute, and sell modified and unmodified copies of the Font 51 | Software, subject to the following conditions: 52 | 53 | 1) Neither the Font Software nor any of its individual components, 54 | in Original or Modified Versions, may be sold by itself. 55 | 56 | 2) Original or Modified Versions of the Font Software may be bundled, 57 | redistributed and/or sold with any software, provided that each copy 58 | contains the above copyright notice and this license. These can be 59 | included either as stand-alone text files, human-readable headers or 60 | in the appropriate machine-readable metadata fields within text or 61 | binary files as long as those fields can be easily viewed by the user. 62 | 63 | 3) No Modified Version of the Font Software may use the Reserved Font 64 | Name(s) unless explicit written permission is granted by the corresponding 65 | Copyright Holder. This restriction only applies to the primary font name as 66 | presented to the users. 67 | 68 | 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font 69 | Software shall not be used to promote, endorse or advertise any 70 | Modified Version, except to acknowledge the contribution(s) of the 71 | Copyright Holder(s) and the Author(s) or with their explicit written 72 | permission. 73 | 74 | 5) The Font Software, modified or unmodified, in part or in whole, 75 | must be distributed entirely under this license, and must not be 76 | distributed under any other license. The requirement for fonts to 77 | remain under this license does not apply to any document created 78 | using the Font Software. 79 | 80 | TERMINATION 81 | This license becomes null and void if any of the above conditions are 82 | not met. 83 | 84 | DISCLAIMER 85 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 86 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF 87 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT 88 | OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE 89 | COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 90 | INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL 91 | DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 92 | FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM 93 | OTHER DEALINGS IN THE FONT SOFTWARE. 94 | -------------------------------------------------------------------------------- /assets/fonts/Source_Sans_Pro/SourceSansPro-Black.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/assets/fonts/Source_Sans_Pro/SourceSansPro-Black.ttf -------------------------------------------------------------------------------- /assets/fonts/Source_Sans_Pro/SourceSansPro-BlackItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/assets/fonts/Source_Sans_Pro/SourceSansPro-BlackItalic.ttf -------------------------------------------------------------------------------- /assets/fonts/Source_Sans_Pro/SourceSansPro-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/assets/fonts/Source_Sans_Pro/SourceSansPro-Bold.ttf -------------------------------------------------------------------------------- /assets/fonts/Source_Sans_Pro/SourceSansPro-BoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/assets/fonts/Source_Sans_Pro/SourceSansPro-BoldItalic.ttf -------------------------------------------------------------------------------- /assets/fonts/Source_Sans_Pro/SourceSansPro-ExtraLight.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/assets/fonts/Source_Sans_Pro/SourceSansPro-ExtraLight.ttf -------------------------------------------------------------------------------- /assets/fonts/Source_Sans_Pro/SourceSansPro-ExtraLightItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/assets/fonts/Source_Sans_Pro/SourceSansPro-ExtraLightItalic.ttf -------------------------------------------------------------------------------- /assets/fonts/Source_Sans_Pro/SourceSansPro-Italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/assets/fonts/Source_Sans_Pro/SourceSansPro-Italic.ttf -------------------------------------------------------------------------------- /assets/fonts/Source_Sans_Pro/SourceSansPro-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/assets/fonts/Source_Sans_Pro/SourceSansPro-Light.ttf -------------------------------------------------------------------------------- /assets/fonts/Source_Sans_Pro/SourceSansPro-LightItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/assets/fonts/Source_Sans_Pro/SourceSansPro-LightItalic.ttf -------------------------------------------------------------------------------- /assets/fonts/Source_Sans_Pro/SourceSansPro-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/assets/fonts/Source_Sans_Pro/SourceSansPro-Regular.ttf -------------------------------------------------------------------------------- /assets/fonts/Source_Sans_Pro/SourceSansPro-SemiBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/assets/fonts/Source_Sans_Pro/SourceSansPro-SemiBold.ttf -------------------------------------------------------------------------------- /assets/fonts/Source_Sans_Pro/SourceSansPro-SemiBoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/assets/fonts/Source_Sans_Pro/SourceSansPro-SemiBoldItalic.ttf -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | module.exports = { 3 | presets: ['module:metro-react-native-babel-preset'], 4 | plugins: ['react-native-reanimated/plugin'], 5 | }; 6 | -------------------------------------------------------------------------------- /docs/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/docs/demo.gif -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @format 3 | */ 4 | 5 | import {AppRegistry} from 'react-native'; 6 | import 'react-native-gesture-handler'; 7 | import App from './src/App'; 8 | import {name as appName} from './app.json'; 9 | 10 | AppRegistry.registerComponent(appName, () => App); 11 | -------------------------------------------------------------------------------- /ios/MagentoReactNativeCommunity.xcodeproj/xcshareddata/xcschemes/MagentoReactNativeCommunity-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 | -------------------------------------------------------------------------------- /ios/MagentoReactNativeCommunity.xcodeproj/xcshareddata/xcschemes/MagentoReactNativeCommunity.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 | -------------------------------------------------------------------------------- /ios/MagentoReactNativeCommunity.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /ios/MagentoReactNativeCommunity.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/MagentoReactNativeCommunity/AppDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @interface AppDelegate : UIResponder 5 | 6 | @property (nonatomic, strong) UIWindow *window; 7 | 8 | @end 9 | -------------------------------------------------------------------------------- /ios/MagentoReactNativeCommunity/AppDelegate.m: -------------------------------------------------------------------------------- 1 | #import "AppDelegate.h" 2 | 3 | #import 4 | #import 5 | #import 6 | 7 | #import 8 | 9 | #ifdef FB_SONARKIT_ENABLED 10 | #import 11 | #import 12 | #import 13 | #import 14 | #import 15 | #import 16 | 17 | static void InitializeFlipper(UIApplication *application) { 18 | FlipperClient *client = [FlipperClient sharedClient]; 19 | SKDescriptorMapper *layoutDescriptorMapper = [[SKDescriptorMapper alloc] initWithDefaults]; 20 | [client addPlugin:[[FlipperKitLayoutPlugin alloc] initWithRootNode:application withDescriptorMapper:layoutDescriptorMapper]]; 21 | [client addPlugin:[[FKUserDefaultsPlugin alloc] initWithSuiteName:nil]]; 22 | [client addPlugin:[FlipperKitReactPlugin new]]; 23 | [client addPlugin:[[FlipperKitNetworkPlugin alloc] initWithNetworkAdapter:[SKIOSNetworkAdapter new]]]; 24 | [client start]; 25 | } 26 | #endif 27 | 28 | @implementation AppDelegate 29 | 30 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 31 | { 32 | #ifdef FB_SONARKIT_ENABLED 33 | InitializeFlipper(application); 34 | #endif 35 | 36 | RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions]; 37 | RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge 38 | moduleName:@"MagentoReactNativeCommunity" 39 | initialProperties:nil]; 40 | 41 | if (@available(iOS 13.0, *)) { 42 | rootView.backgroundColor = [UIColor systemBackgroundColor]; 43 | } else { 44 | rootView.backgroundColor = [UIColor whiteColor]; 45 | } 46 | 47 | self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; 48 | UIViewController *rootViewController = [UIViewController new]; 49 | rootViewController.view = rootView; 50 | self.window.rootViewController = rootViewController; 51 | [self.window makeKeyAndVisible]; 52 | 53 | [RNSplashScreen show]; 54 | 55 | return YES; 56 | } 57 | 58 | - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge 59 | { 60 | #if DEBUG 61 | return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil]; 62 | #else 63 | return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; 64 | #endif 65 | } 66 | 67 | @end 68 | -------------------------------------------------------------------------------- /ios/MagentoReactNativeCommunity/Images.xcassets/AppIcon.appiconset/100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/ios/MagentoReactNativeCommunity/Images.xcassets/AppIcon.appiconset/100.png -------------------------------------------------------------------------------- /ios/MagentoReactNativeCommunity/Images.xcassets/AppIcon.appiconset/1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/ios/MagentoReactNativeCommunity/Images.xcassets/AppIcon.appiconset/1024.png -------------------------------------------------------------------------------- /ios/MagentoReactNativeCommunity/Images.xcassets/AppIcon.appiconset/114.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/ios/MagentoReactNativeCommunity/Images.xcassets/AppIcon.appiconset/114.png -------------------------------------------------------------------------------- /ios/MagentoReactNativeCommunity/Images.xcassets/AppIcon.appiconset/120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/ios/MagentoReactNativeCommunity/Images.xcassets/AppIcon.appiconset/120.png -------------------------------------------------------------------------------- /ios/MagentoReactNativeCommunity/Images.xcassets/AppIcon.appiconset/128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/ios/MagentoReactNativeCommunity/Images.xcassets/AppIcon.appiconset/128.png -------------------------------------------------------------------------------- /ios/MagentoReactNativeCommunity/Images.xcassets/AppIcon.appiconset/144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/ios/MagentoReactNativeCommunity/Images.xcassets/AppIcon.appiconset/144.png -------------------------------------------------------------------------------- /ios/MagentoReactNativeCommunity/Images.xcassets/AppIcon.appiconset/152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/ios/MagentoReactNativeCommunity/Images.xcassets/AppIcon.appiconset/152.png -------------------------------------------------------------------------------- /ios/MagentoReactNativeCommunity/Images.xcassets/AppIcon.appiconset/16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/ios/MagentoReactNativeCommunity/Images.xcassets/AppIcon.appiconset/16.png -------------------------------------------------------------------------------- /ios/MagentoReactNativeCommunity/Images.xcassets/AppIcon.appiconset/167.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/ios/MagentoReactNativeCommunity/Images.xcassets/AppIcon.appiconset/167.png -------------------------------------------------------------------------------- /ios/MagentoReactNativeCommunity/Images.xcassets/AppIcon.appiconset/172.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/ios/MagentoReactNativeCommunity/Images.xcassets/AppIcon.appiconset/172.png -------------------------------------------------------------------------------- /ios/MagentoReactNativeCommunity/Images.xcassets/AppIcon.appiconset/180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/ios/MagentoReactNativeCommunity/Images.xcassets/AppIcon.appiconset/180.png -------------------------------------------------------------------------------- /ios/MagentoReactNativeCommunity/Images.xcassets/AppIcon.appiconset/196.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/ios/MagentoReactNativeCommunity/Images.xcassets/AppIcon.appiconset/196.png -------------------------------------------------------------------------------- /ios/MagentoReactNativeCommunity/Images.xcassets/AppIcon.appiconset/20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/ios/MagentoReactNativeCommunity/Images.xcassets/AppIcon.appiconset/20.png -------------------------------------------------------------------------------- /ios/MagentoReactNativeCommunity/Images.xcassets/AppIcon.appiconset/216.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/ios/MagentoReactNativeCommunity/Images.xcassets/AppIcon.appiconset/216.png -------------------------------------------------------------------------------- /ios/MagentoReactNativeCommunity/Images.xcassets/AppIcon.appiconset/256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/ios/MagentoReactNativeCommunity/Images.xcassets/AppIcon.appiconset/256.png -------------------------------------------------------------------------------- /ios/MagentoReactNativeCommunity/Images.xcassets/AppIcon.appiconset/29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/ios/MagentoReactNativeCommunity/Images.xcassets/AppIcon.appiconset/29.png -------------------------------------------------------------------------------- /ios/MagentoReactNativeCommunity/Images.xcassets/AppIcon.appiconset/32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/ios/MagentoReactNativeCommunity/Images.xcassets/AppIcon.appiconset/32.png -------------------------------------------------------------------------------- /ios/MagentoReactNativeCommunity/Images.xcassets/AppIcon.appiconset/40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/ios/MagentoReactNativeCommunity/Images.xcassets/AppIcon.appiconset/40.png -------------------------------------------------------------------------------- /ios/MagentoReactNativeCommunity/Images.xcassets/AppIcon.appiconset/48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/ios/MagentoReactNativeCommunity/Images.xcassets/AppIcon.appiconset/48.png -------------------------------------------------------------------------------- /ios/MagentoReactNativeCommunity/Images.xcassets/AppIcon.appiconset/50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/ios/MagentoReactNativeCommunity/Images.xcassets/AppIcon.appiconset/50.png -------------------------------------------------------------------------------- /ios/MagentoReactNativeCommunity/Images.xcassets/AppIcon.appiconset/512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/ios/MagentoReactNativeCommunity/Images.xcassets/AppIcon.appiconset/512.png -------------------------------------------------------------------------------- /ios/MagentoReactNativeCommunity/Images.xcassets/AppIcon.appiconset/55.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/ios/MagentoReactNativeCommunity/Images.xcassets/AppIcon.appiconset/55.png -------------------------------------------------------------------------------- /ios/MagentoReactNativeCommunity/Images.xcassets/AppIcon.appiconset/57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/ios/MagentoReactNativeCommunity/Images.xcassets/AppIcon.appiconset/57.png -------------------------------------------------------------------------------- /ios/MagentoReactNativeCommunity/Images.xcassets/AppIcon.appiconset/58.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/ios/MagentoReactNativeCommunity/Images.xcassets/AppIcon.appiconset/58.png -------------------------------------------------------------------------------- /ios/MagentoReactNativeCommunity/Images.xcassets/AppIcon.appiconset/60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/ios/MagentoReactNativeCommunity/Images.xcassets/AppIcon.appiconset/60.png -------------------------------------------------------------------------------- /ios/MagentoReactNativeCommunity/Images.xcassets/AppIcon.appiconset/64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/ios/MagentoReactNativeCommunity/Images.xcassets/AppIcon.appiconset/64.png -------------------------------------------------------------------------------- /ios/MagentoReactNativeCommunity/Images.xcassets/AppIcon.appiconset/72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/ios/MagentoReactNativeCommunity/Images.xcassets/AppIcon.appiconset/72.png -------------------------------------------------------------------------------- /ios/MagentoReactNativeCommunity/Images.xcassets/AppIcon.appiconset/76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/ios/MagentoReactNativeCommunity/Images.xcassets/AppIcon.appiconset/76.png -------------------------------------------------------------------------------- /ios/MagentoReactNativeCommunity/Images.xcassets/AppIcon.appiconset/80.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/ios/MagentoReactNativeCommunity/Images.xcassets/AppIcon.appiconset/80.png -------------------------------------------------------------------------------- /ios/MagentoReactNativeCommunity/Images.xcassets/AppIcon.appiconset/87.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/ios/MagentoReactNativeCommunity/Images.xcassets/AppIcon.appiconset/87.png -------------------------------------------------------------------------------- /ios/MagentoReactNativeCommunity/Images.xcassets/AppIcon.appiconset/88.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/ios/MagentoReactNativeCommunity/Images.xcassets/AppIcon.appiconset/88.png -------------------------------------------------------------------------------- /ios/MagentoReactNativeCommunity/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "40.png", 5 | "idiom" : "iphone", 6 | "scale" : "2x", 7 | "size" : "20x20" 8 | }, 9 | { 10 | "filename" : "60.png", 11 | "idiom" : "iphone", 12 | "scale" : "3x", 13 | "size" : "20x20" 14 | }, 15 | { 16 | "filename" : "29.png", 17 | "idiom" : "iphone", 18 | "scale" : "1x", 19 | "size" : "29x29" 20 | }, 21 | { 22 | "filename" : "58.png", 23 | "idiom" : "iphone", 24 | "scale" : "2x", 25 | "size" : "29x29" 26 | }, 27 | { 28 | "filename" : "87.png", 29 | "idiom" : "iphone", 30 | "scale" : "3x", 31 | "size" : "29x29" 32 | }, 33 | { 34 | "filename" : "80.png", 35 | "idiom" : "iphone", 36 | "scale" : "2x", 37 | "size" : "40x40" 38 | }, 39 | { 40 | "filename" : "120.png", 41 | "idiom" : "iphone", 42 | "scale" : "3x", 43 | "size" : "40x40" 44 | }, 45 | { 46 | "filename" : "57.png", 47 | "idiom" : "iphone", 48 | "scale" : "1x", 49 | "size" : "57x57" 50 | }, 51 | { 52 | "filename" : "114.png", 53 | "idiom" : "iphone", 54 | "scale" : "2x", 55 | "size" : "57x57" 56 | }, 57 | { 58 | "filename" : "120.png", 59 | "idiom" : "iphone", 60 | "scale" : "2x", 61 | "size" : "60x60" 62 | }, 63 | { 64 | "filename" : "180.png", 65 | "idiom" : "iphone", 66 | "scale" : "3x", 67 | "size" : "60x60" 68 | }, 69 | { 70 | "filename" : "20.png", 71 | "idiom" : "ipad", 72 | "scale" : "1x", 73 | "size" : "20x20" 74 | }, 75 | { 76 | "filename" : "40.png", 77 | "idiom" : "ipad", 78 | "scale" : "2x", 79 | "size" : "20x20" 80 | }, 81 | { 82 | "filename" : "29.png", 83 | "idiom" : "ipad", 84 | "scale" : "1x", 85 | "size" : "29x29" 86 | }, 87 | { 88 | "filename" : "58.png", 89 | "idiom" : "ipad", 90 | "scale" : "2x", 91 | "size" : "29x29" 92 | }, 93 | { 94 | "filename" : "40.png", 95 | "idiom" : "ipad", 96 | "scale" : "1x", 97 | "size" : "40x40" 98 | }, 99 | { 100 | "filename" : "80.png", 101 | "idiom" : "ipad", 102 | "scale" : "2x", 103 | "size" : "40x40" 104 | }, 105 | { 106 | "filename" : "50.png", 107 | "idiom" : "ipad", 108 | "scale" : "1x", 109 | "size" : "50x50" 110 | }, 111 | { 112 | "filename" : "100.png", 113 | "idiom" : "ipad", 114 | "scale" : "2x", 115 | "size" : "50x50" 116 | }, 117 | { 118 | "filename" : "72.png", 119 | "idiom" : "ipad", 120 | "scale" : "1x", 121 | "size" : "72x72" 122 | }, 123 | { 124 | "filename" : "144.png", 125 | "idiom" : "ipad", 126 | "scale" : "2x", 127 | "size" : "72x72" 128 | }, 129 | { 130 | "filename" : "76.png", 131 | "idiom" : "ipad", 132 | "scale" : "1x", 133 | "size" : "76x76" 134 | }, 135 | { 136 | "filename" : "152.png", 137 | "idiom" : "ipad", 138 | "scale" : "2x", 139 | "size" : "76x76" 140 | }, 141 | { 142 | "filename" : "167.png", 143 | "idiom" : "ipad", 144 | "scale" : "2x", 145 | "size" : "83.5x83.5" 146 | }, 147 | { 148 | "filename" : "1024.png", 149 | "idiom" : "ios-marketing", 150 | "scale" : "1x", 151 | "size" : "1024x1024" 152 | }, 153 | { 154 | "filename" : "48.png", 155 | "idiom" : "watch", 156 | "role" : "notificationCenter", 157 | "scale" : "2x", 158 | "size" : "24x24", 159 | "subtype" : "38mm" 160 | }, 161 | { 162 | "filename" : "55.png", 163 | "idiom" : "watch", 164 | "role" : "notificationCenter", 165 | "scale" : "2x", 166 | "size" : "27.5x27.5", 167 | "subtype" : "42mm" 168 | }, 169 | { 170 | "filename" : "58.png", 171 | "idiom" : "watch", 172 | "role" : "companionSettings", 173 | "scale" : "2x", 174 | "size" : "29x29" 175 | }, 176 | { 177 | "filename" : "87.png", 178 | "idiom" : "watch", 179 | "role" : "companionSettings", 180 | "scale" : "3x", 181 | "size" : "29x29" 182 | }, 183 | { 184 | "filename" : "80.png", 185 | "idiom" : "watch", 186 | "role" : "appLauncher", 187 | "scale" : "2x", 188 | "size" : "40x40", 189 | "subtype" : "38mm" 190 | }, 191 | { 192 | "filename" : "88.png", 193 | "idiom" : "watch", 194 | "role" : "appLauncher", 195 | "scale" : "2x", 196 | "size" : "44x44", 197 | "subtype" : "40mm" 198 | }, 199 | { 200 | "filename" : "100.png", 201 | "idiom" : "watch", 202 | "role" : "appLauncher", 203 | "scale" : "2x", 204 | "size" : "50x50", 205 | "subtype" : "44mm" 206 | }, 207 | { 208 | "filename" : "172.png", 209 | "idiom" : "watch", 210 | "role" : "quickLook", 211 | "scale" : "2x", 212 | "size" : "86x86", 213 | "subtype" : "38mm" 214 | }, 215 | { 216 | "filename" : "196.png", 217 | "idiom" : "watch", 218 | "role" : "quickLook", 219 | "scale" : "2x", 220 | "size" : "98x98", 221 | "subtype" : "42mm" 222 | }, 223 | { 224 | "filename" : "216.png", 225 | "idiom" : "watch", 226 | "role" : "quickLook", 227 | "scale" : "2x", 228 | "size" : "108x108", 229 | "subtype" : "44mm" 230 | }, 231 | { 232 | "filename" : "1024.png", 233 | "idiom" : "watch-marketing", 234 | "scale" : "1x", 235 | "size" : "1024x1024" 236 | }, 237 | { 238 | "filename" : "16.png", 239 | "idiom" : "mac", 240 | "scale" : "1x", 241 | "size" : "16x16" 242 | }, 243 | { 244 | "filename" : "32.png", 245 | "idiom" : "mac", 246 | "scale" : "2x", 247 | "size" : "16x16" 248 | }, 249 | { 250 | "filename" : "32.png", 251 | "idiom" : "mac", 252 | "scale" : "1x", 253 | "size" : "32x32" 254 | }, 255 | { 256 | "filename" : "64.png", 257 | "idiom" : "mac", 258 | "scale" : "2x", 259 | "size" : "32x32" 260 | }, 261 | { 262 | "filename" : "128.png", 263 | "idiom" : "mac", 264 | "scale" : "1x", 265 | "size" : "128x128" 266 | }, 267 | { 268 | "filename" : "256.png", 269 | "idiom" : "mac", 270 | "scale" : "2x", 271 | "size" : "128x128" 272 | }, 273 | { 274 | "filename" : "256.png", 275 | "idiom" : "mac", 276 | "scale" : "1x", 277 | "size" : "256x256" 278 | }, 279 | { 280 | "filename" : "512.png", 281 | "idiom" : "mac", 282 | "scale" : "2x", 283 | "size" : "256x256" 284 | }, 285 | { 286 | "filename" : "512.png", 287 | "idiom" : "mac", 288 | "scale" : "1x", 289 | "size" : "512x512" 290 | }, 291 | { 292 | "filename" : "1024.png", 293 | "idiom" : "mac", 294 | "scale" : "2x", 295 | "size" : "512x512" 296 | } 297 | ], 298 | "info" : { 299 | "author" : "xcode", 300 | "version" : 1 301 | } 302 | } 303 | -------------------------------------------------------------------------------- /ios/MagentoReactNativeCommunity/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /ios/MagentoReactNativeCommunity/Images.xcassets/splash.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "mrn-bold.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /ios/MagentoReactNativeCommunity/Images.xcassets/splash.imageset/mrn-bold.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimaportenko/magento-react-native-community/53f94595f9140e9b7faaace70d9369d9dd0e8766/ios/MagentoReactNativeCommunity/Images.xcassets/splash.imageset/mrn-bold.png -------------------------------------------------------------------------------- /ios/MagentoReactNativeCommunity/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | UIAppFonts 6 | 7 | Ionicons.ttf 8 | SourceSansPro-Black.ttf 9 | SourceSansPro-BlackItalic.ttf 10 | SourceSansPro-Bold.ttf 11 | SourceSansPro-BoldItalic.ttf 12 | SourceSansPro-ExtraLight.ttf 13 | SourceSansPro-ExtraLightItalic.ttf 14 | SourceSansPro-Italic.ttf 15 | SourceSansPro-Light.ttf 16 | SourceSansPro-LightItalic.ttf 17 | SourceSansPro-Regular.ttf 18 | SourceSansPro-SemiBold.ttf 19 | SourceSansPro-SemiBoldItalic.ttf 20 | AntDesign.ttf 21 | Entypo.ttf 22 | EvilIcons.ttf 23 | Feather.ttf 24 | FontAwesome.ttf 25 | FontAwesome5_Brands.ttf 26 | FontAwesome5_Regular.ttf 27 | FontAwesome5_Solid.ttf 28 | Fontisto.ttf 29 | Foundation.ttf 30 | MaterialCommunityIcons.ttf 31 | MaterialIcons.ttf 32 | Octicons.ttf 33 | SimpleLineIcons.ttf 34 | Zocial.ttf 35 | 36 | CFBundleDevelopmentRegion 37 | en 38 | CFBundleDisplayName 39 | MagentoReactNativeCommunity 40 | CFBundleExecutable 41 | $(EXECUTABLE_NAME) 42 | CFBundleIdentifier 43 | $(PRODUCT_BUNDLE_IDENTIFIER) 44 | CFBundleInfoDictionaryVersion 45 | 6.0 46 | CFBundleName 47 | $(PRODUCT_NAME) 48 | CFBundlePackageType 49 | APPL 50 | CFBundleShortVersionString 51 | 1.0 52 | CFBundleSignature 53 | ???? 54 | CFBundleVersion 55 | 1 56 | LSRequiresIPhoneOS 57 | 58 | NSAppTransportSecurity 59 | 60 | NSAllowsArbitraryLoads 61 | 62 | NSExceptionDomains 63 | 64 | localhost 65 | 66 | NSExceptionAllowsInsecureHTTPLoads 67 | 68 | 69 | 70 | 71 | NSLocationWhenInUseUsageDescription 72 | 73 | UILaunchStoryboardName 74 | LaunchScreen 75 | UIRequiredDeviceCapabilities 76 | 77 | armv7 78 | 79 | UISupportedInterfaceOrientations 80 | 81 | UIInterfaceOrientationPortrait 82 | UIInterfaceOrientationLandscapeLeft 83 | UIInterfaceOrientationLandscapeRight 84 | 85 | UIViewControllerBasedStatusBarAppearance 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /ios/MagentoReactNativeCommunity/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /ios/MagentoReactNativeCommunity/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 | -------------------------------------------------------------------------------- /ios/MagentoReactNativeCommunityTests/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 | -------------------------------------------------------------------------------- /ios/MagentoReactNativeCommunityTests/MagentoReactNativeCommunityTests.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 MagentoReactNativeCommunityTests : XCTestCase 11 | 12 | @end 13 | 14 | @implementation MagentoReactNativeCommunityTests 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 | -------------------------------------------------------------------------------- /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 'MagentoReactNativeCommunity' do 7 | config = use_native_modules! 8 | 9 | use_react_native!( 10 | :path => config[:reactNativePath], 11 | # to enable hermes on iOS, change `false` to `true` and then install pods 12 | :hermes_enabled => true 13 | ) 14 | 15 | target 'MagentoReactNativeCommunityTests' do 16 | inherit! :complete 17 | # Pods for testing 18 | end 19 | 20 | # Enables Flipper. 21 | # 22 | # Note that if you have use_frameworks! enabled, Flipper will not work and 23 | # you should disable the next line. 24 | system('chmod +rw Pods/RCT-Folly/folly/synchronization/DistributedMutex-inl.h') 25 | use_flipper!({ 'Flipper' => '0.87.0' }) 26 | 27 | post_install do |installer| 28 | react_native_post_install(installer) 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | preset: 'react-native', 3 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'] 4 | }; 5 | -------------------------------------------------------------------------------- /magento.config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @flow 3 | * Created by Dima Portenko on 10.10.2020 4 | */ 5 | 6 | module.exports = { 7 | magentoConfig: { 8 | url: 'https://master-7rqtwti-mfwmkrjfqvbjk.us-4.magentosite.cloud/', 9 | }, 10 | }; 11 | -------------------------------------------------------------------------------- /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: true, 14 | }, 15 | }), 16 | }, 17 | }; 18 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "MagentoReactNativeCommunity", 3 | "version": "0.0.1", 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 | "generatePossibleTypes": "node ./scripts/generatePossibleTypes.js" 12 | }, 13 | "dependencies": { 14 | "@apollo/client": "^3.2.2", 15 | "@react-native-async-storage/async-storage": "^1.13.2", 16 | "@react-native-community/masked-view": "^0.1.10", 17 | "@react-navigation/native": "^5.7.5", 18 | "@react-navigation/stack": "^5.9.2", 19 | "@reduxjs/toolkit": "^1.5.0", 20 | "graphql": "^15.3.0", 21 | "react": "17.0.1", 22 | "react-native": "0.64.1", 23 | "react-native-flash-message": "^0.1.22", 24 | "react-native-gesture-handler": "^1.8.0", 25 | "react-native-reanimated": "^2.0.0", 26 | "react-native-redash": "14.2.3", 27 | "react-native-render-html": "^5.0.0", 28 | "react-native-safe-area-context": "^3.1.8", 29 | "react-native-screens": "^2.11.0", 30 | "react-native-splash-screen": "^3.2.0", 31 | "react-native-ui-lib": "^5.21.0", 32 | "react-native-vector-icons": "^7.1.0", 33 | "react-redux": "^7.2.2", 34 | "redux": "^4.0.5", 35 | "redux-persist": "^6.0.0" 36 | }, 37 | "devDependencies": { 38 | "@babel/core": "^7.12.9", 39 | "@babel/runtime": "^7.12.5", 40 | "@react-native-community/eslint-config": "^2.0.0", 41 | "@types/jest": "^26.0.21", 42 | "@types/react": "^17.0.3", 43 | "@types/react-native": "^0.64.0", 44 | "@types/react-native-vector-icons": "^6.4.6", 45 | "@types/react-redux": "^7.1.16", 46 | "@types/react-test-renderer": "^17.0.1", 47 | "babel-jest": "^26.6.3", 48 | "eslint": "^7.14.0", 49 | "flow-bin": "^0.137.0", 50 | "jest": "^26.6.3", 51 | "metro-react-native-babel-preset": "^0.64.0", 52 | "react-native-flipper": "^0.74.0", 53 | "react-native-flipper-apollo-devtools": "^0.0.2", 54 | "react-test-renderer": "17.0.1", 55 | "typescript": "^4.2.3" 56 | }, 57 | "jest": { 58 | "preset": "react-native" 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /react-native.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | assets: ['./assets/fonts'], 3 | }; 4 | -------------------------------------------------------------------------------- /scripts/generatePossibleTypes.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | const fetch = require('cross-fetch'); 3 | const fs = require('fs'); 4 | const config = require('../magento.config').magentoConfig; 5 | 6 | fetch(`${config.url}/graphql`, { 7 | method: 'POST', 8 | headers: { 'Content-Type': 'application/json' }, 9 | body: JSON.stringify({ 10 | variables: {}, 11 | query: ` 12 | { 13 | __schema { 14 | types { 15 | kind 16 | name 17 | possibleTypes { 18 | name 19 | } 20 | } 21 | } 22 | } 23 | `, 24 | }), 25 | }) 26 | .then((result) => result.json()) 27 | .then((result) => { 28 | const possibleTypes = {}; 29 | 30 | result.data.__schema.types.forEach((supertype) => { 31 | if (supertype.possibleTypes) { 32 | possibleTypes[supertype.name] = supertype.possibleTypes.map((subtype) => subtype.name); 33 | } 34 | }); 35 | 36 | fs.writeFile('./src/apollo/data/possibleTypes.json', JSON.stringify(possibleTypes), (err) => { 37 | if (err) { 38 | console.error('Error writing possibleTypes.json', err); 39 | } else { 40 | console.log('Fragment types successfully extracted!'); 41 | } 42 | }); 43 | }); 44 | -------------------------------------------------------------------------------- /src/App.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Sample React Native App 3 | * https://github.com/facebook/react-native 4 | * 5 | * @format 6 | * @flow 7 | */ 8 | 9 | import React, { useEffect } from 'react'; 10 | import { ApolloProvider } from '@apollo/client'; 11 | import View from 'react-native-ui-lib/view'; 12 | import FlashMessage from 'react-native-flash-message'; 13 | import { Provider } from 'react-redux'; 14 | import { PersistGate } from 'redux-persist/integration/react'; 15 | import SplashScreen from 'react-native-splash-screen'; 16 | import { Navigation } from './navigation/Navigation'; 17 | import { apolloClient } from './apollo/client'; 18 | import { persistor, store } from './redux/store'; 19 | import { initTheme } from './theme'; 20 | 21 | const App = () => { 22 | useEffect(() => { 23 | initTheme(); 24 | SplashScreen.hide(); 25 | }, []); 26 | 27 | return ( 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | ); 39 | }; 40 | 41 | export default App; 42 | -------------------------------------------------------------------------------- /src/apollo/client.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @flow 3 | * Created by Dima Portenko on 10.10.2020 4 | */ 5 | import { ApolloClient, InMemoryCache } from '@apollo/client'; 6 | import { magentoConfig } from '../../magento.config'; 7 | import possibleTypes from './data/possibleTypes.json'; 8 | import { enableFlipperApolloDevtools } from 'react-native-flipper-apollo-devtools'; 9 | 10 | export const apolloClient = new ApolloClient({ 11 | uri: `${magentoConfig.url}/graphql`, 12 | cache: new InMemoryCache({ 13 | possibleTypes, 14 | }), 15 | defaultOptions: { 16 | watchQuery: { 17 | fetchPolicy: 'cache-first', 18 | }, 19 | }, 20 | }); 21 | 22 | // @ts-ignore 23 | enableFlipperApolloDevtools(apolloClient); 24 | -------------------------------------------------------------------------------- /src/apollo/data/possibleTypes.json: -------------------------------------------------------------------------------- 1 | {"CartAddressInterface":["BillingCartAddress","ShippingCartAddress"],"CartItemInterface":["SimpleCartItem","VirtualCartItem","DownloadableCartItem","ConfigurableCartItem","BundleCartItem","GiftCardCartItem"],"ProductInterface":["VirtualProduct","SimpleProduct","DownloadableProduct","BundleProduct","GroupedProduct","ConfigurableProduct","GiftCardProduct"],"CategoryInterface":["CategoryTree"],"MediaGalleryInterface":["ProductImage","ProductVideo"],"ProductLinksInterface":["ProductLinks"],"CreditMemoItemInterface":["DownloadableCreditMemoItem","BundleCreditMemoItem","CreditMemoItem","GiftCardCreditMemoItem"],"OrderItemInterface":["DownloadableOrderItem","BundleOrderItem","OrderItem","GiftCardOrderItem"],"InvoiceItemInterface":["DownloadableInvoiceItem","BundleInvoiceItem","InvoiceItem","GiftCardInvoiceItem"],"ShipmentItemInterface":["BundleShipmentItem","ShipmentItem","GiftCardShipmentItem"],"WishlistItemInterface":["SimpleWishlistItem","VirtualWishlistItem","DownloadableWishlistItem","BundleWishlistItem","GroupedProductWishlistItem","ConfigurableWishlistItem","GiftCardWishlistItem"],"AggregationOptionInterface":["AggregationOption"],"LayerFilterItemInterface":["LayerFilterItem","SwatchLayerFilterItem"],"PhysicalProductInterface":["SimpleProduct","BundleProduct","GroupedProduct","ConfigurableProduct","GiftCardProduct"],"CustomizableOptionInterface":["CustomizableAreaOption","CustomizableDateOption","CustomizableDropDownOption","CustomizableMultipleOption","CustomizableFieldOption","CustomizableFileOption","CustomizableRadioOption","CustomizableCheckboxOption"],"CustomizableProductInterface":["VirtualProduct","SimpleProduct","DownloadableProduct","BundleProduct","ConfigurableProduct","GiftCardProduct"],"SwatchDataInterface":["ImageSwatchData","TextSwatchData","ColorSwatchData"],"SwatchLayerFilterItemInterface":["SwatchLayerFilterItem"]} -------------------------------------------------------------------------------- /src/apollo/mutations/addProductsToCart.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @flow 3 | * Created by Dima Portenko on 24.11.2020 4 | */ 5 | import { gql } from '@apollo/client'; 6 | 7 | export const ADD_PRODUCTS_TO_CART = gql` 8 | mutation AddProductsToCart($cartId: String!, $quantity: Float!, $sku: String!) { 9 | addProductsToCart(cartId: $cartId, cartItems: [{ quantity: $quantity, sku: $sku }]) { 10 | cart { 11 | items { 12 | id 13 | product { 14 | name 15 | sku 16 | } 17 | quantity 18 | } 19 | } 20 | user_errors { 21 | message 22 | } 23 | } 24 | } 25 | `; 26 | 27 | export type AddProductsToCartResponseType = { 28 | addProductsToCart: { 29 | cart: { 30 | items: { 31 | id: string; 32 | product: { 33 | name: string; 34 | sku: string; 35 | }; 36 | quantity: number; 37 | }; 38 | }; 39 | user_errors: Array<{ 40 | message: string; 41 | }>; 42 | }; 43 | }; 44 | -------------------------------------------------------------------------------- /src/apollo/mutations/createCart.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @flow 3 | * Created by Dima Portenko on 24.11.2020 4 | */ 5 | import { gql } from '@apollo/client'; 6 | 7 | export const CREATE_CART = gql` 8 | mutation createCart { 9 | cartId: createEmptyCart 10 | } 11 | `; 12 | 13 | export type CreateCartResponseType = { 14 | cartId: string; 15 | }; 16 | -------------------------------------------------------------------------------- /src/apollo/mutations/removeItemFromCart.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @flow 3 | * Created by Dima Portenko on 24.11.2020 4 | */ 5 | import { gql } from '@apollo/client'; 6 | import { CART_DETAIL_ITEMS_FRAGMENT } from '../queries/cartItemsFragment'; 7 | import { GetCartDetailsResponse } from '../queries/getCartDetails'; 8 | 9 | export const REMOVE_ITEM_FROM_CART = gql` 10 | mutation RemoveItemFromCart($cartId: String!, $cart_item_uid: ID) { 11 | removeItemFromCart(input: { cart_id: $cartId, cart_item_uid: $cart_item_uid }) { 12 | cart { 13 | ...CartDetailItems 14 | } 15 | } 16 | } 17 | ${CART_DETAIL_ITEMS_FRAGMENT} 18 | `; 19 | 20 | export type RemoveItemFromCartResponse = { 21 | removeItemFromCart: GetCartDetailsResponse; 22 | }; 23 | -------------------------------------------------------------------------------- /src/apollo/queries/cartItemsFragment.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @flow 3 | * Created by Dima Portenko on 24.11.2020 4 | */ 5 | import { gql } from '@apollo/client'; 6 | 7 | export const CART_DETAIL_ITEMS_FRAGMENT = gql` 8 | fragment CartDetailItems on Cart { 9 | items { 10 | uid 11 | prices { 12 | price { 13 | currency 14 | value 15 | } 16 | } 17 | product { 18 | sku 19 | name 20 | image { 21 | url 22 | } 23 | } 24 | quantity 25 | 26 | ... on ConfigurableCartItem { 27 | configurable_options { 28 | option_label 29 | value_label 30 | } 31 | } 32 | } 33 | prices { 34 | grand_total { 35 | currency 36 | value 37 | } 38 | } 39 | } 40 | `; 41 | 42 | export type CartDetailTotals = { 43 | grand_total: { 44 | currency: string; 45 | value: number; 46 | }; 47 | }; 48 | 49 | export type CartDetailItemType = { 50 | uid: string; 51 | prices: { 52 | price: { 53 | currency: string; 54 | value: number; 55 | }; 56 | }; 57 | product: { 58 | sku: string; 59 | name: string; 60 | image: { 61 | url: string; 62 | }; 63 | }; 64 | quantity: number; 65 | 66 | configurable_options?: { 67 | option_label: string; 68 | value_label: string; 69 | }; 70 | }; 71 | 72 | export type CartDetailItemsType = { 73 | items: CartDetailItemType[]; 74 | }; 75 | -------------------------------------------------------------------------------- /src/apollo/queries/getCartDetails.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @flow 3 | * Created by Dima Portenko on 10.10.2020 4 | */ 5 | 6 | import { gql } from '@apollo/client'; 7 | import { 8 | CartDetailItemType, 9 | CART_DETAIL_ITEMS_FRAGMENT, 10 | CartDetailTotals, 11 | } from './cartItemsFragment'; 12 | 13 | export const GET_CART_DETAILS = gql` 14 | query GetCartDetails($cartId: String!) { 15 | cart(cart_id: $cartId) { 16 | ...CartDetailItems 17 | } 18 | } 19 | ${CART_DETAIL_ITEMS_FRAGMENT} 20 | `; 21 | 22 | export type GetCartDetailsResponse = { 23 | cart: { 24 | items: CartDetailItemType[]; 25 | prices: CartDetailTotals; 26 | }; 27 | }; 28 | -------------------------------------------------------------------------------- /src/apollo/queries/getCategory.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @flow 3 | * Created by Dima Portenko on 10.10.2020 4 | */ 5 | 6 | import { gql } from '@apollo/client'; 7 | 8 | export const GET_CATEGORIES = gql` 9 | query GetCategories($id: String!) { 10 | categoryList(filters: { ids: { eq: $id } }) { 11 | id 12 | children { 13 | id 14 | name 15 | product_count 16 | children_count 17 | image 18 | productPreviewImage: products(pageSize: 1) { 19 | items { 20 | small_image { 21 | url 22 | } 23 | } 24 | } 25 | } 26 | } 27 | } 28 | `; 29 | 30 | export type CategoryListType = { 31 | categoryList: Array; 32 | }; 33 | 34 | export type CategoryListNodeType = { 35 | id: number; 36 | children: Array; 37 | }; 38 | 39 | type CategoryProductPreviwImageType = { 40 | items: Array<{ 41 | small_image: { 42 | url: string | null; 43 | }; 44 | }>; 45 | }; 46 | 47 | export type CategoryType = { 48 | id: number; 49 | name: string; 50 | product_count: number; 51 | children_count: number; 52 | image: string | null; 53 | productPreviewImage: CategoryProductPreviwImageType; 54 | }; 55 | -------------------------------------------------------------------------------- /src/apollo/queries/getCategoryProducts.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @flow 3 | * Created by Dima Portenko on 10.10.2020 4 | */ 5 | 6 | import { gql } from '@apollo/client'; 7 | 8 | export const GET_CATEGORY_PRODUCTS = gql` 9 | query GetCategoryProducts($id: String!, $pageSize: Int!, $currentPage: Int!) { 10 | products(filter: { category_id: { eq: $id } }, pageSize: $pageSize, currentPage: $currentPage) { 11 | total_count 12 | items { 13 | id 14 | name 15 | sku 16 | small_image { 17 | url 18 | } 19 | price_range { 20 | minimum_price { 21 | final_price { 22 | currency 23 | value 24 | } 25 | } 26 | } 27 | } 28 | } 29 | } 30 | `; 31 | 32 | export type GetCategoryProductsType = { 33 | products: { 34 | total_count: number; 35 | items: Array; 36 | }; 37 | }; 38 | 39 | export type PriceRange = { 40 | minimum_price: { 41 | final_price: { 42 | currency: string; 43 | value: number; 44 | }; 45 | }; 46 | }; 47 | 48 | export type ProductType = { 49 | id: number; 50 | name: string; 51 | sku: string; 52 | small_image: { 53 | url: string; 54 | }; 55 | price_range: PriceRange; 56 | }; 57 | -------------------------------------------------------------------------------- /src/apollo/queries/getProductDetails.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @flow 3 | * Created by Dima Portenko on 10.10.2020 4 | */ 5 | 6 | import { gql } from '@apollo/client'; 7 | import { MEDIA_GALLERY_FRAGMENT } from './mediaGalleryFragment'; 8 | import { PRODUCT_PRICE_FRAGMENT } from './productPriceFragment'; 9 | import type { MediaGalleryItemType } from './mediaGalleryFragment'; 10 | import type { PriceRange } from './getCategoryProducts'; 11 | 12 | export const GET_PRODUCT_DETAILS = gql` 13 | query GetProductDetails($sku: String!) { 14 | products(filter: { sku: { eq: $sku } }) { 15 | items { 16 | id 17 | sku 18 | name 19 | description { 20 | html 21 | } 22 | price_range { 23 | minimum_price { 24 | final_price { 25 | currency 26 | value 27 | } 28 | } 29 | } 30 | ...MediaGallery 31 | ... on ConfigurableProduct { 32 | configurable_options { 33 | attribute_code 34 | label 35 | values { 36 | label 37 | value_index 38 | swatch_data { 39 | value 40 | } 41 | } 42 | } 43 | variants { 44 | attributes { 45 | code 46 | value_index 47 | } 48 | product { 49 | sku 50 | ...MediaGallery 51 | ...ProductPrice 52 | } 53 | } 54 | } 55 | } 56 | total_count 57 | } 58 | } 59 | ${MEDIA_GALLERY_FRAGMENT} 60 | ${PRODUCT_PRICE_FRAGMENT} 61 | `; 62 | 63 | export type ProductInterfaceDetailsType = { 64 | id: number; 65 | sku: string; 66 | name: string; 67 | media_gallery: Array; 68 | price_range: PriceRange; 69 | description: { 70 | html: string; 71 | }; 72 | }; 73 | 74 | export type SimpleProductDetailsType = ProductInterfaceDetailsType & { 75 | __typename: 'SimpleProduct'; 76 | }; 77 | 78 | export type ConfigurableProductOptionValueType = { 79 | label: string; 80 | value_index: number; 81 | swatch_data: { 82 | value: string; 83 | __typename: 'ImageSwatchData' | 'TextSwatchData' | 'ColorSwatchData'; 84 | }; 85 | }; 86 | 87 | export type ConfigurableProductOptionsType = { 88 | attribute_code: string; 89 | label: string; 90 | values: ConfigurableProductOptionValueType[]; 91 | }; 92 | 93 | export type ConfigurableProductVariantAttribute = { 94 | code: string; 95 | value_index: number; 96 | }; 97 | 98 | export type ConfigurableProductVariantProduct = { 99 | sku: string; 100 | media_gallery: Array; 101 | price_range: PriceRange; 102 | }; 103 | 104 | export type ConfigurableProductVariant = { 105 | attributes: ConfigurableProductVariantAttribute[]; 106 | product: ConfigurableProductVariantProduct; 107 | }; 108 | 109 | export type ConfigurableProductDetailsType = ProductInterfaceDetailsType & { 110 | __typename: 'ConfigurableProduct'; 111 | configurable_options: ConfigurableProductOptionsType[]; 112 | variants: ConfigurableProductVariant[]; 113 | }; 114 | 115 | export type ProductDetailsType = SimpleProductDetailsType | ConfigurableProductDetailsType; 116 | 117 | export type ProductDetailsResponseType = { 118 | products: { 119 | total_count: number; 120 | items: Array; 121 | }; 122 | }; 123 | -------------------------------------------------------------------------------- /src/apollo/queries/mediaGalleryFragment.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @flow 3 | * Created by Dima Portenko on 24.11.2020 4 | */ 5 | import { gql } from '@apollo/client'; 6 | 7 | export const MEDIA_GALLERY_FRAGMENT = gql` 8 | fragment MediaGallery on ProductInterface { 9 | media_gallery { 10 | disabled 11 | label 12 | position 13 | url 14 | } 15 | } 16 | `; 17 | 18 | export type MediaGalleryItemType = { 19 | disabled: boolean; 20 | label: string; 21 | position: number; 22 | url: string; 23 | }; 24 | -------------------------------------------------------------------------------- /src/apollo/queries/productPriceFragment.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @flow 3 | * Created by Dima Portenko on 24.11.2020 4 | */ 5 | import { gql } from '@apollo/client'; 6 | 7 | export const PRODUCT_PRICE_FRAGMENT = gql` 8 | fragment ProductPrice on ProductInterface { 9 | price_range { 10 | minimum_price { 11 | final_price { 12 | currency 13 | value 14 | } 15 | } 16 | } 17 | } 18 | `; 19 | -------------------------------------------------------------------------------- /src/components/cart/CartDetailsListItem.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Dima Portenko on 04.05.2021 3 | */ 4 | import React from 'react'; 5 | import { AnimatedAppearance } from '../common/AnimatedAppearance'; 6 | import { Text, View } from 'react-native-ui-lib'; 7 | import { ActivityIndicator, Image } from 'react-native'; 8 | import { getPriceString } from '../../logic/util/price'; 9 | import { TouchableScale } from '../common/TouchableScale'; 10 | import Icon from 'react-native-vector-icons/EvilIcons'; 11 | import { CartDetailItemType } from '../../apollo/queries/cartItemsFragment'; 12 | 13 | interface CartDetailsListItemProps { 14 | index: number; 15 | isLast: boolean; 16 | removing: boolean; 17 | item: CartDetailItemType; 18 | onRemoveCartItemPress: (item: CartDetailItemType) => void; 19 | } 20 | 21 | export const CartDetailsListItem = ({ index, isLast, item, onRemoveCartItemPress, removing }: CartDetailsListItemProps) => { 22 | 23 | return ( 24 | 25 | 26 | 27 | 28 | 33 | 34 | 35 | 36 | {item.product.name} 37 | {getPriceString(item.prices.price)} 38 | {`qty: ${item.quantity}`} 39 | 40 | 41 | 42 | onRemoveCartItemPress(item)} scaleTo={0.93}> 43 | 44 | {removing ? ( 45 | 46 | ) : ( 47 | 48 | )} 49 | 50 | 51 | 52 | 53 | {!isLast && ( 54 | 55 | )} 56 | 57 | 58 | ); 59 | }; 60 | -------------------------------------------------------------------------------- /src/components/cart/CartDetailsScreen.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Dima Portenko on 02.04.2021 3 | */ 4 | import React, { useEffect, useState } from 'react'; 5 | import { View, Text } from 'react-native-ui-lib'; 6 | import { useCartDetails } from '../../logic/cart/useCartDetails'; 7 | import { ActivityIndicator, FlatList, ListRenderItem, RefreshControl } from 'react-native'; 8 | import { CartDetailItemType } from '../../apollo/queries/cartItemsFragment'; 9 | import { useSafeAreaInsets } from 'react-native-safe-area-context'; 10 | import { getPriceString } from '../../logic/util/price'; 11 | import { CartDetailsListItem } from './CartDetailsListItem'; 12 | import TouchableRipple from '../common/TouchableRipple'; 13 | import { CartDetailsScreenNavigationProp } from '../../navigation/Navigation'; 14 | import * as routes from '../../navigation/routes'; 15 | 16 | interface CartDetailsScreenProps { 17 | navigation: CartDetailsScreenNavigationProp; 18 | } 19 | 20 | export const CartDetailsScreen = ({ navigation }: CartDetailsScreenProps) => { 21 | const [removeItemUid, setRemoveItemUid] = useState(''); 22 | const { 23 | getCartDetails, 24 | loading, 25 | cartItems, 26 | totals, 27 | removeFromCart, 28 | removeItemLoading, 29 | } = useCartDetails(); 30 | const insets = useSafeAreaInsets(); 31 | 32 | useEffect(() => { 33 | getCartDetails(); 34 | }, []); 35 | 36 | const onRemoveCartItemPress = (item: CartDetailItemType) => { 37 | setRemoveItemUid(item.uid); 38 | removeFromCart(item.uid); 39 | }; 40 | 41 | const renderCartItem: ListRenderItem = ({ item, index }) => { 42 | const isLast = cartItems.length - 1 === index; 43 | return ( 44 | 51 | ); 52 | }; 53 | 54 | return ( 55 | 56 | item.product.sku} 60 | showsVerticalScrollIndicator={false} 61 | refreshControl={} 62 | /> 63 | 64 | {!!totals && ( 65 | {`Totals: ${getPriceString(totals?.grand_total)}`} 66 | )} 67 | { 72 | navigation.navigate(routes.NAVIGATION_CHECKOUT_ROUTE); 73 | }}> 74 | 75 | 76 | 77 | Checkout 78 | 79 | 80 | 81 | 82 | 83 | 84 | ); 85 | }; 86 | -------------------------------------------------------------------------------- /src/components/cart/HeaderCartButton.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Dima Portenko on 02.04.2021 3 | */ 4 | import { useNavigation } from '@react-navigation/native'; 5 | import React from 'react'; 6 | import { View } from 'react-native-ui-lib'; 7 | import Icon from 'react-native-vector-icons/EvilIcons'; 8 | import { TouchableScale } from '../common/TouchableScale'; 9 | import * as routes from '../../navigation/routes'; 10 | 11 | interface HeaderCartButtonProps { 12 | 13 | } 14 | 15 | export const HeaderCartButton = (props: HeaderCartButtonProps) => { 16 | const navigation = useNavigation(); 17 | 18 | const onPress = () => { 19 | navigation.navigate(routes.NAVIGATION_CART_DETAILS_ROUTE); 20 | }; 21 | 22 | return ( 23 | 24 | 25 | 26 | 27 | 28 | ); 29 | }; 30 | -------------------------------------------------------------------------------- /src/components/categories/CategoriesScreen.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * @flow 3 | * Created by Dima Portenko on 06.10.2020 4 | */ 5 | import React, { useEffect } from 'react'; 6 | import { FlatList, ListRenderItemInfo, RefreshControl } from 'react-native'; 7 | import View from 'react-native-ui-lib/view'; 8 | import { useCategories } from '../../logic/categories/useCategories'; 9 | import * as routes from '../../navigation/routes'; 10 | import { CategoryListItem } from './CategoryListItem'; 11 | import { useCategoryColors } from '../../logic/categories/useCategoryColors'; 12 | import { CategoryType } from '../../apollo/queries/getCategory'; 13 | import { 14 | CategoriesScreenRouteProp, 15 | CategoriesScreenNavigationProp, 16 | } from '../../navigation/Navigation'; 17 | 18 | type CategoriesScreenProps = { 19 | route: CategoriesScreenRouteProp; 20 | navigation: CategoriesScreenNavigationProp; 21 | }; 22 | 23 | export const CategoriesScreen = ({ route, navigation }: CategoriesScreenProps) => { 24 | const { getCategoryColorByIndex } = useCategoryColors(); 25 | const { getCategories, categories, loading } = useCategories({ 26 | categoryId: route?.params?.categoryId ?? 2, 27 | }); 28 | 29 | useEffect(() => { 30 | getCategories(); 31 | }, [getCategories]); 32 | 33 | const onCategoryItemPress = (item: CategoryType) => { 34 | if (item.children_count > 0) { 35 | navigation.push(routes.NAVIGATION_CATEGORIES_ROUTE, { 36 | categoryId: item.id, 37 | title: item.name, 38 | }); 39 | } else if (item.product_count > 0) { 40 | navigation.push(routes.NAVIGATION_PRODUCTS_ROUTE, { 41 | categoryId: item.id, 42 | title: item.name, 43 | }); 44 | } 45 | }; 46 | 47 | const renderItem = ({ item, index }: ListRenderItemInfo) => { 48 | return ( 49 | 55 | ); 56 | }; 57 | 58 | return ( 59 | 60 | `categoryItem${item.id.toString()}`} 64 | renderItem={renderItem} 65 | refreshControl={} 66 | /> 67 | 68 | ); 69 | }; 70 | -------------------------------------------------------------------------------- /src/components/categories/CategoryListItem.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * @flow 3 | * Created by Dima Portenko on 04.11.2020 4 | */ 5 | import React, { useState } from 'react'; 6 | import { Image, StyleSheet } from 'react-native'; 7 | import View from 'react-native-ui-lib/view'; 8 | import Text from 'react-native-ui-lib/text'; 9 | import type { CategoryType } from '../../apollo/queries/getCategory'; 10 | import { TouchableScale } from '../common/TouchableScale'; 11 | import { AnimatedAppearance } from '../common/AnimatedAppearance'; 12 | import { Shadows } from '../../theme/shadows'; 13 | import { fonts } from '../../theme/fonts'; 14 | 15 | type Props = { 16 | item: CategoryType; 17 | onPress(item: CategoryType): void; 18 | color: string; 19 | index: number; 20 | }; 21 | 22 | const ITEM_HEIGHT = 80; 23 | 24 | export const CategoryListItem = ({ item, onPress, color, index }: Props) => { 25 | const [disabled] = useState(item.children_count < 1 && item.product_count < 1); 26 | 27 | const renderText = () => ( 28 | 29 | {item.name} 30 | 31 | ); 32 | 33 | const renderImage = (isRight: boolean) => { 34 | const rawUri = item.image ?? item?.productPreviewImage?.items?.[0]?.small_image?.url; 35 | if (!rawUri) { 36 | return null; 37 | } 38 | const uri = `${rawUri ?? ''}?width=300`; 39 | // console.log({ uri }); 40 | return ( 41 | 42 | 43 | 44 | ); 45 | }; 46 | 47 | const renderContent = () => { 48 | const isRight = index % 2 === 0; 49 | if (isRight) { 50 | return ( 51 | <> 52 | {renderText()} 53 | {renderImage(isRight)} 54 | 55 | ); 56 | } 57 | return ( 58 | <> 59 | {renderImage(isRight)} 60 | {renderText()} 61 | 62 | ); 63 | }; 64 | 65 | return ( 66 | 67 | onPress(item)} disabled={disabled} scaleTo={0.97}> 68 | 77 | {renderContent()} 78 | 79 | 80 | 81 | ); 82 | }; 83 | 84 | const styles = StyleSheet.create({ 85 | image: { 86 | height: ITEM_HEIGHT, 87 | width: ITEM_HEIGHT, 88 | }, 89 | left: { 90 | borderTopLeftRadius: 12, 91 | borderBottomLeftRadius: 12, 92 | overflow: 'hidden', 93 | }, 94 | right: { 95 | borderTopRightRadius: 12, 96 | borderBottomRightRadius: 12, 97 | overflow: 'hidden', 98 | }, 99 | title: { 100 | fontFamily: fonts.SourceSansProLight, 101 | fontSize: 24, 102 | }, 103 | }); 104 | -------------------------------------------------------------------------------- /src/components/checkout/CheckoutScreen.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Dima Portenko on 13.05.2021 3 | */ 4 | import React from 'react'; 5 | import { View, Text } from 'react-native-ui-lib'; 6 | 7 | interface CheckoutScreenProps { 8 | 9 | } 10 | 11 | export const CheckoutScreen = (props: CheckoutScreenProps) => { 12 | 13 | return ( 14 | 15 | Checkout Screen 16 | 17 | ); 18 | }; 19 | -------------------------------------------------------------------------------- /src/components/common/AnimatedAppearance.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * @flow 3 | * Created by Dima Portenko on 06.11.2020 4 | */ 5 | import React, { ReactElement, useEffect } from 'react'; 6 | import Animated, { 7 | useAnimatedStyle, 8 | useSharedValue, 9 | useDerivedValue, 10 | interpolate, 11 | withDelay, 12 | withTiming, 13 | } from 'react-native-reanimated'; 14 | 15 | type Props = { 16 | children: ReactElement; 17 | index?: number; 18 | }; 19 | 20 | export const AnimatedAppearance = ({ children, index }: Props) => { 21 | const play = useSharedValue(false); 22 | const progress = useDerivedValue(() => { 23 | return play.value ? withDelay(50 * (index ?? 0), withTiming(1, { duration: 350 })) : 0; 24 | }); 25 | 26 | useEffect(() => { 27 | play.value = true; 28 | }, []); // eslint-disable-line 29 | 30 | const animatedStyle = useAnimatedStyle(() => { 31 | const opacity = interpolate(progress.value, [0, 1], [0, 1]); 32 | 33 | const translateY = interpolate(progress.value, [0, 1], [100, 0]); 34 | 35 | return { 36 | opacity, 37 | transform: [{ translateY }], 38 | }; 39 | }); 40 | 41 | return {children}; 42 | }; 43 | -------------------------------------------------------------------------------- /src/components/common/MediaGallery.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * @flow 3 | * Created by Dima Portenko on 27.11.2020 4 | */ 5 | import React, { useState } from 'react'; 6 | import { 7 | FlatList, 8 | Image, 9 | ListRenderItemInfo, 10 | NativeScrollEvent, 11 | NativeSyntheticEvent, 12 | useWindowDimensions, 13 | } from 'react-native'; 14 | import View from 'react-native-ui-lib/view'; 15 | import Text from 'react-native-ui-lib/text'; 16 | import { MediaGalleryItemType } from '../../apollo/queries/mediaGalleryFragment'; 17 | 18 | type Props = { 19 | items: Array; 20 | }; 21 | 22 | export const MediaGallery = ({ items }: Props) => { 23 | const [currentPage, setCurrentPage] = useState(1); 24 | const { width: screenWidth } = useWindowDimensions(); 25 | 26 | const renderItem = ({ item }: ListRenderItemInfo) => { 27 | return ( 28 | 29 | 37 | 38 | ); 39 | }; 40 | 41 | const onMomentumScrollEnd = (event: NativeSyntheticEvent) => { 42 | const contentOffset = event.nativeEvent.contentOffset.x; 43 | const width = event.nativeEvent.layoutMeasurement.width; 44 | 45 | const currentNumber = Math.floor(contentOffset / width) + 1; 46 | setCurrentPage(currentNumber); 47 | }; 48 | 49 | return ( 50 | 51 | `MediaGallery${index}`} 54 | renderItem={renderItem} 55 | horizontal 56 | showsHorizontalScrollIndicator={false} 57 | pagingEnabled 58 | onMomentumScrollEnd={onMomentumScrollEnd} 59 | /> 60 | 70 | {`${currentPage} / ${items?.length}`} 71 | 72 | 73 | ); 74 | }; 75 | -------------------------------------------------------------------------------- /src/components/common/TouchableRipple.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * @flow 3 | * Created by Dima Portenko on 03.01.2021 4 | */ 5 | import React, { Children, ReactElement, useState } from 'react'; 6 | import { State, TapGestureHandler } from 'react-native-gesture-handler'; 7 | import Animated, { 8 | call, 9 | cond, 10 | diff, 11 | eq, 12 | greaterThan, 13 | onChange, 14 | or, 15 | useCode, 16 | } from 'react-native-reanimated'; 17 | import { StyleSheet, View } from 'react-native'; 18 | import { mix, translate, useTapGestureHandler, vec } from 'react-native-redash'; 19 | import { withTransition } from './util/Transitions'; 20 | 21 | type RippleButtonProps = { 22 | children: ReactElement; 23 | color: string; 24 | rippleColor: string; 25 | onPress?: () => void; 26 | enabled: boolean; 27 | }; 28 | 29 | const TouchableRipple = ({ children, color, onPress, rippleColor, enabled }: RippleButtonProps) => { 30 | const [radius, setRadius] = useState(-1); 31 | const { gestureHandler, position, state } = useTapGestureHandler(); 32 | const child = Children.only(children); 33 | const progress = withTransition(eq(state, State.BEGAN)); 34 | const isGoingUp = or(greaterThan(diff(progress), 0), eq(progress, 1)); 35 | const scale = mix(progress, 0.001, 1); 36 | const opacity = isGoingUp; 37 | const backgroundColor = rippleColor; 38 | useCode( 39 | () => [onChange(state, cond(eq(state, State.END), [call([], onPress || (() => null))]))], 40 | [onPress], 41 | ); 42 | return ( 43 | 44 | 45 | setRadius(Math.sqrt(width ** 2 + height ** 2))}> 56 | {radius !== -1 && ( 57 | 67 | )} 68 | 69 | {child.props.children} 70 | 71 | 72 | ); 73 | }; 74 | 75 | export default TouchableRipple; 76 | -------------------------------------------------------------------------------- /src/components/common/TouchableScale.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * @flow 3 | * Created by Dima Portenko on 06.11.2020 4 | */ 5 | import React, { ReactElement } from 'react'; 6 | import { TouchableWithoutFeedback } from 'react-native'; 7 | import Animated, { 8 | useAnimatedStyle, 9 | useSharedValue, 10 | useDerivedValue, 11 | withTiming, 12 | interpolate, 13 | Extrapolate, 14 | } from 'react-native-reanimated'; 15 | 16 | type Props = { 17 | children: ReactElement; 18 | onPress(): void; 19 | scaleTo?: number; 20 | disabled?: boolean; 21 | }; 22 | 23 | const TimingConfig = { duration: 50 }; 24 | 25 | export const TouchableScale = ({ onPress, children, scaleTo = 0.97, disabled = false }: Props) => { 26 | const pressed = useSharedValue(false); 27 | const progress = useDerivedValue(() => { 28 | return pressed.value ? withTiming(1, TimingConfig) : withTiming(0, TimingConfig); 29 | }); 30 | const animatedStyle = useAnimatedStyle(() => { 31 | const scale = interpolate(progress.value, [0, 1], [1, scaleTo], Extrapolate.CLAMP); 32 | 33 | return { 34 | transform: [{ scale }], 35 | }; 36 | }); 37 | 38 | return ( 39 | { 41 | pressed.value = true; 42 | }} 43 | onPressOut={() => { 44 | pressed.value = false; 45 | }} 46 | onPress={onPress} 47 | disabled={disabled}> 48 | {children} 49 | 50 | ); 51 | }; 52 | -------------------------------------------------------------------------------- /src/components/common/util/Transitions.ts: -------------------------------------------------------------------------------- 1 | import { useEffect, useRef } from 'react'; 2 | import Animated, { EasingNode, not } from 'react-native-reanimated'; 3 | 4 | type SpringConfig = Partial>; 5 | type TimingConfig = Partial>; 6 | 7 | const { 8 | Value, 9 | cond, 10 | block, 11 | set, 12 | Clock, 13 | spring, 14 | startClock, 15 | stopClock, 16 | timing, 17 | neq, 18 | SpringUtils, 19 | } = Animated; 20 | 21 | const defaultSpringConfig = SpringUtils.makeDefaultConfig(); 22 | 23 | export const useConst = (initialValue: T | (() => T)): T => { 24 | const ref = useRef<{ value: T }>(); 25 | if (ref.current === undefined) { 26 | // Box the value in an object so we can tell if it's initialized even if the initializer 27 | // returns/is undefined 28 | ref.current = { 29 | value: typeof initialValue === 'function' ? (initialValue as Function)() : initialValue, 30 | }; 31 | } 32 | return ref.current.value; 33 | }; 34 | 35 | export const withTransition = (value: Animated.Node, timingConfig: TimingConfig = {}) => { 36 | const init = new Value(0); 37 | const clock = new Clock(); 38 | const state = { 39 | finished: new Value(0), 40 | frameTime: new Value(0), 41 | position: new Value(0), 42 | time: new Value(0), 43 | }; 44 | const config = { 45 | toValue: new Value(0), 46 | duration: 150, 47 | easing: EasingNode.linear, 48 | ...timingConfig, 49 | }; 50 | return block([ 51 | cond(not(init), [set(init, 1), set(state.position, value)]), 52 | cond(neq(config.toValue, value), [ 53 | set(state.frameTime, 0), 54 | set(state.time, 0), 55 | set(state.finished, 0), 56 | set(config.toValue, value), 57 | startClock(clock), 58 | ]), 59 | timing(clock, state, config), 60 | cond(state.finished, stopClock(clock)), 61 | state.position, 62 | ]); 63 | }; 64 | 65 | export const withSpringTransition = ( 66 | value: Animated.Node, 67 | springConfig: SpringConfig = defaultSpringConfig, 68 | velocity: Animated.Adaptable = 0, 69 | ) => { 70 | const init = new Value(0); 71 | const clock = new Clock(); 72 | const state = { 73 | finished: new Value(0), 74 | velocity: new Value(0), 75 | position: new Value(0), 76 | time: new Value(0), 77 | }; 78 | const config = { 79 | toValue: new Value(0), 80 | damping: 15, 81 | mass: 1, 82 | stiffness: 150, 83 | overshootClamping: false, 84 | restSpeedThreshold: 1, 85 | restDisplacementThreshold: 1, 86 | ...springConfig, 87 | }; 88 | return block([ 89 | cond(not(init), [set(init, 1), set(state.position, value)]), 90 | cond(neq(config.toValue, value), [ 91 | set(state.velocity, velocity), 92 | set(state.time, 0), 93 | set(state.finished, 0), 94 | set(config.toValue, value), 95 | startClock(clock), 96 | ]), 97 | spring(clock, state, config), 98 | cond(state.finished, stopClock(clock)), 99 | state.position, 100 | ]); 101 | }; 102 | 103 | export const withTimingTransition = withTransition; 104 | 105 | export const useTransition = (state: boolean | number, config: TimingConfig = {}) => { 106 | const value: Animated.Value = useConst(() => new Value(0)); 107 | useEffect(() => { 108 | value.setValue(typeof state === 'boolean' ? (state ? 1 : 0) : state); 109 | }, [value, state]); 110 | const transition = useConst(() => withTransition(value, config)); 111 | return transition; 112 | }; 113 | 114 | export const useSpringTransition = ( 115 | state: boolean | number, 116 | config: SpringConfig = defaultSpringConfig, 117 | ) => { 118 | const value: Animated.Value = useConst(() => new Value(0)); 119 | 120 | useEffect(() => { 121 | value.setValue(typeof state === 'boolean' ? (state ? 1 : 0) : state); 122 | }, [value, state]); 123 | 124 | const transition = useConst(() => withSpringTransition(value, config)); 125 | return transition; 126 | }; 127 | 128 | export const useTimingTransition = useTransition; 129 | -------------------------------------------------------------------------------- /src/components/products/ProductDetailsScreen.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * @flow 3 | * Created by Dima Portenko on 23.11.2020 4 | */ 5 | import React, { useEffect } from 'react'; 6 | import { ActivityIndicator, ScrollView, StyleSheet, useWindowDimensions } from 'react-native'; 7 | import View from 'react-native-ui-lib/view'; 8 | import Text from 'react-native-ui-lib/text'; 9 | import Icon from 'react-native-vector-icons/EvilIcons'; 10 | import { useProductDetails } from '../../logic/products/useProductDetails'; 11 | import { MediaGallery } from '../common/MediaGallery'; 12 | import { priceStringFromPriceRange } from '../../logic/util/price'; 13 | import HTML from 'react-native-render-html'; 14 | import { useSafeAreaInsets } from 'react-native-safe-area-context'; 15 | import TouchableRipple from '../common/TouchableRipple'; 16 | import { ConfigurableProductOptions } from './options/ConfigurableProductOptions'; 17 | import { ProductDetailsScreenRouteProp } from '../../navigation/Navigation'; 18 | import { fonts } from '../../theme/fonts'; 19 | 20 | type ProductDetailsScreenProps = { 21 | route: ProductDetailsScreenRouteProp; 22 | }; 23 | 24 | export const ProductDetailsScreen = ({ route }: ProductDetailsScreenProps) => { 25 | const insets = useSafeAreaInsets(); 26 | const { width: screenWidth } = useWindowDimensions(); 27 | const { 28 | getProductDetails, 29 | loading, 30 | productData, 31 | selectedConfigurableProductOptions, 32 | handleSelectConfigurableOption, 33 | mediaGallery, 34 | price, 35 | addToCart, 36 | addProductLoading, 37 | } = useProductDetails({ 38 | sku: route?.params?.sku, 39 | }); 40 | 41 | useEffect(() => { 42 | getProductDetails(); 43 | }, []); // eslint-disable-line 44 | 45 | const onAddToCartPress = () => { 46 | addToCart(); 47 | }; 48 | 49 | if (loading) { 50 | return ( 51 | 52 | 53 | 54 | ); 55 | } 56 | 57 | const renderOptions = () => { 58 | if (productData?.__typename === 'ConfigurableProduct') { 59 | return ( 60 | 61 | 66 | 67 | ); 68 | } 69 | return null; 70 | }; 71 | 72 | return ( 73 | 74 | 75 | 76 | 77 | 78 | {productData?.name} 79 | 80 | 81 | {priceStringFromPriceRange(price)} 82 | 83 | {renderOptions()} 84 | {!!productData && ( 85 | 86 | 91 | 92 | )} 93 | 94 | 95 | 100 | 101 | 102 | {addProductLoading ? ( 103 | 104 | ) : ( 105 | 106 | )} 107 | 108 | Add To Cart 109 | 110 | 111 | 112 | 113 | 114 | 115 | ); 116 | }; 117 | 118 | const styles = StyleSheet.create({ 119 | title: { 120 | fontFamily: fonts.SourceSansProRegular, 121 | fontSize: 18, 122 | }, 123 | }); 124 | -------------------------------------------------------------------------------- /src/components/products/ProductListItem.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * @flow 3 | * Created by Dima Portenko on 11.11.2020 4 | */ 5 | import React from 'react'; 6 | import { Image, StyleSheet, useWindowDimensions } from 'react-native'; 7 | import View from 'react-native-ui-lib/view'; 8 | import Text from 'react-native-ui-lib/text'; 9 | import { Spacings } from 'react-native-ui-lib/core'; 10 | import { TouchableScale } from '../common/TouchableScale'; 11 | import { AnimatedAppearance } from '../common/AnimatedAppearance'; 12 | import { priceStringFromPriceRange } from '../../logic/util/price'; 13 | import { Shadows } from '../../theme/shadows'; 14 | import { ProductType } from '../../apollo/queries/getCategoryProducts'; 15 | 16 | type Props = { 17 | item: ProductType; 18 | index: number; 19 | onPress(item: ProductType): void; 20 | }; 21 | 22 | export const ProductListItem = ({ item, index, onPress }: Props) => { 23 | const { width: screenWidth } = useWindowDimensions(); 24 | const COLUMN_SIZE = screenWidth / 2 - Spacings.s2 * 3; 25 | 26 | return ( 27 | 28 | { 30 | onPress(item); 31 | }} 32 | scaleTo={0.97} 33 | disabled={false}> 34 | 35 | 44 | 51 | 52 | 53 | {item.name} 54 | 55 | 56 | {priceStringFromPriceRange(item.price_range)} 57 | 58 | 59 | 60 | 61 | ); 62 | }; 63 | 64 | const styles = StyleSheet.create({ 65 | imageWrap: { 66 | overflow: 'hidden', 67 | }, 68 | }); 69 | -------------------------------------------------------------------------------- /src/components/products/ProductListScreen.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * @flow 3 | * Created by Dima Portenko on 09.11.2020 4 | */ 5 | import React, { useEffect } from 'react'; 6 | import { ActivityIndicator, FlatList, ListRenderItemInfo, RefreshControl } from 'react-native'; 7 | import View from 'react-native-ui-lib/view'; 8 | import { useCategoryProducts } from '../../logic/products/useCategoryProducts'; 9 | import { ProductListItem } from './ProductListItem'; 10 | import * as routes from '../../navigation/routes'; 11 | import { Spacings } from 'react-native-ui-lib/core'; 12 | import { ProductType } from '../../apollo/queries/getCategoryProducts'; 13 | import { 14 | ProductListScreenNavigationProp, 15 | ProductListScreenRouteProp, 16 | } from '../../navigation/Navigation'; 17 | 18 | type ProductListScreenProps = { 19 | route: ProductListScreenRouteProp; 20 | navigation: ProductListScreenNavigationProp; 21 | }; 22 | 23 | export const ProductListScreen = ({ route, navigation }: ProductListScreenProps) => { 24 | const { loading, products, loadMore, refreshing, refresh } = useCategoryProducts({ 25 | categoryId: route?.params?.categoryId, 26 | }); 27 | 28 | const onProductItemPress = (item: ProductType) => { 29 | navigation.push(routes.NAVIGATION_PRODUCT_DETAILS_ROUTE, { 30 | title: item.name, 31 | sku: item.sku, 32 | }); 33 | }; 34 | 35 | const renderItem = ({ item, index }: ListRenderItemInfo) => { 36 | return ; 37 | }; 38 | 39 | const footerComponent = () => { 40 | if (loading && products.length !== 0) { 41 | return ( 42 | 43 | 44 | 45 | ); 46 | } 47 | return null; 48 | }; 49 | 50 | return ( 51 | 52 | `productItem${item.id.toString()}`} 60 | renderItem={renderItem} 61 | refreshControl={} 62 | onEndReached={loadMore} 63 | ListFooterComponent={footerComponent} 64 | /> 65 | 66 | ); 67 | }; 68 | -------------------------------------------------------------------------------- /src/components/products/options/ConfigurableOptionValues.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * @flow 3 | * Created by Dima Portenko on 16.02.2021 4 | */ 5 | import React from 'react'; 6 | import { StyleSheet } from 'react-native'; 7 | import View from 'react-native-ui-lib/view'; 8 | import Text from 'react-native-ui-lib/text'; 9 | import type { ConfigurableProductOptionValueType } from '../../../apollo/queries/getProductDetails'; 10 | import { TouchableScale } from '../../common/TouchableScale'; 11 | import Icon from 'react-native-vector-icons/Ionicons'; 12 | import type { HandleSelectConfigurableOption } from '../../../logic/products/useProductDetails'; 13 | 14 | type Props = { 15 | values: ConfigurableProductOptionValueType[]; 16 | optionCode: string; 17 | selectedIndex: number; 18 | handleSelectConfigurableOption: HandleSelectConfigurableOption; 19 | }; 20 | 21 | export const ConfigurableOptionValues = ({ 22 | values, 23 | selectedIndex, 24 | handleSelectConfigurableOption, 25 | optionCode, 26 | }: Props) => { 27 | const renderValue = (value: ConfigurableProductOptionValueType) => { 28 | const selected = selectedIndex === value.value_index; 29 | switch (value.swatch_data.__typename) { 30 | case 'ColorSwatchData': { 31 | return ( 32 | <> 33 | 34 | {selected ? ( 35 | 36 | 37 | 38 | ) : null} 39 | 40 | ); 41 | } 42 | case 'TextSwatchData': { 43 | return ( 44 | 46 | 47 | {value.swatch_data.value} 48 | 49 | 50 | ); 51 | } 52 | default: { 53 | return null; 54 | } 55 | } 56 | }; 57 | 58 | return ( 59 | 60 | {values.map(value => ( 61 | handleSelectConfigurableOption(optionCode, value.value_index)}> 64 | {renderValue(value)} 65 | 66 | ))} 67 | 68 | ); 69 | }; 70 | 71 | const styles = StyleSheet.create({ 72 | values: { 73 | borderColor: 'black', 74 | borderWidth: 1, 75 | marginRight: 10, 76 | alignItems: 'center', 77 | justifyContent: 'center', 78 | width: 48, 79 | height: 48, 80 | }, 81 | selectedColor: { 82 | ...StyleSheet.absoluteFillObject, 83 | backgroundColor: 'rgba(0, 0, 0, 0.1)', 84 | justifyContent: 'center', 85 | alignItems: 'center', 86 | }, 87 | selectedText: { 88 | ...StyleSheet.absoluteFillObject, 89 | justifyContent: 'center', 90 | alignItems: 'center', 91 | }, 92 | }); 93 | -------------------------------------------------------------------------------- /src/components/products/options/ConfigurableProductOptions.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * @flow 3 | * Created by Dima Portenko on 16.02.2021 4 | */ 5 | import React from 'react'; 6 | import { View } from 'react-native'; 7 | import type { ConfigurableProductOptionsType } from '../../../apollo/queries/getProductDetails'; 8 | import type { 9 | HandleSelectConfigurableOption, 10 | SelectedConfigurableProductOptions, 11 | } from '../../../logic/products/useProductDetails'; 12 | import Text from 'react-native-ui-lib/text'; 13 | import { ConfigurableOptionValues } from './ConfigurableOptionValues'; 14 | 15 | type Props = { 16 | options: ConfigurableProductOptionsType[]; 17 | selectedConfigurableProductOptions: SelectedConfigurableProductOptions; 18 | handleSelectConfigurableOption: HandleSelectConfigurableOption; 19 | }; 20 | 21 | export const ConfigurableProductOptions = ({ 22 | options, 23 | selectedConfigurableProductOptions, 24 | handleSelectConfigurableOption, 25 | }: Props) => { 26 | const renderOption = (option: ConfigurableProductOptionsType) => { 27 | return ( 28 | 29 | {option.label} 30 | 36 | 37 | ); 38 | }; 39 | 40 | return ( 41 | 42 | {options.map(option => { 43 | return renderOption(option); 44 | })} 45 | 46 | ); 47 | }; 48 | -------------------------------------------------------------------------------- /src/logic/cart/useCart.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @flow 3 | * Created by Dima Portenko on 04.01.2021 4 | */ 5 | import React, { useState, useEffect } from 'react'; 6 | import { ApolloError, useMutation } from '@apollo/client'; 7 | import { showMessage } from 'react-native-flash-message'; 8 | import { CreateCartResponseType, CREATE_CART } from '../../apollo/mutations/createCart'; 9 | import { useDispatch, useSelector } from 'react-redux'; 10 | import { getCartId, setCartId } from '../../redux/cart'; 11 | import { 12 | ADD_PRODUCTS_TO_CART, 13 | AddProductsToCartResponseType, 14 | } from '../../apollo/mutations/addProductsToCart'; 15 | 16 | type Props = {}; 17 | 18 | type CartPayloadType = { 19 | sku: string; 20 | quantity: number; 21 | parent_sku?: string; 22 | }; 23 | 24 | type Result = { 25 | cartId: string | null; 26 | addToCart: (payload: CartPayloadType, name: string) => Promise; 27 | addProductLoading: boolean; 28 | }; 29 | 30 | export const useCart = (): Result => { 31 | const cartId = useSelector(getCartId); 32 | const dispatch = useDispatch(); 33 | 34 | const [fetchCartId] = useMutation(CREATE_CART); 35 | const [addProductsToCart, { loading: addProductLoading }] = useMutation< 36 | AddProductsToCartResponseType 37 | >(ADD_PRODUCTS_TO_CART); 38 | 39 | const createCart = async () => { 40 | try { 41 | const { data, errors } = await fetchCartId(); 42 | 43 | dispatch(setCartId(data?.cartId)); 44 | } catch (error) { 45 | console.log(error); 46 | } 47 | }; 48 | 49 | const addToCart = async (payload: CartPayloadType, name: string) => { 50 | try { 51 | const { data, errors } = await addProductsToCart({ 52 | variables: { 53 | cartId, 54 | ...payload, 55 | }, 56 | }); 57 | 58 | if (data && data.addProductsToCart.user_errors.length > 0) { 59 | showMessage({ 60 | message: 'Error', 61 | description: data.addProductsToCart.user_errors[0].message, 62 | type: 'danger', 63 | }); 64 | } else { 65 | showMessage({ 66 | message: 'Success', 67 | description: `${name} is added to the cart.`, 68 | type: 'success', 69 | }); 70 | } 71 | 72 | console.log(data, errors); 73 | } catch (error) { 74 | console.log(error); 75 | } 76 | }; 77 | 78 | useEffect(() => { 79 | if (!cartId) { 80 | createCart(); 81 | } 82 | }, []); // eslint-disable-line 83 | 84 | return { 85 | cartId, 86 | addProductLoading, 87 | addToCart, 88 | }; 89 | }; 90 | -------------------------------------------------------------------------------- /src/logic/cart/useCartDetails.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @flow 3 | * Created by Dima Portenko on 02.04.2021 4 | */ 5 | import React, { useEffect } from 'react'; 6 | import { useLazyQuery, useMutation } from '@apollo/client'; 7 | import { GET_CART_DETAILS, GetCartDetailsResponse } from '../../apollo/queries/getCartDetails'; 8 | import { useSelector } from 'react-redux'; 9 | import { getCartId } from '../../redux/cart'; 10 | import { useState } from 'react'; 11 | import { CartDetailItemType, CartDetailTotals } from '../../apollo/queries/cartItemsFragment'; 12 | import { 13 | ADD_PRODUCTS_TO_CART, 14 | AddProductsToCartResponseType, 15 | } from '../../apollo/mutations/addProductsToCart'; 16 | import { 17 | REMOVE_ITEM_FROM_CART, 18 | RemoveItemFromCartResponse, 19 | } from '../../apollo/mutations/removeItemFromCart'; 20 | import { showMessage } from 'react-native-flash-message'; 21 | 22 | interface Props {} 23 | 24 | type RemoveFromCartFunc = (itemUid: string) => Promise; 25 | 26 | interface Result { 27 | getCartDetails(): void; 28 | cartItems: CartDetailItemType[]; 29 | loading: boolean; 30 | removeItemLoading: boolean; 31 | totals: CartDetailTotals | null; 32 | removeFromCart: RemoveFromCartFunc; 33 | } 34 | 35 | export const useCartDetails = (): Result => { 36 | const cartId = useSelector(getCartId); 37 | const [cartItems, setCartItems] = useState([]); 38 | const [totals, setTotals] = useState(null); 39 | 40 | const [getCartDetails, responseObject] = useLazyQuery(GET_CART_DETAILS, { 41 | variables: { cartId }, 42 | fetchPolicy: 'cache-and-network', 43 | }); 44 | 45 | const [removeItemFromCart, { loading: removeItemLoading }] = useMutation< 46 | RemoveItemFromCartResponse 47 | >(REMOVE_ITEM_FROM_CART); 48 | 49 | const { data, loading, error } = responseObject; 50 | 51 | useEffect(() => { 52 | if (data) { 53 | setCartItems(data?.cart.items); 54 | setTotals(data?.cart.prices); 55 | } 56 | console.log('cart details data', data); 57 | console.log('cart details error', error); 58 | }, [data, error]); 59 | 60 | const removeFromCart: RemoveFromCartFunc = async (itemUid: string) => { 61 | try { 62 | const response = await removeItemFromCart({ 63 | variables: { 64 | cartId, 65 | cart_item_uid: itemUid, 66 | }, 67 | }); 68 | 69 | if (response.data) { 70 | setCartItems(response.data?.removeItemFromCart.cart.items); 71 | setTotals(response.data?.removeItemFromCart.cart.prices); 72 | } 73 | 74 | if (response.errors) { 75 | showMessage({ 76 | message: 'Error', 77 | description: response.errors?.[0].message, 78 | type: 'danger', 79 | }); 80 | } 81 | } catch (error) { 82 | console.log(error); 83 | } 84 | }; 85 | 86 | return { 87 | getCartDetails, 88 | cartItems, 89 | loading, 90 | removeItemLoading, 91 | totals, 92 | removeFromCart, 93 | }; 94 | }; 95 | -------------------------------------------------------------------------------- /src/logic/categories/useCategories.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @flow 3 | * Created by Dima Portenko on 10.10.2020 4 | */ 5 | import React, { useEffect, useState } from 'react'; 6 | import { useLazyQuery } from '@apollo/client'; 7 | import { GET_CATEGORIES } from '../../apollo/queries/getCategory'; 8 | import type { CategoryListType, CategoryType } from '../../apollo/queries/getCategory'; 9 | 10 | type Props = { 11 | categoryId: number; 12 | }; 13 | 14 | type Result = { 15 | getCategories(): void; 16 | categories: Array; 17 | loading: boolean; 18 | }; 19 | 20 | export const useCategories = (props: Props): Result => { 21 | const [categories, setCategories] = useState>([]); 22 | const [getCategories, { called, loading, data, error }] = useLazyQuery(GET_CATEGORIES, { 23 | variables: { id: props.categoryId }, 24 | }); 25 | 26 | useEffect(() => { 27 | if (data) { 28 | console.log({ data }); 29 | const list: CategoryListType = data; 30 | if (list.categoryList?.[0]?.children?.length > 0) { 31 | setCategories(list.categoryList?.[0]?.children); 32 | } 33 | } 34 | if (error) { 35 | console.log({ error }); 36 | } 37 | }, [data, error]); 38 | 39 | return { 40 | getCategories, 41 | categories, 42 | loading, 43 | }; 44 | }; 45 | -------------------------------------------------------------------------------- /src/logic/categories/useCategoryColors.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @flow 3 | * Created by Dima Portenko on 04.11.2020 4 | */ 5 | import React, { useState, useEffect } from 'react'; 6 | import { getCategoryColors } from '../../theme/colors'; 7 | 8 | type Props = {}; 9 | 10 | type Result = { 11 | getCategoryColorByIndex(index: number): string; 12 | }; 13 | 14 | export const useCategoryColors = (): Result => { 15 | const [colors, setColors] = useState([]); 16 | 17 | useEffect(() => { 18 | setColors(getCategoryColors()); 19 | }, []); 20 | 21 | const getCategoryColorByIndex = (index: number): string => { 22 | const colorIndex = index % colors.length; 23 | return colors[colorIndex]; 24 | }; 25 | 26 | return { 27 | getCategoryColorByIndex, 28 | }; 29 | }; 30 | -------------------------------------------------------------------------------- /src/logic/products/useCategoryProducts.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @flow 3 | * Created by Dima Portenko on 09.11.2020 4 | */ 5 | import React, { useState, useEffect } from 'react'; 6 | import { useLazyQuery } from '@apollo/client'; 7 | import { 8 | GET_CATEGORY_PRODUCTS, 9 | GetCategoryProductsType, 10 | ProductType, 11 | } from '../../apollo/queries/getCategoryProducts'; 12 | 13 | type Props = { 14 | categoryId: number; 15 | }; 16 | 17 | type Result = { 18 | products: Array; 19 | getCategoryProducts(): void; 20 | loading: boolean; 21 | refreshing: boolean; 22 | refresh(): void; 23 | loadMore(): void; 24 | }; 25 | 26 | const PAGE_SIZE = 10; 27 | 28 | export const useCategoryProducts = ({ categoryId }: Props): Result => { 29 | const [products, setProducts] = useState([]); 30 | const [currentPage, setCurrentPage] = useState(1); 31 | 32 | const [getCategoryProducts, queryResponse] = useLazyQuery( 33 | GET_CATEGORY_PRODUCTS, 34 | { 35 | variables: { id: categoryId, pageSize: PAGE_SIZE, currentPage }, 36 | }, 37 | ); 38 | const { loading, error, data } = queryResponse; 39 | 40 | useEffect(() => { 41 | if (!loading) { 42 | getCategoryProducts(); 43 | } 44 | }, [currentPage, getCategoryProducts]); // eslint-disable-line 45 | 46 | useEffect(() => { 47 | if (data?.products?.items && currentPage === 1) { 48 | setProducts(data?.products?.items); 49 | } else if ( 50 | data?.products?.items && 51 | products.length < data.products.total_count && 52 | products.length < currentPage * PAGE_SIZE 53 | ) { 54 | setProducts([...products, ...data?.products?.items]); 55 | } 56 | }, [data]); // eslint-disable-line 57 | 58 | const refresh = () => { 59 | if (currentPage !== 1) { 60 | setCurrentPage(1); 61 | } else { 62 | getCategoryProducts(); 63 | } 64 | }; 65 | 66 | const loadMore = () => { 67 | if (loading) { 68 | return; 69 | } 70 | 71 | if (currentPage * PAGE_SIZE === products.length) { 72 | setCurrentPage(currentPage + 1); 73 | } 74 | }; 75 | 76 | return { 77 | products, 78 | getCategoryProducts, 79 | loading, 80 | refreshing: loading, 81 | refresh, 82 | loadMore, 83 | }; 84 | }; 85 | -------------------------------------------------------------------------------- /src/logic/products/useProductDetails.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @flow 3 | * Created by Dima Portenko on 23.11.2020 4 | */ 5 | import React, { useState, useEffect } from 'react'; 6 | import { useLazyQuery } from '@apollo/client'; 7 | import { 8 | ConfigurableProductVariant, 9 | GET_PRODUCT_DETAILS, 10 | ProductDetailsResponseType, 11 | ProductDetailsType, 12 | } from '../../apollo/queries/getProductDetails'; 13 | import { useCart } from '../cart/useCart'; 14 | import { PriceRange } from '../../apollo/queries/getCategoryProducts'; 15 | import { MediaGalleryItemType } from '../../apollo/queries/mediaGalleryFragment'; 16 | 17 | export type SelectedConfigurableProductOptions = { [key: string]: number }; 18 | export type HandleSelectConfigurableOption = (optionCode: string, valueIndex: number) => void; 19 | 20 | type Props = { 21 | sku: string; 22 | }; 23 | 24 | type Result = { 25 | getProductDetails: () => void; 26 | loading: boolean; 27 | productData: ProductDetailsType | null | undefined; 28 | selectedConfigurableProductOptions: SelectedConfigurableProductOptions; 29 | handleSelectConfigurableOption: HandleSelectConfigurableOption; 30 | price: PriceRange | null; 31 | mediaGallery: MediaGalleryItemType[]; 32 | addProductLoading: boolean; 33 | addToCart(): void; 34 | }; 35 | 36 | const findSelectProductVariant = ( 37 | selectedConfigurableProductOptions: SelectedConfigurableProductOptions, 38 | productData: ProductDetailsType, 39 | ): ConfigurableProductVariant | null => { 40 | if (productData.__typename !== 'ConfigurableProduct') { 41 | return null; 42 | } 43 | let variants = productData.variants; 44 | Object.keys(selectedConfigurableProductOptions).forEach(code => { 45 | variants = variants.filter(variant => { 46 | const attribute = variant.attributes.find(attr => attr.code === code); 47 | return attribute?.value_index === selectedConfigurableProductOptions[code]; 48 | }); 49 | }); 50 | 51 | return variants?.[0]; 52 | }; 53 | 54 | export const useProductDetails = ({ sku }: Props): Result => { 55 | const [productData, setProductData] = useState(null); 56 | const [selectedConfigurableProductOptions, setSelectedConfigurableProductOptions] = useState< 57 | SelectedConfigurableProductOptions 58 | >({}); 59 | const [selectedVariant, setSelectedVariant] = useState(null); 60 | const [price, setPrice] = useState(null); 61 | const [mediaGallery, setMediaGallery] = useState([]); 62 | 63 | const { addToCart, addProductLoading } = useCart(); 64 | 65 | const [getProductDetailsQuery, responseObject] = useLazyQuery( 66 | GET_PRODUCT_DETAILS, 67 | { 68 | variables: { sku }, 69 | }, 70 | ); 71 | 72 | const { loading, data } = responseObject; 73 | 74 | const getProductDetails = () => { 75 | getProductDetailsQuery(); 76 | }; 77 | 78 | useEffect(() => { 79 | setProductData(data?.products?.items?.[0]); 80 | }, [data]); 81 | 82 | useEffect(() => { 83 | if (productData) { 84 | if (selectedVariant) { 85 | setPrice(selectedVariant.product.price_range); 86 | setMediaGallery([...selectedVariant.product.media_gallery, ...productData.media_gallery]); 87 | } else { 88 | setPrice(productData.price_range); 89 | setMediaGallery(productData.media_gallery); 90 | } 91 | } 92 | }, [selectedVariant, productData]); 93 | 94 | useEffect(() => { 95 | if (productData && Object.keys(selectedConfigurableProductOptions).length > 0) { 96 | const variant = findSelectProductVariant(selectedConfigurableProductOptions, productData); 97 | setSelectedVariant(variant); 98 | } 99 | }, [productData, selectedConfigurableProductOptions]); 100 | 101 | const handleSelectConfigurableOption: HandleSelectConfigurableOption = ( 102 | optionCode, 103 | valueIndex, 104 | ) => { 105 | setSelectedConfigurableProductOptions({ 106 | ...selectedConfigurableProductOptions, 107 | [optionCode]: valueIndex, 108 | }); 109 | }; 110 | 111 | const addProductToCart = () => { 112 | if (productData?.__typename === 'SimpleProduct') { 113 | addToCart( 114 | { 115 | sku: productData.sku, 116 | quantity: 1, 117 | }, 118 | productData.name, 119 | ); 120 | } else if (productData?.__typename === 'ConfigurableProduct' && selectedVariant) { 121 | addToCart( 122 | { 123 | parent_sku: productData.sku, 124 | sku: selectedVariant.product.sku, 125 | quantity: 1, 126 | }, 127 | productData.name, 128 | ); 129 | } 130 | }; 131 | 132 | return { 133 | getProductDetails, 134 | loading, 135 | productData, 136 | selectedConfigurableProductOptions, 137 | handleSelectConfigurableOption, 138 | price, 139 | mediaGallery, 140 | addToCart: addProductToCart, 141 | addProductLoading, 142 | }; 143 | }; 144 | -------------------------------------------------------------------------------- /src/logic/util/price.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @flow 3 | * Created by Dima Portenko on 06.12.2020 4 | */ 5 | import type { PriceRange } from '../../apollo/queries/getCategoryProducts'; 6 | 7 | const CURRENCY_SYMBOLS: { [key: string]: string | undefined } = { 8 | USD: '$', 9 | }; 10 | 11 | export const priceStringFromPriceRange = (priceRange: PriceRange | null) => { 12 | if (priceRange) { 13 | return `${getPriceString(priceRange.minimum_price.final_price)}`; 14 | } 15 | 16 | return ''; 17 | }; 18 | 19 | type PriceValue = { 20 | currency: string; 21 | value: number; 22 | }; 23 | 24 | export const getPriceString = (price?: PriceValue) => { 25 | const currencyName = price?.currency ?? ''; 26 | const currency = CURRENCY_SYMBOLS[currencyName] ?? price?.currency; 27 | return `${currency} ${price?.value}`; 28 | }; 29 | -------------------------------------------------------------------------------- /src/navigation/Navigation.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * @flow 3 | * Created by Dima Portenko on 06.10.2020 4 | */ 5 | import * as React from 'react'; 6 | import { NavigationContainer, RouteProp } from '@react-navigation/native'; 7 | import { createStackNavigator, StackNavigationProp } from '@react-navigation/stack'; 8 | import Icon from 'react-native-vector-icons/EvilIcons'; 9 | import { CategoriesScreen } from '../components/categories/CategoriesScreen'; 10 | import * as routes from './routes'; 11 | import { ProductListScreen } from '../components/products/ProductListScreen'; 12 | import { ProductDetailsScreen } from '../components/products/ProductDetailsScreen'; 13 | import { useCart } from '../logic/cart/useCart'; 14 | import { HeaderCartButton } from '../components/cart/HeaderCartButton'; 15 | import { CartDetailsScreen } from '../components/cart/CartDetailsScreen'; 16 | import { fonts } from '../theme/fonts'; 17 | import { CheckoutScreen } from '../components/checkout/CheckoutScreen'; 18 | 19 | export type RootStackParamList = { 20 | [routes.NAVIGATION_CATEGORIES_ROUTE]: { 21 | categoryId: number | undefined; 22 | title: string; 23 | }; 24 | [routes.NAVIGATION_PRODUCT_DETAILS_ROUTE]: { 25 | sku: string; 26 | title: string; 27 | }; 28 | [routes.NAVIGATION_PRODUCTS_ROUTE]: { 29 | categoryId: number; 30 | title: string; 31 | }; 32 | [routes.NAVIGATION_CART_DETAILS_ROUTE]: { 33 | title: string; 34 | }; 35 | [routes.NAVIGATION_CHECKOUT_ROUTE]: 36 | | { 37 | title: string; 38 | } 39 | | undefined; 40 | }; 41 | 42 | export type CategoriesScreenNavigationProp = StackNavigationProp< 43 | RootStackParamList, 44 | typeof routes.NAVIGATION_CATEGORIES_ROUTE 45 | >; 46 | 47 | export type CategoriesScreenRouteProp = RouteProp< 48 | RootStackParamList, 49 | typeof routes.NAVIGATION_CATEGORIES_ROUTE 50 | >; 51 | 52 | export type ProductListScreenNavigationProp = StackNavigationProp< 53 | RootStackParamList, 54 | typeof routes.NAVIGATION_PRODUCTS_ROUTE 55 | >; 56 | 57 | export type ProductListScreenRouteProp = RouteProp< 58 | RootStackParamList, 59 | typeof routes.NAVIGATION_PRODUCTS_ROUTE 60 | >; 61 | 62 | export type ProductDetailsScreenRouteProp = RouteProp< 63 | RootStackParamList, 64 | typeof routes.NAVIGATION_PRODUCT_DETAILS_ROUTE 65 | >; 66 | 67 | export type CartDetailsScreenNavigationProp = StackNavigationProp< 68 | RootStackParamList, 69 | typeof routes.NAVIGATION_CART_DETAILS_ROUTE 70 | >; 71 | 72 | const Stack = createStackNavigator(); 73 | 74 | const RootStack = () => { 75 | const { cartId } = useCart(); 76 | 77 | return ( 78 | ({ 80 | headerBackTitleVisible: false, 81 | headerTintColor: 'black', 82 | headerRight: () => , 83 | headerTitleStyle: { 84 | fontFamily: fonts.SourceSansProLight, 85 | fontSize: 24, 86 | fontWeight: '300', 87 | }, 88 | headerBackImage: () => , 89 | })}> 90 | ({ 94 | title: route?.params?.title ?? 'Categories', 95 | })} 96 | /> 97 | ({ 101 | title: route?.params?.title ?? 'Products', 102 | })} 103 | /> 104 | ({ 108 | title: route?.params?.title ?? 'Product Details', 109 | })} 110 | /> 111 | ({ 115 | title: 'Cart Details', 116 | headerRight: undefined, 117 | })} 118 | /> 119 | ({ 123 | title: 'Checkout', 124 | headerRight: undefined, 125 | })} 126 | /> 127 | 128 | ); 129 | }; 130 | 131 | export const Navigation = () => { 132 | return ( 133 | 134 | 135 | 136 | ); 137 | }; 138 | -------------------------------------------------------------------------------- /src/navigation/routes.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @flow 3 | * Created by Dima Portenko on 06.10.2020 4 | */ 5 | 6 | export const NAVIGATION_CATEGORIES_ROUTE = 'NAVIGATION_CATEGORIES_ROUTE'; 7 | export const NAVIGATION_PRODUCTS_ROUTE = 'NAVIGATION_PRODUCTS_ROUTE'; 8 | export const NAVIGATION_PRODUCT_DETAILS_ROUTE = 'NAVIGATION_PRODUCT_DETAILS_ROUTE'; 9 | export const NAVIGATION_CART_DETAILS_ROUTE = 'NAVIGATION_CART_DETAILS_ROUTE'; 10 | export const NAVIGATION_CHECKOUT_ROUTE = 'NAVIGATION_CHECKOUT_ROUTE'; 11 | -------------------------------------------------------------------------------- /src/redux/cart.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @flow 3 | * Created by Dima Portenko on 10.01.2021 4 | */ 5 | import { createSlice, createSelector } from '@reduxjs/toolkit'; 6 | import { StoreState } from './reducers'; 7 | 8 | export type CartReducerState = { 9 | cartId: string | null; 10 | }; 11 | 12 | const initialState: CartReducerState = { 13 | cartId: null, 14 | }; 15 | 16 | const cartSlice = createSlice({ 17 | name: 'cart', 18 | initialState, 19 | reducers: { 20 | setCartId(state, action?) { 21 | state.cartId = action.payload; 22 | }, 23 | }, 24 | }); 25 | 26 | export const { setCartId } = cartSlice.actions; 27 | 28 | export const getCartId = createSelector( 29 | (state: StoreState) => state.cart, 30 | cart => cart.cartId, 31 | ); 32 | 33 | export default cartSlice.reducer; 34 | -------------------------------------------------------------------------------- /src/redux/reducers.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @flow 3 | * Created by Dima Portenko on 10.01.2021 4 | */ 5 | import { combineReducers } from 'redux'; 6 | import cartReducer, { CartReducerState } from './cart'; 7 | 8 | export type StoreState = { 9 | cart: CartReducerState; 10 | }; 11 | 12 | export default combineReducers({ 13 | cart: cartReducer, 14 | }); 15 | -------------------------------------------------------------------------------- /src/redux/store.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @flow 3 | * Created by Dima Portenko on 10.01.2021 4 | */ 5 | import { configureStore, getDefaultMiddleware } from '@reduxjs/toolkit'; 6 | import { persistStore, persistReducer } from 'redux-persist'; 7 | import AsyncStorage from '@react-native-async-storage/async-storage'; 8 | 9 | import rootReducer from './reducers'; 10 | 11 | const persistConfig = { 12 | key: 'root', 13 | storage: AsyncStorage, 14 | }; 15 | 16 | const persistedReducer = persistReducer(persistConfig, rootReducer); 17 | 18 | export const store = configureStore({ 19 | reducer: persistedReducer, 20 | middleware: getDefaultMiddleware({ 21 | serializableCheck: false, 22 | }), 23 | }); 24 | 25 | export const persistor = persistStore(store); 26 | -------------------------------------------------------------------------------- /src/theme/colors.ts: -------------------------------------------------------------------------------- 1 | /** @flow */ 2 | 3 | const categoryColors = [ 4 | '#e5cabb', 5 | '#cb6442', 6 | '#ddb875', 7 | '#8d9969', 8 | '#7ab2c9', 9 | // '#27527a', 10 | '#ae8a95', 11 | ]; 12 | 13 | const shuffle = (array: Array): Array => array.sort(() => Math.random() - 0.5); 14 | 15 | export const getCategoryColors = (): string[] => shuffle(categoryColors); 16 | -------------------------------------------------------------------------------- /src/theme/fonts.ts: -------------------------------------------------------------------------------- 1 | export const fonts = { 2 | SourceSansProBlack: 'SourceSansPro-Black', 3 | SourceSansProBlackItalic: 'SourceSansPro-BlackItalic', 4 | SourceSansProBold: 'SourceSansPro-Bold', 5 | SourceSansProBoldItalic: 'SourceSansPro-BoldItalic', 6 | SourceSansProExtraLight: 'SourceSansPro-ExtraLight', 7 | SourceSansProExtraLightItalic: 'SourceSansPro-ExtraLightItalic', 8 | SourceSansProItalic: 'SourceSansPro-Italic', 9 | SourceSansProLight: 'SourceSansPro-Light', 10 | SourceSansProLightItalic: 'SourceSansPro-LightItalic', 11 | SourceSansProRegular: 'SourceSansPro-Regular', 12 | SourceSansProSemiBold: 'SourceSansPro-SemiBold', 13 | SourceSansProSemiBoldItalic: 'SourceSansPro-SemiBoldItalic', 14 | }; 15 | -------------------------------------------------------------------------------- /src/theme/index.ts: -------------------------------------------------------------------------------- 1 | import { Typography, ThemeManager } from 'react-native-ui-lib/core'; 2 | import { fonts } from './fonts'; 3 | 4 | export const initTheme = () => { 5 | Typography.loadTypographies({ 6 | black: { 7 | fontFamily: fonts.SourceSansProBlack, 8 | }, 9 | blackItalic: { 10 | fontFamily: fonts.SourceSansProBlackItalic, 11 | }, 12 | bold: { 13 | fontFamily: fonts.SourceSansProBold, 14 | }, 15 | boldItalic: { 16 | fontFamily: fonts.SourceSansProBoldItalic, 17 | }, 18 | extraLight: { 19 | fontFamily: fonts.SourceSansProExtraLight, 20 | }, 21 | extraLightItalic: { 22 | fontFamily: fonts.SourceSansProExtraLightItalic, 23 | }, 24 | italic: { 25 | fontFamily: fonts.SourceSansProItalic, 26 | }, 27 | light: { 28 | fontFamily: fonts.SourceSansProLight, 29 | }, 30 | lightItalic: { 31 | fontFamily: fonts.SourceSansProLightItalic, 32 | }, 33 | regular: { 34 | fontFamily: fonts.SourceSansProRegular, 35 | }, 36 | semiBold: { 37 | fontFamily: fonts.SourceSansProSemiBold, 38 | }, 39 | semiBoldItalic: { 40 | fontFamily: fonts.SourceSansProSemiBoldItalic, 41 | }, 42 | }); 43 | 44 | ThemeManager.setComponentTheme('Text', { 45 | regular: true, 46 | }); 47 | }; 48 | -------------------------------------------------------------------------------- /src/theme/shadows.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @flow 3 | * Created by Dima Portenko on 22.03.2021 4 | */ 5 | 6 | export const Shadows = { 7 | shadow70: { 8 | shadowColor: '#000', 9 | shadowOffset: { 10 | width: 0, 11 | height: 3, 12 | }, 13 | shadowOpacity: 0.29, 14 | shadowRadius: 4.65, 15 | 16 | elevation: 7, 17 | }, 18 | }; 19 | -------------------------------------------------------------------------------- /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 | "resolveJsonModule": true 14 | }, 15 | "exclude": [ 16 | "node_modules", 17 | "babel.config.js", 18 | "metro.config.js", 19 | "jest.config.js" 20 | ] 21 | } 22 | --------------------------------------------------------------------------------